diff --git a/src/cc/CCPrices.h b/src/cc/CCPrices.h index 633cc32e2..3dbe6a87c 100644 --- a/src/cc/CCPrices.h +++ b/src/cc/CCPrices.h @@ -18,7 +18,6 @@ #define CC_PRICES_H #include "CCinclude.h" -int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind); int32_t komodo_priceget(int64_t *buf64,int32_t ind,int32_t height,int32_t numblocks); #define PRICES_DAYWINDOW ((3600*24/ASSETCHAINS_BLOCKTIME) + 1) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 5b6d575f3..6ca6fa3bc 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -226,8 +226,8 @@ bool priv2addr(char *coinaddr,uint8_t buf33[33],uint8_t priv32[32]); CPubKey buf2pk(uint8_t *buf33); void endiancpy(uint8_t *dest,uint8_t *src,int32_t len); uint256 DiceHashEntropy(uint256 &entropy,uint256 _txidpriv,int32_t entropyvout,int32_t usevout); -CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk); -CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2); +CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk, const std::vector>* vData = NULL); +CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk,CPubKey pk2, const std::vector>* vData = NULL); CC *MakeCCcond1(uint8_t evalcode,CPubKey pk); CC *MakeCCcond1of2(uint8_t evalcode,CPubKey pk1,CPubKey pk2); CC* GetCryptoCondition(CScript const& scriptSig); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 55c93d7b3..a34bf1a81 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -58,20 +58,37 @@ CC *MakeCCcond1(uint8_t evalcode,CPubKey pk) return CCNewThreshold(2, {condCC, Sig}); } -CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue,CPubKey pk) +CTxOut MakeCC1vout(uint8_t evalcode,CAmount nValue, CPubKey pk, const std::vector>* vData) { CTxOut vout; CC *payoutCond = MakeCCcond1(evalcode,pk); vout = CTxOut(nValue,CCPubKey(payoutCond)); + if ( vData ) + { + std::vector> vtmpData = std::vector>(vData->begin(), vData->end()); + std::vector vPubKeys = std::vector(); + vPubKeys.push_back(pk); + COptCCParams ccp = COptCCParams(COptCCParams::VERSION, evalcode, 1, 1, vPubKeys, vtmpData); + vout.scriptPubKey << ccp.AsVector() << OP_DROP; + } cc_free(payoutCond); return(vout); } -CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2) +CTxOut MakeCC1of2vout(uint8_t evalcode,CAmount nValue,CPubKey pk1,CPubKey pk2, const std::vector>* vData) { CTxOut vout; CC *payoutCond = MakeCCcond1of2(evalcode,pk1,pk2); vout = CTxOut(nValue,CCPubKey(payoutCond)); + if ( vData ) + { + std::vector> vtmpData = std::vector>(vData->begin(), vData->end()); + std::vector vPubKeys = std::vector(); + vPubKeys.push_back(pk1); + vPubKeys.push_back(pk2); + COptCCParams ccp = COptCCParams(COptCCParams::VERSION, evalcode, 1, 2, vPubKeys, vtmpData); + vout.scriptPubKey << ccp.AsVector() << OP_DROP; + } cc_free(payoutCond); return(vout); } diff --git a/src/cc/customcc.cpp b/src/cc/customcc.cpp index 9f58c5c8b..2e174f510 100644 --- a/src/cc/customcc.cpp +++ b/src/cc/customcc.cpp @@ -11,7 +11,7 @@ */ CScript custom_opret(uint8_t funcid,CPubKey pk) -{ +{ CScript opret; uint8_t evalcode = EVAL_CUSTOM; opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk); return(opret); @@ -64,25 +64,54 @@ UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params) mypk = pubkey2pk(Mypubkey()); if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx { - mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk)); // make vout0 - // add opreturn, change is automatically added and tx is properly signed - rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,custom_opret('1',mypk)); + // make op_return payload as normal. + CScript opret = custom_opret('1',mypk); + std::vector> vData = std::vector>(); + vData.push_back(std::vector(opret.begin(), opret.end())); + // make vout0 with op_return included as payload. + mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk,&vData)); + fprintf(stderr, "vout size2.%li\n", mtx.vout.size()); + rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,CScript()); return(custom_rawtxresult(result,rawtx,broadcastflag)); } return(result); } +bool has_opret(const CTransaction &tx, uint8_t evalcode) +{ + for ( auto vout : tx.vout ) + { + if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[1] == evalcode ) + return true; + } + return false; +} + bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx) { char expectedaddress[64]; CPubKey pk; - if ( tx.vout.size() != 2 ) // make sure the tx only has 2 outputs + CScript opret; int32_t numvout; + if ( !has_opret(tx, EVAL_CUSTOM) ) + { + std::vector> vParams = std::vector>(); + CScript dummy; + if ( tx.vout[0].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() == 1 ) + { + opret << E_MARSHAL(ss << vParams[0]); + } + numvout = 1; + } + else + { + opret = tx.vout[1].scriptPubKey; + numvout = 2; + } + if ( tx.vout.size() != numvout ) // make sure the tx only has appropriate outputs return eval->Invalid("invalid number of vouts"); - else if ( custom_opretdecode(pk,tx.vout[1].scriptPubKey) != '1' ) // verify has opreturn + else if ( custom_opretdecode(pk,opret) != '1' ) // verify opreturn payload return eval->Invalid("invalid opreturn"); GetCCaddress(cp,expectedaddress,pk); if ( IsCClibvout(cp,tx,0,expectedaddress) == COIN ) // make sure amount and destination matches return(true); else return eval->Invalid("invalid vout0 amount"); } - - diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 5d164d97e..407cd81fa 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -320,8 +320,7 @@ int32_t prices_syntheticvec(std::vector &vec,std::vector int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t minmax,int16_t leverage) { - int32_t i,ind,errcode,depth,retval = -1; uint16_t opcode; int64_t *pricedata,pricestack[4],price,den,a,b,c; - pricedata = (int64_t *)calloc(sizeof(*pricedata)*3,1 + PRICES_DAYWINDOW*2 + PRICES_SMOOTHWIDTH); + int32_t i,ind,errcode,depth,retval = -1; uint16_t opcode; int64_t pricedata[PRICES_MAXDATAPOINTS],pricestack[4],price,den,a,b,c; price = den = depth = errcode = 0; for (i=0; i vec,int32_t height,int32_t m { case 0: pricestack[depth] = 0; - if ( prices_extract(pricedata,height,1,ind) == 0 ) + if ( komodo_priceget(pricedata,ind,height,1) > 0 ) { if ( minmax == 0 ) pricestack[depth] = pricedata[2]; @@ -420,7 +419,6 @@ int64_t prices_syntheticprice(std::vector vec,int32_t height,int32_t m if ( errcode != 0 ) break; } - free(pricedata); if ( den == 0 ) return(-11); else if ( depth != 0 ) diff --git a/src/komodo_defs.h b/src/komodo_defs.h index 4db390494..23a689154 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -85,6 +85,7 @@ void komodo_netevent(std::vector payload); #define KOMODO_KVDURATION 1440 #define KOMODO_KVBINARY 2 #define PRICES_SMOOTHWIDTH 1 +#define PRICES_MAXDATAPOINTS 8 uint64_t komodo_paxprice(uint64_t *seedp,int32_t height,char *base,char *rel,uint64_t basevolume); int32_t komodo_paxprices(int32_t *heights,uint64_t *prices,int32_t max,char *base,char *rel); int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp); diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index a6b5b4566..ed80c2a4a 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -1555,7 +1555,6 @@ extern std::vector Mineropret; // opreturn data set by the data gatheri #define KOMODO_LOCALPRICE_CACHESIZE 13 #define KOMODO_MAXPRICES 2048 #define PRICES_SMOOTHWIDTH 1 -#define PRICES_MAXDATAPOINTS 8 #define issue_curl(cmdstr) bitcoind_RPC(0,(char *)"CBCOINBASE",cmdstr,0,0,0) diff --git a/src/main.cpp b/src/main.cpp index e0e40c9a5..304ff52a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -796,7 +796,7 @@ bool IsStandardTx(const CTransaction& tx, string& reason, const int nHeight) else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) { reason = "bare-multisig"; return false; - } else if (txout.scriptPubKey.IsPayToCryptoCondition() == 0 && txout.IsDust(::minRelayTxFee)) { + } else if (whichType != TX_CRYPTOCONDITION && txout.IsDust(::minRelayTxFee)) { reason = "dust"; return false; } diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 18f7b0fc0..035d44662 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1156,7 +1156,7 @@ UniValue paxprice(const UniValue& params, bool fHelp) return ret; } -int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind) +/*int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks,int32_t ind) { int32_t height,i,n,width,numpricefeeds = -1; uint64_t seed,ignore,rngval; uint32_t rawprices[1440*6],*ptr; int64_t *tmpbuf; width = numblocks+PRICES_DAYWINDOW*2+PRICES_SMOOTHWIDTH; @@ -1188,14 +1188,14 @@ int32_t prices_extract(int64_t *pricedata,int32_t firstheight,int32_t numblocks, pricedata[i*3+2] = komodo_priceave(tmpbuf,&pricedata[i*3+1],3); free(tmpbuf); return(0); -} +}*/ UniValue prices(const UniValue& params, bool fHelp) { if ( fHelp || params.size() != 1 ) throw runtime_error("prices maxsamples\n"); LOCK(cs_main); - UniValue ret(UniValue::VOBJ); uint64_t seed,rngval; int64_t *tmpbuf,smoothed,*correlated; char name[64],*str; uint32_t rawprices[1440*6],*prices; uint32_t i,width,j,numpricefeeds=-1,n,numsamples,nextheight,offset,ht; + UniValue ret(UniValue::VOBJ); uint64_t seed,rngval; int64_t *tmpbuf,smoothed,*correlated,checkprices[PRICES_MAXDATAPOINTS]; char name[64],*str; uint32_t rawprices[1440*6],*prices; uint32_t i,width,j,numpricefeeds=-1,n,numsamples,nextheight,offset,ht; if ( ASSETCHAINS_CBOPRET == 0 ) throw JSONRPCError(RPC_INVALID_PARAMETER, "only -ac_cbopret chains have prices"); @@ -1255,13 +1255,30 @@ UniValue prices(const UniValue& params, bool fHelp) rngval = (rngval*11109 + 13849); if ( (correlated[i]= komodo_pricecorrelated(rngval,j,&prices[offset],1,0,PRICES_SMOOTHWIDTH)) < 0 ) throw JSONRPCError(RPC_INVALID_PARAMETER, "null correlated price"); - + { + if ( komodo_priceget(checkprices,j,nextheight-1-i,1) >= 0 ) + { + if ( checkprices[1] != correlated[i] ) + { + //fprintf(stderr,"ind.%d ht.%d %.8f != %.8f\n",j,nextheight-1-i,(double)checkprices[1]/COIN,(double)correlated[i]/COIN); + correlated[i] = checkprices[1]; + } + } + } } tmpbuf = (int64_t *)calloc(sizeof(int64_t),2*PRICES_DAYWINDOW); for (i=0; i= 0 ) + { + if ( checkprices[2] != smoothed ) + { + fprintf(stderr,"ind.%d ht.%d %.8f != %.8f\n",j,nextheight-1-i,(double)checkprices[2]/COIN,(double)smoothed/COIN); + smoothed = checkprices[2]; + } + } UniValue parr(UniValue::VARR); parr.push_back(ValueFromAmount((int64_t)prices[offset] * komodo_pricemult(j))); parr.push_back(ValueFromAmount(correlated[i]));