From e5907e31a6c0ceb8368e8af260c6ae903207100b Mon Sep 17 00:00:00 2001 From: Alrighttt Date: Sun, 5 May 2019 22:14:32 +0000 Subject: [PATCH 01/35] add oracles non-final oracle changes --- src/cc/oracles.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index ef457fe82..a5d61d404 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -935,13 +935,13 @@ UniValue OracleFormat(uint8_t *data,int32_t datalen,char *format,int32_t formatl if ( j >= datalen ) break; } - return(obj); + return(str); } UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid; - CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector data; char *formatstr = 0; + UniValue result(UniValue::VOBJ),b(UniValue::VARR); CTransaction tx,oracletx; uint256 hashBlock,btxid,oracletxid; + CPubKey pk; std::string name,description,format; int32_t numvouts,n=0; std::vector data; char str[67], *formatstr = 0; result.push_back(Pair("result","success")); if ( GetTransaction(reforacletxid,oracletx,hashBlock,false) != 0 && (numvouts=oracletx.vout.size()) > 0 ) @@ -954,15 +954,18 @@ UniValue OracleDataSamples(uint256 reforacletxid,uint256 batontxid,int32_t num) { if ( (formatstr= (char *)format.c_str()) == 0 ) formatstr = (char *)""; + UniValue a(UniValue::VARR); a.push_back(OracleFormat((uint8_t *)data.data(),(int32_t)data.size(),formatstr,(int32_t)format.size())); + a.push_back(uint256_str(str,batontxid)); + b.push_back(a); batontxid = btxid; - if ( ++n >= num ) + if ( ++n >= num && num != 0) break; } else break; } } } - result.push_back(Pair("samples",a)); + result.push_back(Pair("samples",b)); return(result); } From 6e7b2363be01eb7cb33d4322b2cb92964bdf60a7 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 12:13:17 +0800 Subject: [PATCH 02/35] undo stuff --- src/chain.h | 2 +- src/komodo_nk.h | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/chain.h b/src/chain.h index b893e3a06..ac60dc277 100644 --- a/src/chain.h +++ b/src/chain.h @@ -547,7 +547,7 @@ public: if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) { READWRITE(nSaplingValue); } - if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 ) + if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) )// && ASSETCHAINS_NOTARY_PAY[0] != 0 ) { READWRITE(nNotaryPay); READWRITE(segid); diff --git a/src/komodo_nk.h b/src/komodo_nk.h index 3c9034dde..708e8ba6c 100644 --- a/src/komodo_nk.h +++ b/src/komodo_nk.h @@ -1,7 +1,10 @@ #ifndef KOMODO_NK_H #define KOMODO_NK_H -#define ASSETCHAINS_N 96 -#define ASSETCHAINS_K 5 +#define ASSETCHAINS_N 77 +#define ASSETCHAINS_K 3 + +//#define ASSETCHAINS_N 95 +//#define ASSETCHAINS_K 5 #endif From ab6e923cfb58911f12975f56ad574284ea058ad2 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 6 May 2019 14:54:59 +0800 Subject: [PATCH 03/35] fixes --- src/cc/payments.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index eda1bdb41..12d5cff62 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -303,7 +303,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & pub2createtxid(temp); createtxid = Parseuint256(temp); } - printf("createtxid.%s\n",createtxid.ToString().c_str()); + //printf("createtxid.%s\n",createtxid.ToString().c_str()); // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) @@ -496,7 +496,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); return(eval->Invalid("vin is not paymentsCC type")); } - } + } else if ( fIsMerge && getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret) && opret.size() > 2 && DecodePaymentsMergeOpRet(opret,checktxid) == 'M' ) { mergeoffset = PAYMENTS_MERGEOFSET; @@ -514,7 +514,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("must have at least 2 vins to carry out merge")); else if ( i == dust+1 ) return(eval->Invalid("cannot merge only dust")); - } + } } else return(eval->Invalid("create transaction cannot decode")); } else return(eval->Invalid("Could not get contract transaction")); return(true); @@ -595,7 +595,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract } } } - if ( GetBalance == 3 ) // return elegible balance to be spent, and blocks left until min release can be released. + if ( GetBalance == 3 && totalinputs < minrelease ) // return elegible balance to be spent, and blocks left until min release can be released. { int64_t lockedblocks_balance = totalinputs; // inputs that can be spent already. // sort utxos by blocks until able to be spent, smallest at top. @@ -800,7 +800,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) return(result); } i = 0; - //for ( auto address : vAddressSnapshot ) if ( fixedAmount == 7 ) { // game setting, randomise bottom and top values @@ -846,7 +845,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) newamount = amount; int64_t totalamountsent = 0; mpz_t mpzAmount; mpz_init(mpzAmount); mpz_set_si(mpzAmount,amount); - fprintf(stderr, "m.%i\n",m); for (i=0; i txidoprets; + CPubKey Paymentspk,mypk,txidpk; uint256 createtxid,hashBlock; int64_t inputsum,totalallocations=0; CScript opret; CTransaction tx; char txidaddr[64],destaddr[64]; std::string rawtx; + int32_t n,lockedblocks,minrelease,top,bottom,minimum=10000,blocksleft; std::vector txidoprets; std::vector> excludeScriptPubKeys; // snapshot uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); @@ -1033,7 +1031,6 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); - //mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,txidpk,&vData)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); @@ -1364,12 +1361,9 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); funds = AddPaymentsInputs(false,2,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - //CCaddress_balance(fundsaddr,1); result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); GetCCaddress(cp,fundsopretaddr,Paymentspk); - // TODO: Shows balance for ALL payments plans, not just the one asked for! Needs to be reworked. fundsopret = AddPaymentsInputs(false,1,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); - //CCaddress_balance(fundsopretaddr,1); result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); // Blocks until minrelease can be released. From f5a234c45f85ad27d9c92a711e56caba82215bf1 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 7 May 2019 14:29:32 +0800 Subject: [PATCH 04/35] bug fixes paymentsinfo, getCCopret --- src/cc/CCutils.cpp | 2 +- src/cc/payments.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 363b54ad5..2d64e9a4f 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -64,7 +64,7 @@ int32_t has_opret(const CTransaction &tx, uint8_t evalcode) for ( auto vout : tx.vout ) { //fprintf(stderr, "[txid.%s] 1.%i 2.%i 3.%i 4.%i\n",tx.GetHash().GetHex().c_str(), vout.scriptPubKey[0], vout.scriptPubKey[1], vout.scriptPubKey[2], vout.scriptPubKey[3]); - if ( vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[2] == evalcode ) + if ( vout.scriptPubKey.size() > 2 && vout.scriptPubKey[0] == OP_RETURN && vout.scriptPubKey[2] == evalcode ) return i; i++; } diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 12d5cff62..498d9d014 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -595,7 +595,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract } } } - if ( GetBalance == 3 && totalinputs < minrelease ) // return elegible balance to be spent, and blocks left until min release can be released. + if ( GetBalance == 3 && totalinputs < minrelease*COIN ) // return elegible balance to be spent, and blocks left until min release can be released. { int64_t lockedblocks_balance = totalinputs; // inputs that can be spent already. // sort utxos by blocks until able to be spent, smallest at top. From 43142447041d2aa130f118004c023ffc2682eab0 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 17:42:58 +0800 Subject: [PATCH 05/35] prepare tokens airdrop --- src/cc/payments.cpp | 47 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index ce817ac0d..ecb302a8d 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -160,13 +160,7 @@ uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t & CScript EncodePaymentsSnapsShotOpRet(int32_t lockedblocks,int32_t minrelease,int32_t minimum,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - if ( (strcmp(ASSETCHAINS_SYMBOL, "CFEKPAY") == 0) ) // exempt for now, remove this after game completed. - { - minimum = 10000; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << top << bottom << fixedAmount << excludeScriptPubKeys); - } - else - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'S' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys); return(opret); } @@ -175,40 +169,27 @@ uint8_t DecodePaymentsSnapsShotOpRet(CScript scriptPubKey,int32_t &lockedblocks, std::vector vopret; uint8_t *script,e,f; GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); - if ( (strcmp(ASSETCHAINS_SYMBOL, "CFEKPAY") == 0) ) // exempt for now, remove this after game completed. + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) { - minimum = 10000; - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'S' ) - return(f); - } - } - else - { - - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys) != 0 ) - { - if ( e == EVAL_PAYMENTS && f == 'S' ) - return(f); - } + if ( e == EVAL_PAYMENTS && f == 'S' ) + return(f); } return(0); } -CScript EncodePaymentsTokensOpRet(int32_t lockedblocks,int32_t minrelease,int32_t top,std::vector> excludeScriptPubKeys, uint256 tokenid) +CScript EncodePaymentsTokensOpRet(int32_t lockedblocks,int32_t minrelease,int32_t minimum,int32_t top,int32_t bottom,int8_t fixedAmount,std::vector> excludeScriptPubKeys,uint256 tokenid) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; - opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'O' << lockedblocks << minrelease << top << excludeScriptPubKeys << tokenid); + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'O' << lockedblocks << minrelease << minimum << top << bottom << fixedAmount << excludeScriptPubKeys << tokenid); return(opret); } -uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &top,std::vector> &excludeScriptPubKeys, uint256 &tokenid) +uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &minimum,int32_t &top,int32_t &bottom,int8_t &fixedAmount,std::vector> &excludeScriptPubKeys, uint256 &tokenid) { std::vector vopret; uint8_t *script,e,f; GetOpReturnData(scriptPubKey, vopret); script = (uint8_t *)vopret.data(); - if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> top; ss >> excludeScriptPubKeys; ss >> tokenid) != 0 ) + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minimum; ss >> top; ; ss >> bottom; ss >> fixedAmount; ss >> excludeScriptPubKeys; ss >> tokenid) != 0 ) { if ( e == EVAL_PAYMENTS && f == 'O' ) return(f); @@ -308,7 +289,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(plantx.vout[plantx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid)) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) return(eval->Invalid("negative values")); @@ -703,7 +684,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { - if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid)) == 'O') ) + if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid)) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) ) { @@ -948,7 +929,7 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( n == 3 ) useopret = jint(jitem(params,2),0) != 0; - if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) + if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid createtxid")); @@ -1014,7 +995,7 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) { createtxid = payments_juint256(jitem(params,0)); txidpk = CCtxidaddr(txidaddr,createtxid); - if ( myGetTransaction(createtxid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 0) ) + if ( myGetTransaction(createtxid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); result.push_back(Pair("error","invalid createtxid")); @@ -1345,7 +1326,7 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) } result.push_back(Pair("excludeAddresses",a)); } - else if ( DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) != 0 ) + else if ( DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) != 0 ) { if ( lockedblocks < 0 || minrelease < 0 || top <= 0 ) { @@ -1416,7 +1397,7 @@ UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr) txid = it->first.txhash; if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 ) { - if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,top,excludeScriptPubKeys,tokenid) == 'O') ) + if ( tx.vout.size() > 0 && (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' || DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 'S' || DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 'O') ) { if ( lockedblocks < 0 || minrelease < 0 || (totalallocations <= 0 && top <= 0 ) || bottom < 0 || fixedAmount < 0 || minimum < 10000 ) { From 162694ad6a53c219bdfaf5848f8efdea8be6832b Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 17:48:21 +0800 Subject: [PATCH 06/35] fix pricesbet --- src/cc/prices.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 27529bca4..2116f2e8e 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -1380,15 +1380,6 @@ int64_t prices_enumaddedbets(uint256 &batontxid, std::vector &bets, // pricesbet rpc impl: make betting tx UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector synthetic) { - fprintf(stderr, "assetchains_contract.%i vs eval_prices.%i\n",ASSETCHAINS_EARLYTXIDCONTRACT, EVAL_PRICES); - if ( ASSETCHAINS_EARLYTXIDCONTRACT == EVAL_PRICES && KOMODO_EARLYTXID_SCRIPTPUB.size() == 0 ) - { - // Lock here, as in validation we cannot call lock in the function itself. - // may not be needed as the validation call to update the global, is called in a LOCK already, and it can only update there and here. - LOCK(cs_main); - GetKomodoEarlytxidScriptPub(); - } - /* int32_t nextheight = komodo_nextheight(); CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextheight); UniValue result(UniValue::VOBJ); struct CCcontract_info *cp, C; @@ -1439,7 +1430,6 @@ UniValue PricesBet(int64_t txfee, int64_t amount, int16_t leverage, std::vector< result.push_back(Pair("result", "error")); result.push_back(Pair("error", "not enough funds")); return(result); - */ } // pricesaddfunding rpc impl: add yet another bet From ffbb7a92f201e5b6d7a709e0d32c76e888392d2c Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 18:20:58 +0800 Subject: [PATCH 07/35] add utxos to paymentsinfo --- src/cc/payments.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index ecb302a8d..118342bc7 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -568,8 +568,10 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract if ( (GetBalance == 0 && total != 0 && maxinputs != 0) || GetBalance == 4 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); nValue = it->second.satoshis; - if ( nValue < COIN ) + if ( GetBalance == 4 && nValue < COIN ) blocksleft++; // count dust with unused variable. + if ( GetBalance == 2 || GetBalance == 1 ) + blocksleft++; // count all utxos with unused variable. totalinputs += nValue; n++; //fprintf(stderr,"iter.%d %s/v%d %s %.8f\n",iter,txid.GetHex().c_str(),vout,coinaddr,(double)nValue/COIN); @@ -1355,11 +1357,15 @@ UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk); + blocksleft = 0; funds = AddPaymentsInputs(false,2,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); result.push_back(Pair(fundsaddr,ValueFromAmount(funds))); + result.push_back(Pair("utxos", (int64_t)blocksleft)); + blocksleft = 0; GetCCaddress(cp,fundsopretaddr,Paymentspk); fundsopret = AddPaymentsInputs(false,1,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret))); + result.push_back(Pair("utxos", (int64_t)blocksleft)); result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret))); // Blocks until minrelease can be released. elegiblefunds = AddPaymentsInputs(true,3,cp,mtx,txidpk,0,CC_MAXVINS,createtxid,lockedblocks,minrelease,blocksleft); From 113d3c779fdd4adb068f0707005340d9d8e868de Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 19:18:10 +0800 Subject: [PATCH 08/35] tokens airdrop RPC --- src/cc/CCPayments.h | 1 + src/cc/payments.cpp | 81 ++++++++++++++++++++++++++++++++++++++++ src/rpc/server.cpp | 1 + src/rpc/server.h | 1 + src/wallet/rpcwallet.cpp | 13 +++++++ 5 files changed, 97 insertions(+) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index a7cd4f916..effa837f2 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -35,6 +35,7 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr); +UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr); UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr); diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 118342bc7..57e85f615 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -1241,6 +1241,87 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) return(result); } +UniValue PaymentsAirdropTokens(struct CCcontract_info *cp,char *jsonstr) +{ + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ); + uint256 hashBlock, tokenid = zeroid; CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::string rawtx; + int32_t lockedblocks,minrelease,top,bottom,n,i,minimum=10000; std::vector> excludeScriptPubKeys; int8_t fixedAmount; + cJSON *params = payments_reparse(&n,jsonstr); + if ( params != 0 && n >= 6 ) + { + tokenid = payments_juint256(jitem(params,0)); + lockedblocks = juint(jitem(params,1),0); + minrelease = juint(jitem(params,2),0); + minimum = juint(jitem(params,3),0); + if ( minimum < 10000 ) minimum = 10000; + top = juint(jitem(params,4),0); + bottom = juint(jitem(params,5),0); + fixedAmount = juint(jitem(params,6),0); // fixed amount is a flag, set to 7 does game mode, 0 normal snapshot, anything else fixed allocations. + if ( lockedblocks < 0 || minrelease < 0 || top <= 0 || bottom < 0 || minimum < 0 || fixedAmount < 0 || top > 3999 || tokenid == zeroid ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","negative parameter, or top over 3999")); + if ( params != 0 ) + free_json(params); + return(result); + } + // TODO: lookup tokenid and make sure it exists. + if ( n > 7 ) + { + for (i=0; i vscriptPubKey; + CScript scriptPubKey = GetScriptForDestination(destination); + vscriptPubKey.assign(scriptPubKey.begin(), scriptPubKey.end()); + excludeScriptPubKeys.push_back(vscriptPubKey); + } + } + mypk = pubkey2pk(Mypubkey()); + Paymentspk = GetUnspendable(cp,0); + if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 ) + { + mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk)); + CScript tempopret = EncodePaymentsTokensOpRet(lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid); + if ( tempopret.size() > 10000 ) // TODO: Check this! + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","op_return is too big, try with less exclude pubkeys.")); + if ( params != 0 ) + free_json(params); + return(result); + } + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,tempopret); + if ( params != 0 ) + free_json(params); + return(payments_rawtxresult(result,rawtx,0)); + } + result.push_back(Pair("result","error")); + result.push_back(Pair("error","not enough normal funds")); + } + else + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","parameters error")); + } + if ( params != 0 ) + free_json(params); + return(result); +} + UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,numoprets=0,lockedblocks,minrelease,blocksleft=0; std::vector txidoprets; int64_t funds,fundsopret,elegiblefunds,totalallocations=0,allocation; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index a41c7f413..c35647f8c 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -492,6 +492,7 @@ static const CRPCCommand vRPCCommands[] = { "payments", "paymentstxidopret", &payments_txidopret, true }, { "payments", "paymentscreate", &payments_create, true }, { "payments", "paymentsairdrop", &payments_airdrop, true }, + { "payments", "paymentsairdroptokens", &payments_airdroptokens, true }, { "payments", "paymentslist", &payments_list, true }, { "payments", "paymentsinfo", &payments_info, true }, { "payments", "paymentsfund", &payments_fund, true }, diff --git a/src/rpc/server.h b/src/rpc/server.h index d0882d6cb..c61f62dc3 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -292,6 +292,7 @@ extern UniValue payments_merge(const UniValue& params, bool fHelp); extern UniValue payments_txidopret(const UniValue& params, bool fHelp); extern UniValue payments_create(const UniValue& params, bool fHelp); extern UniValue payments_airdrop(const UniValue& params, bool fHelp); +extern UniValue payments_airdroptokens(const UniValue& params, bool fHelp); extern UniValue payments_info(const UniValue& params, bool fHelp); extern UniValue payments_list(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5ce7ae773..209ed034c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5656,6 +5656,19 @@ UniValue payments_airdrop(const UniValue& params, bool fHelp) return(PaymentsAirdrop(cp,(char *)params[0].get_str().c_str())); } +UniValue payments_airdroptokens(const UniValue& params, bool fHelp) +{ + struct CCcontract_info *cp,C; + if ( fHelp || params.size() != 1 ) + throw runtime_error("paymentsairdrop \"[%22tokenid%22,lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludePubKey%22,...,%22excludePubKeyN%22]\"\n"); + if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) + throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); + const CKeyStore& keystore = *pwalletMain; + LOCK2(cs_main, pwalletMain->cs_wallet); + cp = CCinit(&C,EVAL_PAYMENTS); + return(PaymentsAirdropTokens(cp,(char *)params[0].get_str().c_str())); +} + UniValue payments_info(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; From 46d997f3190312111f90b5a359a03b127aa9a11e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 22:04:33 +0800 Subject: [PATCH 09/35] fix --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 5203888de..82b95b146 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6503,7 +6503,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) blkdat.SetPos(nBlockPos); CBlock block; blkdat >> block; - nRewind = blkdat.GetPos(); + nRewind = blkdat.GetPos(); // detect out of order blocks, and store them for later uint256 hash = block.GetHash(); From 9d22819247541cdf329954750ba05cad7a9c6f2c Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 9 May 2019 22:09:34 +0800 Subject: [PATCH 10/35] try this --- src/cc/payments.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 57e85f615..5d6383c29 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -1108,6 +1108,7 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) for (i=0; i scriptPubKey,opret; int64_t allocation; + fprintf(stderr, "txid.%s\n",txidoprets[i].GetHex().c_str()); if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) { totalallocations += allocation; From 6f1f4413babd28a4993ced50d3d51d06fbb25a29 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 11 May 2019 16:25:27 +0800 Subject: [PATCH 11/35] fix payments release --- src/cc/payments.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 5d6383c29..a8630f25c 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -716,6 +716,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( funcid == 'C' ) { // normal payments + m = txidoprets.size(); for (i=0; i scriptPubKey,opret; @@ -1108,7 +1109,7 @@ UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr) for (i=0; i scriptPubKey,opret; int64_t allocation; - fprintf(stderr, "txid.%s\n",txidoprets[i].GetHex().c_str()); + //fprintf(stderr, "txid.%s\n",txidoprets[i].GetHex().c_str()); if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) { totalallocations += allocation; From f5f476ae5af2eee33445b9ad27812814e263e90d Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 11 May 2019 16:38:15 +0800 Subject: [PATCH 12/35] fix reindex --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 82b95b146..20354fd59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6469,7 +6469,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) try { // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor //CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION); - CBufferedFile blkdat(fileIn, 32*MAX_BLOCK_SIZE(10000000), MAX_BLOCK_SIZE(10000000)+8, SER_DISK, CLIENT_VERSION); + CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE(10000000), MAX_BLOCK_SIZE(10000000)+8, SER_DISK, CLIENT_VERSION); uint64_t nRewind = blkdat.GetPos(); while (!blkdat.eof()) { boost::this_thread::interruption_point(); From 462320cfaf2af75a532f144e21569568a7f6f1e6 Mon Sep 17 00:00:00 2001 From: Alrighttt <36680730+Alrighttt@users.noreply.github.com> Date: Sat, 11 May 2019 14:34:41 +0200 Subject: [PATCH 13/35] fix getaddresstxids help --- src/rpc/misc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 4ea6e94e3..41134e831 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1432,8 +1432,8 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) UniValue getaddresstxids(const UniValue& params, bool fHelp) { - if (fHelp || params.size() > 2) - throw runtime_error( + if (fHelp || params.size() > 2 || params.size() < 1) + throw runtime_error "getaddresstxids (ccvout)\n" "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n" "\nArguments:\n" From b489328ce87ff8ee517f961b92fb515c1850908c Mon Sep 17 00:00:00 2001 From: Alrighttt <36680730+Alrighttt@users.noreply.github.com> Date: Sat, 11 May 2019 14:35:51 +0200 Subject: [PATCH 14/35] syntax --- src/rpc/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 41134e831..4f296174f 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1433,7 +1433,7 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) UniValue getaddresstxids(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2 || params.size() < 1) - throw runtime_error + throw runtime_error( "getaddresstxids (ccvout)\n" "\nReturns the txids for an address(es) (requires addressindex to be enabled).\n" "\nArguments:\n" From fb9320dfbb7da5429ba82ac3b8f82b4940b6f4eb Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 13 May 2019 15:54:15 +0800 Subject: [PATCH 15/35] fix payments allocation for alright --- src/cc/payments.cpp | 3 ++- src/rpc/misc.cpp | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index a8630f25c..63e9f4681 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -426,8 +426,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & test = mpz_get_si(mpzAllocation); mpz_clear(mpzAllocation); } + //fprintf(stderr, "vout %i test.%li nValue.%li\n", i, test, tx.vout[i].nValue); // Vairance of 1 sat is allowed, for rounding errors. - if ( test >= tx.vout[i].nValue+1 && test <= tx.vout[i].nValue-1 ) + if ( test > tx.vout[i].nValue+1 || test < tx.vout[i].nValue-1 ) { fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); return(eval->Invalid("amounts do not match")); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 4ea6e94e3..058cd0241 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1383,9 +1383,13 @@ UniValue getsnapshot(const UniValue& params, bool fHelp) if (params.size() > 0 && !params[0].isNull()) { top = atoi(params[0].get_str().c_str()); - if (top < 0) - //throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer"); - top = -1; + if ( top < 0 ) + { + if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, top must be a positive integer"); + else + top = -1; + } } if ( fHelp || params.size() > 1) From 93c37122444fbe46b991f70948cdc139469a013e Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 13 May 2019 18:35:28 +0800 Subject: [PATCH 16/35] Try to fix allocations --- src/cc/CCinclude.h | 2 +- src/cc/CCutils.cpp | 7 +++-- src/cc/payments.cpp | 71 ++++++++++++++++++++++++++++++--------------- src/cc/rewards.cpp | 3 +- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 75d804df5..3681cf2f3 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -251,7 +251,7 @@ void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, c int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode); bool IsCCInput(CScript const& scriptSig); -bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime); +bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime,int64_t &actualtxfee); int32_t unstringbits(char *buf,uint64_t bits); uint64_t stringbits(char *str); uint256 revuint256(uint256 txid); diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 023858dc2..1b326b85f 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -150,7 +150,7 @@ bool IsCCInput(CScript const& scriptSig) return true; } -bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime) +bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_t blocktime, int64_t &actualtxfee) { LOCK(mempool.cs); CCoinsView dummy; @@ -159,9 +159,10 @@ bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_ CCoinsViewMemPool viewMemPool(pcoinsTip, mempool); view.SetBackend(viewMemPool); valuein = view.GetValueIn(height,&interest,tx,blocktime); - if ( valuein-tx.GetValueOut() > txfee ) + actualtxfee = valuein-tx.GetValueOut(); + if ( actualtxfee > txfee ) { - //fprintf(stderr, "txfee.%li vs txfee.%li\n", valuein-tx.GetValueOut(), txfee); + fprintf(stderr, "actualtxfee.%li vs txfee.%li\n", actualtxfee, txfee); return false; } return true; diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 63e9f4681..2141f77ee 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -261,9 +261,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // only 'F' or 1of2 txidaddr can be spent // all vouts must match exactly char temp[128], coinaddr[64]={0}, txidaddr[64]; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; - int32_t i,lockedblocks,minrelease; int64_t change,totalallocations; std::vector txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; + int32_t i,lockedblocks,minrelease; int64_t change,totalallocations,actualtxfee; std::vector txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; int32_t top,bottom=0,minimum=10000; std::vector> excludeScriptPubKeys; bool fFixedAmount = false; CScript ccopret; - mpz_t mpzTotalAllocations, mpzAllocation;; mpz_init(mpzTotalAllocations); + mpz_t mpzTotalAllocations,mpzAllocation; mpz_init(mpzTotalAllocations); // user marker vout to get the createtxid if ( tx.vout.size() == 1 ) { @@ -299,7 +299,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); - if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) + if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, actualtxfee) ) return eval->Invalid("txfee is too high"); // make sure change is in vout 0 and is paying to the contract address. if ( (change= IsPaymentsvout(cp,tx,0,coinaddr,ccopret)) == 0 ) @@ -385,8 +385,10 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! break; } - if ( i != tx.vout.size()-2 ) - return(eval->Invalid("pays wrong amount of recipients")); + + // need to check this later on as less can now be paid. + //if ( i != tx.vout.size()-2 ) + // return(eval->Invalid("pays wrong amount of recipients")); } else if ( funcid == 'O' ) { @@ -403,7 +405,8 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // Check vouts go to the right place and pay the right amounts. int64_t amount = 0, checkamount; int32_t n = 0; - checkamount = tx.GetValueOut() - change - PAYMENTS_TXFEE; + checkamount = tx.GetValueOut() - change - actualtxfee; //PAYMENTS_TXFEE; + fprintf(stderr, "totalvalueout.%li change.%li txfee.%li checkamount.%li\n",tx.GetValueOut(), change, actualtxfee, checkamount); mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) { @@ -422,12 +425,12 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & mpz_init(mpzAllocation); mpz_set_si(mpzAllocation,allocations[n]); mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_cdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); + mpz_tdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); test = mpz_get_si(mpzAllocation); mpz_clear(mpzAllocation); } //fprintf(stderr, "vout %i test.%li nValue.%li\n", i, test, tx.vout[i].nValue); - // Vairance of 1 sat is allowed, for rounding errors. + // I cant fix this! I dont understand the rouncing errors sorry. if ( test > tx.vout[i].nValue+1 || test < tx.vout[i].nValue-1 ) { fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); @@ -441,7 +444,18 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & amount += tx.vout[i].nValue; n++; } - mpz_clear(mpzTotalAllocations); + if ( allocations.size() > n ) + { + // need to check that the next allocation was less than 10k sat, otherwise ppl can truncate the tx at any place. + mpz_init(mpzAllocation); + mpz_set_si(mpzAllocation,allocations[n+1]); + mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); + mpz_tdiv_q (mpzAllocation,mpzAllocation,mpzTotalAllocations); + int64_t test = mpz_get_si(mpzAllocation); + if ( test > minimum+1 ) + return(eval->Invalid("next allocation was not under minimum")); + } + mpz_clear(mpzTotalAllocations); mpz_clear(mpzCheckamount); // This is a backup check to make sure there are no extra vouts paying something else! if ( checkamount != amount ) return(eval->Invalid("amounts do not match")); @@ -672,19 +686,20 @@ int32_t payments_parsehexdata(std::vector &hexdata,cJSON *item,int32_t UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { - int32_t nextheight = komodo_nextheight(); - //int32_t latestheight,nextheight = komodo_nextheight(); - CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; + LOCK(cs_main); + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight()); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; - int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0; bool fFixedAmount = false; + int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0,skipminimum=0; bool fFixedAmount = false; mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); - if ( params != 0 && n == 2 ) + if ( params != 0 && n >= 2 ) { createtxid = payments_juint256(jitem(params,0)); amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; + if ( n == 3 ) + skipminimum = juint(jitem(params,2),0); if ( myGetTransaction(createtxid,tx,hashBlock) != 0 && tx.vout.size() > 0 ) { if ( ((funcid= DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets)) == 'C' || (funcid= DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys)) == 'S' || (funcid= DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid)) == 'O') ) @@ -700,7 +715,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) // set minimum size to 10k sat otherwise the tx will be invalid. if ( minimum < 10000 ) minimum = 10000; - //latestheight = (nextheight - lockedblocks - 1); if ( amount < minrelease*COIN ) { result.push_back(Pair("result","error")); @@ -845,7 +859,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { mpz_set_si(mpzValue,mtx.vout[i+1].nValue); mpz_mul(mpzValue,mpzValue,mpzAmount); - mpz_cdiv_q(mpzValue,mpzValue,mpzTotalAllocations); + mpz_tdiv_q(mpzValue,mpzValue,mpzTotalAllocations); if ( mpz_fits_slong_p(mpzValue) ) mtx.vout[i+1].nValue = mpz_get_si(mpzValue); else @@ -861,16 +875,24 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) mpz_clear(mpzValue); if ( mtx.vout[i+1].nValue < minimum ) { - result.push_back(Pair("result","error")); - result.push_back(Pair("error","value too small, try releasing a larger amount")); - if ( params != 0 ) - free_json(params); - return(result); + if ( skipminimum == 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","value too small, try releasing a larger amount")); + if ( params != 0 ) + free_json(params); + return(result); + } + else + { + // truncate off any vouts that are less than minimum. + mtx.vout.resize(i); + break; + } } totalamountsent += mtx.vout[i+1].nValue; } if ( totalamountsent < amount ) newamount = totalamountsent; - fprintf(stderr, "newamount.%li totalamountsent.%li\n", newamount, totalamountsent); mpz_clear(mpzAmount); mpz_clear(mpzTotalAllocations); } else @@ -884,8 +906,9 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( (inputsum= AddPaymentsInputs(true,0,cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,lockedblocks,minrelease,blocksleft)) >= newamount+2*PAYMENTS_TXFEE ) { std::string rawtx; - if ( (CCchange= (inputsum - newamount - 2*PAYMENTS_TXFEE)) >= PAYMENTS_TXFEE ) - mtx.vout[0].nValue = CCchange; + fprintf(stderr, "inputsum.%li - newamount.%li = ",inputsum,newamount); + mtx.vout[0].nValue = inputsum - newamount - 2*PAYMENTS_TXFEE; + fprintf(stderr, "change.%li\n", mtx.vout[0].nValue); mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 5ca2b038a..2edd275ec 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -195,6 +195,7 @@ bool RewardsExactAmounts(struct CCcontract_info *cp,Eval *eval,const CTransactio bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { uint256 txid,fundingtxid,hashBlock,vinfundingtxid; uint64_t vinsbits,sbits,APR,minseconds,maxseconds,mindeposit,amount,reward,txfee=10000; int32_t numvins,numvouts,preventCCvins,preventCCvouts,i; uint8_t funcid; CScript scriptPubKey; CTransaction fundingTx,vinTx; + int64_t dummy; numvins = tx.vin.size(); numvouts = tx.vout.size(); preventCCvins = preventCCvouts = -1; @@ -255,7 +256,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t if ( (*cp->ismyvin)(tx.vin[i].scriptSig) == 0 ) return eval->Invalid("unexpected normal vin for unlock"); } - if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime) ) + if ( !CheckTxFee(tx, txfee, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, dummy) ) return eval->Invalid("txfee is too high"); amount = vinTx.vout[0].nValue; reward = RewardsCalc(amount,tx.vin[0].prevout.hash,APR,minseconds,maxseconds,mindeposit); From 9b35a646936240b6df11ccd197fa2f1aefe240ec Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Mon, 13 May 2019 20:44:42 +0800 Subject: [PATCH 17/35] prints --- src/cc/payments.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 2141f77ee..954d2b93a 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -405,8 +405,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & // Check vouts go to the right place and pay the right amounts. int64_t amount = 0, checkamount; int32_t n = 0; - checkamount = tx.GetValueOut() - change - actualtxfee; //PAYMENTS_TXFEE; - fprintf(stderr, "totalvalueout.%li change.%li txfee.%li checkamount.%li\n",tx.GetValueOut(), change, actualtxfee, checkamount); + checkamount = tx.GetValueOut() - change - actualtxfee - PAYMENTS_TXFEE; + int64_t temptst = mpz_get_si(mpzTotalAllocations); + fprintf(stderr, "validation checkamount.%li totalallocations.%li\n",checkamount,temptst); mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) { @@ -893,6 +894,8 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) totalamountsent += mtx.vout[i+1].nValue; } if ( totalamountsent < amount ) newamount = totalamountsent; + int64_t temptst = mpz_get_si(mpzTotalAllocations); + fprintf(stderr, "checkamount RPC.%li totalallocations.%li\n",totalamountsent, temptst); mpz_clear(mpzAmount); mpz_clear(mpzTotalAllocations); } else @@ -906,9 +909,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( (inputsum= AddPaymentsInputs(true,0,cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,lockedblocks,minrelease,blocksleft)) >= newamount+2*PAYMENTS_TXFEE ) { std::string rawtx; - fprintf(stderr, "inputsum.%li - newamount.%li = ",inputsum,newamount); mtx.vout[0].nValue = inputsum - newamount - 2*PAYMENTS_TXFEE; - fprintf(stderr, "change.%li\n", mtx.vout[0].nValue); mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); From 030f99652a7fca92194290a964b3e853ff2498a5 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 14 May 2019 06:21:50 +0800 Subject: [PATCH 18/35] Fix paymentsCC, add skipminimum to validation and paymentsrelease --- src/cc/CCPayments.h | 2 +- src/cc/payments.cpp | 288 +++++++++++++++++++-------------------- src/wallet/rpcwallet.cpp | 2 +- 3 files changed, 140 insertions(+), 152 deletions(-) diff --git a/src/cc/CCPayments.h b/src/cc/CCPayments.h index effa837f2..ac5f22c47 100644 --- a/src/cc/CCPayments.h +++ b/src/cc/CCPayments.h @@ -22,7 +22,7 @@ #include #define PAYMENTS_TXFEE 10000 -#define PAYMENTS_MERGEOFSET 10 // 100? +#define PAYMENTS_MERGEOFSET 60 // 1H extra. extern std::vector > vAddressSnapshot; extern int32_t lastSnapShotHeight; diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 954d2b93a..528e6ec7f 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -137,6 +137,26 @@ uint8_t DecodePaymentsMergeOpRet(CScript scriptPubKey,uint256 &checktxid) return(0); } +CScript EncodePaymentsReleaseOpRet(uint256 checktxid, int64_t amountReleased) +{ + CScript opret; uint8_t evalcode = EVAL_PAYMENTS; + opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'R' << checktxid << amountReleased); + return(opret); +} + +uint8_t DecodePaymentsReleaseOpRet(CScript scriptPubKey,uint256 &checktxid,int64_t &amountReleased) +{ + std::vector vopret; uint8_t *script,e,f; + GetOpReturnData(scriptPubKey, vopret); + script = (uint8_t *)vopret.data(); + if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid; ss >> amountReleased) != 0 ) + { + if ( e == EVAL_PAYMENTS && f == 'R' ) + return(f); + } + return(0); +} + CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int64_t totalallocations,std::vector txidoprets) { CScript opret; uint8_t evalcode = EVAL_PAYMENTS; @@ -200,7 +220,6 @@ uint8_t DecodePaymentsTokensOpRet(CScript scriptPubKey,int32_t &lockedblocks,int int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr, CScript &ccopret) { char destaddr[64]; - //if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) if ( getCCopret(tx.vout[v].scriptPubKey, ccopret) ) { if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && (cmpaddr[0] == 0 || strcmp(destaddr,cmpaddr) == 0) ) @@ -209,22 +228,6 @@ int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t return(0); } -void pub2createtxid(char *str) -{ - int i,n; - char *rev; - n = (int32_t)strlen(str); - rev = (char *)malloc(n + 1); - for (i=0; i txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; - int32_t top,bottom=0,minimum=10000; std::vector> excludeScriptPubKeys; bool fFixedAmount = false; CScript ccopret; - mpz_t mpzTotalAllocations,mpzAllocation; mpz_init(mpzTotalAllocations); - // user marker vout to get the createtxid - if ( tx.vout.size() == 1 ) + char temp[128], txidaddr[64]={0}; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; + int32_t i,lockedblocks,minrelease,blocksleft,dust = 0, top,bottom=0,minimum=10000; int64_t change,totalallocations,actualtxfee,amountReleased=0; std::vector txidoprets; bool fHasOpret = false,fIsMerge = false; CPubKey txidpk,Paymentspk; + std::vector> excludeScriptPubKeys; bool fFixedAmount = false; CScript ccopret; + mpz_t mpzTotalAllocations,mpzAllocation,mpzCheckamount; + mpz_init(mpzCheckamount); mpz_init(mpzTotalAllocations); + // Check change is in vout[0], and also fetch the ccopret to determine what type of tx this is. txidaddr is unknown, recheck this later. + if ( (change= IsPaymentsvout(cp,tx,0,txidaddr,ccopret)) != 0 && ccopret.size() > 2 ) { - if ( IsPaymentsvout(cp,tx,0,coinaddr,ccopret) != 0 && ccopret.size() > 2 && DecodePaymentsMergeOpRet(ccopret,createtxid) ) - { + // get the checktxid and the amount released if doing release tx. + if ( DecodePaymentsMergeOpRet(ccopret,createtxid) == 'M' ) fIsMerge = true; - } else return(eval->Invalid("not enough vouts")); - } - else if ( tx.vout.back().scriptPubKey[0] == OP_RETURN ) - { - scriptpubkey = HexStr(tx.vout[tx.vout.size()-2].scriptPubKey.begin()+2, tx.vout[tx.vout.size()-2].scriptPubKey.end()-1); - fHasOpret = true; - } - else scriptpubkey = HexStr(tx.vout[tx.vout.size()-1].scriptPubKey.begin()+2,tx.vout[tx.vout.size()-1].scriptPubKey.end()-1); - if ( !fIsMerge ) - { - strcpy(temp, scriptpubkey.c_str()); - pub2createtxid(temp); - createtxid = Parseuint256(temp); - } - //printf("createtxid.%s\n",createtxid.ToString().c_str()); + else if ( DecodePaymentsReleaseOpRet(ccopret,createtxid,amountReleased) != 'R' ) + return(eval->Invalid("could not decode ccopret")); + mpz_set_si(mpzCheckamount,amountReleased); + } else return(eval->Invalid("could not decode ccopret")); // use the createtxid to fetch the tx and all of the plans info. if ( myGetTransaction(createtxid,plantx,blockhash) != 0 && plantx.vout.size() > 0 ) @@ -295,27 +283,32 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("negative values")); if ( minimum < 10000 ) return(eval->Invalid("minimum must be over 10000")); + if ( amountReleased < minrelease*COIN ) + { + fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amountReleased, (int64_t)minrelease*COIN); + return(eval->Invalid("amount is too small")); + } Paymentspk = GetUnspendable(cp,0); txidpk = CCtxidaddr(txidaddr,createtxid); - GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk); + GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); //fprintf(stderr, "lockedblocks.%i minrelease.%i totalallocations.%i txidopret1.%s txidopret2.%s\n",lockedblocks, minrelease, totalallocations, txidoprets[0].ToString().c_str(), txidoprets[1].ToString().c_str() ); if ( !CheckTxFee(tx, PAYMENTS_TXFEE+1, chainActive.LastTip()->GetHeight(), chainActive.LastTip()->nTime, actualtxfee) ) return eval->Invalid("txfee is too high"); - // make sure change is in vout 0 and is paying to the contract address. - if ( (change= IsPaymentsvout(cp,tx,0,coinaddr,ccopret)) == 0 ) - return(eval->Invalid("change is in wrong vout or is wrong tx type")); - + // Check that the change vout is playing the txid address. + if ( IsPaymentsvout(cp,tx,0,txidaddr,ccopret) == 0 ) + return eval->Invalid("change pays wrong address"); + if ( !fIsMerge ) { // Get all the script pubkeys and allocations std::vector allocations; std::vector scriptPubKeys; - int64_t checkallocations = 0; i = 0; if ( funcid == 'C' ) { // normal payment - for (const uint256& txidopret : txidoprets) + int64_t checkallocations = 0; + for ( auto txidopret : txidoprets) { CTransaction tx0; std::vector scriptPubKey,opret; int64_t allocation; if ( myGetTransaction(txidopret,tx0,blockhash) != 0 && tx0.vout.size() > 1 && DecodePaymentsTxidOpRet(tx0.vout[tx0.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' ) @@ -341,10 +334,14 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & } i++; } + //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); + if ( totalallocations != checkallocations ) + return(eval->Invalid("allocation missmatch")); mpz_set_si(mpzTotalAllocations,totalallocations); } else if ( funcid == 'S' ) { + // snapshot payment if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) return(eval->Invalid("snapshots not activated on this chain")); if ( vAddressSnapshot.size() == 0 ) @@ -363,14 +360,13 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) { auto &address = vAddressSnapshot[j]; - CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; + CScript scriptPubKey = GetScriptForDestination(address.second); + bool skip = false; + // skip excluded addresses. for ( auto skipkey : excludeScriptPubKeys ) { if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) - { skip = true; - //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); - } } if ( !skip ) { @@ -382,13 +378,9 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); mpz_clear(mpzAllocation); } - if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! - break; + if ( i+bottom == top ) + break; // we reached top amount to pay, it can be less than this, if less address exist on chain. } - - // need to check this later on as less can now be paid. - //if ( i != tx.vout.size()-2 ) - // return(eval->Invalid("pays wrong amount of recipients")); } else if ( funcid == 'O' ) { @@ -398,28 +390,25 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) return(eval->Invalid("missing data cannot validate")); - - //fprintf(stderr, "totalallocations.%li checkallocations.%li\n",totalallocations, checkallocations); - if ( funcid == 'C' && totalallocations != checkallocations ) // only check for normal payments release. - return(eval->Invalid("allocation missmatch")); // Check vouts go to the right place and pay the right amounts. - int64_t amount = 0, checkamount; int32_t n = 0; - checkamount = tx.GetValueOut() - change - actualtxfee - PAYMENTS_TXFEE; - int64_t temptst = mpz_get_si(mpzTotalAllocations); - fprintf(stderr, "validation checkamount.%li totalallocations.%li\n",checkamount,temptst); - mpz_t mpzCheckamount; mpz_init(mpzCheckamount); mpz_set_si(mpzCheckamount,checkamount); - for (i = 1; i < (fHasOpret ? tx.vout.size()-2 : tx.vout.size()-1); i++) + int64_t amount = 0; int32_t n = 0; + // We place amount released into ccopret, so that these calcualtion are accurate! + // If you change the amount released in the RPC these calcs will be wrong, and validation will fail. + for (i = 1; i < (fHasOpret ? tx.vout.size()-1 : tx.vout.size()); i++) { + int64_t test; if ( scriptPubKeys[n] != tx.vout[i].scriptPubKey ) { fprintf(stderr, "pays wrong destination destscriptPubKey.%s voutscriptPubKey.%s\n", HexStr(scriptPubKeys[n].begin(),scriptPubKeys[n].end()).c_str(), HexStr(tx.vout[i].scriptPubKey.begin(),tx.vout[i].scriptPubKey.end()).c_str()); return(eval->Invalid("pays wrong address")); } - int64_t test; if ( fFixedAmount ) { - test = checkamount / (top-bottom); + if ( (top-bottom) > 0 ) + test = amountReleased / (top-bottom); + else + return(eval->Invalid("top/bottom range is illegal")); } else { @@ -431,14 +420,14 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & mpz_clear(mpzAllocation); } //fprintf(stderr, "vout %i test.%li nValue.%li\n", i, test, tx.vout[i].nValue); - // I cant fix this! I dont understand the rouncing errors sorry. - if ( test > tx.vout[i].nValue+1 || test < tx.vout[i].nValue-1 ) + if ( test != tx.vout[i].nValue ) { fprintf(stderr, "vout.%i test.%li vs nVlaue.%li\n",i, test, tx.vout[i].nValue); return(eval->Invalid("amounts do not match")); } if ( test < minimum ) { + // prevent anyone being paid the minimum. fprintf(stderr, "vout.%i test.%li vs minimum.%i\n",i, test, minimum); return(eval->Invalid("under minimum size")); } @@ -447,61 +436,57 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & } if ( allocations.size() > n ) { - // need to check that the next allocation was less than 10k sat, otherwise ppl can truncate the tx at any place. + // need to check that the next allocation was less than minimum, otherwise ppl can truncate the tx at any place not paying all elegible addresses. mpz_init(mpzAllocation); mpz_set_si(mpzAllocation,allocations[n+1]); mpz_mul(mpzAllocation,mpzAllocation,mpzCheckamount); - mpz_tdiv_q (mpzAllocation,mpzAllocation,mpzTotalAllocations); + mpz_tdiv_q(mpzAllocation,mpzAllocation,mpzTotalAllocations); int64_t test = mpz_get_si(mpzAllocation); - if ( test > minimum+1 ) + //fprintf(stderr, "check next vout pays under min: test.%li > minimuim.%i\n", test, minimum); + if ( test > minimum ) return(eval->Invalid("next allocation was not under minimum")); } mpz_clear(mpzTotalAllocations); mpz_clear(mpzCheckamount); - // This is a backup check to make sure there are no extra vouts paying something else! - if ( checkamount != amount ) - return(eval->Invalid("amounts do not match")); - - if ( amount < minrelease*COIN ) - { - fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amount, (int64_t)minrelease*COIN ); - return(eval->Invalid("amount is too small")); - } } // Check vins - i = 0; int32_t dust = 0; - int32_t blocksleft; - BOOST_FOREACH(const CTxIn& vin, tx.vin) + i = 0; + for (auto vin : tx.vin) { CTransaction txin; if ( myGetTransaction(vin.prevout.hash,txin,blockhash) ) { // check the vin comes from the CC address's - char destaddr[64]; int32_t mergeoffset = 0; CScript opret; uint256 checktxid; - Getscriptaddress(destaddr,txin.vout[vin.prevout.n].scriptPubKey); + char fromaddr[64]; int32_t mergeoffset = 0; CScript vinccopret; uint256 checktxid; + Getscriptaddress(fromaddr,txin.vout[vin.prevout.n].scriptPubKey); if ( fIsMerge && txin.vout[vin.prevout.n].nValue < COIN ) dust++; - if ( strcmp(destaddr,coinaddr) != 0 ) + if ( IsPaymentsvout(cp,txin,vin.prevout.n,cp->unspendableCCaddr,vinccopret) != 0 ) { - // if does not come from address its in the global payments adddress and we need to check the opreturn. - uint256 checktxid; int32_t opret_ind; - if ( (opret_ind= has_opret(txin, EVAL_PAYMENTS)) == 0 ) - getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret); // get op_return from CCvout, - else - opret = txin.vout[opret_ind].scriptPubKey; - if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) + // if from global payments address get ccopret to detemine pays correct plan. + uint256 checktxid; + if ( vinccopret.size() < 2 || DecodePaymentsFundOpRet(vinccopret,checktxid) != 'F' || checktxid != createtxid ) { - fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s\n", i, txin.GetHash().ToString().c_str()); + fprintf(stderr, "vin.%i is not a payments CC vout: txid.%s vout.%i\n", i, txin.GetHash().ToString().c_str(), vin.prevout.n); return(eval->Invalid("vin is not paymentsCC type")); } } - else if ( fIsMerge && getCCopret(txin.vout[vin.prevout.n].scriptPubKey,opret) && opret.size() > 2 && DecodePaymentsMergeOpRet(opret,checktxid) == 'M' ) + else if ( IsPaymentsvout(cp,txin,vin.prevout.n,txidaddr,vinccopret) != 0 ) { - mergeoffset = PAYMENTS_MERGEOFSET; - } - //fprintf(stderr, "mergeoffset.%i\n", mergeoffset); + // if in txid address apply merge offset if applicable. + if ( fIsMerge && vinccopret.size() > 2 && DecodePaymentsMergeOpRet(vinccopret,checktxid) == 'M' ) + { + // Apply merge offset to locked blocks, this prevents people spaming payments fund and payments merge to prevent release happening. + mergeoffset = PAYMENTS_MERGEOFSET; + } + } + else // not from global payments plan, or txid address. + return(eval->Invalid("utxo comes from incorrect address")); // check the chain depth vs locked blocks requirement. if ( !payments_lockedblocks(blockhash, lockedblocks+mergeoffset, blocksleft) ) + { + fprintf(stderr, "vin.%i is not elegible for.%i blocks \n",i, blocksleft); return(eval->Invalid("vin not elegible")); + } i++; } else return(eval->Invalid("cant get vin transaction")); } @@ -551,30 +536,21 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract //fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr); if ( (vout == 0 || vout == 1) && GetTransaction(txid,vintx,hashBlock,false) != 0 ) { - if ( iter == 0 ) - { - CScript opret; uint256 checktxid; int32_t opret_ind; - if ( (opret_ind= has_opret(vintx, EVAL_PAYMENTS)) == 0 ) - { - // get op_return from CCvout - getCCopret(vintx.vout[vout].scriptPubKey,opret); - } - else - { - // get op_return from the op_return - opret = vintx.vout[opret_ind].scriptPubKey; - } - if ( DecodePaymentsFundOpRet(opret,checktxid) != 'F' || checktxid != createtxid ) - { - fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str()); - continue; - } - } if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { int32_t offset = 0; - if ( ccopret.size() > 2 && DecodePaymentsMergeOpRet(ccopret,checktxid) == 'M' ) - offset = PAYMENTS_MERGEOFSET; + if ( ccopret.size() > 2 ) + { + if ( iter == 0 && (DecodePaymentsFundOpRet(ccopret,checktxid) != 'F' || checktxid != createtxid) ) + { + // global address but not for this plan. + fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str()); + continue; + } + // increase merge offset, if this is a merge tx, merging merged utxos. + if ( iter == 1 && GetBalance == 4 && DecodePaymentsMergeOpRet(ccopret,checktxid) == 'M' ) + offset = PAYMENTS_MERGEOFSET; + } int32_t tmpblocksleft = 0; if ( fLockedBlocks && !payments_lockedblocks(hashBlock, lockedblocks+offset, tmpblocksleft) ) { @@ -689,7 +665,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { LOCK(cs_main); CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight()); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; - CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; + CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret,ccopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0,skipminimum=0; bool fFixedAmount = false; mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); @@ -727,7 +703,10 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) return(result); } txidpk = CCtxidaddr(txidaddr,createtxid); - mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk)); + ccopret = EncodePaymentsReleaseOpRet(createtxid, amount); + std::vector> vData = std::vector>(); + if ( makeCCopret(ccopret, vData) ) + mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,0,Paymentspk,txidpk,&vData)); //fprintf(stderr, "funcid.%i\n", funcid); if ( funcid == 'C' ) { @@ -812,6 +791,14 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { fFixedAmount = true; } + if ( (top-bottom) < 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","invalid range top/bottom")); + if ( params != 0 ) + free_json(params); + return(result); + } for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) { auto &address = vAddressSnapshot[j]; @@ -852,10 +839,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) { mpz_t mpzValue; mpz_init(mpzValue); if ( fFixedAmount ) - { mtx.vout[i+1].nValue = amount / (top-bottom); - //fprintf(stderr, "amount.%li / top-bottom.%i = value.%li\n", amount, (top-bottom-2), mtx.vout[i+1].nValue); - } else { mpz_set_si(mpzValue,mtx.vout[i+1].nValue); @@ -872,8 +856,8 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) return(result); } } - //fprintf(stderr, "nValue.%li \n", mtx.vout[i+1].nValue); mpz_clear(mpzValue); + //fprintf(stderr, "[%i] nValue.%li minimum.%i scriptpubkey.%s\n", i, mtx.vout[i+1].nValue, minimum, HexStr(mtx.vout[i+1].scriptPubKey.begin(),mtx.vout[i+1].scriptPubKey.end()).c_str()); if ( mtx.vout[i+1].nValue < minimum ) { if ( skipminimum == 0 ) @@ -887,15 +871,15 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) else { // truncate off any vouts that are less than minimum. - mtx.vout.resize(i); + mtx.vout.resize(i+1); break; } } totalamountsent += mtx.vout[i+1].nValue; } if ( totalamountsent < amount ) newamount = totalamountsent; - int64_t temptst = mpz_get_si(mpzTotalAllocations); - fprintf(stderr, "checkamount RPC.%li totalallocations.%li\n",totalamountsent, temptst); + //int64_t temptst = mpz_get_si(mpzTotalAllocations); + //fprintf(stderr, "checkamount RPC.%li totalallocations.%li\n",totalamountsent, temptst); mpz_clear(mpzAmount); mpz_clear(mpzTotalAllocations); } else @@ -909,8 +893,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( (inputsum= AddPaymentsInputs(true,0,cp,mtx,txidpk,newamount+2*PAYMENTS_TXFEE,CC_MAXVINS/2,createtxid,lockedblocks,minrelease,blocksleft)) >= newamount+2*PAYMENTS_TXFEE ) { std::string rawtx; - mtx.vout[0].nValue = inputsum - newamount - 2*PAYMENTS_TXFEE; - mtx.vout.push_back(CTxOut(PAYMENTS_TXFEE,CScript() << ParseHex(HexStr(txidpk)) << OP_CHECKSIG)); + mtx.vout[0].nValue = inputsum - newamount - PAYMENTS_TXFEE; // only 1 txfee, so the minimum in this vout is a tx fee. GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr); rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret); @@ -945,18 +928,20 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) { CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); - CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease; std::vector txidoprets; + CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount,totalallocations; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,broadcast=0,lockedblocks,minrelease; std::vector txidoprets; int32_t top,bottom,minimum=10000; std::vector> excludeScriptPubKeys; // snapshot uint256 tokenid; int8_t fixedAmount; cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); - if ( params != 0 && n > 1 && n <= 3 ) + if ( params != 0 && n > 1 && n <= 4 ) { txid = payments_juint256(jitem(params,0)); amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049; if ( n == 3 ) useopret = jint(jitem(params,2),0) != 0; + if ( n == 4 ) + broadcast = jint(jitem(params,3),0) != 0; if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || (DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 && DecodePaymentsSnapsShotOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys) == 0 && DecodePaymentsTokensOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,minimum,top,bottom,fixedAmount,excludeScriptPubKeys,tokenid) == 0) ) { result.push_back(Pair("result","error")); @@ -979,18 +964,14 @@ UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr) } else { - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk)); opret = EncodePaymentsFundOpRet(txid); - // Use the below one along with other FinalizeCCTx/return, to get the ccvout scriptpubkey - /*std::vector> vData = std::vector>(); + std::vector> vData = std::vector>(); if ( makeCCopret(opret, vData) ) - mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); */ + mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk,&vData)); } - rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret); - //rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); // use this one to get ccvout scriptpubkey. + rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,CScript()); if ( params != 0 ) - free_json(params); - //return(payments_rawtxresult(result,rawtx,0)); // disable sending for CCvout, as we only need to decode the tx. + free_json(params); return(payments_rawtxresult(result,rawtx,1)); } else @@ -1041,7 +1022,6 @@ UniValue PaymentsMerge(struct CCcontract_info *cp,char *jsonstr) // encode the checktxid into the end of the ccvout, along with 'M' to flag merge type tx. opret = EncodePaymentsMergeOpRet(createtxid); std::vector> vData = std::vector>(); - // try to pay to diffrent pubkey here... change txidpk. if ( makeCCopret(opret, vData) ) mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,inputsum-PAYMENTS_TXFEE,Paymentspk,txidpk,&vData)); GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk); @@ -1214,6 +1194,14 @@ UniValue PaymentsAirdrop(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } + if ( top-bottom < 0 ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","invalid range, top/bottom")); + if ( params != 0 ) + free_json(params); + return(result); + } if ( n > 6 ) { for (i=0; i Date: Tue, 14 May 2019 08:27:56 +0800 Subject: [PATCH 19/35] change snapshot allocations to function --- src/cc/payments.cpp | 137 ++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 528e6ec7f..6207915d9 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -256,6 +256,49 @@ bool payments_lockedblocks(uint256 blockhash,int32_t lockedblocks,int32_t &block return true; } +int32_t payments_getallocations(int32_t top, int32_t bottom, const std::vector> &excludeScriptPubKeys, mpz_t &mpzTotalAllocations, std::vector &scriptPubKeys, std::vector &allocations) +{ + mpz_t mpzAllocation; int32_t i =0; + for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + { + auto &address = vAddressSnapshot[j]; + CScript scriptPubKey = GetScriptForDestination(address.second); + bool skip = false; + // skip excluded addresses. + for ( auto skipkey : excludeScriptPubKeys ) + { + if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) + skip = true; + } + if ( !skip ) + { + mpz_init(mpzAllocation); + i++; + //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); + scriptPubKeys.push_back(scriptPubKey); + allocations.push_back(address.first); + mpz_set_si(mpzAllocation,address.first); + mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); + mpz_clear(mpzAllocation); + } + if ( i+bottom == top ) + break; // we reached top amount to pay, it can be less than this, if less address exist on chain, return the number we got. + } + return(i); +} + +int32_t payments_gettokenallocations(int32_t top, int32_t bottom, const std::vector> &excludeScriptPubKeys, uint256 tokenid, mpz_t &mpzTotalAllocations, std::vector &scriptPubKeys, std::vector &allocations) +{ + /* + - check tokenid exists. + - iterate tokenid address and extract all pubkeys, add to map. + - rewind to last notarized height for balances? + - convert balances to mpz_t and add up totalallocations + - sort the map into a vector, then convert to the correct output. + */ + return(0); +} + bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { char temp[128], txidaddr[64]={0}; std::string scriptpubkey; uint256 createtxid, blockhash, tokenid; CTransaction plantx; int8_t funcid=0, fixedAmount=0; @@ -339,7 +382,7 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("allocation missmatch")); mpz_set_si(mpzTotalAllocations,totalallocations); } - else if ( funcid == 'S' ) + else if ( funcid == 'S' || funcid == 'O' ) { // snapshot payment if ( KOMODO_SNAPSHOT_INTERVAL == 0 ) @@ -357,35 +400,14 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & { fFixedAmount = true; } - for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + if ( funcid == 'S' ) + payments_getallocations(top, bottom, excludeScriptPubKeys, mpzTotalAllocations, scriptPubKeys, allocations); + else { - auto &address = vAddressSnapshot[j]; - CScript scriptPubKey = GetScriptForDestination(address.second); - bool skip = false; - // skip excluded addresses. - for ( auto skipkey : excludeScriptPubKeys ) - { - if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) - skip = true; - } - if ( !skip ) - { - mpz_init(mpzAllocation); - i++; - scriptPubKeys.push_back(scriptPubKey); - allocations.push_back(address.first); - mpz_set_si(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); - mpz_clear(mpzAllocation); - } - if ( i+bottom == top ) - break; // we reached top amount to pay, it can be less than this, if less address exist on chain. + // token snapshot + // payments_gettokenallocations(top, bottom, excludeScriptPubKeys, tokenid, mpzTotalAllocations, scriptPubKeys, allocations); } } - else if ( funcid == 'O' ) - { - // tokens snapshot. - } // sanity check to make sure we got all the required info, skip for merge type tx //fprintf(stderr, " allocations.size().%li scriptPubKeys.size.%li\n",allocations.size(), scriptPubKeys.size()); if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) @@ -667,7 +689,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight()); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock,tokenid; CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,m,numoprets=0,lockedblocks,minrelease; int64_t newamount,inputsum,amount,CCchange=0,totalallocations=0,checkallocations=0,allocation; CTxOut vout; CScript onlyopret,ccopret; char txidaddr[64],destaddr[64]; std::vector txidoprets; int32_t top,bottom=0,blocksleft=0,minimum=10000; std::vector> excludeScriptPubKeys; int8_t funcid,fixedAmount=0,skipminimum=0; bool fFixedAmount = false; - mpz_t mpzTotalAllocations; mpz_init(mpzTotalAllocations); + mpz_t mpzTotalAllocations, mpzAllocation; mpz_init(mpzTotalAllocations); cJSON *params = payments_reparse(&n,jsonstr); mypk = pubkey2pk(Mypubkey()); Paymentspk = GetUnspendable(cp,0); @@ -762,7 +784,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) // set totalallocations to a mpz_t bignum, for amounts calculation later. mpz_set_si(mpzTotalAllocations,totalallocations); } - else if ( funcid == 'S' ) + else if ( funcid == 'S' || funcid == 'O' ) { // normal snapshot if ( vAddressSnapshot.size() == 0 ) @@ -781,7 +803,6 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - i = 0; if ( fixedAmount == 7 ) { // game setting, randomise bottom and top values @@ -799,38 +820,32 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) free_json(params); return(result); } - for (int32_t j = bottom; j < vAddressSnapshot.size(); j++) + + std::vector allocations; + std::vector scriptPubKeys; + if ( funcid == 'S' ) + m = payments_getallocations(top, bottom, excludeScriptPubKeys, mpzTotalAllocations, scriptPubKeys, allocations); + else { - auto &address = vAddressSnapshot[j]; - CScript scriptPubKey = GetScriptForDestination(address.second); bool skip = false; - for ( auto skipkey : excludeScriptPubKeys ) - { - if ( scriptPubKey == CScript(skipkey.begin(), skipkey.end()) ) - { - skip = true; - //fprintf(stderr, "SKIPPED::: %s\n", CBitcoinAddress(address.second).ToString().c_str()); - } - } - if ( !skip ) - { - mpz_t mpzAllocation; mpz_init(mpzAllocation); - i++; - //fprintf(stderr, "address: %s nValue.%li \n", CBitcoinAddress(address.second).ToString().c_str(), address.first); - vout.nValue = address.first; - vout.scriptPubKey = scriptPubKey; - mpz_set_si(mpzAllocation,address.first); - mpz_add(mpzTotalAllocations,mpzTotalAllocations,mpzAllocation); - mtx.vout.push_back(vout); - mpz_clear(mpzAllocation); - } - if ( i+bottom == top ) // we reached top amount to pay, it can be less than this! - break; + // token snapshot + // payments_gettokenallocations(top, bottom, excludeScriptPubKeys, tokenid, mpzTotalAllocations, scriptPubKeys, allocations); + } + if ( (allocations.size() == 0 || scriptPubKeys.size() == 0 || allocations.size() != scriptPubKeys.size()) ) + { + result.push_back(Pair("result","error")); + result.push_back(Pair("error","mismatched allocations, scriptpubkeys")); + if ( params != 0 ) + free_json(params); + return(result); + } + i = 0; + for ( auto allocation : allocations ) + { + vout.nValue = allocation; + vout.scriptPubKey = scriptPubKeys[i]; + mtx.vout.push_back(vout); + i++; } - m = i; // this is the amount we got, either top, or all of the address on the chain. - } - else if ( funcid == 'O' ) - { - // token snapshot } newamount = amount; int64_t totalamountsent = 0; @@ -863,7 +878,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) if ( skipminimum == 0 ) { result.push_back(Pair("result","error")); - result.push_back(Pair("error","value too small, try releasing a larger amount")); + result.push_back(Pair("error","value too small, try releasing a larger amount, or use skipminimum flag")); if ( params != 0 ) free_json(params); return(result); From 389da98eb8998186de5648bcb2f318cc284504f7 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 14 May 2019 09:00:30 +0800 Subject: [PATCH 20/35] revert labs exemption --- src/cc/CCutils.cpp | 2 +- src/chain.h | 2 +- src/komodo_nk.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/CCutils.cpp b/src/cc/CCutils.cpp index 1b326b85f..5de5ed0db 100644 --- a/src/cc/CCutils.cpp +++ b/src/cc/CCutils.cpp @@ -162,7 +162,7 @@ bool CheckTxFee(const CTransaction &tx, uint64_t txfee, uint32_t height, uint64_ actualtxfee = valuein-tx.GetValueOut(); if ( actualtxfee > txfee ) { - fprintf(stderr, "actualtxfee.%li vs txfee.%li\n", actualtxfee, txfee); + //fprintf(stderr, "actualtxfee.%li vs txfee.%li\n", actualtxfee, txfee); return false; } return true; diff --git a/src/chain.h b/src/chain.h index ac60dc277..b893e3a06 100644 --- a/src/chain.h +++ b/src/chain.h @@ -547,7 +547,7 @@ public: if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) { READWRITE(nSaplingValue); } - if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) )// && ASSETCHAINS_NOTARY_PAY[0] != 0 ) + if ( (s.GetType() & SER_DISK) && (is_STAKED(ASSETCHAINS_SYMBOL) != 0) && ASSETCHAINS_NOTARY_PAY[0] != 0 ) { READWRITE(nNotaryPay); READWRITE(segid); diff --git a/src/komodo_nk.h b/src/komodo_nk.h index 708e8ba6c..68512dfd7 100644 --- a/src/komodo_nk.h +++ b/src/komodo_nk.h @@ -1,10 +1,10 @@ #ifndef KOMODO_NK_H #define KOMODO_NK_H -#define ASSETCHAINS_N 77 -#define ASSETCHAINS_K 3 +//#define ASSETCHAINS_N 77 +//#define ASSETCHAINS_K 3 -//#define ASSETCHAINS_N 95 -//#define ASSETCHAINS_K 5 +#define ASSETCHAINS_N 96 +#define ASSETCHAINS_K 5 #endif From fae5d3b4f0063201f57f4b0827a9e0397d757f4d Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Tue, 14 May 2019 09:57:51 +0800 Subject: [PATCH 21/35] revert short reorg limit. Add some comments to dailysnapshot --- src/cc/payments.cpp | 3 ++- src/main.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 6207915d9..0ea339f3a 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -292,7 +292,7 @@ int32_t payments_gettokenallocations(int32_t top, int32_t bottom, const std::vec /* - check tokenid exists. - iterate tokenid address and extract all pubkeys, add to map. - - rewind to last notarized height for balances? + - rewind to last notarized height for balances? see main.cpp: line# 660. - convert balances to mpz_t and add up totalallocations - sort the map into a vector, then convert to the correct output. */ @@ -885,6 +885,7 @@ UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr) } else { + // NOTE: should make this default behaviour. // truncate off any vouts that are less than minimum. mtx.vout.resize(i+1); break; diff --git a/src/main.cpp b/src/main.cpp index 20354fd59..7198fe7e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -656,8 +656,12 @@ std::vector > vAddressSnapshot; bool komodo_dailysnapshot(int32_t height) { - int reorglimit = 10; // CHANGE BACK TO 100 AFTER TESTING! + int reorglimit = 100; uint256 notarized_hash,notarized_desttxid; int32_t prevMoMheight,notarized_height,undo_height,extraoffset; + // NOTE: To make this 100% safe under all sync conditions, it should be using a notarized notarization, from the DB. + // Under heavy reorg attack, its possible `komodo_notarized_height` can return a height that can't be found on chain sync. + // However, the DB can reorg the last notarization. By using 2 deep, we know 100% that the previous notarization cannot be reorged by online nodes, + // and as such will always be notarizing the same height. May need to check heights on scan back to make sure they are confirmed in correct order. if ( (extraoffset= height % KOMODO_SNAPSHOT_INTERVAL) != 0 ) { // we are on chain init, and need to scan all the way back to the correct height, other wise our node will have a diffrent snapshot to online nodes. From 73fd95119fc133943eb23a924394ca24f3d851fe Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 14 May 2019 15:26:21 +0500 Subject: [PATCH 22/35] added protection from corrupted old version targetSymbol --- src/rpc/crosschain.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 35409323d..dc8aecd46 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -1420,6 +1420,7 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp) UnmarshalBurnTx(*pwtx, targetSymbol, &targetCCid, payoutsHash, rawproof)) { UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", pwtx->GetHash().GetHex())); + if (vopret.begin()[0] == EVAL_TOKENS) { // get burned token value std::vector> oprets; @@ -1460,6 +1461,12 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp) } else entry.push_back(Pair("burnedAmount", ValueFromAmount(pwtx->vout.back().nValue))); // coins + + // check for corrupted strings (look for non-printable chars) from some older versions + // which caused "couldn't parse reply from server" error on client: + if (std::find_if(targetSymbol.begin(), targetSymbol.end(), [](int c) {return !std::isprint(c);}) != targetSymbol.end()) + targetSymbol = "corrupted"; + entry.push_back(Pair("targetSymbol", targetSymbol)); entry.push_back(Pair("targetCCid", std::to_string(targetCCid))); if (mytxid_inmempool(pwtx->GetHash())) From 95907695349b2afc901124e25803dee9cd8fef8f Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 14 May 2019 18:43:19 +0500 Subject: [PATCH 23/35] corr check for corrupt val --- src/rpc/crosschain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index dc8aecd46..407d32f25 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -1464,8 +1464,10 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp) // check for corrupted strings (look for non-printable chars) from some older versions // which caused "couldn't parse reply from server" error on client: - if (std::find_if(targetSymbol.begin(), targetSymbol.end(), [](int c) {return !std::isprint(c);}) != targetSymbol.end()) - targetSymbol = "corrupted"; + // if (std::find_if(targetSymbol.begin(), targetSymbol.end(), [](int c) {return !std::isprint(c);}) != targetSymbol.end()) + UniValue testval(UniValue::VSTR); + if( !testval.read(targetSymbol) ) + targetSymbol = ""; entry.push_back(Pair("targetSymbol", targetSymbol)); entry.push_back(Pair("targetCCid", std::to_string(targetCCid))); From 406e54a00e30ccd6d88bf61b4da34b5cb3de2f0c Mon Sep 17 00:00:00 2001 From: dimxy Date: Tue, 14 May 2019 19:13:18 +0500 Subject: [PATCH 24/35] returned isprint check --- src/rpc/crosschain.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rpc/crosschain.cpp b/src/rpc/crosschain.cpp index 407d32f25..bf0dbea4c 100644 --- a/src/rpc/crosschain.cpp +++ b/src/rpc/crosschain.cpp @@ -1464,9 +1464,7 @@ UniValue getwalletburntransactions(const UniValue& params, bool fHelp) // check for corrupted strings (look for non-printable chars) from some older versions // which caused "couldn't parse reply from server" error on client: - // if (std::find_if(targetSymbol.begin(), targetSymbol.end(), [](int c) {return !std::isprint(c);}) != targetSymbol.end()) - UniValue testval(UniValue::VSTR); - if( !testval.read(targetSymbol) ) + if (std::find_if(targetSymbol.begin(), targetSymbol.end(), [](int c) {return !std::isprint(c);}) != targetSymbol.end()) targetSymbol = ""; entry.push_back(Pair("targetSymbol", targetSymbol)); From 8d506a51a6d3cceda0262bdd44e2392e2392b6e2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 May 2019 23:54:12 -1100 Subject: [PATCH 25/35] +print --- src/deprecation.h | 2 +- src/komodo_gateway.h | 1 + src/main.cpp | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/deprecation.h b/src/deprecation.h index 427234b4a..dde45e22c 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -24,7 +24,7 @@ // * Shut down WEEKS_UNTIL_DEPRECATION weeks' worth of blocks after the estimated release block height. // * A warning is shown during the DEPRECATION_WARN_LIMIT worth of blocks prior to shut down. static const int WEEKS_UNTIL_DEPRECATION = 52; -static const int DEPRECATION_HEIGHT = 1600000; +static const int DEPRECATION_HEIGHT = 2200000; static const int APPROX_RELEASE_HEIGHT = DEPRECATION_HEIGHT - (WEEKS_UNTIL_DEPRECATION * 7 * 24 * 60); // Number of blocks before deprecation to warn users diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 1fafcc856..62e42fad8 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2019,6 +2019,7 @@ int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector s sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // { + fprintf(stderr,"stocks.(%s)\n",jprint(json,0)); if ( (n= cJSON_GetArraySize(json)) > 0 ) { retval = n; diff --git a/src/main.cpp b/src/main.cpp index 7198fe7e6..4fdf39f43 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1373,9 +1373,10 @@ bool CheckTransaction(uint32_t tiptime,const CTransaction& tx, CValidationState } } -int32_t komodo_isnotaryvout(char *coinaddr) // from ac_private chains only +int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime) // from ac_private chains only { static int32_t didinit; static char notaryaddrs[sizeof(Notaries_elected1)/sizeof(*Notaries_elected1) + 1][64]; + //use normal notary functions int32_t i; if ( didinit == 0 ) { @@ -1484,7 +1485,7 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio // char destaddr[65]; Getscriptaddress(destaddr,txout.scriptPubKey); - if ( komodo_isnotaryvout(destaddr) == 0 ) + if ( komodo_isnotaryvout(destaddr,tiptime) == 0 ) { invalid_private_taddr = 1; //return state.DoS(100, error("CheckTransaction(): this is a private chain, no public allowed"),REJECT_INVALID, "bad-txns-acprivacy-chain"); From 598cb471ad397f529f994a4e751788ff5014d229 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 14 May 2019 23:58:37 -1100 Subject: [PATCH 26/35] Tiptime --- src/wallet/rpcwallet.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a22a81e34..5ecefce6f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -72,7 +72,7 @@ const std::string ADDR_TYPE_SAPLING = "sapling"; extern UniValue TxJoinSplitToJSON(const CTransaction& tx); uint32_t komodo_segid32(char *coinaddr); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); -int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only +int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only CBlockIndex *komodo_getblockindex(uint256 hash); int64_t nWalletUnlockTime; @@ -461,7 +461,6 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } -int32_t komodo_isnotaryvout(char *coinaddr); UniValue sendtoaddress(const UniValue& params, bool fHelp) { @@ -494,7 +493,7 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp) if ( ASSETCHAINS_PRIVATE != 0 && AmountFromValue(params[1]) > 0 ) { - if ( komodo_isnotaryvout((char *)params[0].get_str().c_str()) == 0 ) + if ( komodo_isnotaryvout((char *)params[0].get_str().c_str(),chainActive.LastTip()->nTime) == 0 ) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid " + strprintf("%s",komodo_chainname()) + " address"); } From bd73b0772401148e1c9875ffc8086dcf89e8cb26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 May 2019 00:03:03 -1100 Subject: [PATCH 27/35] +print --- src/komodo_gateway.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 62e42fad8..1455c34b3 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2017,6 +2017,7 @@ int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector s { char url[32768],*symbol,*timestr; cJSON *json,*obj; int32_t i,n=0,retval=-1; uint32_t uprice,timestamp; sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); + fprintf(stderr,"url.(%s)\n",url); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // { fprintf(stderr,"stocks.(%s)\n",jprint(json,0)); From d96d5f8ddfe79d34445cc5b88c9d009a3fce16e8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 May 2019 00:05:56 -1100 Subject: [PATCH 28/35] http --- src/komodo_gateway.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index 1455c34b3..fbd8915ee 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2016,7 +2016,7 @@ cJSON *get_urljson(char *url) int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector symbols) { char url[32768],*symbol,*timestr; cJSON *json,*obj; int32_t i,n=0,retval=-1; uint32_t uprice,timestamp; - sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); + sprintf(url,"http://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); fprintf(stderr,"url.(%s)\n",url); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // { From 532fe32e759ea1a1217198c6c9caf9b9eade3e43 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 May 2019 00:34:23 -1100 Subject: [PATCH 29/35] https --- src/komodo_gateway.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_gateway.h b/src/komodo_gateway.h index fbd8915ee..1455c34b3 100644 --- a/src/komodo_gateway.h +++ b/src/komodo_gateway.h @@ -2016,7 +2016,7 @@ cJSON *get_urljson(char *url) int32_t get_stockprices(uint32_t now,uint32_t *prices,std::vector symbols) { char url[32768],*symbol,*timestr; cJSON *json,*obj; int32_t i,n=0,retval=-1; uint32_t uprice,timestamp; - sprintf(url,"http://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); + sprintf(url,"https://api.iextrading.com/1.0/tops/last?symbols=%s",GetArg("-ac_stocks","").c_str()); fprintf(stderr,"url.(%s)\n",url); if ( (json= get_urljson(url)) != 0 ) //if ( (json= send_curl(url,(char *)"iex")) != 0 ) // { From 6f2903addfd5b24df1437cfd0fb570a3fb2c6d83 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 May 2019 01:44:43 -1100 Subject: [PATCH 30/35] Verbose --- src/komodo_bitcoind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e616fb179..518bc4a4e 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -212,7 +212,7 @@ try_again: /* printf("[ Decker ] SSL: %s\n", curl_version()); */ curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); - //curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // this is useful for debug, but seems crash on libcurl/7.64.1 OpenSSL/1.1.1b zlib/1.2.8 librtmp/2.3 + curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // this is useful for debug, but seems crash on libcurl/7.64.1 OpenSSL/1.1.1b zlib/1.2.8 librtmp/2.3 } if ( userpass != 0 ) curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass); From a033c8717338d4b48801542dbeb1c8930d609dff Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 15 May 2019 01:47:15 -1100 Subject: [PATCH 31/35] -debug --- src/komodo_bitcoind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 518bc4a4e..e616fb179 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -212,7 +212,7 @@ try_again: /* printf("[ Decker ] SSL: %s\n", curl_version()); */ curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // this is useful for debug, but seems crash on libcurl/7.64.1 OpenSSL/1.1.1b zlib/1.2.8 librtmp/2.3 + //curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); // this is useful for debug, but seems crash on libcurl/7.64.1 OpenSSL/1.1.1b zlib/1.2.8 librtmp/2.3 } if ( userpass != 0 ) curl_easy_setopt(curl_handle,CURLOPT_USERPWD, userpass); From 46d00eced0df37ea6f7d2b9521cda0bd2d6ac067 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Wed, 15 May 2019 23:47:53 +0800 Subject: [PATCH 32/35] fix payments balance --- src/cc/payments.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 0ea339f3a..3d28a8da8 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -556,7 +556,7 @@ int64_t AddPaymentsInputs(bool fLockedBlocks,int8_t GetBalance,struct CCcontract txid = it->first.txhash; vout = (int32_t)it->first.index; //fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr); - if ( (vout == 0 || vout == 1) && GetTransaction(txid,vintx,hashBlock,false) != 0 ) + if ( GetTransaction(txid,vintx,hashBlock,false) != 0 ) { if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr,ccopret)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 ) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a22a81e34..8311a1b44 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5660,7 +5660,7 @@ UniValue payments_airdroptokens(const UniValue& params, bool fHelp) { struct CCcontract_info *cp,C; if ( fHelp || params.size() != 1 ) - throw runtime_error("paymentsairdrop \"[%22tokenid%22,lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludePubKey%22,...,%22excludePubKeyN%22]\"\n"); + throw runtime_error("payments_airdroptokens \"[%22tokenid%22,lockedblocks,minamount,mintoaddress,top,bottom,fixedFlag,%22excludePubKey%22,...,%22excludePubKeyN%22]\"\n"); if ( ensure_CCrequirements(EVAL_PAYMENTS) < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); const CKeyStore& keystore = *pwalletMain; From aa919f3847072e642eec289f7969fe02ad9329ae Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 16 May 2019 01:06:56 +0800 Subject: [PATCH 33/35] fix paymentsmerge --- src/cc/payments.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index 3d28a8da8..1cf7e3319 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -326,11 +326,6 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & return(eval->Invalid("negative values")); if ( minimum < 10000 ) return(eval->Invalid("minimum must be over 10000")); - if ( amountReleased < minrelease*COIN ) - { - fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amountReleased, (int64_t)minrelease*COIN); - return(eval->Invalid("amount is too small")); - } Paymentspk = GetUnspendable(cp,0); txidpk = CCtxidaddr(txidaddr,createtxid); GetCCaddress1of2(cp,txidaddr,Paymentspk,txidpk); @@ -343,6 +338,11 @@ bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction & if ( !fIsMerge ) { + if ( amountReleased < minrelease*COIN ) + { + fprintf(stderr, "does not meet minrelease amount.%li minrelease.%li\n",amountReleased, (int64_t)minrelease*COIN); + return(eval->Invalid("amount is too small")); + } // Get all the script pubkeys and allocations std::vector allocations; std::vector scriptPubKeys; From 8b57ca63b870f49ebd9306af454374f31b0b2aaa Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Wed, 15 May 2019 21:27:05 -0700 Subject: [PATCH 34/35] Prevent linkability analysis on out-of-sync nodes This addresses upstream issue https://github.com/zcash/zcash/issues/3996 by preventing z_sendmany, z_mergecoinbase and z_shieldcoinbase from making shielded transactions if the node is out of sync. This prevents metadata leakage which can be used in blockchain analysis. --- src/wallet/rpcwallet.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a22a81e34..23b62c2fe 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -70,6 +70,7 @@ extern std::string ASSETCHAINS_OVERRIDE_PUBKEY; const std::string ADDR_TYPE_SPROUT = "sprout"; const std::string ADDR_TYPE_SAPLING = "sapling"; extern UniValue TxJoinSplitToJSON(const CTransaction& tx); +extern int32_t KOMODO_INSYNC; uint32_t komodo_segid32(char *coinaddr); int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only @@ -84,6 +85,7 @@ UniValue z_getoperationstatus_IMPL(const UniValue&, bool); #define PLAN_NAME_MAX 8 #define VALID_PLAN_NAME(x) (strlen(x) <= PLAN_NAME_MAX) +#define THROW_IF_SYNCING(INSYNC) if (INSYNC == 0) { throw runtime_error(strprintf("%s: Chain still syncing at height %d, aborting to prevent linkability analysis!",__FUNCTION__,chainActive.Tip()->GetHeight())); } int tx_height( const uint256 &hash ); @@ -4248,6 +4250,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) + HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]") ); + THROW_IF_SYNCING(KOMODO_INSYNC); + LOCK2(cs_main, pwalletMain->cs_wallet); // Check that the from address is valid. @@ -4557,6 +4561,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) + HelpExampleRpc("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") ); + THROW_IF_SYNCING(KOMODO_INSYNC); + LOCK2(cs_main, pwalletMain->cs_wallet); // Validate the from address @@ -4817,6 +4823,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled."); } + THROW_IF_SYNCING(KOMODO_INSYNC); + LOCK2(cs_main, pwalletMain->cs_wallet); bool useAnyUTXO = false; From 3275b435dea4e9348ea495d4be9a76e265573ab2 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Wed, 15 May 2019 22:07:09 -0700 Subject: [PATCH 35/35] Add synced key to getinfo+getblockchaininfo This addresses #3 of upstream issue https://github.com/zcash/zcash/issues/3996 . Any software that creates a transaction outside of the RPC interface MUST check if synced==true beforehand, otherwise metadata leakage which leads to linkability analysis is possible. The z_sendmany, z_shieldcoinbase and z_mergetoaddress RPCs have their own synced checks, so it's not needed to look at this new synced value when using those RPCs. --- src/rpc/blockchain.cpp | 4 +++- src/rpc/misc.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cb2cfce92..042b6591f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -48,6 +48,7 @@ using namespace std; +extern int32_t KOMODO_INSYNC; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); #include "komodo_defs.h" @@ -1689,6 +1690,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); + obj.push_back(Pair("synced", KOMODO_INSYNC!=0)); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->GetHeight() : -1)); obj.push_back(Pair("bestblockhash", chainActive.LastTip()->GetBlockHash().GetHex())); obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); @@ -2082,4 +2084,4 @@ void RegisterBlockchainRPCCommands(CRPCTable &tableRPC) { for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]); -} \ No newline at end of file +} diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 5a495c005..eca4abb36 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -69,7 +69,7 @@ bool komodo_txnotarizedconfirmed(uint256 txid); uint32_t komodo_chainactive_timestamp(); int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp); extern uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; -extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN,IS_STAKED_NOTARY,IS_KOMODO_NOTARY,STAKED_ERA; +extern int32_t KOMODO_LASTMINED,JUMBLR_PAUSE,KOMODO_LONGESTCHAIN,IS_STAKED_NOTARY,IS_KOMODO_NOTARY,STAKED_ERA,KOMODO_INSYNC; extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int64_t *sproutfundsp,int32_t height); @@ -237,6 +237,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); obj.push_back(Pair("KMDversion", KOMODO_VERSION)); + obj.push_back(Pair("synced", KOMODO_INSYNC!=0)); //obj.push_back(Pair("VRSCversion", VERUS_VERSION)); obj.push_back(Pair("notarized", notarized_height)); obj.push_back(Pair("prevMoMheight", prevMoMheight));