From 4d6cd59768415248ebca6de079184cc0c628964a Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Tue, 4 Sep 2018 05:29:36 -0300 Subject: [PATCH 01/94] put burntx opreturn at end of vout and fix crash with import tx --- src/cc/import.cpp | 2 +- src/importcoin.cpp | 4 ++-- src/main.cpp | 17 ++++++++++------- src/test-komodo/test_coinimport.cpp | 4 ++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/cc/import.cpp b/src/cc/import.cpp index 99418f711..ffc94ac43 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -59,7 +59,7 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp // check burn amount { - uint64_t burnAmount = burnTx.vout[0].nValue; + uint64_t burnAmount = burnTx.vout.back().nValue; if (burnAmount == 0) return Invalid("invalid-burn-amount"); uint64_t totalOut = 0; diff --git a/src/importcoin.cpp b/src/importcoin.cpp index 8b87cb535..d36943b5d 100644 --- a/src/importcoin.cpp +++ b/src/importcoin.cpp @@ -45,7 +45,7 @@ bool UnmarshalBurnTx(const CTransaction &burnTx, std::string &targetSymbol, uint { std::vector burnOpret; if (burnTx.vout.size() == 0) return false; - GetOpReturnData(burnTx.vout[0].scriptPubKey, burnOpret); + GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret); return E_UNMARSHAL(burnOpret, ss >> VARINT(*targetCCid); ss >> targetSymbol; ss >> payoutsHash); @@ -61,7 +61,7 @@ CAmount GetCoinImportValue(const CTransaction &tx) CTransaction burnTx; std::vector payouts; if (UnmarshalImportTx(tx, proof, burnTx, payouts)) { - return burnTx.vout.size() ? burnTx.vout[0].nValue : 0; + return burnTx.vout.size() ? burnTx.vout.back().nValue : 0; } return 0; } diff --git a/src/main.cpp b/src/main.cpp index e25d6419b..ce61a0e35 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1547,14 +1547,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa KOMODO_ON_DEMAND++; pool.addUnchecked(hash, entry, !IsInitialBlockDownload()); - // Add memory address index - if (fAddressIndex) { - pool.addAddressIndex(entry, view); - } + if (!tx.IsCoinImport()) + { + // Add memory address index + if (fAddressIndex) { + pool.addAddressIndex(entry, view); + } - // Add memory spent index - if (fSpentIndex) { - pool.addSpentIndex(entry, view); + // Add memory spent index + if (fSpentIndex) { + pool.addSpentIndex(entry, view); + } } } diff --git a/src/test-komodo/test_coinimport.cpp b/src/test-komodo/test_coinimport.cpp index eac21428a..8c1d8b0f8 100644 --- a/src/test-komodo/test_coinimport.cpp +++ b/src/test-komodo/test_coinimport.cpp @@ -180,7 +180,7 @@ TEST_F(TestCoinImport, testInvalidBurnOutputs) TEST_F(TestCoinImport, testInvalidBurnParams) { - burnTx.vout[0].scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << VARINT(testCcid)); + burnTx.vout.back().scriptPubKey = CScript() << OP_RETURN << E_MARSHAL(ss << VARINT(testCcid)); MoMoM = burnTx.GetHash(); // TODO: an actual branch CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts); TestRunCCEval(tx); @@ -198,7 +198,7 @@ TEST_F(TestCoinImport, testWrongChainId) TEST_F(TestCoinImport, testInvalidBurnAmount) { - burnTx.vout[0].nValue = 0; + burnTx.vout.back().nValue = 0; MoMoM = burnTx.GetHash(); // TODO: an actual branch CTransaction tx = MakeImportCoinTransaction(proof, CTransaction(burnTx), payouts); TestRunCCEval(tx); From 96ac747dcdf59a0a9f7fe9113ffa6dfd98ce3f1f Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Tue, 4 Sep 2018 06:05:26 -0300 Subject: [PATCH 02/94] shell script to document migrate process --- migratecoin.md | 61 -------------------------------------------------- migratecoin.sh | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 61 deletions(-) delete mode 100644 migratecoin.md create mode 100644 migratecoin.sh diff --git a/migratecoin.md b/migratecoin.md deleted file mode 100644 index 7859bdff2..000000000 --- a/migratecoin.md +++ /dev/null @@ -1,61 +0,0 @@ -# MigrateCoin protocol - - - -## ExportCoins tx: - - - -``` - -vin: - - [ any ] - -vout: - - - amount: {burnAmount} - - script: OP_RETURN "send to ledger {id} {voutsHash}" - -``` - - - -* ExportCoin is a standard tx which burns coins in an OP_RETURN - - - -## ImportCoins tx: - - - -``` - -vin: - - - txid: 0000000000000000000000000000000000000000000000000000000000000000 - - idx: 0 - - script: CC_EVAL(EVAL_IMPORTCOINS, {momoProof},{exportCoin}) OP_CHECKCRYPTOCONDITION_UNILATERAL - -vout: - - - [ vouts matching voutsHash in exportCoin ] - -``` - - - -* ImportCoin transaction has no signature - -* ImportCoin is non malleable - -* ImportCoin satisfies tx.IsCoinBase() - -* ImportCoin uses a new opcode which allows a one sided check (no scriptPubKey) - -* ImportCoin must contain CC opcode EVAL_IMPORTCOINS - -* ImportCoin fees are equal to the difference between burnAmount in exportCoins and the sum of outputs. diff --git a/migratecoin.sh b/migratecoin.sh new file mode 100644 index 000000000..6cd09ba04 --- /dev/null +++ b/migratecoin.sh @@ -0,0 +1,43 @@ +#!/usr/bin/bash + +# This script makes the neccesary transactions to migrate +# coin between 2 assetchains on the same -ac_cc id + +set -e + +source=TXSCL +target=TXSCL000 +address="RFw7byY4xZpZCrtkMk3nFuuG1NTs9rSGgQ" +amount=1 + +# Alias for running cli on source chain +cli_source="komodo-cli -ac_name=$source" + +# Raw tx that we will work with +txraw=`$cli_source createrawtransaction "[]" "{\"$address\":$amount}"` + +# Convert to an export tx +exportData=`$cli_source migrate_converttoexport $txraw $target $amount` +exportRaw=`echo $exportData | jq -r .exportTx` +exportPayouts=`echo $exportData | jq -r .payouts` + +# Fund +exportFundedData=`$cli_source fundrawtransaction $exportRaw` +exportFundedTx=`echo $exportFundedData | jq -r .hex` + +# Sign +exportSignedData=`$cli_source signrawtransaction $exportFundedTx` +exportSignedTx=`echo $exportSignedData | jq -r .hex` + +# Send +echo "Sending export tx" +$cli_source sendrawtransaction $exportSignedTx + +read -p "Wait for a notarisation to KMD, and then two more notarisations from the target chain, and then press enter to continue" + +# Create import +importTx=`$cli_source migrate_createimporttransaction $exportSignedTx $payouts` +importTx=`komodo-cli migrate_completeimporttransaction $importTx` + +# Send import +komodo-cli -ac_name=$target sendrawtransaction $importTx From 63cadcf444b9be1f9c3208469ffdf0283fa240db Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 24 Sep 2018 05:45:38 -1100 Subject: [PATCH 03/94] Help human fix --- src/main.cpp | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f93cab2f5..c6188cf47 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3619,23 +3619,34 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // our genesis block. In practice this (probably) won't happen because of checks elsewhere. auto reorgLength = pindexOldTip ? pindexOldTip->nHeight - (pindexFork ? pindexFork->nHeight : -1) : 0; static_assert(MAX_REORG_LENGTH > 0, "We must be able to reorg some distance"); - if (reorgLength > MAX_REORG_LENGTH) { - auto msg = strprintf(_( - "A block chain reorganization has been detected that would roll back %d blocks! " - "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety." - ), reorgLength, MAX_REORG_LENGTH) + "\n\n" + - _("Reorganization details") + ":\n" + - "- " + strprintf(_("Current tip: %s, height %d, work %s"), - pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" + - "- " + strprintf(_("New tip: %s, height %d, work %s"), - pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" + - "- " + strprintf(_("Fork point: %s %s, height %d"), - ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + - _("Please help, human!"); - LogPrintf("*** %s\n", msg); - uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); - StartShutdown(); - return false; + if (reorgLength > MAX_REORG_LENGTH) + { + int32_t notarizedht,prevMoMheight; uint256 notarizedhash,txid; + notarizedht = komodo_notarized_height(&prevMoMheight,¬arizedhash,&txid); + if ( pindexFork->nHeight < notarizedht ) + { + fprintf(stderr,"pindexFork->nHeight.%d is < notarizedht %d, so ignore it\n",(int32_t)pindexFork->nHeight,notarizedht); + pindexFork = pindexOldTip; + } + else + { + auto msg = strprintf(_( + "A block chain reorganization has been detected that would roll back %d blocks! " + "This is larger than the maximum of %d blocks, and so the node is shutting down for your safety." + ), reorgLength, MAX_REORG_LENGTH) + "\n\n" + + _("Reorganization details") + ":\n" + + "- " + strprintf(_("Current tip: %s, height %d, work %s"), + pindexOldTip->phashBlock->GetHex(), pindexOldTip->nHeight, pindexOldTip->nChainWork.GetHex()) + "\n" + + "- " + strprintf(_("New tip: %s, height %d, work %s"), + pindexMostWork->phashBlock->GetHex(), pindexMostWork->nHeight, pindexMostWork->nChainWork.GetHex()) + "\n" + + "- " + strprintf(_("Fork point: %s %s, height %d"), + ASSETCHAINS_SYMBOL,pindexFork->phashBlock->GetHex(), pindexFork->nHeight) + "\n\n" + + _("Please help, human!"); + LogPrintf("*** %s\n", msg); + uiInterface.ThreadSafeMessageBox(msg, "", CClientUIInterface::MSG_ERROR); + StartShutdown(); + return false; + } } // Disconnect active blocks which are no longer in the best chain. From dd74b40db3ec80378a17b71c6e7645dbd01b1fd3 Mon Sep 17 00:00:00 2001 From: SHossain Date: Sun, 30 Sep 2018 20:02:05 +0100 Subject: [PATCH 04/94] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e8ed8c3cb..9585c7f78 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,14 @@ This is the official Komodo sourcecode repository based on https://github.com/jl ## Development Resources - Komodo Website: [https://komodoplatform.com/](https://komodoplatform.com/) -- Komodo Blockexplorer: [https://kmdexplorer.io//](https://https://kmdexplorer.io/) +- Komodo Blockexplorer: [https://kmdexplorer.io//](https://kmdexplorer.io/) +- Komodo Discord: [https://komodoplatform.com/discord](https://komodoplatform.com/discord) - Forum: [https://forum.komodoplatform.com/](https://forum.komodoplatform.com/) - Mail: [info@komodoplatform.com](mailto:info@komodoplatform.com) - Support: [https://support.komodoplatform.com/support/home](https://support.komodoplatform.com/support/home) -- Knowledgebase & How-to: [https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages](https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages) -- API references: [http://docs.komodoplatform.com/](http://docs.komodoplatform.com/) -- Blog: [http://blog.komodoplatform.com/](http://blog.komodoplatform.com/) +- Knowledgebase & How-to: [https://support.komodoplatform.com/en/support/solutions](https://support.komodoplatform.com/en/support/solutions) +- API references & Dev Documentation: [https://docs.komodoplatform.com/](https://docs.komodoplatform.com/) +- Blog: [https://blog.komodoplatform.com/](https://blog.komodoplatform.com/) - Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/03/2018-03-12-Komodo-White-Paper-Full.pdf) - Komodo Platform public material: [Komodo Platform public material](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) From 7d88c013d0487b948c436107d0e34b73a0610596 Mon Sep 17 00:00:00 2001 From: SHossain Date: Mon, 1 Oct 2018 10:51:05 +0100 Subject: [PATCH 05/94] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9585c7f78..92a7014f4 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,16 @@ This is the official Komodo sourcecode repository based on https://github.com/jl ## Development Resources -- Komodo Website: [https://komodoplatform.com/](https://komodoplatform.com/) -- Komodo Blockexplorer: [https://kmdexplorer.io//](https://kmdexplorer.io/) +- Komodo Website: [https://komodoplatform.com](https://komodoplatform.com/) +- Komodo Blockexplorer: [https://kmdexplorer.io](https://kmdexplorer.io/) - Komodo Discord: [https://komodoplatform.com/discord](https://komodoplatform.com/discord) -- Forum: [https://forum.komodoplatform.com/](https://forum.komodoplatform.com/) +- Forum: [https://forum.komodoplatform.com](https://forum.komodoplatform.com/) - Mail: [info@komodoplatform.com](mailto:info@komodoplatform.com) - Support: [https://support.komodoplatform.com/support/home](https://support.komodoplatform.com/support/home) - Knowledgebase & How-to: [https://support.komodoplatform.com/en/support/solutions](https://support.komodoplatform.com/en/support/solutions) -- API references & Dev Documentation: [https://docs.komodoplatform.com/](https://docs.komodoplatform.com/) -- Blog: [https://blog.komodoplatform.com/](https://blog.komodoplatform.com/) -- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/wp-content/uploads/2018/03/2018-03-12-Komodo-White-Paper-Full.pdf) +- API references & Dev Documentation: [https://docs.komodoplatform.com](https://docs.komodoplatform.com/) +- Blog: [https://blog.komodoplatform.com](https://blog.komodoplatform.com/) +- Whitepaper: [Komodo Whitepaper](https://komodoplatform.com/whitepaper) - Komodo Platform public material: [Komodo Platform public material](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) ## List of Komodo Platform Technologies From f8ffce7f35e4769a8efc62dce98c97feae76466d Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Thu, 18 Oct 2018 10:11:48 -0700 Subject: [PATCH 06/94] This extracts new concept of dpowconfs (confs vs rawconfs) from fsm branch to master --- src/cryptoconditions/compile | 13 +++++++------ src/komodo.h | 2 +- src/komodo_bitcoind.h | 21 +++++++++------------ src/komodo_globals.h | 2 +- src/komodo_kv.h | 2 +- src/komodo_notary.h | 15 +++++++++++++++ src/komodo_utils.h | 4 ++++ src/rpcblockchain.cpp | 16 ++++++++++++---- src/rpcrawtransaction.cpp | 9 ++++++--- 9 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/cryptoconditions/compile b/src/cryptoconditions/compile index a85b723c7..99e50524b 100755 --- a/src/cryptoconditions/compile +++ b/src/cryptoconditions/compile @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -255,7 +255,8 @@ EOF echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,9 +340,9 @@ exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/src/komodo.h b/src/komodo.h index b233f2ffa..e303c2bac 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -851,7 +851,7 @@ void komodo_connectblock(CBlockIndex *pindex,CBlock& block) printf("%02x",scriptPubKey[k]); printf(" scriptPubKey doesnt match any notary vini.%d of %d\n",j,numvins); } - } else printf("cant get scriptPubKey for ht.%d txi.%d vin.%d\n",height,i,j); + } //else printf("cant get scriptPubKey for ht.%d txi.%d vin.%d\n",height,i,j); } numvalid = bitweight(signedmask); if ( (((height < 90000 || (signedmask & 1) != 0) && numvalid >= KOMODO_MINRATIFY) || diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 13501d2a9..73a49e10c 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -391,7 +391,7 @@ int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heig { if ( (item= jobj(json,(char *)"result")) != 0 ) { - txid_confirmations = jint(item,(char *)"confirmations"); + txid_confirmations = jint(item,(char *)"rawconfirmations"); if ( txid_confirmations > 0 && height > txid_confirmations ) txid_height = height - txid_confirmations; else txid_height = height; @@ -1284,7 +1284,7 @@ uint32_t komodo_stake(int32_t validateflag,arith_uint256 bnTarget,int32_t nHeigh arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc) { - int32_t oldflag = 0; + int32_t oldflag = 0,dispflag = 0; CBlockIndex *pindex; arith_uint256 easydiff,bnTarget,hashval,sum,ave; bool fNegative,fOverflow; int32_t i,n,m,ht,percPoS,diff,val; *percPoSp = percPoS = 0; if ( height <= 10 || (ASSETCHAINS_STAKED == 100 && height <= 100) ) @@ -1303,23 +1303,23 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he { n++; percPoS++; - if ( ASSETCHAINS_STAKED < 100 ) + if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 ) fprintf(stderr,"0"); } else { - if ( ASSETCHAINS_STAKED < 100 ) + if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 ) fprintf(stderr,"1"); sum += UintToArith256(pindex->GetBlockHash()); m++; } } - if ( ASSETCHAINS_STAKED < 100 && (i % 10) == 9 ) + if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 && (i % 10) == 9 ) fprintf(stderr," %d, ",percPoS); } if ( m+n < 100 ) percPoS = ((percPoS * n) + (goalperc * (100-n))) / 100; - if ( ASSETCHAINS_STAKED < 100 ) + if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 ) fprintf(stderr," -> %d%% percPoS vs goalperc.%d ht.%d\n",percPoS,goalperc,height); *percPoSp = percPoS; if ( m > 0 ) @@ -1332,12 +1332,10 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he percPoS = 1; if ( percPoS < goalperc ) // increase PoW diff -> lower bnTarget { - //if ( oldflag != 0 ) - // bnTarget = (ave * arith_uint256(percPoS * percPoS)) / arith_uint256(goalperc * goalperc * goalperc); if ( oldflag != 0 ) bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS); else bnTarget = (ave / arith_uint256(goalperc * goalperc * goalperc * goalperc)) * arith_uint256(percPoS * percPoS); - if ( ASSETCHAINS_STAKED < 100 ) + if ( dispflag != 0 && ASSETCHAINS_STAKED < 100 ) { for (i=31; i>=24; i--) fprintf(stderr,"%02x",((uint8_t *)&ave)[i]); @@ -1355,7 +1353,6 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he if ( oldflag != 0 ) { bnTarget = ((ave * arith_uint256(goalperc)) + (easydiff * arith_uint256(percPoS))) / arith_uint256(percPoS + goalperc); - //bnTarget = (bnTarget * arith_uint256(percPoS * percPoS * percPoS)) / arith_uint256(goalperc * goalperc); bnTarget = (bnTarget / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS); } else bnTarget = (ave / arith_uint256(goalperc * goalperc)) * arith_uint256(percPoS * percPoS * percPoS); @@ -1367,7 +1364,7 @@ arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t he if ( bnTarget < ave ) bnTarget = ave; } - if ( 1 ) + if ( dispflag != 0 ) { for (i=31; i>=24; i--) fprintf(stderr,"%02x",((uint8_t *)&ave)[i]); @@ -1453,7 +1450,7 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED); if ( bhash < bnTarget ) { - fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); + //fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); isPoS = 0; } } diff --git a/src/komodo_globals.h b/src/komodo_globals.h index f352b5333..a3a4e3cae 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -52,7 +52,7 @@ uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN],ASSETCHAINS_USERPASS[4096]; uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; -uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT; +uint32_t ASSETCHAIN_INIT,ASSETCHAINS_CC,KOMODO_STOPAT,KOMODO_DPOWCONFS = 1; uint32_t ASSETCHAINS_MAGIC = 2387029918; uint64_t KOMODO_INTERESTSUM,KOMODO_WALLETBALANCE; uint64_t ASSETCHAINS_ENDSUBSIDY,ASSETCHAINS_REWARD,ASSETCHAINS_HALVING,ASSETCHAINS_DECAY,ASSETCHAINS_COMMISSION,ASSETCHAINS_STAKED,ASSETCHAINS_SUPPLY = 10; diff --git a/src/komodo_kv.h b/src/komodo_kv.h index 37e11d06d..834584e44 100644 --- a/src/komodo_kv.h +++ b/src/komodo_kv.h @@ -117,7 +117,7 @@ void komodo_kvupdate(uint8_t *opretbuf,int32_t opretlen,uint64_t value) } valueptr = &key[keylen]; fee = komodo_kvfee(flags,opretlen,keylen); - //printf("fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]); + //fprintf(stderr,"fee %.8f vs %.8f flags.%d keylen.%d valuesize.%d height.%d (%02x %02x %02x) (%02x %02x %02x)\n",(double)fee/COIN,(double)value/COIN,flags,keylen,valuesize,height,key[0],key[1],key[2],valueptr[0],valueptr[1],valueptr[2]); if ( value >= fee ) { coresize = (int32_t)(sizeof(flags)+sizeof(height)+sizeof(keylen)+sizeof(valuesize)+keylen+valuesize+1); diff --git a/src/komodo_notary.h b/src/komodo_notary.h index 04fd30d5f..8c51c7924 100644 --- a/src/komodo_notary.h +++ b/src/komodo_notary.h @@ -452,6 +452,21 @@ int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 * } } +int32_t komodo_dpowconfs(int32_t txheight,int32_t numconfs) +{ + char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; + if ( KOMODO_DPOWCONFS != 0 && txheight > 0 && numconfs > 0 && (sp= komodo_stateptr(symbol,dest)) != 0 ) + { + if ( sp->NOTARIZED_HEIGHT > 0 ) + { + if ( txheight < sp->NOTARIZED_HEIGHT ) + return(numconfs); + else return(1); + } + } + return(numconfs); +} + int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t height,uint256 *MoMoMp,int32_t *MoMoMoffsetp,int32_t *MoMoMdepthp,int32_t *kmdstartip,int32_t *kmdendip) { struct notarized_checkpoint *np = 0; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index 75f68d87d..e6f6a044d 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1700,6 +1700,7 @@ void komodo_args(char *argv0) break; } } + int32_t dpowconfs = KOMODO_DPOWCONFS; if ( ASSETCHAINS_SYMBOL[0] != 0 ) { BITCOIND_RPCPORT = GetArg("-rpcport", ASSETCHAINS_RPCPORT); @@ -1709,7 +1710,10 @@ void komodo_args(char *argv0) ASSETCHAINS_HALVING *= 5; fprintf(stderr,"PIRATE halving changed to %d %.1f days\n",(int32_t)ASSETCHAINS_HALVING,(double)ASSETCHAINS_HALVING/1440); } + else if ( strcmp("VRSC",ASSETCHAINS_SYMBOL) == 0 ) + dpowconfs = 0; } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); + KOMODO_DPOWCONFS = GetArg("-dpowconfs",dpowconfs); } void komodo_nameset(char *symbol,char *dest,char *source) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index e9cf54bb4..815860c7d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -32,6 +32,7 @@ using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); int32_t komodo_longestchain(); +int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty) { @@ -117,7 +118,8 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex) // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", blockindex->nVersion)); result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); @@ -148,7 +150,8 @@ UniValue blockToDeltasJSON(const CBlock& block, const CBlockIndex* blockindex) } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block is an orphan"); } - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -265,7 +268,8 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); + result.push_back(Pair("confirmations", komodo_dpowconfs(blockindex->nHeight,confirmations))); + result.push_back(Pair("rawconfirmations", confirmations)); result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); @@ -1150,7 +1154,11 @@ UniValue gettxout(const UniValue& params, bool fHelp) ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) ret.push_back(Pair("confirmations", 0)); - else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); + else + { + ret.push_back(Pair("confirmations", komodo_dpowconfs(coins.nHeight,pindex->nHeight - coins.nHeight + 1))); + ret.push_back(Pair("rawconfirmations", pindex->nHeight - coins.nHeight + 1)); + } ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); uint64_t interest; int32_t txheight; uint32_t locktime; if ( (interest= komodo_accrued_interest(&txheight,&locktime,hash,n,coins.nHeight,coins.vout[n].nValue,(int32_t)pindex->nHeight)) != 0 ) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 798b991d7..a870d526c 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -34,6 +34,7 @@ using namespace std; extern char ASSETCHAINS_SYMBOL[]; +int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { @@ -230,7 +231,8 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue& if (nConfirmations > 0) { entry.push_back(Pair("height", nHeight)); - entry.push_back(Pair("confirmations", nConfirmations)); + entry.push_back(Pair("confirmations", komodo_dpowconfs(nHeight,nConfirmations))); + entry.push_back(Pair("rawconfirmations", nConfirmations)); entry.push_back(Pair("time", nBlockTime)); entry.push_back(Pair("blocktime", nBlockTime)); } else { @@ -290,7 +292,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { entry.push_back(Pair("height", pindex->nHeight)); - entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); + entry.push_back(Pair("rawconfirmations", 1 + chainActive.Height() - pindex->nHeight)); + entry.push_back(Pair("confirmations", komodo_dpowconfs(pindex->nHeight,1 + chainActive.Height() - pindex->nHeight))); entry.push_back(Pair("time", pindex->GetBlockTime())); entry.push_back(Pair("blocktime", pindex->GetBlockTime())); } else { @@ -477,7 +480,7 @@ int32_t gettxout_scriptPubKey(uint8_t *scriptPubKey,int32_t maxsize,uint256 txid uint256 hashBlock; if ( GetTransaction(txid,tx,hashBlock,false) == 0 ) return(-1); - else if ( n <= tx.vout.size() ) // vout.size() seems off by 1 + else if ( n < tx.vout.size() ) { ptr = (uint8_t *)tx.vout[n].scriptPubKey.data(); m = tx.vout[n].scriptPubKey.size(); From 9bf7b5c1f5f48c054794666201db3411a7341ef2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 19 Oct 2018 06:38:28 -1100 Subject: [PATCH 07/94] Dpowconfs for wallet --- src/wallet/rpcwallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 386208039..93ec9cf0b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -89,7 +89,8 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0; int confirms = wtx.GetDepthInMainChain(); - entry.push_back(Pair("confirmations", confirms)); + entry.push_back(Pair("rawconfirmations", confirms)); + entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); if (wtx.IsCoinBase()) entry.push_back(Pair("generated", true)); if (confirms > 0) From b4e1a4f87bf9baeb26b9403f1445ec7bd1b30210 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 19 Oct 2018 06:49:32 -1100 Subject: [PATCH 08/94] Fix syntax --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 93ec9cf0b..20e5eb27e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -47,6 +47,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; extern UniValue TxJoinSplitToJSON(const CTransaction& tx); extern uint8_t ASSETCHAINS_PRIVATE; uint32_t komodo_segid32(char *coinaddr); +int32_t komodo_dpowconfs(int32_t txheight,int32_t numconfs); int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; From f776d511492946b075aabcd0417e498b54b72d79 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 24 Oct 2018 04:54:29 -1100 Subject: [PATCH 09/94] Fix gettransaction crash with dpowconfs --- src/cc/dice.cpp | 2 +- src/wallet/rpcwallet.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 4271186da..b0bb8ba49 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -279,7 +279,7 @@ uint64_t DiceCalc(int64_t bet,int64_t odds,int64_t minbet,int64_t maxbet,int64_t break; } } - fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1))); + //fprintf(stderr,"modval %d vs %d\n",modval,(int32_t)(10000/(odds+1))); if ( modval < 10000/(odds+1) ) winnings = bet * (odds+1); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 20e5eb27e..1a1963852 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -91,16 +91,16 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) //int32_t i,n,txheight; uint32_t locktime; uint64_t interest = 0; int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("rawconfirmations", confirms)); - entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); if (wtx.IsCoinBase()) entry.push_back(Pair("generated", true)); if (confirms > 0) { + entry.push_back(Pair("confirmations", komodo_dpowconfs((int32_t)mapBlockIndex[wtx.hashBlock]->nHeight,confirms))); entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); entry.push_back(Pair("blockindex", wtx.nIndex)); entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); entry.push_back(Pair("expiryheight", (int64_t)wtx.nExpiryHeight)); - } + } else entry.push_back(Pair("confirmations", confirms)); uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); UniValue conflicts(UniValue::VARR); From f51c4d471692b016921cfc443bb653b50a39f6a2 Mon Sep 17 00:00:00 2001 From: Scott Sadler Date: Thu, 1 Nov 2018 10:12:18 +0100 Subject: [PATCH 10/94] check many MoMoMs on tx import --- src/Makefile.ktest.include | 1 - src/cc/eval.cpp | 11 -- src/cc/eval.h | 1 - src/cc/import.cpp | 9 +- src/crosschain.cpp | 35 ++++- src/crosschain.h | 2 +- src/test-komodo/test_crosschain.cpp | 213 ---------------------------- 7 files changed, 38 insertions(+), 234 deletions(-) delete mode 100644 src/test-komodo/test_crosschain.cpp diff --git a/src/Makefile.ktest.include b/src/Makefile.ktest.include index 07c64caa0..640c154e4 100644 --- a/src/Makefile.ktest.include +++ b/src/Makefile.ktest.include @@ -10,7 +10,6 @@ komodo_test_SOURCES = \ test-komodo/test_coinimport.cpp \ test-komodo/test_eval_bet.cpp \ test-komodo/test_eval_notarisation.cpp \ - test-komodo/test_crosschain.cpp \ test-komodo/test_parse_notarisation.cpp komodo_test_CPPFLAGS = $(komodod_CPPFLAGS) diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index b6fcf57dd..1aaa24d56 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -192,17 +192,6 @@ bool Eval::GetNotarisationData(const uint256 notaryHash, NotarisationData &data) return true; } -/* - * Get MoMoM corresponding to a notarisation tx hash (on assetchain) - */ -bool Eval::GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const -{ - std::pair out; - if (!GetNextBacknotarisation(kmdNotarisationHash, out)) return false; - momom = out.second.MoMoM; - return true; -} - uint32_t Eval::GetAssetchainsCC() const { diff --git a/src/cc/eval.h b/src/cc/eval.h index 9ff0ca623..b9189bc89 100644 --- a/src/cc/eval.h +++ b/src/cc/eval.h @@ -103,7 +103,6 @@ public: virtual bool GetBlock(uint256 hash, CBlockIndex& blockIdx) const; virtual int32_t GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t timestamp) const; virtual bool GetNotarisationData(uint256 notarisationHash, NotarisationData &data) const; - virtual bool GetProofRoot(uint256 kmdNotarisationHash, uint256 &momom) const; virtual bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const; virtual uint32_t GetAssetchainsCC() const; virtual std::string GetAssetchainsSymbol() const; diff --git a/src/cc/import.cpp b/src/cc/import.cpp index ffc94ac43..b250bb7bf 100644 --- a/src/cc/import.cpp +++ b/src/cc/import.cpp @@ -16,6 +16,7 @@ #include "cc/eval.h" #include "cc/utils.h" #include "importcoin.h" +#include "crosschain.h" #include "primitives/transaction.h" @@ -75,12 +76,8 @@ bool Eval::ImportCoin(const std::vector params, const CTransaction &imp // Check proof confirms existance of burnTx { - uint256 momom, target; - if (!GetProofRoot(proof.first, momom)) - return Invalid("coudnt-load-momom"); - - target = proof.second.Exec(burnTx.GetHash()); - if (momom != proof.second.Exec(burnTx.GetHash())) + uint256 target = proof.second.Exec(burnTx.GetHash()); + if (!CheckMoMoM(proof.first, target)) return Invalid("momom-check-fail"); } diff --git a/src/crosschain.cpp b/src/crosschain.cpp index 831c7bcae..01763c975 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -95,8 +95,9 @@ template int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &found) { int limit = std::min(nHeight + NOTARISATION_SCAN_LIMIT_BLOCKS, chainActive.Height()); + int start = std::max(nHeight, 1); - for (int h=nHeight; hphashBlock, notarisations)) @@ -245,6 +246,38 @@ bool GetNextBacknotarisation(uint256 kmdNotarisationTxid, Notarisation &out) } +bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) +{ + /* + * Given a notarisation hash and an MoMoM. Backnotarisations may arrive out of order + * or multiple in the same block. So dereference the notarisation hash to the corresponding + * backnotarisation and scan around the kmdheight to see if the MoMoM is a match. + * This is a sledgehammer approach... + */ + + Notarisation bn; + if (!GetBackNotarisation(kmdNotarisationHash, bn)) + return false; + + // Need to get block height of that backnotarisation + EvalRef eval; + CBlockIndex block; + CTransaction tx; + if (!eval->GetTxConfirmed(bn.first, tx, block)){ + fprintf(stderr, "Can't get height of backnotarisation, this should not happen\n"); + return false; + } + + Notarisation nota; + auto checkMoMoM = [&](Notarisation ¬a) { + return nota.second.MoMoM == momom; + }; + + return (bool) ScanNotarisationsFromHeight(block.nHeight-100, checkMoMoM, nota); + +} + + /* * On assetchain * in: txid diff --git a/src/crosschain.h b/src/crosschain.h index 15452ac63..1fbd7603a 100644 --- a/src/crosschain.h +++ b/src/crosschain.h @@ -15,7 +15,7 @@ TxProof GetCrossChainProof(const uint256 txid, const char* targetSymbol, uint32_ void CompleteImportTransaction(CTransaction &importTx); /* On assetchain */ -bool GetNextBacknotarisation(uint256 txid, std::pair &bn); +bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom); #endif /* CROSSCHAIN_H */ diff --git a/src/test-komodo/test_crosschain.cpp b/src/test-komodo/test_crosschain.cpp deleted file mode 100644 index 9d24b4d1d..000000000 --- a/src/test-komodo/test_crosschain.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include - -#include "cc/eval.h" -#include "importcoin.h" -#include "base58.h" -#include "core_io.h" -#include "crosschain.h" -#include "key.h" -#include "komodo_structs.h" -#include "main.h" -#include "notarisationdb.h" -#include "primitives/block.h" -#include "primitives/transaction.h" -#include "script/cc.h" -#include "script/interpreter.h" -#include "script/serverchecker.h" -#include "txmempool.h" -#include "crosschain.h" - -#include "testutils.h" - - -extern uint256 komodo_calcMoM(int32_t height,int32_t MoMdepth); -extern bool KOMODO_TEST_ASSETCHAIN_SKIP_POW; - - -/* - * Tests for the whole process of creating and validating notary proofs - * using proof roots (MoMoMs). This is to support coin imports. - */ - -namespace TestCrossChainProof { - - -class TestCrossChain : public ::testing::Test, public Eval { -public: - bool CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const - { - NotarisationData data(2); - return ParseNotarisationOpReturn(tx, data); // If it parses it's valid - } -protected: - static void SetUpTestCase() { } - virtual void SetUp() { - KOMODO_TEST_ASSETCHAIN_SKIP_POW = 1; - ASSETCHAINS_CC = 1; - EVAL_TEST = this; - } -}; - - -uint256 endianHash(uint256 h) -{ - uint256 out; - for (int i=0; i<32; i++) { - out.begin()[31-i] = h.begin()[i]; - } - return out; -} - - -TEST_F(TestCrossChain, testCreateAndValidateImportProof) -{ - /* - * This tests the full process of creation of a cross chain proof. - * For the purposes of the test we will use one assetchain and a KMD chain. - * - * In order to do this test, we need 2 blockchains, so we'll fork and make a socket - * for IPC. - */ - - int childPid = fork(); - void *ctx = zmq_ctx_new(); - void *socket = zmq_socket(ctx, ZMQ_PAIR); - if (!childPid) - strcpy(ASSETCHAINS_SYMBOL, "PIZZA"); - setupChain(); - std::vector blocks; - blocks.resize(1000); - NotarisationData a2kmd(0), kmd2a(1); - int numTestNotarisations = 10; - - - auto SendIPC = [&] (std::vector v) { - assert(v.size() == zmq_send(socket, v.data(), v.size(), 0)); - }; - - auto RecvIPC = [&] () { - std::vector out; - out.resize(100000); - int len = zmq_recv(socket, out.data(), out.size(), 0); - assert(len != -1); - out.resize(len); - return out; - }; - - auto RecordNotarisation = [&] (CTransaction inputTx, NotarisationData data) { - CMutableTransaction mtx = spendTx(inputTx); - mtx.vout.resize(2); - mtx.vout[0].scriptPubKey << VCH(notaryKey.GetPubKey().begin(), 33) << OP_CHECKSIG; - mtx.vout[1].scriptPubKey << OP_RETURN << E_MARSHAL(ss << data); - mtx.vout[1].nValue = 0; - mtx.vin[0].scriptSig << getSig(mtx, inputTx.vout[0].scriptPubKey); - - acceptTxFail(CTransaction(mtx)); - return mtx.GetHash(); - }; - - auto RunTestAssetchain = [&] () - { - NotarisationData n(0), back(1); - strcpy(n.symbol, "PIZZA"); - n.ccId = 2; - int height = 0; - - /* - * Send notarisations and write backnotarisations - */ - for (int ni=0; ni> back)); - RecordNotarisation(blocks[height].vtx[0], back); - } - - /* - * Test a proof - */ - uint256 txid = blocks[7].vtx[0].GetHash(); - TxProof proof = GetAssetchainProof(txid); - SendIPC(E_MARSHAL(ss << txid; ss << proof)); - E_UNMARSHAL(RecvIPC(), ss >> proof); - - std::pair bn; - if (!GetNextBacknotarisation(proof.first, bn)) { - printf("GetNextBackNotarisation failed\n"); - return 1; - } - if (proof.second.Exec(txid) != bn.second.MoMoM) { - printf("MoMom incorrect\n"); - return 1; - } - return 0; - }; - - auto RunTestKmd = [&] () - { - NotarisationData n(0); - int height = 0; - - /* - * Write notarisations and send backnotarisations - */ - for (int ni=0; ni> n); - // Grab a coinbase input to fund notarisation - generateBlock(&blocks[++height]); - n.txHash = RecordNotarisation(blocks[height].vtx[0], n); - { - std::vector moms; - uint256 destNotarisationTxid; - n.MoMoM = CalculateProofRoot(n.symbol, 2, height, moms, destNotarisationTxid); - } - n.IsBackNotarisation = 1; - SendIPC(E_MARSHAL(ss << n)); - } - - /* - * Extend proof - */ - TxProof proof; - uint256 txid; - // Extend proof to MoMoM - assert(E_UNMARSHAL(RecvIPC(), ss >> txid; ss >> proof)); - proof = GetCrossChainProof(txid, (char*)"PIZZA", 2, proof); - SendIPC(E_MARSHAL(ss << proof)); - }; - - const char endpoint[] = "ipc://tmpKomodoTestCrossChainSock"; - - if (!childPid) { - assert(0 == zmq_connect(socket, endpoint)); - usleep(20000); - int out = RunTestAssetchain(); - if (!out) printf("Assetchain success\n"); - exit(out); - } - else { - assert(0 == zmq_bind(socket, endpoint)); - RunTestKmd(); - int returnStatus; - waitpid(childPid, &returnStatus, 0); - unlink("tmpKomodoTestCrossChainSock"); - ASSERT_EQ(0, returnStatus); - } - -} - - -} /* namespace TestCrossChainProof */ From 4b3228fccfa1d4f9777f3ceb486959117f567d91 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 6 Nov 2018 22:55:29 -1100 Subject: [PATCH 11/94] Prevent illegal CC funcid --- src/cc/assets.cpp | 11 ++++++++--- src/cc/dice.cpp | 4 ++++ src/cc/oracles.cpp | 4 ++++ src/cc/rewards.cpp | 4 ++++ src/wallet/rpcwallet.cpp | 3 ++- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 1ddbdc4f8..331959a37 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -249,8 +249,8 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx } fprintf(stderr,"fillbuy validated\n"); break; - case 'e': // selloffer - break; // disable swaps + //case 'e': // selloffer + // break; // disable swaps case 's': // selloffer //vin.0: normal input //vin.1+: valid CC output for sale @@ -322,6 +322,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx fprintf(stderr,"fill validated\n"); break; case 'E': // fillexchange + return(false); break; // disable asset swaps //vin.0: normal input //vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0] @@ -371,7 +372,11 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx } fprintf(stderr,"fill validated\n"); break; - } + default: + fprintf(stderr,"illegal assets funcid.(%c)\n",funcid); + return(false); + break; + } return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); } diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index b0bb8ba49..a86fbea0c 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -605,6 +605,10 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx) else if ( DiceVerifyTimeout(vinTx,timeoutblocks) == 0 ) return eval->Invalid("invalid timeout claim for timeout"); break; + default: + fprintf(stderr,"illegal dice funcid.(%c)\n",funcid); + return(false); + break; } } return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index c24ad5a8b..5abeada8e 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -649,6 +649,10 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t } return eval->Invalid("unexpected OraclesValidate 'D' tx invalid"); break; + default: + fprintf(stderr,"illegal oracles funcid.(%c)\n",script[1]); + return(false); + break; } } return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index a70071af9..dd637a342 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -287,6 +287,10 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t return eval->Invalid("unlock tx vout.2 isnt 0"); preventCCvouts = 1; break; + default: + fprintf(stderr,"illegal rewards funcid.(%c)\n",funcid); + return(false); + break; } } return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1a1963852..fa8d3ec31 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -48,6 +48,7 @@ extern UniValue TxJoinSplitToJSON(const CTransaction& tx); extern uint8_t ASSETCHAINS_PRIVATE; uint32_t komodo_segid32(char *coinaddr); int32_t komodo_dpowconfs(int32_t txheight,int32_t numconfs); +int32_t komodo_isnotaryvout(char *coinaddr); // from ac_private chains only int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -3789,7 +3790,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address ); } } - else if ( ASSETCHAINS_PRIVATE != 0 ) + else if ( ASSETCHAINS_PRIVATE != 0 && komodo_isnotaryvout((char *)address.c_str()) == 0 ) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain"); if (setAddress.count(address)) From 1eb57a7d9791101cf584feca0faad741c38a9cbb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 7 Nov 2018 00:33:16 -1100 Subject: [PATCH 12/94] Eval->error() --- src/cc/assets.cpp | 4 ++-- src/cc/dice.cpp | 2 +- src/cc/oracles.cpp | 2 +- src/cc/rewards.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 331959a37..1892a383f 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -322,7 +322,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx fprintf(stderr,"fill validated\n"); break; case 'E': // fillexchange - return(false); + return eval->Invalid("unexpected assets funcid"); break; // disable asset swaps //vin.0: normal input //vin.1: unspendable.(vout.0 assetoshis from selloffer) sellTx.vout[0] @@ -374,7 +374,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx break; default: fprintf(stderr,"illegal assets funcid.(%c)\n",funcid); - return(false); + return eval->Invalid("unexpected assets funcid"); break; } return(PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts)); diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index a86fbea0c..c83ecf17a 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -607,7 +607,7 @@ bool DiceValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &tx) break; default: fprintf(stderr,"illegal dice funcid.(%c)\n",funcid); - return(false); + return eval->Invalid("unexpected dice funcid"); break; } } diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index 5abeada8e..168f62313 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -651,7 +651,7 @@ bool OraclesValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t break; default: fprintf(stderr,"illegal oracles funcid.(%c)\n",script[1]); - return(false); + return eval->Invalid("unexpected OraclesValidate funcid"); break; } } diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index dd637a342..dc4c3be96 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -289,7 +289,7 @@ bool RewardsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &t break; default: fprintf(stderr,"illegal rewards funcid.(%c)\n",funcid); - return(false); + return eval->Invalid("unexpected rewards funcid"); break; } } From f5e142203e9d62db10a0500752fbfafb7e14ca14 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 13 Nov 2018 09:47:15 -1100 Subject: [PATCH 13/94] KOMODO_EXTRASATOSHI --- src/komodo_globals.h | 2 +- src/komodo_utils.h | 2 ++ src/main.cpp | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/komodo_globals.h b/src/komodo_globals.h index a3a4e3cae..1df5682a2 100644 --- a/src/komodo_globals.h +++ b/src/komodo_globals.h @@ -45,7 +45,7 @@ struct komodo_state KOMODO_STATES[34]; #define _COINBASE_MATURITY 100 int COINBASE_MATURITY = _COINBASE_MATURITY;//100; -int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1; +int32_t KOMODO_MININGTHREADS = -1,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAINS_SEED,KOMODO_ON_DEMAND,KOMODO_EXTERNAL_NOTARIES,KOMODO_PASSPORT_INITDONE,KOMODO_PAX,KOMODO_EXCHANGEWALLET,KOMODO_REWIND,KOMODO_CONNECTING = -1,KOMODO_EXTRASATOSHI; int32_t KOMODO_INSYNC,KOMODO_LASTMINED,prevKOMODO_LASTMINED,KOMODO_CCACTIVATE,JUMBLR_PAUSE = 1; std::string NOTARY_PUBKEY,ASSETCHAINS_NOTARIES,ASSETCHAINS_OVERRIDE_PUBKEY,DONATION_PUBKEY; uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33],ASSETCHAINS_PUBLIC,ASSETCHAINS_PRIVATE; diff --git a/src/komodo_utils.h b/src/komodo_utils.h index e6f6a044d..37820e3de 100644 --- a/src/komodo_utils.h +++ b/src/komodo_utils.h @@ -1714,6 +1714,8 @@ void komodo_args(char *argv0) dpowconfs = 0; } else BITCOIND_RPCPORT = GetArg("-rpcport", BaseParams().RPCPort()); KOMODO_DPOWCONFS = GetArg("-dpowconfs",dpowconfs); + if ( ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"SUPERNET") == 0 || strcmp(ASSETCHAINS_SYMBOL,"DEX") == 0 || strcmp(ASSETCHAINS_SYMBOL,"COQUI") == 0 || strcmp(ASSETCHAINS_SYMBOL,"PIRATE") == 0 ) + KOMODO_EXTRASATOSHI = 1; } void komodo_nameset(char *symbol,char *dest,char *source) diff --git a/src/main.cpp b/src/main.cpp index 3df3d39c9..9e5d3fbe9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -56,7 +56,7 @@ using namespace std; CCriticalSection cs_main; extern uint8_t NOTARY_PUBKEY33[33]; -extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING; +extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI; int32_t KOMODO_NEWBLOCKS; int32_t komodo_block2pubkey33(uint8_t *pubkey33,CBlock *block); void komodo_broadcast(CBlock *pblock,int32_t limit); @@ -3116,7 +3116,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin else fprintf(stderr,"checktoshis %.8f numvouts %d\n",dstr(checktoshis),(int32_t)block.vtx[0].vout.size()); } } - if ( block.vtx[0].GetValueOut() > blockReward+1 ) + if ( block.vtx[0].GetValueOut() > blockReward+KOMODO_EXTRASATOSHI ) { if ( ASSETCHAINS_SYMBOL[0] != 0 || pindex->nHeight >= KOMODO_NOTARIES_HEIGHT1 || block.vtx[0].vout[0].nValue > blockReward ) { From 7eaff5d90a579c3359d4abf83f309a1a62736d8c Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 27 Nov 2018 08:31:51 -1100 Subject: [PATCH 14/94] Possible fix for sapling CC --- src/cc/CCinclude.h | 1 + src/cc/faucet.cpp | 3 ++- src/komodo_bitcoind.h | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index 5cf549706..ddfecd47a 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -105,6 +105,7 @@ extern CWallet* pwalletMain; #endif bool GetAddressUnspent(uint160 addressHash, int type,std::vector > &unspentOutputs); CBlockIndex *komodo_getblockindex(uint256 hash); +int32_t komodo_nextheight(); static const uint256 zeroid; bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock); diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index baa32b856..ed457f234 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -214,7 +214,8 @@ std::string FaucetGet(uint64_t txfee) std::string FaucetFund(uint64_t txfee,int64_t funds) { - CMutableTransaction mtx; CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,faucetpk; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_FAUCET); if ( txfee == 0 ) txfee = 10000; diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 943c8c413..53c4afb08 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1062,6 +1062,14 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 return(0); } +int32_t komodo_nextheight() +{ + int32_t longest = komodo_longestchain(); + if ( (pindex= chainActive.LastTip()) != 0 && (ht= pindex->GetHeight()) >= longest ) + return(ht+1); + else return(longest + 1); +} + int32_t komodo_isrealtime(int32_t *kmdheightp) { struct komodo_state *sp; CBlockIndex *pindex; From 7d69cacf371991dc7bad9dcd9d53f81731f853d2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 27 Nov 2018 08:36:05 -1100 Subject: [PATCH 15/94] Ht --- 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 53c4afb08..34bd7e514 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1064,7 +1064,7 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 int32_t komodo_nextheight() { - int32_t longest = komodo_longestchain(); + int32_t ht,longest = komodo_longestchain(); if ( (pindex= chainActive.LastTip()) != 0 && (ht= pindex->GetHeight()) >= longest ) return(ht+1); else return(longest + 1); From 561a4a15ebe5b4e39d977bb619ebaef2ee659ef8 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 27 Nov 2018 08:37:10 -1100 Subject: [PATCH 16/94] CBlockIndex *pindex; --- 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 34bd7e514..1a0fad409 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1064,7 +1064,7 @@ uint64_t komodo_accrued_interest(int32_t *txheightp,uint32_t *locktimep,uint256 int32_t komodo_nextheight() { - int32_t ht,longest = komodo_longestchain(); + CBlockIndex *pindex; int32_t ht,longest = komodo_longestchain(); if ( (pindex= chainActive.LastTip()) != 0 && (ht= pindex->GetHeight()) >= longest ) return(ht+1); else return(longest + 1); From a0e51c46b16c52726dfa4bd8b541c951c855c1ff Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 27 Nov 2018 23:00:15 -1100 Subject: [PATCH 17/94] Sapling CC tx support --- src/cc/CCassetstx.cpp | 33 ++++++++++++++++++++++----------- src/cc/auction.cpp | 9 ++++++--- src/cc/betprotocol.cpp | 12 ++++++------ src/cc/channels.cpp | 12 ++++++++---- src/cc/dice.cpp | 12 ++++++++---- src/cc/faucet.cpp | 6 ++++-- src/cc/fsm.cpp | 6 ++++-- src/cc/gateways.cpp | 24 ++++++++++++++++-------- src/cc/heir.cpp | 9 ++++++--- src/cc/lotto.cpp | 9 ++++++--- src/cc/oracles.cpp | 15 ++++++++++----- src/cc/payments.cpp | 9 ++++++--- src/cc/pegs.cpp | 9 ++++++--- src/cc/prices.cpp | 9 ++++++--- src/cc/rewards.cpp | 12 ++++++++---- src/cc/triggers.cpp | 9 ++++++--- 16 files changed, 128 insertions(+), 67 deletions(-) diff --git a/src/cc/CCassetstx.cpp b/src/cc/CCassetstx.cpp index b374f00d4..ef208f87c 100644 --- a/src/cc/CCassetstx.cpp +++ b/src/cc/CCassetstx.cpp @@ -56,7 +56,8 @@ int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK int64_t GetAssetBalance(CPubKey pk,uint256 tokenid) { - CMutableTransaction mtx; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_ASSETS); return(AddAssetInputs(cp,mtx,pk,tokenid,0,0)); } @@ -186,7 +187,8 @@ UniValue AssetOrders(uint256 refassetid) std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std::string description) { - CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; struct CCcontract_info *cp,C; if ( assetsupply < 0 ) { fprintf(stderr,"negative assetsupply %lld\n",(long long)assetsupply); @@ -212,7 +214,8 @@ std::string CreateAsset(int64_t txfee,int64_t assetsupply,std::string name,std:: std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total) { - CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; uint64_t mask; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; if ( total < 0 ) { fprintf(stderr,"negative total %lld\n",(long long)total); @@ -247,7 +250,8 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector des std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector destpubkey,int64_t total,int32_t evalcode) { - CMutableTransaction mtx; CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; int64_t CCchange=0,inputs=0; struct CCcontract_info *cp,C; if ( total < 0 ) { fprintf(stderr,"negative total %lld\n",(long long)total); @@ -273,7 +277,8 @@ std::string AssetConvert(int64_t txfee,uint256 assetid,std::vector dest std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64_t pricetotal) { - CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector origpubkey; std::string name,description; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; struct CCcontract_info *cp,C; uint256 hashBlock; CTransaction vintx; std::vector origpubkey; std::string name,description; if ( bidamount < 0 || pricetotal < 0 ) { fprintf(stderr,"negative bidamount %lld, pricetotal %lld\n",(long long)bidamount,(long long)pricetotal); @@ -303,7 +308,8 @@ std::string CreateBuyOffer(int64_t txfee,int64_t bidamount,uint256 assetid,int64 std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t pricetotal) { - CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; if ( askamount < 0 || pricetotal < 0 ) { fprintf(stderr,"negative askamount %lld, askamount %lld\n",(long long)pricetotal,(long long)askamount); @@ -335,7 +341,8 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 assetid2,int64_t pricetotal) { - CMutableTransaction mtx; CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; uint64_t mask; int64_t inputs,CCchange; CScript opret; struct CCcontract_info *cp,C; fprintf(stderr,"asset swaps disabled\n"); return(""); if ( askamount < 0 || pricetotal < 0 ) @@ -374,7 +381,8 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid) { - CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t bidamount; CPubKey mypk; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_ASSETS); if ( txfee == 0 ) txfee = 10000; @@ -395,7 +403,8 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid) std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid) { - CMutableTransaction mtx; CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction vintx; uint64_t mask; uint256 hashBlock; int64_t askamount; CPubKey mypk; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_ASSETS); if ( txfee == 0 ) txfee = 10000; @@ -416,7 +425,8 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid) std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t fillamount) { - CTransaction vintx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction vintx; uint256 hashBlock; CPubKey mypk; std::vector origpubkey; int32_t bidvout=0; uint64_t mask; int64_t origprice,bidamount,paid_amount,remaining_required,inputs,CCchange=0; struct CCcontract_info *cp,C; if ( fillamount < 0 ) { fprintf(stderr,"negative fillamount %lld\n",(long long)fillamount); @@ -456,7 +466,8 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f std::string FillSell(int64_t txfee,uint256 assetid,uint256 assetid2,uint256 asktxid,int64_t fillunits) { - CTransaction vintx,filltx; uint256 hashBlock; CMutableTransaction mtx; CPubKey mypk; std::vector origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction vintx,filltx; uint256 hashBlock; CPubKey mypk; std::vector origpubkey; double dprice; uint64_t mask; int32_t askvout=0; int64_t received_assetoshis,total_nValue,orig_assetoshis,paid_nValue,remaining_nValue,inputs,CCchange=0; struct CCcontract_info *cp,C; if ( fillunits < 0 ) { CCerror = strprintf("negative fillunits %lld\n",(long long)fillunits); diff --git a/src/cc/auction.cpp b/src/cc/auction.cpp index 77650405e..1bc8533ec 100644 --- a/src/cc/auction.cpp +++ b/src/cc/auction.cpp @@ -150,7 +150,8 @@ int64_t AddAuctionInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPu std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount) { - CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_AUCTION); if ( txfee == 0 ) txfee = 10000; @@ -170,7 +171,8 @@ std::string AuctionBid(uint64_t txfee,uint256 itemhash,int64_t amount) std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid) { - CMutableTransaction mtx; CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Auctionpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_AUCTION); if ( txfee == 0 ) txfee = 10000; @@ -190,7 +192,8 @@ std::string AuctionDeliver(uint64_t txfee,uint256 itemhash,uint256 bidtxid) std::string AuctionPost(uint64_t txfee,uint256 itemhash,int64_t minbid,char *title,char *description) { - CMutableTransaction mtx; CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Auctionpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_AUCTION); if ( txfee == 0 ) txfee = 10000; diff --git a/src/cc/betprotocol.cpp b/src/cc/betprotocol.cpp index 41a05a797..fe3ae31c6 100644 --- a/src/cc/betprotocol.cpp +++ b/src/cc/betprotocol.cpp @@ -53,7 +53,7 @@ CC* BetProtocol::MakeDisputeCond() */ CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CC *disputeCond = MakeDisputeCond(); mtx.vout.push_back(CTxOut(spendFee, CCPubKey(disputeCond))); @@ -70,7 +70,7 @@ CMutableTransaction BetProtocol::MakeSessionTx(CAmount spendFee) CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint256 vmResultHash) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CC *disputeCond = MakeDisputeCond(); mtx.vin.push_back(CTxIn(signedSessionTxHash, 0, CScript())); @@ -84,7 +84,7 @@ CMutableTransaction BetProtocol::MakeDisputeTx(uint256 signedSessionTxHash, uint CMutableTransaction BetProtocol::MakePostEvidenceTx(uint256 signedSessionTxHash, int playerIdx, std::vector state) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); mtx.vin.push_back(CTxIn(signedSessionTxHash, playerIdx+1, CScript())); mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << state)); @@ -115,7 +115,7 @@ CC* BetProtocol::MakePayoutCond(uint256 signedSessionTxHash) CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signedSessionTxHash) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); CC *payoutCond = MakePayoutCond(signedSessionTxHash); mtx.vout.push_back(CTxOut(totalPayout, CCPubKey(payoutCond))); @@ -128,7 +128,7 @@ CMutableTransaction BetProtocol::MakeStakeTx(CAmount totalPayout, uint256 signed CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector payouts, uint256 signedStakeTxHash) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript())); mtx.vout = payouts; return mtx; @@ -138,7 +138,7 @@ CMutableTransaction BetProtocol::MakeAgreePayoutTx(std::vector payouts, CMutableTransaction BetProtocol::MakeImportPayoutTx(std::vector payouts, CTransaction signedDisputeTx, uint256 signedStakeTxHash, MoMProof momProof) { - CMutableTransaction mtx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CScript())); mtx.vout = payouts; CScript proofData; diff --git a/src/cc/channels.cpp b/src/cc/channels.cpp index 6ef09bfc5..60f907c27 100644 --- a/src/cc/channels.cpp +++ b/src/cc/channels.cpp @@ -430,7 +430,8 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64_t payment) { - CMutableTransaction mtx; uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + uint8_t hash[32],hashdest[32]; uint64_t funds; int32_t i; uint256 hashchain,entropy,hentropy; CPubKey mypk; struct CCcontract_info *cp,C; if ( numpayments <= 0 || payment <= 0 || numpayments > CHANNELS_MAXPAYMENTS ) @@ -464,7 +465,8 @@ std::string ChannelOpen(uint64_t txfee,CPubKey destpub,int32_t numpayments,int64 std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint256 secret) { - CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,srcpub,destpub; uint256 txid,hashchain,gensecret,hashblock,entropy,hentropy,prevtxid,param3; struct CCcontract_info *cp,C; int32_t i,funcid,prevdepth,numvouts,numpayments,totalnumpayments; int64_t payment,change,funds,param2; uint8_t hash[32],hashdest[32]; @@ -569,7 +571,8 @@ std::string ChannelPayment(uint64_t txfee,uint256 opentxid,int64_t amount, uint2 std::string ChannelClose(uint64_t txfee,uint256 opentxid) { - CMutableTransaction mtx; CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,srcpub,destpub; struct CCcontract_info *cp,C; CTransaction channelOpenTx; uint256 hashblock,tmp_txid,prevtxid,hashchain; int32_t numvouts,numpayments; @@ -616,7 +619,8 @@ std::string ChannelClose(uint64_t txfee,uint256 opentxid) std::string ChannelRefund(uint64_t txfee,uint256 opentxid,uint256 closetxid) { - CMutableTransaction mtx; CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk; struct CCcontract_info *cp,C; int64_t funds,payment,param2; int32_t i,numpayments,numvouts,param1; uint256 hashchain,hashblock,txid,prevtxid,param3,entropy,hentropy,secret; CTransaction channelOpenTx,channelCloseTx,prevTx; diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index a434a407a..37d6bfd41 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1329,7 +1329,8 @@ UniValue DiceList() std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t minbet,int64_t maxbet,int64_t maxodds,int64_t timeoutblocks) { - CMutableTransaction mtx; uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + uint256 zero; CScript fundingPubKey; CPubKey mypk,dicepk; int64_t a,b,c,d; uint64_t sbits; struct CCcontract_info *cp,C; if ( funds < 0 || minbet < 0 || maxbet < 0 || maxodds < 1 || maxodds > 9999 || timeoutblocks < 0 || timeoutblocks > 1440 ) { CCerror = "invalid parameter error"; @@ -1363,7 +1364,8 @@ std::string DiceCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) { - CMutableTransaction mtx; CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CScript fundingPubKey,scriptPubKey; uint256 entropy,hentropy; CPubKey mypk,dicepk; uint64_t sbits; struct CCcontract_info *cp,C; int64_t minbet,maxbet,maxodds,timeoutblocks; if ( amount < 0 ) { CCerror = "amount must be positive"; @@ -1406,7 +1408,8 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet,int32_t odds) { - CMutableTransaction mtx; CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CScript fundingPubKey; CPubKey mypk,dicepk; uint64_t sbits,entropyval,entropyval2; int64_t funding,minbet,maxbet,maxodds,timeoutblocks; uint256 entropytxid,entropytxid2,entropy,hentropy; struct CCcontract_info *cp,C; if ( bet < 0 ) { CCerror = "bet must be positive"; @@ -1464,7 +1467,8 @@ std::string DiceBet(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t bet std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyvout,int32_t *resultp,uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 bettxid,int32_t winlosetimeout,uint256 vin0txid,int32_t vin0vout) { - CMutableTransaction mtx,savemtx; CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits; + CMutableTransaction savemtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CScript scriptPubKey,fundingPubKey; CTransaction oldbetTx,betTx,entropyTx; uint256 hentropyproof,entropytxid,hashBlock,bettorentropy,entropy,hentropy,oldbettxid; CPubKey mypk,dicepk,fundingpk; struct CCcontract_info *cp,C; int64_t inputs=0,CCchange=0,odds,fundsneeded,minbet,maxbet,maxodds,timeoutblocks; int32_t oldentropyvout,retval=0,iswin=0; uint64_t entropyval,sbits; entropyused = zeroid; *resultp = 0; funcid = 0; diff --git a/src/cc/faucet.cpp b/src/cc/faucet.cpp index ed457f234..afd97c1aa 100644 --- a/src/cc/faucet.cpp +++ b/src/cc/faucet.cpp @@ -174,7 +174,8 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub std::string FaucetGet(uint64_t txfee) { - CMutableTransaction mtx,tmpmtx; CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,faucetpk; int64_t inputs,CCchange=0,nValue=FAUCETSIZE; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; cp = CCinit(&C,EVAL_FAUCET); if ( txfee == 0 ) txfee = 10000; @@ -232,7 +233,8 @@ std::string FaucetFund(uint64_t txfee,int64_t funds) UniValue FaucetInfo() { UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx; CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey faucetpk; struct CCcontract_info *cp,C; int64_t funding; result.push_back(Pair("result","success")); result.push_back(Pair("name","Faucet")); cp = CCinit(&C,EVAL_FAUCET); diff --git a/src/cc/fsm.cpp b/src/cc/fsm.cpp index 676537929..e75c53bcc 100644 --- a/src/cc/fsm.cpp +++ b/src/cc/fsm.cpp @@ -157,7 +157,8 @@ std::string FSMList() std::string FSMCreate(uint64_t txfee,std::string name,std::string states) { - CMutableTransaction mtx; CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,fsmpk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_FSM); if ( txfee == 0 ) txfee = 10000; @@ -177,7 +178,8 @@ std::string FSMCreate(uint64_t txfee,std::string name,std::string states) std::string FSMInfo(uint256 fsmtxid) { - CMutableTransaction mtx; CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,fsmpk; int64_t funds = 0; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_FSM); mypk = pubkey2pk(Mypubkey()); fsmpk = GetUnspendable(cp,0); diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 1abe73259..94d662193 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -748,7 +748,8 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256 std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t totalsupply,uint256 oracletxid,uint8_t M,uint8_t N,std::vector pubkeys) { - CMutableTransaction mtx; CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction oracletx; uint8_t taddr,prefix,prefix2; CPubKey mypk,gatewayspk; CScript opret; uint256 hashBlock; struct CCcontract_info *cp,C; std::string name,description,format; int32_t i,numvouts; int64_t fullsupply; char destaddr[64],coinaddr[64],str[65],*fstr; cp = CCinit(&C,EVAL_GATEWAYS); if ( strcmp((char *)"KMD",coin.c_str()) == 0 ) { @@ -833,7 +834,8 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::string refcoin,uint256 cointxid,int32_t claimvout,std::string deposithex,std::vectorproof,CPubKey destpub,int64_t amount) { - CMutableTransaction mtx; CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction bindtx; CPubKey mypk,gatewayspk; uint256 oracletxid,merkleroot,mhash,hashBlock,tokenid,txid; int64_t totalsupply; int32_t i,m,n,numvouts; uint8_t M,N,taddr,prefix,prefix2; std::string coin; struct CCcontract_info *cp,C; std::vector pubkeys,publishers; std::vectortxids; char str[67],depositaddr[64],txidaddr[64]; @@ -899,7 +901,8 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std:: std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,uint256 deposittxid,CPubKey destpub,int64_t amount) { - CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction tx; CPubKey mypk,gatewayspk,tmpdestpub; struct CCcontract_info *cp,C; uint8_t M,N,taddr,prefix,prefix2; std::string coin, deposithex; std::vector msigpubkeys,publishers; int64_t totalsupply,depositamount,tmpamount,inputs,CCchange=0; int32_t numvouts,claimvout,height; std::vector proof; uint256 hashBlock,assetid,oracletxid,tmptxid,cointxid; char str[65],depositaddr[64],coinaddr[64],destaddr[64]; std::vector txids; @@ -962,7 +965,8 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin,CPubKey withdrawpub,int64_t amount) { - CMutableTransaction mtx; CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction tx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; uint256 assetid,hashBlock,oracletxid; int32_t numvouts; int64_t totalsupply,inputs,CCchange=0; uint8_t M,N,taddr,prefix,prefix2; std::string coin; std::vector msigpubkeys; char depositaddr[64],str[65],coinaddr[64]; cp = CCinit(&C,EVAL_GATEWAYS); @@ -1001,7 +1005,8 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string hex) { - CMutableTransaction mtx; CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,txidaddrpk,signerpk; struct CCcontract_info *cp,C; CTransaction tx; std::vector > unspentOutputs; char txidaddr[65]; int32_t maxK,K=0; uint256 tmptxid,parttxid,hashBlock; cp = CCinit(&C,EVAL_GATEWAYS); @@ -1040,7 +1045,8 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 txid,std::string refcoin, std::string GatewaysCompleteSigning(uint64_t txfee,uint256 withdrawtxid,std::string refcoin,std::string hex) { - CMutableTransaction mtx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65]; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65]; cp = CCinit(&C,EVAL_GATEWAYS); mypk = pubkey2pk(Mypubkey()); gatewayspk = GetUnspendable(cp,0); @@ -1054,7 +1060,8 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 withdrawtxid,std::str std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string refcoin) { - CMutableTransaction mtx; CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65]; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,gatewayspk; struct CCcontract_info *cp,C; char txidaddr[65]; cp = CCinit(&C,EVAL_GATEWAYS); mypk = pubkey2pk(Mypubkey()); if ( txfee == 0 ) @@ -1247,7 +1254,8 @@ UniValue GatewaysList() UniValue GatewaysInfo(uint256 bindtxid) { - UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::string coin; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CMutableTransaction mtx; CPubKey Gatewayspk; struct CCcontract_info *cp,C; int32_t i; int64_t totalsupply,remaining; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::string coin; char str[67],numstr[65],depositaddr[64],gatewaysassets[64]; uint8_t M,N; std::vector pubkeys; uint8_t taddr,prefix,prefix2; uint256 tokenid,oracletxid,hashBlock; CTransaction tx; CPubKey Gatewayspk; struct CCcontract_info *cp,C; int32_t i; int64_t totalsupply,remaining; result.push_back(Pair("result","success")); result.push_back(Pair("name","Gateways")); cp = CCinit(&C,EVAL_GATEWAYS); diff --git a/src/cc/heir.cpp b/src/cc/heir.cpp index cdbc7918e..24aa35f59 100644 --- a/src/cc/heir.cpp +++ b/src/cc/heir.cpp @@ -143,7 +143,8 @@ int64_t AddHeirInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe std::string HeirGet(uint64_t txfee,int64_t nValue) { - CMutableTransaction mtx,tmpmtx; CPubKey mypk,Heirpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Heirpk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; cp = CCinit(&C,EVAL_HEIR); if ( txfee == 0 ) txfee = 10000; @@ -183,7 +184,8 @@ std::string HeirGet(uint64_t txfee,int64_t nValue) std::string HeirFund(uint64_t txfee,int64_t funds) { - CMutableTransaction mtx; CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Heirpk; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_HEIR); if ( txfee == 0 ) txfee = 10000; @@ -199,8 +201,9 @@ std::string HeirFund(uint64_t txfee,int64_t funds) UniValue HeirInfo() { + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx; CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding; + CPubKey Heirpk; struct CCcontract_info *cp,C; int64_t funding; result.push_back(Pair("result","success")); result.push_back(Pair("name","Heir")); cp = CCinit(&C,EVAL_HEIR); diff --git a/src/cc/lotto.cpp b/src/cc/lotto.cpp index 26ce11c7f..e89f2692a 100644 --- a/src/cc/lotto.cpp +++ b/src/cc/lotto.cpp @@ -283,7 +283,8 @@ UniValue LottoList() std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t ticketsize,int32_t odds,int32_t firstheight,int32_t period) { - CMutableTransaction mtx; uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + uint256 entropy,hentropy; CPubKey mypk,lottopk; uint64_t sbits; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; @@ -301,7 +302,8 @@ std::string LottoCreate(uint64_t txfee,char *planstr,int64_t funding,int32_t tic std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets) { - CMutableTransaction mtx; CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,lottopk; CScript opret; int64_t inputs,CCchange=0,nValue=COIN; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; @@ -321,7 +323,8 @@ std::string LottoTicket(uint64_t txfee,uint256 lottoid,int64_t numtickets) std::string LottoWinner(uint64_t txfee) { - CMutableTransaction mtx; CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,lottopk; int64_t winnings = 0; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_LOTTO); if ( txfee == 0 ) txfee = 10000; diff --git a/src/cc/oracles.cpp b/src/cc/oracles.cpp index e3cd89166..135f822dc 100644 --- a/src/cc/oracles.cpp +++ b/src/cc/oracles.cpp @@ -728,7 +728,8 @@ int64_t LifetimeOraclesFunds(struct CCcontract_info *cp,uint256 oracletxid,CPubK std::string OracleCreate(int64_t txfee,std::string name,std::string description,std::string format) { - CMutableTransaction mtx; CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Oraclespk; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_ORACLES); if ( name.size() > 32 || description.size() > 4096 || format.size() > 4096 ) { @@ -749,7 +750,8 @@ std::string OracleCreate(int64_t txfee,std::string name,std::string description, std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee) { - CMutableTransaction mtx; CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64]; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,markerpubkey,batonpk; struct CCcontract_info *cp,C; char markeraddr[64],batonaddr[64]; cp = CCinit(&C,EVAL_ORACLES); if ( txfee == 0 ) txfee = 10000; @@ -772,7 +774,8 @@ std::string OracleRegister(int64_t txfee,uint256 oracletxid,int64_t datafee) std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,int64_t amount) { - CMutableTransaction mtx; CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64]; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,markerpubkey; struct CCcontract_info *cp,C; char markeraddr[64]; cp = CCinit(&C,EVAL_ORACLES); if ( txfee == 0 ) txfee = 10000; @@ -789,7 +792,8 @@ std::string OracleSubscribe(int64_t txfee,uint256 oracletxid,CPubKey publisher,i std::string OracleData(int64_t txfee,uint256 oracletxid,std::vector data) { - CMutableTransaction mtx; CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector prevdata; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CScript pubKey; CPubKey mypk,batonpk; int64_t datafee,inputs,CCchange = 0; struct CCcontract_info *cp,C; uint256 batontxid; char coinaddr[64],batonaddr[64]; std::vector prevdata; cp = CCinit(&C,EVAL_ORACLES); mypk = pubkey2pk(Mypubkey()); if ( data.size() > 8192 ) @@ -879,7 +883,8 @@ UniValue OracleInfo(uint256 origtxid) { UniValue result(UniValue::VOBJ),a(UniValue::VARR); std::vector > unspentOutputs; - CMutableTransaction mtx; CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector data; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction regtx,tx; std::string name,description,format; uint256 hashBlock,txid,oracletxid,batontxid; CPubKey pk; struct CCcontract_info *cp,C; int64_t datafee,funding; char str[67],markeraddr[64],numstr[64],batonaddr[64]; std::vector data; cp = CCinit(&C,EVAL_ORACLES); CCtxidaddr(markeraddr,origtxid); if ( GetTransaction(origtxid,tx,hashBlock,false) == 0 ) diff --git a/src/cc/payments.cpp b/src/cc/payments.cpp index de92da9ed..70f1ab914 100644 --- a/src/cc/payments.cpp +++ b/src/cc/payments.cpp @@ -144,7 +144,8 @@ int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP std::string PaymentsGet(uint64_t txfee,int64_t nValue) { - CMutableTransaction mtx,tmpmtx; CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; cp = CCinit(&C,EVAL_PAYMENTS); if ( txfee == 0 ) txfee = 10000; @@ -184,7 +185,8 @@ std::string PaymentsGet(uint64_t txfee,int64_t nValue) std::string PaymentsFund(uint64_t txfee,int64_t funds) { - CMutableTransaction mtx; CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_PAYMENTS); if ( txfee == 0 ) txfee = 10000; @@ -201,7 +203,8 @@ std::string PaymentsFund(uint64_t txfee,int64_t funds) UniValue PaymentsInfo() { UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx; CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding; result.push_back(Pair("result","success")); result.push_back(Pair("name","Payments")); cp = CCinit(&C,EVAL_PAYMENTS); diff --git a/src/cc/pegs.cpp b/src/cc/pegs.cpp index 1de818fe9..403dfb87a 100644 --- a/src/cc/pegs.cpp +++ b/src/cc/pegs.cpp @@ -151,7 +151,8 @@ int64_t AddPegsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKe std::string PegsGet(uint64_t txfee,int64_t nValue) { - CMutableTransaction mtx,tmpmtx; CPubKey mypk,Pegspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Pegspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; cp = CCinit(&C,EVAL_PEGS); if ( txfee == 0 ) txfee = 10000; @@ -191,7 +192,8 @@ std::string PegsGet(uint64_t txfee,int64_t nValue) std::string PegsFund(uint64_t txfee,int64_t funds) { - CMutableTransaction mtx; CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Pegspk; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_PEGS); if ( txfee == 0 ) txfee = 10000; @@ -208,7 +210,8 @@ std::string PegsFund(uint64_t txfee,int64_t funds) UniValue PegsInfo() { UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx; CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey Pegspk; struct CCcontract_info *cp,C; int64_t funding; result.push_back(Pair("result","success")); result.push_back(Pair("name","Pegs")); cp = CCinit(&C,EVAL_PEGS); diff --git a/src/cc/prices.cpp b/src/cc/prices.cpp index 2ec19902e..50787fd34 100644 --- a/src/cc/prices.cpp +++ b/src/cc/prices.cpp @@ -182,7 +182,8 @@ UniValue PricesList() // bettoken std::string PricesCreateFunding(uint64_t txfee,uint256 bettoken,uint256 oracletxid,uint64_t margin,uint64_t mode,uint256 longtoken,uint256 shorttoken,int32_t maxleverage,int64_t funding,std::vector pubkeys) { - CMutableTransaction mtx; CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction oracletx; int64_t fullsupply,inputs,CCchange=0; uint256 hashBlock; char str[65],coinaddr[64],houseaddr[64]; CPubKey mypk,pricespk; int32_t i,N,numvouts; struct CCcontract_info *cp,C; if ( funding < 100*COIN || maxleverage <= 0 || maxleverage > 10000 ) { CCerror = "invalid parameter error"; @@ -293,7 +294,8 @@ UniValue PricesInfo(uint256 fundingtxid) std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount) { - CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vectorpubkeys; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,CCchange = 0; uint64_t funding,mode; int32_t margin,maxleverage; char houseaddr[64],myaddr[64]; std::vectorpubkeys; if ( amount < 10000 ) { CCerror = "amount must be positive"; @@ -343,7 +345,8 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt std::string PricesBet(uint64_t txfee,uint256 refbettoken,uint256 fundingtxid,int64_t amount,int32_t leverage) { - CMutableTransaction mtx; struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vectorpubkeys; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + struct CCcontract_info *cp,C; CPubKey pricespk,planpk,mypk; uint256 hashBlock,oracletxid,longtoken,shorttoken,tokenid,bettoken; CTransaction tx; int64_t balance,supply,exposure,inputs,inputs2,longexposure,netexposure,shortexposure,CCchange = 0,CCchange2 = 0; uint64_t funding,mode; int32_t dir,margin,maxleverage; char houseaddr[64],myaddr[64],exposureaddr[64]; std::vectorpubkeys; if ( amount < 0 ) { amount = -amount; diff --git a/src/cc/rewards.cpp b/src/cc/rewards.cpp index 06002f9c0..7e4626b19 100644 --- a/src/cc/rewards.cpp +++ b/src/cc/rewards.cpp @@ -500,7 +500,8 @@ UniValue RewardsList() std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int64_t APR,int64_t minseconds,int64_t maxseconds,int64_t mindeposit) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; if ( funds < COIN || mindeposit < 0 || minseconds < 0 || maxseconds < 0 ) { fprintf(stderr,"negative parameter error\n"); @@ -534,7 +535,8 @@ std::string RewardsCreateFunding(uint64_t txfee,char *planstr,int64_t funds,int6 std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t amount) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,rewardspk; CScript opret; uint64_t sbits,a,b,c,d; struct CCcontract_info *cp,C; if ( amount < 0 ) { fprintf(stderr,"negative parameter error\n"); @@ -568,7 +570,8 @@ std::string RewardsAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,i std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t deposit) { - CMutableTransaction mtx; CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,rewardspk; CScript opret; uint64_t lockedfunds,sbits,funding,APR,minseconds,maxseconds,mindeposit; struct CCcontract_info *cp,C; if ( deposit < txfee ) { CCerror = "deposit amount less than txfee"; @@ -611,7 +614,8 @@ std::string RewardsLock(uint64_t txfee,char *planstr,uint256 fundingtxid,int64_t std::string RewardsUnlock(uint64_t txfee,char *planstr,uint256 fundingtxid,uint256 locktxid) { - CMutableTransaction mtx,firstmtx; CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C; + CMutableTransaction firstmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CTransaction tx; char coinaddr[64]; CPubKey mypk,rewardspk; CScript scriptPubKey,ignore; uint256 hashBlock; uint64_t sbits,APR,minseconds,maxseconds,mindeposit; int64_t funding,reward=0,amount=0,inputs,CCchange=0; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_REWARDS); if ( txfee == 0 ) txfee = 10000; diff --git a/src/cc/triggers.cpp b/src/cc/triggers.cpp index cc39683cd..ce6f10f58 100644 --- a/src/cc/triggers.cpp +++ b/src/cc/triggers.cpp @@ -143,7 +143,8 @@ int64_t AddTriggersInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP std::string TriggersGet(uint64_t txfee,int64_t nValue) { - CMutableTransaction mtx,tmpmtx; CPubKey mypk,Triggerspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; + CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Triggerspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash; cp = CCinit(&C,EVAL_TRIGGERS); if ( txfee == 0 ) txfee = 10000; @@ -183,7 +184,8 @@ std::string TriggersGet(uint64_t txfee,int64_t nValue) std::string TriggersFund(uint64_t txfee,int64_t funds) { - CMutableTransaction mtx; CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey mypk,Triggerspk; CScript opret; struct CCcontract_info *cp,C; cp = CCinit(&C,EVAL_TRIGGERS); if ( txfee == 0 ) txfee = 10000; @@ -200,7 +202,8 @@ std::string TriggersFund(uint64_t txfee,int64_t funds) UniValue TriggersInfo() { UniValue result(UniValue::VOBJ); char numstr[64]; - CMutableTransaction mtx; CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding; + CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); + CPubKey Triggerspk; struct CCcontract_info *cp,C; int64_t funding; result.push_back(Pair("result","success")); result.push_back(Pair("name","Triggers")); cp = CCinit(&C,EVAL_TRIGGERS); From a3911bbf3dc3efdcefa74548db9f310a72eb839b Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 27 Nov 2018 23:02:57 -1100 Subject: [PATCH 18/94] int32_t komodo_nextheight(); --- src/cc/betprotocol.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cc/betprotocol.cpp b/src/cc/betprotocol.cpp index fe3ae31c6..3efa4ae37 100644 --- a/src/cc/betprotocol.cpp +++ b/src/cc/betprotocol.cpp @@ -25,6 +25,7 @@ #include "cc/utils.h" #include "primitives/transaction.h" +int32_t komodo_nextheight(); std::vector BetProtocol::PlayerConditions() { From a23af09cda6e89cbac25e31792388602251d8bb9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 28 Nov 2018 00:35:31 -1100 Subject: [PATCH 19/94] Prevent sapling activation until ac_sapling set --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index edd1b6605..8586f5840 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5624,7 +5624,8 @@ bool static LoadBlockIndexDB() if ( (pindex= chainActive.LastTip()) != 0 ) { fprintf(stderr,"set sapling height, if possible from ht.%d %u\n",(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime); - komodo_activate_sapling(pindex); + if ( ASSETCHAINS_SAPLING <= 0 ) + komodo_activate_sapling(pindex); } return true; } From ea5b152c583a07f04f823251e70895ebfe87894b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 28 Nov 2018 00:40:11 -1100 Subject: [PATCH 20/94] Move print --- src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8586f5840..80819f296 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5623,9 +5623,11 @@ bool static LoadBlockIndexDB() CBlockIndex *pindex; if ( (pindex= chainActive.LastTip()) != 0 ) { - fprintf(stderr,"set sapling height, if possible from ht.%d %u\n",(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime); if ( ASSETCHAINS_SAPLING <= 0 ) + { + fprintf(stderr,"set sapling height, if possible from ht.%d %u\n",(int32_t)pindex->GetHeight(),(uint32_t)pindex->nTime); komodo_activate_sapling(pindex); + } } return true; } From b0abf90f699d5897b9da4ec6ecef61980656e6ef Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 28 Nov 2018 04:06:49 -1100 Subject: [PATCH 21/94] Fix null ptr in dice status --- src/cc/dice.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 37d6bfd41..8d750b1ed 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -245,9 +245,12 @@ bool mySenddicetransaction(std::string res,uint256 entropyused,int32_t entropyvo { RelayTransaction(tx); fprintf(stderr,"rebroadcast.%c and clear [%d] and broadcast entropyused.%s bettxid.%s -> %s\n",funcid,i,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str()); - if ( ptr->rawtx.empty() == 0 ) - ptr->rawtx.clear(); - ptr->txid = zeroid; + if ( ptr != 0 ) + { + if ( ptr->rawtx.empty() == 0 ) + ptr->rawtx.clear(); + ptr->txid = zeroid; + } //fprintf(stderr,"error adding funcid.%c E.%s bet.%s -> %s to mempool, probably Disable replacement feature size.%d\n",funcid,entropyused.GetHex().c_str(),bettxid.GetHex().c_str(),tx.GetHash().GetHex().c_str(),(int32_t)ptr->rawtx.size()); } } else fprintf(stderr,"error duplicate entropyused different bettxid\n"); From 7cb41a160528c0c6908b0989319da966eb42f4fa Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 29 Nov 2018 11:03:56 +0800 Subject: [PATCH 22/94] fix kmdice twice --- src/assetchains.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/assetchains.json b/src/assetchains.json index 43242ea42..09f7cdb96 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -177,18 +177,6 @@ "190.114.254.104" ] }, - { - "ac_name": "KMDICE", - "ac_supply": "10500000", - "ac_reward": "2500000000", - "ac_halving": "210000", - "ac_cc": "2", - "addressindex": "1", - "spentindex": "1", - "addnode": [ - "144.76.217.232" - ] - }, { "ac_name": "DION", "ac_supply": "3900000000", From 30eae48849a4e7c189de6a5d7f04fabdc148f2cf Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 28 Nov 2018 21:53:27 -1100 Subject: [PATCH 23/94] Mempool fixes in the CC path --- src/main.cpp | 3 ++- src/rpc/misc.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 80819f296..1ca925482 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4678,7 +4678,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C const uint256 &hash = tx.GetHash(); if ( tx.vjoinsplit.size() == 0 ) { transactionsToRemove.push_back(tx); - tmpmempool.addUnchecked(hash,e,!IsInitialBlockDownload()); + tmpmempool.addUnchecked(hash,e,true); } } BOOST_FOREACH(const CTransaction& tx, transactionsToRemove) { @@ -4756,6 +4756,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // here we add back all txs from the temp mempool to the main mempool. // which removes any tx locally that were invalid after the block arrives. int invalidtxs = 0; + LOCK(mempool.cs); BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) { CTransaction tx = e.GetTx(); CValidationState state; bool fMissingInputs,fOverrideFees = false; diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 26c273236..e0bbe86c3 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -56,7 +56,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int32_t height); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); -#define KOMODO_VERSION "0.3.1" +#define KOMODO_VERSION "0.3.2" #define VERUS_VERSION "0.4.0g" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; From 05d0f6c0b346ed760913765c01933eac77a5e645 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 29 Nov 2018 01:58:48 -1100 Subject: [PATCH 24/94] +comments --- src/cc/gateways.cpp | 1 + src/komodo_defs.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index 94d662193..da9b57766 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -707,6 +707,7 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP char str[65],str2[65]; fprintf(stderr,"vout.%d %d:%d (%c) check for refassetid.%s vs %s %.8f\n",vout,evalcode,cp->evalcode,funcid,uint256_str(str,refassetid),uint256_str(str2,assetid),(double)vintx.vout[vout].nValue/COIN); if ( assetid == refassetid && funcid == 't' && (nValue= vintx.vout[vout].nValue) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 ) { + // call IsAssetsVout? //fprintf(stderr,"total %llu maxinputs.%d %.8f\n",(long long)total,maxinputs,(double)it->second.satoshis/COIN); if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); diff --git a/src/komodo_defs.h b/src/komodo_defs.h index a4d5a2df3..e604e1779 100644 --- a/src/komodo_defs.h +++ b/src/komodo_defs.h @@ -13,7 +13,7 @@ #define KOMODO_FIRSTFUNGIBLEID 100 #define KOMODO_SAPLING_ACTIVATION 1544832000 // Dec 15th, 2018 #define KOMODO_SAPLING_DEADLINE 1550188800 // Feb 15th, 2019 - + extern uint8_t ASSETCHAINS_TXPOW,ASSETCHAINS_PUBLIC; int32_t MAX_BLOCK_SIZE(int32_t height); From 9ad8bfa16e325fd66cca8379abae65dab375310e Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 29 Nov 2018 03:02:27 -1100 Subject: [PATCH 25/94] Prevent spurious reindexing --- src/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 701a33e97..f3d728933 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1486,7 +1486,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex, dbCompression, dbMaxOpenFiles); fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX); pblocktree->ReadFlag("addressindex", checkval); - if ( checkval != fAddressIndex ) + if ( checkval != fAddressIndex && fAddressIndex != 0 ) { pblocktree->WriteFlag("addressindex", fAddressIndex); fprintf(stderr,"set addressindex, will reindex. could take a while.\n"); @@ -1494,7 +1494,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX); pblocktree->ReadFlag("spentindex", checkval); - if ( checkval != fSpentIndex ) + if ( checkval != fSpentIndex && fSpentIndex != 0 ) { pblocktree->WriteFlag("spentindex", fSpentIndex); fprintf(stderr,"set spentindex, will reindex. could take a while.\n"); From d89fe8b560d1dee34cdb62d63fcabea0af22c577 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 30 Nov 2018 01:52:39 +0800 Subject: [PATCH 26/94] fix bitcoin-cli.cpp includes --- src/bitcoin-cli.cpp | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 5d818eb5b..64830d463 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -16,6 +16,8 @@ #include #include #include "support/events.h" +uint16_t BITCOIND_RPCPORT = 7771; +char ASSETCHAINS_SYMBOL[65]; #include @@ -64,27 +66,6 @@ public: }; -#define FROM_CLI -#include "uint256.h" -#include "arith_uint256.h" - -#include "komodo_structs.h" - -#include "komodo_globals.h" -#include "komodo_utils.h" -#include "komodo_cJSON.c" -#include "komodo_notary.h" - -void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout,uint256 MoM,int32_t MoMdepth) -{ - -} - -uint32_t komodo_heightstamp(int32_t height) -{ - return(0); -} - // // This function returns either one of EXIT_ codes when it's expected to stop the process or // CONTINUE_EXECUTION when it's expected to continue further. @@ -99,7 +80,11 @@ static int AppInitRPC(int argc, char* argv[]) // Parameters // ParseParameters(argc, argv); - komodo_args(argv[0]); + std:string name; + name = GetArg("-ac_name",""); + if ( !name.empty() ) + strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1); + if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n" + PrivacyInfo(); if (!mapArgs.count("-version")) { From c9e9081c8ac94144626cecb982d633e36f796396 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 29 Nov 2018 07:00:04 -1100 Subject: [PATCH 27/94] Rebase --- src/cc/gateways.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cc/gateways.cpp b/src/cc/gateways.cpp index da9b57766..94d662193 100644 --- a/src/cc/gateways.cpp +++ b/src/cc/gateways.cpp @@ -707,7 +707,6 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP char str[65],str2[65]; fprintf(stderr,"vout.%d %d:%d (%c) check for refassetid.%s vs %s %.8f\n",vout,evalcode,cp->evalcode,funcid,uint256_str(str,refassetid),uint256_str(str2,assetid),(double)vintx.vout[vout].nValue/COIN); if ( assetid == refassetid && funcid == 't' && (nValue= vintx.vout[vout].nValue) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 ) { - // call IsAssetsVout? //fprintf(stderr,"total %llu maxinputs.%d %.8f\n",(long long)total,maxinputs,(double)it->second.satoshis/COIN); if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); From 933e1b4220e6c472458dad1ec4543ae1de17be7a Mon Sep 17 00:00:00 2001 From: dim71 Date: Sat, 1 Dec 2018 03:08:24 +0500 Subject: [PATCH 28/94] added check for bad tx (sending from normal vins to cc vouts) to asset validation and tx creation code --- src/cc/CCassets.h | 5 +- src/cc/CCassetsCore.cpp | 99 ++++++++++++++++++++++++++++++---------- src/cc/CCassetstx.cpp | 42 +++++++++++++---- src/cc/assets.cpp | 68 +++++++++++++++++++++++++-- src/wallet/rpcwallet.cpp | 50 ++++++++++++++------ 5 files changed, 212 insertions(+), 52 deletions(-) diff --git a/src/cc/CCassets.h b/src/cc/CCassets.h index a48195970..67bed7941 100644 --- a/src/cc/CCassets.h +++ b/src/cc/CCassets.h @@ -35,7 +35,7 @@ CScript EncodeAssetOpRet(uint8_t funcid,uint256 assetid,uint256 assetid2,int64_t bool DecodeAssetCreateOpRet(const CScript &scriptPubKey,std::vector &origpubkey,std::string &name,std::string &description); uint8_t DecodeAssetOpRet(const CScript &scriptPubKey,uint256 &assetid,uint256 &assetid2,int64_t &price,std::vector &origpubkey); bool SetAssetOrigpubkey(std::vector &origpubkey,int64_t &price,const CTransaction &tx); -int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid); +int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid); bool ValidateBidRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); bool ValidateAskRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); bool ValidateSwapRemainder(int64_t remaining_price,int64_t remaining_nValue,int64_t orig_nValue,int64_t received_nValue,int64_t paidprice,int64_t totalprice); @@ -44,7 +44,8 @@ bool SetAskFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValu bool SetSwapFillamounts(int64_t &paid,int64_t &remaining_price,int64_t orig_nValue,int64_t &received,int64_t totalprice); int64_t AssetValidateBuyvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 refassetid); int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpprice,std::vector &tmporigpubkey,char *CCaddr,char *origaddr,const CTransaction &tx,uint256 assetid); -bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid); +bool AssetExactAmounts(int32_t maxDepth, struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid); +//bool AssetExactAmounts(bool doValidateTx, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid, std::vector &ccVinsTxs); // CCassetstx int64_t GetAssetBalance(CPubKey pk,uint256 tokenid); diff --git a/src/cc/CCassetsCore.cpp b/src/cc/CCassetsCore.cpp index c9b975c3c..3fce95f0c 100644 --- a/src/cc/CCassetsCore.cpp +++ b/src/cc/CCassetsCore.cpp @@ -342,25 +342,54 @@ bool GetAssetorigaddrs(struct CCcontract_info *cp,char *CCaddr,char *destaddr,co else return(false); } -int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid) + +// Checks if the vout is a really Asset CC vout +// if maxAssetExactAmountDepth > 0, it also validates the vin transaction itself: +// it should be either sum(cc vins) == sum(cc vouts) or the transaction is the 'tokenbase' ('c') tx +int64_t IsAssetvout(int32_t maxAssetExactAmountDepth, struct CCcontract_info *cp, Eval* eval, int64_t &price,std::vector &origpubkey,const CTransaction& tx,int32_t v,uint256 refassetid) { uint256 assetid,assetid2; int64_t nValue=0; int32_t n; uint8_t funcid; + if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 ) // maybe check address too? { - n = tx.vout.size(); + + if (maxAssetExactAmountDepth > 0) { + //validate all tx + int64_t myCCVinsAmount = 0, myCCVoutsAmount = 0; + std::vector ccVinsTxs; + + //std::cerr << "IsAssetvout() validate=yes" << std::endl; + const bool validateVinTxs = false; + bool isEqualAmounts = AssetExactAmounts(maxAssetExactAmountDepth, cp, myCCVinsAmount, 0, myCCVoutsAmount, eval, tx, refassetid); + + // if ccInputs != ccOutputs and it is not the tokenbase tx means it is possibly fake tx (dimxy): + if (!isEqualAmounts && refassetid != tx.GetHash()) { // checking that this is the true tokenbase tx, by verifying that funcid=c, is done further in this function (dimxy) + std::cerr << "IsAssetvout() detected bad tx=" << tx.GetHash().GetHex() << ": cc inputs != cc outputs and not the 'tokenbase' tx" << std::endl; + return 0; + } + } + + + n = tx.vout.size(); + if (v >= n - 1) { // just moved this up (dimxy) + std::cerr << "isAssetVout() internal err: (v >= n - 1), returning 0" << std::endl; + return(0); + } nValue = tx.vout[v].nValue; - //fprintf(stderr,"CC vout v.%d of n.%d %.8f\n",v,n,(double)nValue/COIN); - if ( v >= n-1 ) - return(0); + + // fprintf(stderr,"IsAssetvout() CC vout v.%d of n=%d amount=%.8f\n",v,n,(double)nValue/COIN); + if ( (funcid= DecodeAssetOpRet(tx.vout[n-1].scriptPubKey,assetid,assetid2,price,origpubkey)) == 0 ) { - fprintf(stderr,"null decodeopret v.%d\n",v); + fprintf(stderr,"IsAssetvout() null decodeopret v.%d\n",v); return(0); } else if ( funcid == 'c' ) { - if ( refassetid == tx.GetHash() && v == 0 ) - return(nValue); + if (refassetid == tx.GetHash() && v == 0) { + std::cerr << "isAssetVout() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " returning nValue=" << nValue << std::endl; + return(nValue); + } } else if ( (funcid == 'b' || funcid == 'B') && v == 0 ) // critical! 'b'/'B' vout0 is NOT asset return(0); @@ -368,7 +397,7 @@ int64_t IsAssetvout(int64_t &price,std::vector &origpubkey,const CTrans { if ( assetid == refassetid ) { - //fprintf(stderr,"returning %.8f\n",(double)nValue/COIN); + fprintf(stderr,"IsAssetvout() returning %.8f\n",(double)nValue/COIN); return(nValue); } } @@ -443,29 +472,37 @@ int64_t AssetValidateSellvin(struct CCcontract_info *cp,Eval* eval,int64_t &tmpp fprintf(stderr,"AssetValidateSellvin\n"); if ( (nValue= AssetValidateCCvin(cp,eval,CCaddr,origaddr,tx,1,vinTx)) == 0 ) return(0); - if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 ) + if ( (assetoshis= IsAssetvout(1, cp, NULL, tmpprice,tmporigpubkey,vinTx,0,assetid)) == 0 ) return eval->Invalid("invalid missing CC vout0 for sellvin"); else return(assetoshis); } -bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti,int64_t &outputs,Eval* eval,const CTransaction &tx,uint256 assetid) + +// overload with additional params for deep tx validation (dimxy) +bool AssetExactAmounts(int maxDepth, struct CCcontract_info *cp, int64_t &inputs, int32_t starti, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 assetid) { CTransaction vinTx; uint256 hashBlock,id,id2; int32_t i,flag,numvins,numvouts; int64_t assetoshis; std::vector tmporigpubkey; int64_t tmpprice; numvins = tx.vin.size(); numvouts = tx.vout.size(); inputs = outputs = 0; + + maxDepth--; + for (i=starti; iismyvin)(tx.vin[i].scriptSig) != 0 ) - { - if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 ) + { + //std::cerr << "AssetExactAmounts() eval is true=" << (eval != NULL) << " ismyvin=ok for_i=" << i << std::endl; + // we are really not inside validation! -- dimxy + if ( (eval && eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0) || (!eval && !myGetTransaction(tx.vin[i].prevout.hash, vinTx, hashBlock)) ) { - fprintf(stderr,"i.%d starti.%d numvins.%d\n",i,starti,numvins); - return eval->Invalid("always should find vin, but didnt"); - } - else if ( (assetoshis= IsAssetvout(tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 ) + fprintf(stderr,"AssetExactAmounts() cannot read vintx i.%d starti.%d numvins.%d\n", i,starti,numvins); + return (!eval) ? false : eval->Invalid("always should find vin, but didnt"); + + } // false means 'don't go deeper' -- dimxy + else if ( (assetoshis= IsAssetvout( maxDepth, cp, eval, tmpprice,tmporigpubkey,vinTx,tx.vin[i].prevout.n,assetid)) != 0 ) { - fprintf(stderr,"vin%d %llu, ",i,(long long)assetoshis); + fprintf(stderr,"AssetExactAmounts() vin%d %llu, ",i,(long long)assetoshis); inputs += assetoshis; } else @@ -473,33 +510,47 @@ bool AssetExactAmounts(struct CCcontract_info *cp,int64_t &inputs,int32_t starti if ( vinTx.vout[i].scriptPubKey.IsPayToCryptoCondition() != 0 && DecodeAssetOpRet(vinTx.vout[vinTx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid ) { assetoshis = vinTx.vout[i].nValue; - fprintf(stderr,"vin%d %llu special case, ",i,(long long)assetoshis); + fprintf(stderr,"AssetExactAmounts() vin%d assetoshis=%llu special case, ",i,(long long)assetoshis); inputs += assetoshis; } } } } + + if ( DecodeAssetOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,id,id2,tmpprice,tmporigpubkey) == 't' && id == assetid ) flag = 1; else flag = 0; + for (i=0; i 0 && myIsutxo_spentinmempool(txid,vout) == 0 ) + fprintf(stderr,"AddAssetInputs() check destaddress=%s vout amount=%.8f\n",destaddr,(double)vintx.vout[vout].nValue/COIN); + if ( (nValue= IsAssetvout(1, cp, NULL, price,origpubkey,vintx,vout,assetid)) > 0 && myIsutxo_spentinmempool(txid,vout) == 0 ) { if ( total != 0 && maxinputs != 0 ) mtx.vin.push_back(CTxIn(txid,vout,CScript())); nValue = it->second.satoshis; totalinputs += nValue; + //std::cerr << "AddAssetInputs() adding input nValue=" << nValue << std::endl; n++; if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) ) break; } } } + + //std::cerr << "AddAssetInputs() found totalinputs=" << totalinputs << std::endl; return(totalinputs); } @@ -235,6 +238,11 @@ std::string AssetTransfer(int64_t txfee,uint256 assetid,std::vector des mask = ~((1LL << mtx.vin.size()) - 1); if ( (inputs= AddAssetInputs(cp,mtx,mypk,assetid,total,60)) > 0 ) { + + if (inputs < total) { //added dimxy + std::cerr << "AssetTransfer(): insufficient funds" << std::endl; + return (""); + } if ( inputs > total ) CCchange = (inputs - total); //for (i=0; i 0 ) { - if ( inputs < askamount ) - askamount = inputs; + if (inputs < askamount) { + //askamount = inputs; + std::cerr << "CreateSell(): insufficient tokens for ask" << std::endl; + return (""); + } + mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,askamount,GetUnspendable(cp,0))); if ( inputs > askamount ) CCchange = (inputs - askamount); @@ -333,9 +348,14 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS,CCchange,mypk)); opret = EncodeAssetOpRet('s',assetid,zeroid,pricetotal,Mypubkey()); return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"need some assets to place ask\n"); + } + else { + fprintf(stderr, "need some assets to place ask\n"); + } } - fprintf(stderr,"need some native coins to place ask\n"); + else { // dimxy added 'else', because it was misleading message before + fprintf(stderr, "need some native coins to place ask\n"); + } return(""); } @@ -373,9 +393,15 @@ std::string CreateSwap(int64_t txfee,int64_t askamount,uint256 assetid,uint256 a opret = EncodeAssetOpRet('e',assetid,assetid2,pricetotal,Mypubkey()); } return(FinalizeCCTx(mask,cp,mtx,mypk,txfee,opret)); - } else fprintf(stderr,"need some assets to place ask\n"); + } + else { + fprintf(stderr, "need some assets to place ask\n"); + } } - fprintf(stderr,"need some native coins to place ask\n"); + else { // dimxy added 'else', because it was misleading message before + fprintf(stderr,"need some native coins to place ask\n"); + } + return(""); } diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 41a0ed7b1..92c1ddaac 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -129,6 +129,64 @@ vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey] */ + + +// Recursively browses and verifies tx's vins to make sure no fake tokens have been 'planted' +// This func should be call with maxlevels = 2 +// on the first level it validates that current tx does not have invalid non-cc inputs +// on the second level it validates that all cc inputs of this tx also don't have 'feeding' non-cc inputs +/* +bool ValidateInputsTraversal(int32_t maxlevels, struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint256 assetid) +{ + int64_t dummyPrice; + std::vector dummyPubkey; + uint256 dummyAsset, dummyAsset2; + + int32_t numvins = tx.vin.size(); + int32_t numvouts = tx.vout.size(); + + // check it for the sake of.. + if (numvouts == 0) + return false; + + uint8_t funcId = DecodeAssetOpRet(tx.vout[numvouts - 1].scriptPubKey, dummyAsset, dummyAsset2, dummyPrice, dummyPubkey); + + // this is initial tokenbase tx: + if (tx.GetHash() == assetid && funcId == 'c') { + std::cerr << "ValidateInputsTraversal() found initial tx=" << assetid.GetHex() << std::endl; + return true; + } + + int64_t myCCVinsAmount = 0; + int64_t myCCVoutsAmount = 0; + std::vector ccVinsTxs; + + bool isCCEqual = AssetExactAmounts(cp, myCCVinsAmount, 0, myCCVoutsAmount, eval, tx, assetid); + if (!isCCEqual) { //Note: for the spending tx (1-st level) this condition is also checked in AssetsValidate() itself -- dimxy + std::cerr << "ValidateInputsTraversal() found bad uxto txid=" << tx.GetHash().GetHex() << " ccVinsAmount=" << myCCVinsAmount << " ccVoutsAmount=" << myCCVoutsAmount << std::endl; + eval->Invalid("deep search found bad non-cc uxto"); + return false; + } + + // recursively validate vins' txs (only for one level - see maxlevels var): + bool allVinTxsGood = true; + + if (--maxlevels > 0) { + for (int32_t i = 0; i < ccVinsTxs.size(); i++) { + if (!ValidateInputsTraversal(maxlevels, cp, eval, ccVinsTxs[i], assetid)) { + allVinTxsGood = false; + break; + } + } + } + + std::cerr << "ValidateInputsTraversal() for txid=" << tx.GetHash().GetHex() << " allVinTxsGood=" << std::boolalpha << allVinTxsGood << std::endl; + + return allVinTxsGood; +} +*/ + +// tx validation bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) { static uint256 zero; @@ -155,9 +213,13 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx else starti = 1; if ( assetid == zero ) return eval->Invalid("illegal assetid"); - else if ( AssetExactAmounts(cp,inputs,starti,outputs,eval,tx,assetid) == false ) + else if ( AssetExactAmounts(2, cp,inputs,starti,outputs,eval,tx,assetid) == false ) return eval->Invalid("asset inputs != outputs"); } + +// if( !ValidateInputsTraversal(2, cp, eval, tx, assetid) ) +// return false; + switch ( funcid ) { case 'c': // create wont be called to be verified as it has no CC inputs @@ -321,7 +383,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx } fprintf(stderr,"fill validated\n"); break; - case 'E': // fillexchange + case 'E': // fillexchange return eval->Invalid("unexpected assets fillexchange funcid"); break; // disable asset swaps //vin.0: normal input @@ -333,7 +395,7 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx //vout.3: CC output for asset2 change (if any) //vout.3/4: normal output for change (if any) //vout.n-1: opreturn [EVAL_ASSETS] ['E'] [assetid vin0+1] [assetid vin2] [remaining asset2 required] [origpubkey] - if ( AssetExactAmounts(cp,inputs,1,outputs,eval,tx,assetid2) == false ) + if ( AssetExactAmounts(1, cp,inputs,1,outputs,eval,tx,assetid2) == false ) eval->Invalid("asset2 inputs != outputs"); if ( (assetoshis= AssetValidateSellvin(cp,eval,totalunits,tmporigpubkey,CCaddr,origaddr,tx,assetid)) == 0 ) return(false); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f3b344ecd..9000358d9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5310,6 +5310,7 @@ int32_t ensure_CCrequirements() #include "../cc/CCOracles.h" #include "../cc/CCGateways.h" #include "../cc/CCPrices.h" +#include "../cc/CCHeir.h" UniValue CCaddress(struct CCcontract_info *cp,char *name,std::vector &pubkey) { @@ -5531,15 +5532,25 @@ UniValue gatewaysaddress(const UniValue& params, bool fHelp) UniValue heiraddress(const UniValue& params, bool fHelp) { - struct CCcontract_info *cp,C; std::vector pubkey; + struct CCcontract_info *cp,C; std::vector destPubkey; + cp = CCinit(&C,EVAL_HEIR); - if ( fHelp || params.size() > 1 ) - throw runtime_error("heiraddress [pubkey]\n"); + if ( fHelp || (params.size() != 4 && params.size() != 3)) + throw runtime_error("heiraddress func txid amount [destpubkey]\n"); if ( ensure_CCrequirements() < 0 ) throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n"); - if ( params.size() == 1 ) - pubkey = ParseHex(params[0].get_str().c_str()); - return(CCaddress(cp,(char *)"Heir",pubkey)); + //if ( params.size() == 1 ) + // pubkey = ParseHex(params[0].get_str().c_str()); + + char funcid = ((char *)params[0].get_str().c_str())[0]; + uint256 assetid = Parseuint256((char *)params[1].get_str().c_str()); + int64_t funds = atof(params[2].get_str().c_str()) * COIN ; + if(params.size() == 4) + destPubkey = ParseHex(params[3].get_str().c_str()); + + return HeirFundBad(funcid, assetid, funds, destPubkey); + + //return(CCaddress(cp,(char *)"Heir",pubkey)); } UniValue lottoaddress(const UniValue& params, bool fHelp) @@ -6837,7 +6848,7 @@ UniValue tokencreate(const UniValue& params, bool fHelp) const CKeyStore& keystore = *pwalletMain; LOCK2(cs_main, pwalletMain->cs_wallet); name = params[0].get_str(); - supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999; + supply = atof(params[1].get_str().c_str()) * COIN + 0.00000000499999; // what for is this '+0.00000000499999'? it will be lost while converting double to int64_t (dimxy) if ( name.size() == 0 || name.size() > 32) { ERR_RESULT("Token name must not be empty and up to 32 characters"); @@ -6877,7 +6888,8 @@ UniValue tokentransfer(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); tokenid = Parseuint256((char *)params[0].get_str().c_str()); std::vector pubkey(ParseHex(params[1].get_str().c_str())); - amount = atol(params[2].get_str().c_str()); + //amount = atol(params[2].get_str().c_str()); + amount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance if ( tokenid == zeroid ) { ERR_RESULT("invalid tokenid"); @@ -6913,7 +6925,8 @@ UniValue tokenconvert(const UniValue& params, bool fHelp) evalcode = atoi(params[0].get_str().c_str()); tokenid = Parseuint256((char *)params[1].get_str().c_str()); std::vector pubkey(ParseHex(params[2].get_str().c_str())); - amount = atol(params[3].get_str().c_str()); + //amount = atol(params[3].get_str().c_str()); + amount = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance if ( tokenid == zeroid ) { ERR_RESULT("invalid tokenid"); @@ -6946,7 +6959,8 @@ UniValue tokenbid(const UniValue& params, bool fHelp) 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); - numtokens = atoi(params[0].get_str().c_str()); + //numtokens = atoi(params[0].get_str().c_str()); + numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance tokenid = Parseuint256((char *)params[1].get_str().c_str()); price = atof(params[2].get_str().c_str()); bidamount = (price * numtokens) * COIN + 0.0000000049999; @@ -7014,7 +7028,8 @@ UniValue tokenfillbid(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); tokenid = Parseuint256((char *)params[0].get_str().c_str()); bidtxid = Parseuint256((char *)params[1].get_str().c_str()); - fillamount = atol(params[2].get_str().c_str()); + // fillamount = atol(params[2].get_str().c_str()); + fillamount = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance if ( fillamount <= 0 ) { ERR_RESULT("fillamount must be positive"); @@ -7043,10 +7058,12 @@ UniValue tokenask(const UniValue& params, bool fHelp) 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); - numtokens = atoi(params[0].get_str().c_str()); + //numtokens = atoi(params[0].get_str().c_str()); + numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance tokenid = Parseuint256((char *)params[1].get_str().c_str()); price = atof(params[2].get_str().c_str()); askamount = (price * numtokens) * COIN + 0.0000000049999; + //std::cerr << std::boolalpha << "tokenask(): (tokenid == zeroid) is " << (tokenid == zeroid) << " (numtokens <= 0) is " << (numtokens <= 0) << " (price <= 0) is " << (price <= 0) << " (askamount <= 0) is " << (askamount <= 0) << std::endl; if ( tokenid == zeroid || numtokens <= 0 || price <= 0 || askamount <= 0 ) { ERR_RESULT("invalid parameter"); @@ -7075,7 +7092,8 @@ UniValue tokenswapask(const UniValue& params, bool fHelp) 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); - numtokens = atoi(params[0].get_str().c_str()); + //numtokens = atoi(params[0].get_str().c_str()); + numtokens = atoll(params[0].get_str().c_str()); // dimxy changed to prevent loss of significance tokenid = Parseuint256((char *)params[1].get_str().c_str()); otherid = Parseuint256((char *)params[2].get_str().c_str()); price = atof(params[3].get_str().c_str()); @@ -7129,7 +7147,8 @@ UniValue tokenfillask(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); tokenid = Parseuint256((char *)params[0].get_str().c_str()); asktxid = Parseuint256((char *)params[1].get_str().c_str()); - fillunits = atol(params[2].get_str().c_str()); + //fillunits = atol(params[2].get_str().c_str()); + fillunits = atoll(params[2].get_str().c_str()); // dimxy changed to prevent loss of significance if ( fillunits <= 0 ) { ERR_RESULT("fillunits must be positive"); @@ -7169,7 +7188,8 @@ UniValue tokenfillswap(const UniValue& params, bool fHelp) tokenid = Parseuint256((char *)params[0].get_str().c_str()); otherid = Parseuint256((char *)params[1].get_str().c_str()); asktxid = Parseuint256((char *)params[2].get_str().c_str()); - fillunits = atol(params[3].get_str().c_str()); + //fillunits = atol(params[3].get_str().c_str()); + fillunits = atoll(params[3].get_str().c_str()); // dimxy changed to prevent loss of significance hex = FillSell(0,tokenid,otherid,asktxid,fillunits); if (fillunits > 0) { if ( hex.size() > 0 ) { From a25af8d781ecb891b6fb145cd4cc3b0773b3d605 Mon Sep 17 00:00:00 2001 From: dim71 Date: Sat, 1 Dec 2018 03:28:07 +0500 Subject: [PATCH 29/94] removed unused commented function --- src/cc/assets.cpp | 56 ----------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/src/cc/assets.cpp b/src/cc/assets.cpp index 92c1ddaac..378c427a9 100644 --- a/src/cc/assets.cpp +++ b/src/cc/assets.cpp @@ -131,60 +131,6 @@ -// Recursively browses and verifies tx's vins to make sure no fake tokens have been 'planted' -// This func should be call with maxlevels = 2 -// on the first level it validates that current tx does not have invalid non-cc inputs -// on the second level it validates that all cc inputs of this tx also don't have 'feeding' non-cc inputs -/* -bool ValidateInputsTraversal(int32_t maxlevels, struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint256 assetid) -{ - int64_t dummyPrice; - std::vector dummyPubkey; - uint256 dummyAsset, dummyAsset2; - - int32_t numvins = tx.vin.size(); - int32_t numvouts = tx.vout.size(); - - // check it for the sake of.. - if (numvouts == 0) - return false; - - uint8_t funcId = DecodeAssetOpRet(tx.vout[numvouts - 1].scriptPubKey, dummyAsset, dummyAsset2, dummyPrice, dummyPubkey); - - // this is initial tokenbase tx: - if (tx.GetHash() == assetid && funcId == 'c') { - std::cerr << "ValidateInputsTraversal() found initial tx=" << assetid.GetHex() << std::endl; - return true; - } - - int64_t myCCVinsAmount = 0; - int64_t myCCVoutsAmount = 0; - std::vector ccVinsTxs; - - bool isCCEqual = AssetExactAmounts(cp, myCCVinsAmount, 0, myCCVoutsAmount, eval, tx, assetid); - if (!isCCEqual) { //Note: for the spending tx (1-st level) this condition is also checked in AssetsValidate() itself -- dimxy - std::cerr << "ValidateInputsTraversal() found bad uxto txid=" << tx.GetHash().GetHex() << " ccVinsAmount=" << myCCVinsAmount << " ccVoutsAmount=" << myCCVoutsAmount << std::endl; - eval->Invalid("deep search found bad non-cc uxto"); - return false; - } - - // recursively validate vins' txs (only for one level - see maxlevels var): - bool allVinTxsGood = true; - - if (--maxlevels > 0) { - for (int32_t i = 0; i < ccVinsTxs.size(); i++) { - if (!ValidateInputsTraversal(maxlevels, cp, eval, ccVinsTxs[i], assetid)) { - allVinTxsGood = false; - break; - } - } - } - - std::cerr << "ValidateInputsTraversal() for txid=" << tx.GetHash().GetHex() << " allVinTxsGood=" << std::boolalpha << allVinTxsGood << std::endl; - - return allVinTxsGood; -} -*/ // tx validation bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn) @@ -217,8 +163,6 @@ bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx return eval->Invalid("asset inputs != outputs"); } -// if( !ValidateInputsTraversal(2, cp, eval, tx, assetid) ) -// return false; switch ( funcid ) { From 800396d7461b67045bc489560266c97966d89f26 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 12:13:03 -1100 Subject: [PATCH 30/94] Allow duplicated destination for sendmany --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f3b344ecd..8f0a692b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1319,9 +1319,9 @@ UniValue sendmany(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Zcash address: ") + name_); } - if (destinations.count(dest)) { + /*if (destinations.count(dest)) { throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_); - } + }*/ destinations.insert(dest); CScript scriptPubKey = GetScriptForDestination(dest); From e23cb3e0d291e81236be7113db0eb08618fd0b4e Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 12:22:02 -1100 Subject: [PATCH 31/94] Partial revert of heir address to build --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 26f56b395..c65bdd746 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5548,9 +5548,9 @@ UniValue heiraddress(const UniValue& params, bool fHelp) if(params.size() == 4) destPubkey = ParseHex(params[3].get_str().c_str()); - return HeirFundBad(funcid, assetid, funds, destPubkey); + //return HeirFundBad(funcid, assetid, funds, destPubkey); - //return(CCaddress(cp,(char *)"Heir",pubkey)); + return(CCaddress(cp,(char *)"Heir",destPubkey)); } UniValue lottoaddress(const UniValue& params, bool fHelp) From 7c59f227c5a1025e645687770fd8eb0b2c6ee569 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 13:09:25 -1100 Subject: [PATCH 32/94] Allow bigger auto diceaddfunds --- src/cc/dice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 8d750b1ed..597f2cb38 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -98,7 +98,7 @@ What is needed is for the dealer node to track the entropy tx that was already b #include "../compat/endian.h" #define MAX_ENTROPYUSED 8192 -#define DICE_MINUTXOS 10000 +#define DICE_MINUTXOS 15000 extern int32_t KOMODO_INSYNC; pthread_mutex_t DICE_MUTEX,DICEREVEALED_MUTEX; @@ -1392,7 +1392,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 } if ( scriptPubKey == fundingPubKey ) { - if ( AddNormalinputs(mtx,mypk,amount+2*txfee,1) > 0 ) + if ( AddNormalinputs(mtx,mypk,amount+2*txfee,60) > 0 ) { hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1); mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk)); @@ -1667,7 +1667,7 @@ void *dealer0_loop(void *_arg) n = sqrt(DICE_MINUTXOS - entropytxs) + 10; for (i=0; i 64 && is_hexstr((char *)res.c_str(),0) > 64 ) { if ( DecodeHexTx(tx,res) != 0 ) From db83c122c7c1cc121c61faeed8b86d8626758cf0 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 13:59:03 -1100 Subject: [PATCH 33/94] Reduce network traffic --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1ca925482..de9fe34c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5202,11 +5202,11 @@ bool ProcessNewBlock(bool from_miner,int32_t height,CValidationState &state, CNo CheckBlockIndex(); if (!ret && futureblock == 0) { - if ( ASSETCHAINS_SYMBOL[0] == 0 ) + /*if ( ASSETCHAINS_SYMBOL[0] == 0 ) { //fprintf(stderr,"request headers from failed process block peer\n"); pfrom->PushMessage("getheaders", chainActive.GetLocator(chainActive.LastTip()), uint256()); - } + }*/ komodo_longestchain(); return error("%s: AcceptBlock FAILED", __func__); } From 3043dffcf58a15d7b94f822fbfc616d7f4c79e18 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Sat, 1 Dec 2018 12:52:38 +0800 Subject: [PATCH 34/94] fix getblocktemplate --- src/rpc/mining.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index aed10944c..25b75c301 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -606,9 +606,10 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) return BIP22ValidationResult(state); } } - - if (strMode != "template") - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); + else + { + strMode = "template"; + } bool fvNodesEmpty; { From 46a6e1db66556165c6e35f144df96ab67ae7bf51 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 22:37:48 -1100 Subject: [PATCH 35/94] +prints --- src/cc/dice.cpp | 4 +++- src/wallet/rpcwallet.cpp | 18 +++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 597f2cb38..631951c0d 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1664,7 +1664,9 @@ void *dealer0_loop(void *_arg) DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,entropytxs,false); if ( entropytxs < DICE_MINUTXOS ) { - n = sqrt(DICE_MINUTXOS - entropytxs) + 10; + n = sqrt(DICE_MINUTXOS - entropytxs); + if ( n > 10 ) + n = 10; for (i=0; inTime+27,minage,hashbuf)) == 0 ) continue; eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address); - //fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); +fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); if ( eligible > 0 ) { besttime = m = 0; @@ -5215,7 +5215,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt if ( eligible < block_from_future_rejecttime ) // nothing gained by going earlier break; m++; - //fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible); +fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible); } } else @@ -5225,7 +5225,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt } eligible = besttime; winners++; - //fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible); +fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible); if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp->nValue < *utxovaluep)) ) { earliest = eligible; @@ -5237,8 +5237,8 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt *txtimep = kp->txtime;//(uint32_t)out.tx->nLockTime; fprintf(stderr,"ht.%d earliest.%u [%d].%d (%s) nValue %.8f locktime.%u counter.%d winners.%d\n",nHeight,earliest,(int32_t)(earliest - tipindex->nTime),m,kp->address,(double)kp->nValue/COIN,*txtimep,counter,winners); } - } //else fprintf(stderr,"utxo not eligible\n"); - } //else fprintf(stderr,"no tipindex\n"); + } else fprintf(stderr,"utxo not eligible\n"); + } else fprintf(stderr,"no tipindex\n"); if ( numkp < 10000 && array != 0 ) { free(array); @@ -5273,11 +5273,11 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt for (i=0; i Date: Fri, 30 Nov 2018 22:39:32 -1100 Subject: [PATCH 36/94] -print --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 953a24ef4..03f9c2b36 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5238,7 +5238,7 @@ fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",n fprintf(stderr,"ht.%d earliest.%u [%d].%d (%s) nValue %.8f locktime.%u counter.%d winners.%d\n",nHeight,earliest,(int32_t)(earliest - tipindex->nTime),m,kp->address,(double)kp->nValue/COIN,*txtimep,counter,winners); } } else fprintf(stderr,"utxo not eligible\n"); - } else fprintf(stderr,"no tipindex\n"); + } if ( numkp < 10000 && array != 0 ) { free(array); From 15b9d33d79eecb5a95815c2f5542c3457ed584a6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 22:42:53 -1100 Subject: [PATCH 37/94] Fix staking < 10000 utxo --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 03f9c2b36..941a696ca 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5151,7 +5151,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt if ( *blocktimep > tipindex->nTime+60 ) *blocktimep = tipindex->nTime+60; //fprintf(stderr,"Start scan of utxo for staking %u ht.%d\n",(uint32_t)time(NULL),nHeight); - if ( time(NULL) > lasttime+600 ) + if ( time(NULL) > lasttime+600 || array == 0 ) { if ( array != 0 ) { From dcc2079714f69c554bb762fd160ff6dfa812a18b Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 22:49:26 -1100 Subject: [PATCH 38/94] Fix _komodo_eligible --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 941a696ca..a1eafc6e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5083,7 +5083,7 @@ arith_uint256 _komodo_eligible(struct komodo_staking *kp,arith_uint256 ratio,uin diff = 3600*24*30; if ( iter > 0 ) diff += segid*2; - coinage = ((uint64_t)kp->nValue/COIN * diff); + coinage = ((uint64_t)kp->nValue * diff); if ( blocktime+iter+segid*2 > prevtime+480 ) coinage *= ((blocktime+iter+segid*2) - (prevtime+400)); //if ( nHeight >= 2500 && blocktime+iter+segid*2 > prevtime+180 ) @@ -5188,7 +5188,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt } } lasttime = (uint32_t)time(NULL); -fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); +//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); } block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; for (i=winners=0; i Date: Fri, 30 Nov 2018 22:54:07 -1100 Subject: [PATCH 39/94] Test --- src/wallet/rpcwallet.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a1eafc6e2..6a195c912 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5086,12 +5086,8 @@ arith_uint256 _komodo_eligible(struct komodo_staking *kp,arith_uint256 ratio,uin coinage = ((uint64_t)kp->nValue * diff); if ( blocktime+iter+segid*2 > prevtime+480 ) coinage *= ((blocktime+iter+segid*2) - (prevtime+400)); - //if ( nHeight >= 2500 && blocktime+iter+segid*2 > prevtime+180 ) - // coinage *= ((blocktime+iter+segid*2) - (prevtime+60)); coinage256 = arith_uint256(coinage+1); hashval = ratio * (kp->hashval / coinage256); - //if ( nHeight >= 900 && nHeight < 916 ) - // hashval = (hashval / coinage256); return(hashval); } @@ -5170,19 +5166,23 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt counter++; if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth ) { - //fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth); +fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth); continue; } CAmount nValue = out.tx->vout[out.i].nValue; if ( nValue < COIN || !out.fSpendable ) continue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; + fprintf(stderr,"ExtractDestination\n"); if ( ExtractDestination(pk,address) != 0 ) { + fprintf(stderr,"IsMine\n"); if ( IsMine(*pwalletMain,address) == 0 ) continue; + fprintf(stderr,"GetTransaction\n"); if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 ) { + fprintf(stderr,"addutxo\n"); array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); } } From 257e996fff4bcb31606d104591b706f5fbab3f13 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 22:59:10 -1100 Subject: [PATCH 40/94] Test --- src/wallet/rpcwallet.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6a195c912..c227835bd 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5059,8 +5059,10 @@ struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numk { *maxkp += 1000; array = (struct komodo_staking *)realloc(array,sizeof(*array) * (*maxkp)); + fprintf(stderr,"realloc max.%d array.%p\n",*maxkp,array); } kp = &array[(*numkp)++]; + fprintf(stderr,"kp.%p num.%d\n",kp,*numkp); memset(kp,0,sizeof(*kp)); strcpy(kp->address,address); kp->txid = txid; @@ -5166,30 +5168,28 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt counter++; if ( out.nDepth < nMinDepth || out.nDepth > nMaxDepth ) { -fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth); + fprintf(stderr,"komodo_staked invalid depth %d\n",(int32_t)out.nDepth); continue; } CAmount nValue = out.tx->vout[out.i].nValue; if ( nValue < COIN || !out.fSpendable ) continue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; - fprintf(stderr,"ExtractDestination\n"); if ( ExtractDestination(pk,address) != 0 ) { - fprintf(stderr,"IsMine\n"); if ( IsMine(*pwalletMain,address) == 0 ) continue; - fprintf(stderr,"GetTransaction\n"); if ( GetTransaction(out.tx->GetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 ) { - fprintf(stderr,"addutxo\n"); array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); + fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp); } } } lasttime = (uint32_t)time(NULL); -//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); +fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); } +fprintf(stderr,"numkp.%d\n",numkp); block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; for (i=winners=0; i Date: Fri, 30 Nov 2018 23:07:15 -1100 Subject: [PATCH 41/94] Test --- src/wallet/rpcwallet.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c227835bd..d09c48a95 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5059,10 +5059,10 @@ struct komodo_staking *komodo_addutxo(struct komodo_staking *array,int32_t *numk { *maxkp += 1000; array = (struct komodo_staking *)realloc(array,sizeof(*array) * (*maxkp)); - fprintf(stderr,"realloc max.%d array.%p\n",*maxkp,array); + //fprintf(stderr,"realloc max.%d array.%p\n",*maxkp,array); } kp = &array[(*numkp)++]; - fprintf(stderr,"kp.%p num.%d\n",kp,*numkp); + //fprintf(stderr,"kp.%p num.%d\n",kp,*numkp); memset(kp,0,sizeof(*kp)); strcpy(kp->address,address); kp->txid = txid; @@ -5101,9 +5101,9 @@ uint32_t komodo_eligible(arith_uint256 bnTarget,arith_uint256 ratio,struct komod kp->hashval = UintToArith256(hash); segid = ((nHeight + kp->segid32) & 0x3f); hashval = _komodo_eligible(kp,ratio,blocktime,maxiters,minage,segid,nHeight,prevtime); - //for (int i=32; i>=0; i--) - // fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]); - //fprintf(stderr," b.%u minage.%d segid.%d ht.%d prev.%u\n",blocktime,minage,segid,nHeight,prevtime); + for (int i=32; i>=0; i--) + fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]); + fprintf(stderr," b.%u minage.%d segid.%d ht.%d prev.%u\n",blocktime,minage,segid,nHeight,prevtime); if ( hashval <= bnTarget ) { for (iter=0; iterGetHash(),tx,hashBlock,true) != 0 && (pindex= komodo_getblockindex(hashBlock)) != 0 ) { array = komodo_addutxo(array,&numkp,&maxkp,(uint32_t)pindex->nTime,(uint64_t)nValue,out.tx->GetHash(),out.i,(char *)CBitcoinAddress(address).ToString().c_str(),hashbuf,(CScript)pk); - fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp); + //fprintf(stderr,"addutxo numkp.%d vs max.%d\n",numkp,maxkp); } } } lasttime = (uint32_t)time(NULL); -fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); +//fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); } -fprintf(stderr,"numkp.%d\n",numkp); +fprintf(stderr,"numkp.%d blocktime.%u\n",numkp,*blocktimep); block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; for (i=winners=0; i Date: Fri, 30 Nov 2018 23:11:02 -1100 Subject: [PATCH 42/94] Set blocktime for staking --- src/miner.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 8fb2b4677..981fad63f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -463,8 +463,6 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr; CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight); - //if ( blocktime > pindexPrev->GetMedianTimePast()+60 ) - // blocktime = pindexPrev->GetMedianTimePast() + 60; if (ASSETCHAINS_LWMAPOS != 0) { uint32_t nBitsPOS; @@ -479,6 +477,9 @@ CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, } else { + blocktime = GetAdjustedTime(); + //if ( blocktime > pindexPrev->GetMedianTimePast()+60 ) + // blocktime = pindexPrev->GetMedianTimePast() + 60; siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig); } From 552294da4ae83cf2196f8bc3caee91b669ab671d Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 23:13:07 -1100 Subject: [PATCH 43/94] Max to min --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d09c48a95..31fcdc7e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5146,7 +5146,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt if ( (minage= nHeight*3) > 6000 ) // about 100 blocks minage = 6000; komodo_segids(hashbuf,nHeight-101,100); - if ( *blocktimep > tipindex->nTime+60 ) + if ( *blocktimep < tipindex->nTime+60 ) *blocktimep = tipindex->nTime+60; //fprintf(stderr,"Start scan of utxo for staking %u ht.%d\n",(uint32_t)time(NULL),nHeight); if ( time(NULL) > lasttime+600 || array == 0 ) From 94d569467ec78e7dd5fb05f9c4e88a0cb699d67c Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 23:18:36 -1100 Subject: [PATCH 44/94] Test --- src/komodo_bitcoind.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 1a0fad409..0893ece6d 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1771,12 +1771,12 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) { if ( (is_PoSblock= komodo_is_PoSblock(slowflag,height,pblock,bnTarget,bhash)) == 0 ) { + if ( slowflag == 0 ) // need all past 100 blocks to calculate PoW target + return(0); if ( ASSETCHAINS_STAKED == 100 && height > 100 ) // only PoS allowed! POSTEST64 return(-1); else { - if ( slowflag == 0 ) // need all past 100 blocks to calculate PoW target - return(0); if ( slowflag != 0 ) bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED); if ( bhash > bnTarget ) From 345a7838c289f7fccc95890ec9ed60d9fb4f947a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 23:23:35 -1100 Subject: [PATCH 45/94] Test --- src/komodo_bitcoind.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 0893ece6d..fd18ad0a0 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1472,14 +1472,14 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED); if ( bhash < bnTarget ) { - //fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); +fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); isPoS = 0; } } } //else return(-1); } - //fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS); +fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS); return(isPoS != 0); } @@ -1824,7 +1824,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } } - //fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); +fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); if ( failed != 0 && possible == 0 && notaryid < 0 ) return(-1); else return(0); From 803d74be34cc1ebe1cbbe540c6483273fcdfc4a1 Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 23:30:26 -1100 Subject: [PATCH 46/94] Test --- src/komodo_bitcoind.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index fd18ad0a0..e7ecf5f77 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1472,14 +1472,14 @@ int32_t komodo_is_PoSblock(int32_t slowflag,int32_t height,CBlock *pblock,arith_ bnTarget = komodo_PoWtarget(&PoSperc,bnTarget,height,ASSETCHAINS_STAKED); if ( bhash < bnTarget ) { -fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); + //fprintf(stderr,"ht.%d isPoS but meets PoW diff!\n",height); isPoS = 0; } } } //else return(-1); } -fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS); + //fprintf(stderr,"slow.%d ht.%d isPoS.%d\n",slowflag,height,isPoS); return(isPoS != 0); } @@ -1796,6 +1796,8 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) fprintf(stderr,"unexpected negative is_PoSblock.%d\n",is_PoSblock); return(-1); } + else if ( ASSETCHAINS_STAKED != 0 ) + failed = 0; } if ( failed == 0 && ASSETCHAINS_COMMISSION != 0 ) //ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 ) { @@ -1824,7 +1826,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) return(-1); } } -fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); +//fprintf(stderr,"komodo_checkPOW possible.%d slowflag.%d ht.%d notaryid.%d failed.%d\n",possible,slowflag,height,notaryid,failed); if ( failed != 0 && possible == 0 && notaryid < 0 ) return(-1); else return(0); From 3777611fbc459b3e1a377edcfb2fe7b476a8e76a Mon Sep 17 00:00:00 2001 From: jl777 Date: Fri, 30 Nov 2018 23:34:51 -1100 Subject: [PATCH 47/94] Test --- src/wallet/rpcwallet.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 31fcdc7e2..46b8d1818 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5189,7 +5189,7 @@ int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blockt lasttime = (uint32_t)time(NULL); //fprintf(stderr,"finished kp data of utxo for staking %u ht.%d numkp.%d maxkp.%d\n",(uint32_t)time(NULL),nHeight,numkp,maxkp); } -fprintf(stderr,"numkp.%d blocktime.%u\n",numkp,*blocktimep); +//fprintf(stderr,"numkp.%d blocktime.%u\n",numkp,*blocktimep); block_from_future_rejecttime = (uint32_t)GetAdjustedTime() + 57; for (i=winners=0; inTime+27,minage,hashbuf)) == 0 ) continue; eligible = komodo_stake(0,bnTarget,nHeight,kp->txid,kp->vout,0,(uint32_t)tipindex->nTime+27,kp->address); -fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); +//fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); if ( eligible > 0 ) { besttime = m = 0; @@ -5215,7 +5215,7 @@ fprintf(stderr,"i.%d %u vs %u\n",i,eligible2,eligible); if ( eligible < block_from_future_rejecttime ) // nothing gained by going earlier break; m++; -fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible); +//fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u test prior\n",m,nHeight,*blocktimep,(double)kp->nValue/COIN,eligible); } } else @@ -5225,7 +5225,7 @@ fprintf(stderr,"m.%d ht.%d validated winning blocktime %u -> %.8f eligible.%u te } eligible = besttime; winners++; -fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible); +//fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",nHeight,(int32_t)(eligible - tipindex->nTime),(double)kp->nValue/COIN,eligible); if ( earliest == 0 || eligible < earliest || (eligible == earliest && (*utxovaluep == 0 || kp->nValue < *utxovaluep)) ) { earliest = eligible; @@ -5237,7 +5237,7 @@ fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",n *txtimep = kp->txtime;//(uint32_t)out.tx->nLockTime; fprintf(stderr,"ht.%d earliest.%u [%d].%d (%s) nValue %.8f locktime.%u counter.%d winners.%d\n",nHeight,earliest,(int32_t)(earliest - tipindex->nTime),m,kp->address,(double)kp->nValue/COIN,*txtimep,counter,winners); } - } else fprintf(stderr,"utxo not eligible\n"); + } //else fprintf(stderr,"utxo not eligible\n"); } if ( numkp < 10000 && array != 0 ) { @@ -5273,11 +5273,11 @@ fprintf(stderr,"ht.%d validated winning [%d] -> %.8f eligible.%u test prior\n",n for (i=0; i Date: Fri, 30 Nov 2018 23:36:57 -1100 Subject: [PATCH 48/94] -print --- src/wallet/rpcwallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 46b8d1818..cbba7cca9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -5101,9 +5101,9 @@ uint32_t komodo_eligible(arith_uint256 bnTarget,arith_uint256 ratio,struct komod kp->hashval = UintToArith256(hash); segid = ((nHeight + kp->segid32) & 0x3f); hashval = _komodo_eligible(kp,ratio,blocktime,maxiters,minage,segid,nHeight,prevtime); - for (int i=32; i>=0; i--) - fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]); - fprintf(stderr," b.%u minage.%d segid.%d ht.%d prev.%u\n",blocktime,minage,segid,nHeight,prevtime); + //for (int i=32; i>=0; i--) + // fprintf(stderr,"%02x",((uint8_t *)&hashval)[i]); + //fprintf(stderr," b.%u minage.%d segid.%d ht.%d prev.%u\n",blocktime,minage,segid,nHeight,prevtime); if ( hashval <= bnTarget ) { for (iter=0; iter Date: Sat, 1 Dec 2018 01:19:33 -1100 Subject: [PATCH 49/94] Change entropy tx issuing --- src/cc/dice.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 631951c0d..ae9e01fce 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1652,21 +1652,28 @@ static uint256 dealer0_fundingtxid; void *dealer0_loop(void *_arg) { char *planstr = (char *)_arg; - CTransaction tx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid; int32_t entropytxs,i,n,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; + CTransaction tx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid; int32_t height,lastht,entropytxs,i,n,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) { fprintf(stderr,"error initializing dealer0_loop\n"); exit(-1); } fprintf(stderr,"dealer0 node running\n"); + height = lastht = 0; while ( 1 ) { + while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht ) + { + sleep(3); + } + lastht = height; + fprintf(stderr,"New height.%d\n",height); DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,entropytxs,false); if ( entropytxs < DICE_MINUTXOS ) { n = sqrt(DICE_MINUTXOS - entropytxs); - if ( n > 10 ) - n = 10; + //if ( n > 10 ) + // n = 10; for (i=0; i Date: Sat, 1 Dec 2018 01:23:56 -1100 Subject: [PATCH 50/94] Limit to 10 --- src/cc/dice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index ae9e01fce..a2909efc3 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1672,8 +1672,8 @@ void *dealer0_loop(void *_arg) if ( entropytxs < DICE_MINUTXOS ) { n = sqrt(DICE_MINUTXOS - entropytxs); - //if ( n > 10 ) - // n = 10; + if ( n > 10 ) + n = 10; for (i=0; i Date: Sat, 1 Dec 2018 01:50:35 -1100 Subject: [PATCH 51/94] AddNormalinputs2 bypass bitcoin wallet --- src/cc/CCinclude.h | 1 + src/cc/CCtx.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/cc/dice.cpp | 2 +- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/cc/CCinclude.h b/src/cc/CCinclude.h index ddfecd47a..83c85e551 100644 --- a/src/cc/CCinclude.h +++ b/src/cc/CCinclude.h @@ -178,6 +178,7 @@ std::string FinalizeCCTx(uint64_t skipmask,struct CCcontract_info *cp,CMutableTr void SetCCunspents(std::vector > &unspentOutputs,char *coinaddr); void SetCCtxids(std::vector > &addressIndex,char *coinaddr); int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs); +int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs); int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout); // curve25519 and sha256 diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index b94e1372c..b683a7f51 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -431,3 +431,92 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3 #endif return(0); } + + +int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs) +{ + int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=64; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up; + std::vector > unspentOutputs; + utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos)); + threshold = total/(maxinputs+1); + if ( maxinputs > maxutxos ) + maxutxos = maxinputs; + sum = 0; + Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG); + SetCCunspents(unspentOutputs,coinaddr); + for (std::vector >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++) + { + txid = it->first.txhash; + vout = (int32_t)it->first.index; + if ( it->second.satoshis < threshold ) + continue; + if ( myGetTransaction(txid,tx,hashBlock) != 0 && tx.vout.size() > 0 && vout < tx.vout.size() && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() == 0 ) + { + //fprintf(stderr,"check %.8f to vins array.%d of %d %s/v%d\n",(double)out.tx->vout[out.i].nValue/COIN,n,maxutxos,txid.GetHex().c_str(),(int32_t)vout); + if ( mtx.vin.size() > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; itxid = txid; + up->nValue = it->second.satoshis; + up->vout = vout; + sum += up->nValue; + //fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos); + if ( n >= maxutxos || sum >= total ) + break; + } + } + } + remains = total; + for (i=0; i0; i++) + { + below = above = 0; + abovei = belowi = -1; + if ( CC_vinselect(&abovei,&above,&belowi,&below,utxos,n,remains) < 0 ) + { + printf("error finding unspent i.%d of %d, %.8f vs %.8f\n",i,n,(double)remains/COIN,(double)total/COIN); + free(utxos); + return(0); + } + if ( belowi < 0 || abovei >= 0 ) + ind = abovei; + else ind = belowi; + if ( ind < 0 ) + { + printf("error finding unspent i.%d of %d, %.8f vs %.8f, abovei.%d belowi.%d ind.%d\n",i,n,(double)remains/COIN,(double)total/COIN,abovei,belowi,ind); + free(utxos); + return(0); + } + up = &utxos[ind]; + mtx.vin.push_back(CTxIn(up->txid,up->vout,CScript())); + totalinputs += up->nValue; + remains -= up->nValue; + utxos[ind] = utxos[--n]; + memset(&utxos[n],0,sizeof(utxos[n])); + //fprintf(stderr,"totalinputs %.8f vs total %.8f i.%d vs max.%d\n",(double)totalinputs/COIN,(double)total/COIN,i,maxinputs); + if ( totalinputs >= total || (i+1) >= maxinputs ) + break; + } + free(utxos); + if ( totalinputs >= total ) + { + //fprintf(stderr,"return totalinputs %.8f\n",(double)totalinputs/COIN); + return(totalinputs); + } + return(0); +} diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index a2909efc3..7af73241b 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1392,7 +1392,7 @@ std::string DiceAddfunding(uint64_t txfee,char *planstr,uint256 fundingtxid,int6 } if ( scriptPubKey == fundingPubKey ) { - if ( AddNormalinputs(mtx,mypk,amount+2*txfee,60) > 0 ) + if ( AddNormalinputs2(mtx,amount+2*txfee,60) > 0 ) { hentropy = DiceHashEntropy(entropy,mtx.vin[0].prevout.hash,mtx.vin[0].prevout.n,1); mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,dicepk)); From 69f0b8631f6c028fec0768eb4c3e82a16c0d00e6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 01:56:08 -1100 Subject: [PATCH 52/94] Remove 10 entropy cap --- src/cc/dice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 7af73241b..9c8438fd4 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1672,8 +1672,8 @@ void *dealer0_loop(void *_arg) if ( entropytxs < DICE_MINUTXOS ) { n = sqrt(DICE_MINUTXOS - entropytxs); - if ( n > 10 ) - n = 10; + //if ( n > 10 ) + // n = 10; for (i=0; i Date: Sat, 1 Dec 2018 03:16:26 -1100 Subject: [PATCH 53/94] Verify entropy tx is confirmed for dealer0 --- src/cc/dice.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 9c8438fd4..4f923d754 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1505,7 +1505,7 @@ std::string DiceBetFinish(uint8_t &funcid,uint256 &entropyused,int32_t &entropyv { if ( vin0txid == zeroid || vin0vout < 0 ) { - if ( AddNormalinputs(mtx,mypk,2*txfee,3) == 0 ) // must be a single vin!! + if ( AddNormalinputs2(mtx,2*txfee,3) == 0 ) // must be a single vin!! { CCerror = "no txfee inputs for win/lose"; fprintf(stderr,"%s\n", CCerror.c_str() ); @@ -1652,7 +1652,7 @@ static uint256 dealer0_fundingtxid; void *dealer0_loop(void *_arg) { char *planstr = (char *)_arg; - CTransaction tx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid; int32_t height,lastht,entropytxs,i,n,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; + CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid,txid; int32_t height,lastht,entropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) { fprintf(stderr,"error initializing dealer0_loop\n"); @@ -1660,6 +1660,7 @@ void *dealer0_loop(void *_arg) } fprintf(stderr,"dealer0 node running\n"); height = lastht = 0; + entropytx = (CTransaction *)calloc(sizeof(*entropytx),DICE_MINUTXOS); while ( 1 ) { while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht ) @@ -1674,7 +1675,7 @@ void *dealer0_loop(void *_arg) n = sqrt(DICE_MINUTXOS - entropytxs); //if ( n > 10 ) // n = 10; - for (i=0; i 64 && is_hexstr((char *)res.c_str(),0) > 64 ) @@ -1686,10 +1687,30 @@ void *dealer0_loop(void *_arg) { fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - entropytxs); RelayTransaction(tx); + entropytxs[m++] = tx; } else break; } else break; } else break; } + for (i=0; i Date: Sat, 1 Dec 2018 03:17:26 -1100 Subject: [PATCH 54/94] numentropytxs --- src/cc/dice.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 4f923d754..dd7ef11ab 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1652,7 +1652,7 @@ static uint256 dealer0_fundingtxid; void *dealer0_loop(void *_arg) { char *planstr = (char *)_arg; - CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid,txid; int32_t height,lastht,entropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; + CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid,txid; int32_t height,lastht,numentropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) { fprintf(stderr,"error initializing dealer0_loop\n"); @@ -1669,13 +1669,13 @@ void *dealer0_loop(void *_arg) } lastht = height; fprintf(stderr,"New height.%d\n",height); - DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,entropytxs,false); - if ( entropytxs < DICE_MINUTXOS ) + DicePlanFunds(entropyval,entropytxid,refsbits,cp,dicepk,dealer0_fundingtxid,numentropytxs,false); + if ( numentropytxs < DICE_MINUTXOS ) { - n = sqrt(DICE_MINUTXOS - entropytxs); + n = sqrt(DICE_MINUTXOS - numentropytxs); //if ( n > 10 ) // n = 10; - for (i=m=0; i 64 && is_hexstr((char *)res.c_str(),0) > 64 ) @@ -1685,7 +1685,7 @@ void *dealer0_loop(void *_arg) LOCK(cs_main); if ( myAddtomempool(tx) != 0 ) { - fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - entropytxs); + fprintf(stderr,"ENTROPY %s: %d of %d, %d\n",tx.GetHash().GetHex().c_str(),i,n,DICE_MINUTXOS - numentropytxs); RelayTransaction(tx); entropytxs[m++] = tx; } else break; From 760d30b22bdecc19f6cadeb49fb65ad2a030643b Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:17:56 -1100 Subject: [PATCH 55/94] hashBlock --- src/cc/dice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index dd7ef11ab..3cb1a5a25 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1652,7 +1652,7 @@ static uint256 dealer0_fundingtxid; void *dealer0_loop(void *_arg) { char *planstr = (char *)_arg; - CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 entropytxid,txid; int32_t height,lastht,numentropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; + CTransaction tx,*entropytxs,entropytx; CPubKey mypk,dicepk; uint64_t entropyval; uint256 hashBlock,entropytxid,txid; int32_t height,lastht,numentropytxs,i,n,m,num; CScript fundingPubKey; struct CCcontract_info *cp,C; char coinaddr[64]; std::string res; int64_t minbet,maxbet,maxodds,timeoutblocks; uint64_t refsbits,txfee = 10000; if ( (cp= Diceinit(fundingPubKey,dealer0_fundingtxid,&C,planstr,txfee,mypk,dicepk,refsbits,minbet,maxbet,maxodds,timeoutblocks)) == 0 ) { fprintf(stderr,"error initializing dealer0_loop\n"); From d6dfb8c2506326a9f39b28918e792a655972fa1c Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:18:45 -1100 Subject: [PATCH 56/94] numentropytxs --- src/cc/dice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 3cb1a5a25..0676900e4 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1660,7 +1660,7 @@ void *dealer0_loop(void *_arg) } fprintf(stderr,"dealer0 node running\n"); height = lastht = 0; - entropytx = (CTransaction *)calloc(sizeof(*entropytx),DICE_MINUTXOS); + entropytx = (CTransaction *)calloc(sizeof(*entropytxs),DICE_MINUTXOS); while ( 1 ) { while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht ) From 2ee44287ade0860d1de384f40d517ecb1c95f3fd Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:19:24 -1100 Subject: [PATCH 57/94] Txs --- src/cc/dice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 0676900e4..6d09eda07 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1660,7 +1660,7 @@ void *dealer0_loop(void *_arg) } fprintf(stderr,"dealer0 node running\n"); height = lastht = 0; - entropytx = (CTransaction *)calloc(sizeof(*entropytxs),DICE_MINUTXOS); + entropytxs = (CTransaction *)calloc(sizeof(*entropytxs),DICE_MINUTXOS); while ( 1 ) { while ( KOMODO_INSYNC == 0 || (height= KOMODO_INSYNC) == lastht ) From 4c1cab06b0bdc443855461a55fb0578c7d820a86 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:32:40 -1100 Subject: [PATCH 58/94] +prints --- src/cc/dice.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 6d09eda07..ff55be6ef 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1696,7 +1696,7 @@ void *dealer0_loop(void *_arg) { tx = entropytxs[i]; txid = tx.GetHash(); - fprintf(stderr,"found %d of %d: %s\n",i,m,txid.GetHex().c_str()); + fprintf(stderr,"check %d of %d: %s\n",i,m,txid.GetHex().c_str()); while ( 1 ) { if ( myGetTransaction(txid,entropytx,hashBlock) == 0 || hashBlock == zeroid ) @@ -1708,7 +1708,12 @@ void *dealer0_loop(void *_arg) RelayTransaction(tx); } sleep(10); - } else break; + } + else + { + fprintf(stderr,"found %s in %s\n",txid.GetHex().c_str(),hashBlock.GetHex().c_str()); + break; + } } } } From 2e8f9eda462090ffe43949610251ed4b9891b3ec Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:40:13 -1100 Subject: [PATCH 59/94] Test --- src/cc/dice.cpp | 2 +- src/main.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index ff55be6ef..0581dc9ce 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1707,13 +1707,13 @@ void *dealer0_loop(void *_arg) fprintf(stderr,"resend ENTROPY %s: %d of %d\n",txid.GetHex().c_str(),i,m); RelayTransaction(tx); } - sleep(10); } else { fprintf(stderr,"found %s in %s\n",txid.GetHex().c_str(),hashBlock.GetHex().c_str()); break; } + sleep(10); } } } diff --git a/src/main.cpp b/src/main.cpp index de9fe34c3..564221f17 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1979,6 +1979,7 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate) bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) { + hashBlock = zeroid; // need a GetTransaction without lock so the validation code for assets can run without deadlock { //fprintf(stderr,"check mempool\n"); @@ -2022,6 +2023,7 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; + hashBlock = zeroid; LOCK(cs_main); From e5a4fcc4b82e8160f9671e38a0622958e0338e29 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:42:33 -1100 Subject: [PATCH 60/94] memset(&hashBlock,0,sizeof(hashBlock)); --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 564221f17..942dc120e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1979,7 +1979,7 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate) bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock) { - hashBlock = zeroid; + memset(&hashBlock,0,sizeof(hashBlock)); // need a GetTransaction without lock so the validation code for assets can run without deadlock { //fprintf(stderr,"check mempool\n"); @@ -2023,7 +2023,7 @@ bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlo bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; - hashBlock = zeroid; + memset(&hashBlock,0,sizeof(hashBlock)); LOCK(cs_main); From b0b80e69e68069da8d55537cc1856c83eeeff921 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 1 Dec 2018 03:59:11 -1100 Subject: [PATCH 61/94] Entropy tx size 1.0 --- src/cc/dice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 0581dc9ce..6faaa1f0c 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -1677,7 +1677,7 @@ void *dealer0_loop(void *_arg) // n = 10; for (i=m=0; i 64 && is_hexstr((char *)res.c_str(),0) > 64 ) { if ( DecodeHexTx(tx,res) != 0 ) From d1e8c8c8fc68f7338bf7a41df4d5f092d7c02911 Mon Sep 17 00:00:00 2001 From: SHossain Date: Sun, 2 Dec 2018 17:44:05 +0000 Subject: [PATCH 62/94] Update assetchains.old --- src/assetchains.old | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assetchains.old b/src/assetchains.old index 9164ca316..5389e54bd 100755 --- a/src/assetchains.old +++ b/src/assetchains.old @@ -27,7 +27,7 @@ echo $pubkey ./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=PIZZA -ac_supply=100000000 -addnode=78.47.196.146 & ./komodod -pubkey=$pubkey -ac_name=NINJA -ac_supply=100000000 -addnode=78.47.196.146 & -./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -addnode=174.138.107.226 & +./komodod -pubkey=$pubkey -ac_name=OOT -ac_supply=216000000 -ac_saplinig=5000000 -addnode=174.138.107.226 & ./komodod -pubkey=$pubkey -ac_name=BNTN -ac_supply=500000000 -addnode=94.130.169.205 & ./komodod -pubkey=$pubkey -ac_name=CHAIN -ac_supply=999999 -addnode=78.47.146.222 & ./komodod -pubkey=$pubkey -ac_name=PRLPAY -ac_supply=500000000 -addnode=13.250.226.125 & From 6bd19b0835c42ebec129f5388aa852d79b49909e Mon Sep 17 00:00:00 2001 From: SHossain Date: Sun, 2 Dec 2018 17:47:13 +0000 Subject: [PATCH 63/94] added `-ac_saplinig=5000000` for OOT added `-ac_saplinig=5000000` for OOT --- src/assetchains.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/assetchains.json b/src/assetchains.json index 287a88c19..7bc6b7147 100644 --- a/src/assetchains.json +++ b/src/assetchains.json @@ -94,7 +94,8 @@ }, { "ac_name": "OOT", - "ac_supply": "216000000" + "ac_supply": "216000000", + "ac_sapling": "5000000" }, { "ac_name": "BNTN", From 08e029bf40bd59479e07d2f7a0d0caa369268cfe Mon Sep 17 00:00:00 2001 From: Anton Lysakov Date: Mon, 3 Dec 2018 21:26:33 +0600 Subject: [PATCH 64/94] separated tests for different CCs to different files --- qa/pull-tester/rpc-tests.sh | 5 + qa/rpc-tests/cryptoconditions_dice.py | 259 ++++++++++++++++++++ qa/rpc-tests/cryptoconditions_faucet.py | 173 ++++++++++++++ qa/rpc-tests/cryptoconditions_oracles.py | 142 +++++++++++ qa/rpc-tests/cryptoconditions_rewards.py | 208 ++++++++++++++++ qa/rpc-tests/cryptoconditions_token.py | 288 +++++++++++++++++++++++ 6 files changed, 1075 insertions(+) create mode 100755 qa/rpc-tests/cryptoconditions_dice.py create mode 100755 qa/rpc-tests/cryptoconditions_faucet.py create mode 100755 qa/rpc-tests/cryptoconditions_oracles.py create mode 100755 qa/rpc-tests/cryptoconditions_rewards.py create mode 100755 qa/rpc-tests/cryptoconditions_token.py diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index bc83f9880..0d7d5509c 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -14,6 +14,11 @@ testScripts=( 'ac_private.py' 'verushash.py' 'cryptoconditions.py' + 'cryptoconditions_dice.py' + 'cryptoconditions_faucet.py' + 'cryptoconditions_oracles.py' + 'cryptoconditions_rewards.py' + 'cryptoconditions_token.py' 'paymentdisclosure.py' 'prioritisetransaction.py' 'wallet_treestate.py' diff --git a/qa/rpc-tests/cryptoconditions_dice.py b/qa/rpc-tests/cryptoconditions_dice.py new file mode 100755 index 000000000..9957a8f2b --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_dice.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + +class CryptoconditionsDiceTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 2 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp" + self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0" + self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ], + ['-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node1/REGTEST.conf', + '-port=64365', + '-rpcport=64366', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey1, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-addnode=127.0.0.1:64367', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt']] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.rpc1 = self.nodes[1] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn, rpc_connection): + txid = rpc_connection.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + rpc_connection.generate(1) + return txid + + def run_dice_tests(self): + rpc = self.nodes[0] + rpc1 = self.nodes[1] + self.sync_all() + + # have to generate few blocks on second node to be able to place bets + rpc1.generate(10) + result = rpc1.getbalance() + assert_greater_than(result, 100000) + + dice = rpc.diceaddress() + assert_equal(dice['result'], 'success') + for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']: + assert_equal(dice[x][0], 'R') + + dice = rpc.diceaddress(self.pubkey) + assert_equal(dice['result'], 'success') + for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress', 'CCaddress']: + assert_equal(dice[x][0], 'R') + + # no dice created yet + result = rpc.dicelist() + assert_equal(result, []) + + # creating dice plan with too long name (>8 chars) + result = rpc.dicefund("THISISTOOLONG", "10000", "10", "10000", "10", "5") + assert_error(result) + + # creating dice plan with < 100 funding + result = rpc.dicefund("LUCKY","10","1","10000","10","5") + assert_error(result) + + # creating dice plan with 0 blocks timeout + result = rpc.dicefund("LUCKY","10","1","10000","10","0") + assert_error(result) + + # creating dice plan + dicefundtx = rpc.dicefund("LUCKY","1000","1","800","10","5") + diceid = self.send_and_mine(dicefundtx['hex'], rpc) + + # checking if it in plans list now + result = rpc.dicelist() + assert_equal(result[0], diceid) + + # set dice name for futher usage + dicename = "LUCKY" + + # adding zero funds to plan + result = rpc.diceaddfunds(dicename,diceid,"0") + assert_error(result) + + # adding negative funds to plan + result = rpc.diceaddfunds(dicename,diceid,"-1") + assert_error(result) + + # adding funds to plan + addfundstx = rpc.diceaddfunds(dicename,diceid,"1100") + result = self.send_and_mine(addfundstx['hex'], rpc) + + # checking if funds added to plan + result = rpc.diceinfo(diceid) + assert_equal(result["funding"], "2100.00000000") + + # not valid dice info checking + result = rpc.diceinfo("invalid") + assert_error(result) + + # placing 0 amount bet + result = rpc1.dicebet(dicename,diceid,"0","2") + assert_error(result) + + # placing negative amount bet + result = rpc1.dicebet(dicename,diceid,"-1","2") + assert_error(result) + + # placing bet more than maxbet + result = rpc1.dicebet(dicename,diceid,"900","2") + assert_error(result) + + # placing bet with amount more than funding + result = rpc1.dicebet(dicename,diceid,"3000","2") + assert_error(result) + + # placing bet with potential won more than funding + result = rpc1.dicebet(dicename,diceid,"750","9") + assert_error(result) + + # placing 0 odds bet + result = rpc1.dicebet(dicename,diceid,"1","0") + assert_error(result) + + # placing negative odds bet + result = rpc1.dicebet(dicename,diceid,"1","-1") + assert_error(result) + + # placing bet with odds more than allowed + result = rpc1.dicebet(dicename,diceid,"1","11") + assert_error(result) + + # placing bet with not correct dice name + result = rpc1.dicebet("nope",diceid,"100","2") + assert_error(result) + + # placing bet with not correct dice id + result = rpc1.dicebet(dicename,self.pubkey,"100","2") + assert_error(result) + + # have to make some entropy for the next test + entropytx = 0 + fundingsum = 1 + while entropytx < 110: + fundingsuminput = str(fundingsum) + fundinghex = rpc.diceaddfunds(dicename,diceid,fundingsuminput) + result = self.send_and_mine(fundinghex['hex'], rpc) + entropytx = entropytx + 1 + fundingsum = fundingsum + 1 + + rpc.generate(2) + self.sync_all() + + # valid bet placing + placebet = rpc1.dicebet(dicename,diceid,"100","2") + betid = self.send_and_mine(placebet["hex"], rpc1) + assert result, "bet placed" + + # check bet status + result = rpc1.dicestatus(dicename,diceid,betid) + assert_success(result) + + # note initial dice funding state at this point. + # TODO: track player balance somehow (hard to do because of mining and fees) + diceinfo = rpc.diceinfo(diceid) + funding = float(diceinfo['funding']) + + # # placing same amount bets with amount 1 and odds 1:3, checking if balance changed correct + # losscounter = 0 + # wincounter = 0 + # betcounter = 0 + # + # while (betcounter < 10): + # placebet = rpc1.dicebet(dicename,diceid,"1","2") + # betid = self.send_and_mine(placebet["hex"], rpc1) + # time.sleep(3) + # self.sync_all() + # finish = rpc.dicefinish(dicename,diceid,betid) + # self.send_and_mine(finish["hex"], rpc1) + # self.sync_all() + # time.sleep(3) + # betresult = rpc1.dicestatus(dicename,diceid,betid) + # betcounter = betcounter + 1 + # if betresult["status"] == "loss": + # losscounter = losscounter + 1 + # elif betresult["status"] == "win": + # wincounter = wincounter + 1 + # else: + # pass + # + # # funding balance should increase if player loss, decrease if player won + # fundbalanceguess = funding + losscounter - wincounter * 2 + # fundinfoactual = rpc.diceinfo(diceid) + # assert_equal(round(fundbalanceguess),round(float(fundinfoactual['funding']))) + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_dice_tests() + + +if __name__ == '__main__': + CryptoconditionsDiceTest ().main() diff --git a/qa/rpc-tests/cryptoconditions_faucet.py b/qa/rpc-tests/cryptoconditions_faucet.py new file mode 100755 index 000000000..4f8cb42cf --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_faucet.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + + +class CryptoconditionsFaucetTest(BitcoinTestFramework): + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 2 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp" + self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0" + self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ], + ['-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node1/REGTEST.conf', + '-port=64365', + '-rpcport=64366', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey1, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-addnode=127.0.0.1:64367', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt']] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.rpc1 = self.nodes[1] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn, rpc_connection): + txid = rpc_connection.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + rpc_connection.generate(1) + return txid + + def run_faucet_tests(self): + rpc = self.rpc + rpc1 = self.rpc1 + + # basic sanity tests + result = rpc.getwalletinfo() + assert_greater_than(result['txcount'], 100) + assert_greater_than(result['balance'], 0.0) + balance = result['balance'] + + faucet = rpc.faucetaddress() + assert_equal(faucet['result'], 'success') + # verify all keys look like valid AC addrs, could be better + for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']: + assert_equal(faucet[x][0], 'R') + + result = rpc.faucetaddress(self.pubkey) + assert_success(result) + # test that additional CCaddress key is returned + for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + + # no funds in the faucet yet + result = rpc.faucetget() + assert_error(result) + + result = rpc.faucetinfo() + assert_success(result) + + result = rpc.faucetfund("0") + assert_error(result) + + result = rpc.faucetfund("-1") + assert_error(result) + + # we need at least 1 + txfee to get + result = rpc.faucetfund("2") + assert_success(result) + assert result['hex'], "hex key found" + + # broadcast the xtn + result = rpc.sendrawtransaction(result['hex']) + txid = result[0] + assert txid, "found txid" + + # we need the tx above to be confirmed in the next block + rpc.generate(1) + self.sync_all() + + result = rpc.getwalletinfo() + # minus one block reward + balance2 = result['balance'] - 100000 + # make sure our balance is less now + assert_greater_than(balance, balance2) + + result = rpc.faucetinfo() + assert_success(result) + assert_greater_than( result['funding'], 0 ) + + # claiming faucet on second node + faucetgethex = rpc1.faucetget() + assert_success(faucetgethex) + assert faucetgethex['hex'], "hex key found" + + balance1 = rpc1.getwalletinfo()['balance'] + + # try to broadcast the faucetget transaction + result = self.send_and_mine(faucetgethex['hex'], rpc1) + assert txid, "transaction broadcasted" + + balance2 = rpc1.getwalletinfo()['balance'] + assert_greater_than(balance2, balance1) + + self.sync_all() + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_faucet_tests() + + +if __name__ == '__main__': + CryptoconditionsFaucetTest ().main() diff --git a/qa/rpc-tests/cryptoconditions_oracles.py b/qa/rpc-tests/cryptoconditions_oracles.py new file mode 100755 index 000000000..ded5166ed --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_oracles.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + + +class CryptoconditionsOraclesTest(BitcoinTestFramework): + + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 2 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp" + self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0" + self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ], + ['-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node1/REGTEST.conf', + '-port=64365', + '-rpcport=64366', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey1, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-addnode=127.0.0.1:64367', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt']] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.rpc1 = self.nodes[1] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn, rpc_connection): + txid = rpc_connection.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + rpc_connection.generate(1) + return txid + + def run_oracles_tests(self): + rpc = self.nodes[0] + rpc1 = self.nodes[1] + + result = rpc1.oraclesaddress() + + result = rpc.oraclesaddress() + assert_success(result) + for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.oraclesaddress(self.pubkey) + assert_success(result) + for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']: + assert_equal(result[x][0], 'R') + + # there are no oracles created yet + result = rpc.oracleslist() + assert_equal(result, []) + + # looking up non-existent oracle should return error. + result = rpc.oraclesinfo("none") + assert_error(result) + + # attempt to create oracle with not valid data type should return error + result = rpc.oraclescreate("Test", "Test", "Test") + assert_error(result) + + # attempt to create oracle with description > 32 symbols should return error + too_long_name = generate_random_string(33) + result = rpc.oraclescreate(too_long_name, "Test", "s") + + # attempt to create oracle with description > 4096 symbols should return error + too_long_description = generate_random_string(4100) + result = rpc.oraclescreate("Test", too_long_description, "s") + assert_error(result) + # # valid creating oracles of different types + # # using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type) + # valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"] + # for f in valid_formats: + # result = rpc.oraclescreate("Test", "Test", f) + # assert_success(result) + # globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex'], rpc) + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_oracles_tests() + +if __name__ == '__main__': + CryptoconditionsOraclesTest().main() diff --git a/qa/rpc-tests/cryptoconditions_rewards.py b/qa/rpc-tests/cryptoconditions_rewards.py new file mode 100755 index 000000000..5538a399c --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_rewards.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + + +class CryptoconditionsRewardsTest(BitcoinTestFramework): + + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 2 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp" + self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0" + self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ], + ['-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node1/REGTEST.conf', + '-port=64365', + '-rpcport=64366', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey1, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-addnode=127.0.0.1:64367', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt']] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.rpc1 = self.nodes[1] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn, rpc_connection): + txid = rpc_connection.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + rpc_connection.generate(1) + return txid + + def run_rewards_tests(self): + rpc = self.nodes[0] + result = rpc.rewardsaddress() + for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.rewardsaddress(self.pubkey) + for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + + # no rewards yet + result = rpc.rewardslist() + assert_equal(result, []) + + # looking up non-existent reward should return error + result = rpc.rewardsinfo("none") + assert_error(result) + + # creating rewards plan with name > 8 chars, should return error + result = rpc.rewardscreatefunding("STUFFSTUFF", "7777", "25", "0", "10", "10") + assert_error(result) + + # creating rewards plan with 0 funding + result = rpc.rewardscreatefunding("STUFF", "0", "25", "0", "10", "10") + assert_error(result) + + # creating rewards plan with 0 maxdays + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "0") + assert_error(result) + + # creating rewards plan with > 25% APR + result = rpc.rewardscreatefunding("STUFF", "7777", "30", "0", "10", "10") + assert_error(result) + + # creating valid rewards plan + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10") + assert result['hex'], 'got raw xtn' + fundingtxid = rpc.sendrawtransaction(result['hex']) + assert fundingtxid, 'got txid' + + # confirm the above xtn + rpc.generate(1) + result = rpc.rewardsinfo(fundingtxid) + assert_success(result) + assert_equal(result['name'], 'STUFF') + assert_equal(result['APR'], "25.00000000") + assert_equal(result['minseconds'], 0) + assert_equal(result['maxseconds'], 864000) + assert_equal(result['funding'], "7777.00000000") + assert_equal(result['mindeposit'], "10.00000000") + assert_equal(result['fundingtxid'], fundingtxid) + + # checking if new plan in rewardslist + result = rpc.rewardslist() + assert_equal(result[0], fundingtxid) + + # creating reward plan with already existing name, should return error + result = rpc.rewardscreatefunding("STUFF", "7777", "25", "0", "10", "10") + assert_error(result) + + # add funding amount must be positive + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "-1") + assert_error(result) + + # add funding amount must be positive + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "0") + assert_error(result) + + # adding valid funding + result = rpc.rewardsaddfunding("STUFF", fundingtxid, "555") + addfundingtxid = self.send_and_mine(result['hex'], rpc) + assert addfundingtxid, 'got funding txid' + + # checking if funding added to rewardsplan + result = rpc.rewardsinfo(fundingtxid) + assert_equal(result['funding'], "8332.00000000") + + # trying to lock funds, locking funds amount must be positive + result = rpc.rewardslock("STUFF", fundingtxid, "-5") + assert_error(result) + + # trying to lock funds, locking funds amount must be positive + result = rpc.rewardslock("STUFF", fundingtxid, "0") + assert_error(result) + + # trying to lock less than the min amount is an error + result = rpc.rewardslock("STUFF", fundingtxid, "7") + assert_error(result) + + # locking funds in rewards plan + result = rpc.rewardslock("STUFF", fundingtxid, "10") + assert_success(result) + locktxid = result['hex'] + assert locktxid, "got lock txid" + + # locktxid has not been broadcast yet + result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid) + assert_error(result) + + # broadcast xtn + txid = rpc.sendrawtransaction(locktxid) + assert txid, 'got txid from sendrawtransaction' + + # confirm the xtn above + rpc.generate(1) + + # will not unlock since reward amount is less than tx fee + result = rpc.rewardsunlock("STUFF", fundingtxid, locktxid) + assert_error(result) + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_rewards_tests() + +if __name__ == '__main__': + CryptoconditionsRewardsTest().main() diff --git a/qa/rpc-tests/cryptoconditions_token.py b/qa/rpc-tests/cryptoconditions_token.py new file mode 100755 index 000000000..8120f23bf --- /dev/null +++ b/qa/rpc-tests/cryptoconditions_token.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python2 +# Copyright (c) 2018 SuperNET developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.authproxy import JSONRPCException +from test_framework.util import assert_equal, assert_greater_than, \ + initialize_chain_clean, initialize_chain, start_nodes, start_node, connect_nodes_bi, \ + stop_nodes, sync_blocks, sync_mempools, wait_bitcoinds, rpc_port, assert_raises +from cryptoconditions import assert_success, assert_error, generate_random_string + + +class CryptoconditionsTokenTest(BitcoinTestFramework): + + + def setup_chain(self): + print("Initializing CC test directory "+self.options.tmpdir) + self.num_nodes = 2 + initialize_chain_clean(self.options.tmpdir, self.num_nodes) + + def setup_network(self, split = False): + print("Setting up network...") + self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D" + self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf" + self.privkey = "UqMgxk7ySPNQ4r9nKAFPjkXy6r5t898yhuNCjSZJLg3RAM4WW1m9" + self.addr1 = "RXEXoa1nRmKhMbuZovpcYwQMsicwzccZBp" + self.pubkey1 = "024026d4ad4ecfc1f705a9b42ca64af6d2ad947509c085534a30b8861d756c6ff0" + self.privkey1 = "UtdydP56pGTFmawHzHr1wDrc4oUwCNW1ttX8Pc3KrvH3MA8P49Wi" + self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, + extra_args=[[ + # always give -ac_name as first extra_arg and port as third + '-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node0/REGTEST.conf', + '-port=64367', + '-rpcport=64368', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt' + ], + ['-ac_name=REGTEST', + '-conf='+self.options.tmpdir+'/node1/REGTEST.conf', + '-port=64365', + '-rpcport=64366', + '-regtest', + '-addressindex=1', + '-spentindex=1', + '-ac_supply=5555555', + '-ac_reward=10000000000000', + '-pubkey=' + self.pubkey1, + '-ac_cc=2', + '-whitelist=127.0.0.1', + '-debug', + '-addnode=127.0.0.1:64367', + '--daemon', + '-rpcuser=rt', + '-rpcpassword=rt']] + ) + self.is_network_split = split + self.rpc = self.nodes[0] + self.rpc1 = self.nodes[1] + self.sync_all() + print("Done setting up network") + + def send_and_mine(self, xtn, rpc_connection): + txid = rpc_connection.sendrawtransaction(xtn) + assert txid, 'got txid' + # we need the tx above to be confirmed in the next block + rpc_connection.generate(1) + return txid + + def run_token_tests(self): + rpc = self.nodes[0] + result = rpc.tokenaddress() + assert_success(result) + for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']: + assert_equal(result[x][0], 'R') + + result = rpc.tokenaddress(self.pubkey) + assert_success(result) + for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']: + assert_equal(result[x][0], 'R') + # there are no tokens created yet + result = rpc.tokenlist() + assert_equal(result, []) + + # trying to create token with negaive supply + result = rpc.tokencreate("NUKE", "-1987420", "no bueno supply") + assert_error(result) + + # creating token with name more than 32 chars + result = rpc.tokencreate("NUKE123456789012345678901234567890", "1987420", "name too long") + assert_error(result) + + # creating valid token + result = rpc.tokencreate("DUKE", "1987.420", "Duke's custom token") + assert_success(result) + + tokenid = self.send_and_mine(result['hex'], rpc) + + result = rpc.tokenlist() + assert_equal(result[0], tokenid) + + # there are no token orders yet + result = rpc.tokenorders() + assert_equal(result, []) + + # getting token balance for pubkey + result = rpc.tokenbalance(self.pubkey) + assert_success(result) + assert_equal(result['balance'], 0) + assert_equal(result['CCaddress'], 'RCRsm3VBXz8kKTsYaXKpy7pSEzrtNNQGJC') + assert_equal(result['tokenid'], self.pubkey) + + # get token balance for token with pubkey + result = rpc.tokenbalance(tokenid, self.pubkey) + assert_success(result) + assert_equal(result['balance'], 198742000000) + assert_equal(result['tokenid'], tokenid) + + # get token balance for token without pubkey + result = rpc.tokenbalance(tokenid) + assert_success(result) + assert_equal(result['balance'], 198742000000) + assert_equal(result['tokenid'], tokenid) + + # this is not a valid assetid + result = rpc.tokeninfo(self.pubkey) + assert_error(result) + + # check tokeninfo for valid token + result = rpc.tokeninfo(tokenid) + assert_success(result) + assert_equal(result['tokenid'], tokenid) + assert_equal(result['owner'], self.pubkey) + assert_equal(result['name'], "DUKE") + assert_equal(result['supply'], 198742000000) + assert_equal(result['description'], "Duke's custom token") + + # invalid numtokens ask + result = rpc.tokenask("-1", tokenid, "1") + assert_error(result) + + # invalid numtokens ask + result = rpc.tokenask("0", tokenid, "1") + assert_error(result) + + # invalid price ask + result = rpc.tokenask("1", tokenid, "-1") + assert_error(result) + + # invalid price ask + result = rpc.tokenask("1", tokenid, "0") + assert_error(result) + + # invalid tokenid ask + result = rpc.tokenask("100", "deadbeef", "1") + assert_error(result) + + # valid ask + tokenask = rpc.tokenask("100", tokenid, "7.77") + tokenaskhex = tokenask['hex'] + tokenaskid = self.send_and_mine(tokenask['hex'], rpc) + result = rpc.tokenorders() + order = result[0] + assert order, "found order" + + # invalid ask fillunits + result = rpc.tokenfillask(tokenid, tokenaskid, "0") + assert_error(result) + + # invalid ask fillunits + result = rpc.tokenfillask(tokenid, tokenaskid, "-777") + assert_error(result) + + # valid ask fillunits + fillask = rpc.tokenfillask(tokenid, tokenaskid, "777") + result = self.send_and_mine(fillask['hex'], rpc) + txid = result[0] + assert txid, "found txid" + + # should be no token orders + result = rpc.tokenorders() + assert_equal(result, []) + + # checking ask cancellation + testorder = rpc.tokenask("100", tokenid, "7.77") + testorderid = self.send_and_mine(testorder['hex'], rpc) + cancel = rpc.tokencancelask(tokenid, testorderid) + self.send_and_mine(cancel["hex"], rpc) + result = rpc.tokenorders() + assert_equal(result, []) + + # invalid numtokens bid + result = rpc.tokenbid("-1", tokenid, "1") + assert_error(result) + + # invalid numtokens bid + result = rpc.tokenbid("0", tokenid, "1") + assert_error(result) + + # invalid price bid + result = rpc.tokenbid("1", tokenid, "-1") + assert_error(result) + + # invalid price bid + result = rpc.tokenbid("1", tokenid, "0") + assert_error(result) + + # invalid tokenid bid + result = rpc.tokenbid("100", "deadbeef", "1") + assert_error(result) + + tokenbid = rpc.tokenbid("100", tokenid, "10") + tokenbidhex = tokenbid['hex'] + tokenbidid = self.send_and_mine(tokenbid['hex'], rpc) + result = rpc.tokenorders() + order = result[0] + assert order, "found order" + + # invalid bid fillunits + result = rpc.tokenfillbid(tokenid, tokenbidid, "0") + assert_error(result) + + # invalid bid fillunits + result = rpc.tokenfillbid(tokenid, tokenbidid, "-777") + assert_error(result) + + # valid bid fillunits + fillbid = rpc.tokenfillbid(tokenid, tokenbidid, "1000") + result = self.send_and_mine(fillbid['hex'], rpc) + txid = result[0] + assert txid, "found txid" + + # should be no token orders + result = rpc.tokenorders() + assert_equal(result, []) + + # checking bid cancellation + testorder = rpc.tokenbid("100", tokenid, "7.77") + testorderid = self.send_and_mine(testorder['hex'], rpc) + cancel = rpc.tokencancelbid(tokenid, testorderid) + self.send_and_mine(cancel["hex"], rpc) + result = rpc.tokenorders() + assert_equal(result, []) + + # invalid token transfer amount (have to add status to CC code!) + randompubkey = "021a559101e355c907d9c553671044d619769a6e71d624f68bfec7d0afa6bd6a96" + result = rpc.tokentransfer(tokenid,randompubkey,"0") + assert_error(result) + + # invalid token transfer amount (have to add status to CC code!) + result = rpc.tokentransfer(tokenid,randompubkey,"-1") + assert_error(result) + + # valid token transfer + sendtokens = rpc.tokentransfer(tokenid,randompubkey,"1") + self.send_and_mine(sendtokens["hex"], rpc) + result = rpc.tokenbalance(tokenid,randompubkey) + assert_equal(result["balance"], 1) + + def run_test(self): + print("Mining blocks...") + rpc = self.nodes[0] + rpc1 = self.nodes[1] + # utxos from block 1 become mature in block 101 + rpc.generate(101) + self.sync_all() + rpc.getinfo() + rpc1.getinfo() + # this corresponds to -pubkey above + print("Importing privkeys") + rpc.importprivkey(self.privkey) + rpc1.importprivkey(self.privkey1) + self.run_token_tests() + +if __name__ == '__main__': + CryptoconditionsTokenTest().main() From 1ae28c0ea05e78fe294b2beaf70deb9f9c254773 Mon Sep 17 00:00:00 2001 From: SHossain Date: Mon, 3 Dec 2018 18:05:45 +0000 Subject: [PATCH 65/94] Update README.md --- README.md | 188 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index bb60c2e6e..9a8582891 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,13 @@ -## VerusCoin version 0.4.0c - -VerusCoin is a new, mineable and stakeable cryptocurrency. It is a live fork of Komodo that retains its Zcash lineage and improves it. VerusCoin will leverage the Komodo platform and dPoW notarization for enhanced security and cross-chain interoperability. We have added a variation of a zawy12, lwma difficulty algorithm, a new CPU-optimized hash algorithm and a new algorithm for fair proof of stake. We describe these changes and vision going forward in a [our Phase I white paper](http://185.25.51.16/papers/VerusPhaseI.pdf) and [our Vision](http://185.25.51.16/papers/VerusVision.pdf). -- [VerusCoin web site https://veruscoin.io/ Wallets and CLI tools](https://veruscoin.io/) -- [VerusCoin Explorer](https://explorer.veruscoin.io/) +[![Build Status](https://travis-ci.org/KomodoPlatform/komodo.svg?branch=dev)](https://travis-ci.org/KomodoPlatform/komodo) +--- +![Komodo Logo](https://i.imgur.com/vIwVtqv.png "Komodo Logo") -## Komodo with Bitcore -This version of Komodo contains Bitcore support for komodo and all its assetchains. +## Komodo -## Komodod -This software is the VerusCoin enhanced Komodo client. Generally, you will use this if you want to mine VRSC or setup a full node. When you run the wallet it launches komodod automatically. On first launch it downloads Zcash parameters, roughly 1GB, which is mildly slow. -The wallet downloads and stores the block chain or asset chain of the coin you select. It downloads and stores the entire history of the coins transactions; depending on the speed of your computer and network connection, the synchronization process could take a day or more once the blockchain has reached a significant size. +This is the official Komodo sourcecode repository based on https://github.com/jl777/komodo. + +## Development Resources - Komodo Website: [https://komodoplatform.com](https://komodoplatform.com/) - Komodo Blockexplorer: [https://kmdexplorer.io](https://kmdexplorer.io/) @@ -26,23 +23,23 @@ The wallet downloads and stores the block chain or asset chain of the coin you s ## List of Komodo Platform Technologies -- Delayed Proof of Work (dPoW) - Additional security layer and Komodos own consensus algorithm. -- zk-SNARKs - Komodo Platform's privacy technology for shielded transactions -- Tokens/Assets Technology - create "colored coins" on the Komodo Platform and use them as a layer for securites -- Reward API - Komodo CC technology for securities -- CC - Crypto Conditions to realize "smart contract" logic on top of the Komodo Platform -- Jumblr - Decentralized tumbler for KMD and other cryptocurrencies -- Assetchains - Create your own Blockchain that inherits all Komodo Platform functionalities and blockchain interoperability -- Pegged Assets - Chains that maintain a peg to fiat currencies -- Peerchains - Scalability solution where sibling chains form a network of blockchains -- More in depth covered [here](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) -- Also note you receive 5% APR on your holdings. -[See this article for more details](https://komodoplatform.atlassian.net/wiki/spaces/KPSD/pages/20480015/Claim+KMD+Interest+in+Agama) +- Delayed Proof of Work (dPoW) - Additional security layer and Komodos own consensus algorithm +- zk-SNARKs - Komodo Platform's privacy technology for shielded transactions +- Tokens/Assets Technology - create "colored coins" on the Komodo Platform and use them as a layer for securites +- Reward API - Komodo CC technology for securities +- CC - Crypto Conditions to realize "smart contract" logic on top of the Komodo Platform +- Jumblr - Decentralized tumbler for KMD and other cryptocurrencies +- Assetchains - Create your own Blockchain that inherits all Komodo Platform functionalities and blockchain interoperability +- Pegged Assets - Chains that maintain a peg to fiat currencies +- Peerchains - Scalability solution where sibling chains form a network of blockchains +- More in depth covered [here](https://docs.google.com/document/d/1AbhWrtagu4vYdkl-vsWz-HSNyNvK-W-ZasHCqe7CZy0) +- Also note you receive 5% Active User Reward on your balance. +[See this article for more details](https://support.komodoplatform.com/en/support/solutions/articles/29000024515-how-to-claim-the-kmd-active-user-reward-in-agama) ## Tech Specification -- Max Supply: 200 million KMD. -- Block Time: 1M 2s -- Block Reward: 3KMD +- Max Supply: 200 million KMD +- Block Time: 1m 2s +- Block Reward: 3 KMD - Mining Algorithm: Equihash ## About this Project @@ -57,86 +54,121 @@ Komodo is based on Zcash and has been extended by our innovative consensus algor sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python python-zmq zlib1g-dev wget libcurl4-gnutls-dev bsdmainutils automake curl ``` +### Build Komodo -Building --------- +This software is based on zcash and considered experimental and is continously undergoing heavy development. -First time you'll need to get assorted startup values downloaded. This takes a moderate amount of time once but then does not need to be repeated unless you bring a new system up. The command is: -``` -./zcutil/fetch-params.sh -``` -Building for Ubunutu/Mint: -``` -./zcutil/build.sh -``` -Building for Mac OS/X (see README-MAC.md): -``` -./zcutil/build-mac.sh -``` -Building for Windows: -``` -./zcutil/build-win.sh -``` -VerusCoin ------- -We develop on dev and some other branches and produce releases of of the master branch, using pull requests to manage what goes into master. The dev branch is considered the bleeding edge codebase, and may even be oncompatible from time to time, while the master-branch is considered tested (unit tests, runtime tests, functionality). At no point of time do the Komodo Platform developers or Verus Developers take any responsbility for any damage out of the usage of this software. - -Verus builds for all operating systems out of the same codebase. Follow the OS specific instructions from below. +The dev branch is considered the bleeding edge codebase while the master-branch is considered tested (unit tests, runtime tests, functionality). At no point of time do the Komodo Platform developers take any responsbility for any damage out of the usage of this software. +Komodo builds for all operating systems out of the same codebase. Follow the OS specific instructions from below. #### Linux ```shell -git clone https://github.com/VerusCoin/VerusCoin -cd VerusCoin -#you might want to: git checkout ; git pull +git clone https://github.com/komodoplatform/komodo --branch master --single-branch +cd komodo ./zcutil/fetch-params.sh # -j8 = using 8 threads for the compilation - replace 8 with number of threads you want to use ./zcutil/build.sh -j8 #This can take some time. ``` -**The VerusCoin enhanced komodo is experimental and a work-in-progress.** Use at your own risk. +#### OSX +Ensure you have [brew](https://brew.sh) and the command line tools installed (comes automatically with XCode) and run: +```shell +brew update && brew install gcc@6 +git clone https://github.com/komodoplatform/komodo --branch master --single-branch +cd komodo +./zcutil/fetch-params.sh +# -j8 = using 8 threads for the compilation - replace 8 with number of threads you want to use +./zcutil/build-mac.sh -j8 +#This can take some time. +``` +#### Windows +Use a debian cross-compilation setup with mingw for windows and run: +```shell +sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool ncurses-dev unzip git python python-zmq zlib1g-dev wget libcurl4-gnutls-dev bsdmainutils automake curl cmake mingw-w64 +curl https://sh.rustup.rs -sSf | sh +source $HOME/.cargo/env +rustup target add x86_64-pc-windows-gnu +git clone https://github.com/jl777/komodo --branch master --single-branch +cd komodo +./zcutil/fetch-params.sh +# -j8 = using 8 threads for the compilation - replace 8 with number of threads you want to use +./zcutil/build-win.sh -j8 +#This can take some time. +``` +**komodo is experimental and a work-in-progress.** Use at your own risk. -#To view komodod output: -tail -f ~/.komodo/debug.log -#To view VRSC output: -tail -f ~/.komodo/VRSC/debug.log -Note that this directory is correct for Linux, not Mac or Windows -#To view all command -./src/komodo-cli help -**Zcash is unfinished and highly experimental.** Use at your own risk. +To reset the Komodo blockchain change into the *~/.komodo* data directory and delete the corresponding files by running `rm -rf blocks chainstate debug.log komodostate db.log` -#### :ledger: Deprecation Policy +#### Create komodo.conf -This release is considered deprecated 16 weeks after the release day. There -is an automatic deprecation shutdown feature which will halt the node some -time after this 16 week time period. The automatic feature is based on block -height. +Create a komodo.conf file: -#Older Komodo Details -The remaining text is from the komodo source we forked when creating VerusCoin/Veruscoin. +``` +mkdir ~/.komodo +cd ~/.komodo +touch komodo.conf + +#Add the following lines to the komodo.conf file: +rpcuser=yourrpcusername +rpcpassword=yoursecurerpcpassword +rpcbind=127.0.0.1 +txindex=1 +addnode=5.9.102.210 +addnode=78.47.196.146 +addnode=178.63.69.164 +addnode=88.198.65.74 +addnode=5.9.122.241 +addnode=144.76.94.38 +addnode=89.248.166.91 +``` +### Create your own Blockchain based on Komodo + +Komodo allows anyone to create a runtime fork which represents an independent Blockchain. Below are the detailed instructions: +Setup two independent servers with at least 1 server having a static IP and build komodod on those servers. + +#### On server 1 (with static IP) run: +```shell +./komodod -ac_name=name_of_your_chain -ac_supply=100000 -bind=ip_of_server_1 & +``` + +#### On server 2 run: +```shell +./komodod -ac_name=name_of_your_chain -ac_supply=100000 -addnode=ip_of_server_1 -gen & +``` + +**Komodo is based on Zcash which is unfinished and highly experimental.** Use at your own risk. + +License +------- +For license information see the file [COPYING](COPYING). + +**NOTE TO EXCHANGES:** +https://bitcointalk.org/index.php?topic=1605144.msg17732151#msg17732151 +There is a small chance that an outbound transaction will give an error due to mismatched values in wallet calculations. There is a -exchange option that you can run komodod with, but make sure to have the entire transaction history under the same -exchange mode. Otherwise you will get wallet conflicts. **To change modes:** -a) backup all privkeys (launch komodod with `-exportdir=` and `dumpwallet`) -b) start a totally new sync including `wallet.dat`, launch with same `exportdir` -c) stop it before it gets too far and import all the privkeys from a) using `komodo-cli importwallet filename` -d) resume sync till it gets to chaintip +a) backup all privkeys (launch komodod with `-exportdir=` and `dumpwallet`) +b) start a totally new sync including `wallet.dat`, launch with same `exportdir` +c) stop it before it gets too far and import all the privkeys from a) using `komodo-cli importwallet filename` +d) resume sync till it gets to chaintip For example: ```shell -./verusd -exportdir=/tmp & -./verus dumpwallet example -./verus stop -mv ~/.komodo/VRSC ~/.komodo/VRSC.old && mkdir ~/.komodo/VRSC && cp ~/.komodo/VRSC.old/VRSC.conf ~/.komodo/VRSC.old/peers.dat ~/.komodo/VRSC -./verusd -exchange -exportdir=/tmp & -./verus importwallet /tmp/example +./komodod -exportdir=/tmp & +./komodo-cli dumpwallet example +./komodo-cli stop +mv ~/.komodo ~/.komodo.old && mkdir ~/.komodo && cp ~/.komodo.old/komodo.conf ~/.komodo.old/peers.dat ~/.komodo +./komodod -exchange -exportdir=/tmp & +./komodo-cli importwallet /tmp/example ``` --- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notices and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From a5be135052a98e7c096c883483d74a4502764b82 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 4 Dec 2018 23:51:14 -1100 Subject: [PATCH 66/94] https://github.com/zcash/zcash/pull/3684/files --- qa/rpc-tests/wallet_persistence.py | 14 ++++++++++++-- src/txdb.cpp | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/wallet_persistence.py b/qa/rpc-tests/wallet_persistence.py index f6c227d2a..581cad473 100755 --- a/qa/rpc-tests/wallet_persistence.py +++ b/qa/rpc-tests/wallet_persistence.py @@ -68,12 +68,22 @@ class WalletPersistenceTest (BitcoinTestFramework): # Verify shielded balance assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('20')) - + + # Verify size of shielded pools + pools = self.nodes[0].getblockchaininfo()['valuePools'] + assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout + assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling + # Restart the nodes stop_nodes(self.nodes) wait_bitcoinds() self.setup_network() + # Verify size of shielded pools + pools = self.nodes[0].getblockchaininfo()['valuePools'] + assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout + assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling + # Node 0 sends some shielded funds to Node 1 dest_addr = self.nodes[1].z_getnewaddress('sapling') recipients = [] @@ -128,4 +138,4 @@ class WalletPersistenceTest (BitcoinTestFramework): assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('16')) if __name__ == '__main__': - WalletPersistenceTest().main() \ No newline at end of file + WalletPersistenceTest().main() diff --git a/src/txdb.cpp b/src/txdb.cpp index 212eda7a0..63e00dcd8 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -670,7 +670,8 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nCachedBranchId = diskindex.nCachedBranchId; pindexNew->nTx = diskindex.nTx; pindexNew->nSproutValue = diskindex.nSproutValue; - + pindexNew->nSaplingValue = diskindex.nSaplingValue; + // Consistency checks auto header = pindexNew->GetBlockHeader(); if (header.GetHash() != pindexNew->GetBlockHash()) From 9a59f561356ff1263868a64b60c9ee2eb0a29e72 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 4 Dec 2018 23:56:04 -1100 Subject: [PATCH 67/94] https://github.com/zcash/zcash/pull/3670/files --- src/gtest/test_checkblock.cpp | 4 ++-- src/main.cpp | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/gtest/test_checkblock.cpp b/src/gtest/test_checkblock.cpp index 01f098004..807191b5d 100644 --- a/src/gtest/test_checkblock.cpp +++ b/src/gtest/test_checkblock.cpp @@ -291,7 +291,7 @@ TEST_F(ContextualCheckBlockTest, BlockOverwinterRulesRejectOtherTx) { { SCOPED_TRACE("BlockOverwinterRulesRejectSaplingTx"); - ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-overwinter-tx-version-group-id"); + ExpectInvalidBlockFromTx(CTransaction(mtx), 0, "bad-overwinter-tx-version-group-id"); } } @@ -319,6 +319,6 @@ TEST_F(ContextualCheckBlockTest, BlockSaplingRulesRejectOtherTx) { { SCOPED_TRACE("BlockSaplingRulesRejectOverwinterTx"); - ExpectInvalidBlockFromTx(CTransaction(mtx), 100, "bad-sapling-tx-version-group-id"); + ExpectInvalidBlockFromTx(CTransaction(mtx), 0, "bad-sapling-tx-version-group-id"); } } diff --git a/src/main.cpp b/src/main.cpp index 942dc120e..b664f3405 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1034,9 +1034,12 @@ bool ContextualCheckTransaction( } // Reject transactions with non-Sapling version group ID - if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) { - return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"), - REJECT_INVALID, "bad-sapling-tx-version-group-id"); + if (tx.fOverwintered && tx.nVersionGroupId != SAPLING_VERSION_GROUP_ID) + { + //return state.DoS(dosLevel, error("CheckTransaction(): invalid Sapling tx version"),REJECT_INVALID, "bad-sapling-tx-version-group-id"); + return state.DoS(isInitBlockDownload() ? 0 : dosLevel, + error("CheckTransaction(): invalid Sapling tx version"), + REJECT_INVALID, "bad-sapling-tx-version-group-id"); } // Reject transactions with invalid version @@ -1058,9 +1061,12 @@ bool ContextualCheckTransaction( } // Reject transactions with non-Overwinter version group ID - if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) { - return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"), - REJECT_INVALID, "bad-overwinter-tx-version-group-id"); + if (tx.fOverwintered && tx.nVersionGroupId != OVERWINTER_VERSION_GROUP_ID) + { + //return state.DoS(dosLevel, error("CheckTransaction(): invalid Overwinter tx version"),REJECT_INVALID, "bad-overwinter-tx-version-group-id"); + return state.DoS(isInitBlockDownload() ? 0 : dosLevel, + error("CheckTransaction(): invalid Overwinter tx version"), + REJECT_INVALID, "bad-overwinter-tx-version-group-id"); } // Reject transactions with invalid version From 8c939c1af5fe05993aed20d0bbc1e070c883f38b Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 00:01:01 -1100 Subject: [PATCH 68/94] https://github.com/zcash/zcash/pull/3605/files --- qa/rpc-tests/wallet_listreceived.py | 14 +++++++------- src/wallet/asyncrpcoperation_sendmany.cpp | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/qa/rpc-tests/wallet_listreceived.py b/qa/rpc-tests/wallet_listreceived.py index 9ece27772..5d9e583ee 100755 --- a/qa/rpc-tests/wallet_listreceived.py +++ b/qa/rpc-tests/wallet_listreceived.py @@ -28,7 +28,7 @@ class ListReceivedTest (BitcoinTestFramework): self.sync_all() assert_equal(new_height, self.nodes[0].getblockcount()) - def run_test_release(self, release, expected_memo, height): + def run_test_release(self, release, height): self.generate_and_sync(height+1) taddr = self.nodes[1].getnewaddress() zaddr1 = self.nodes[1].z_getnewaddress(release) @@ -61,7 +61,7 @@ class ListReceivedTest (BitcoinTestFramework): # Generate some change by sending part of zaddr1 to zaddr2 zaddr2 = self.nodes[1].z_getnewaddress(release) opid = self.nodes[1].z_sendmany(zaddr1, - [{'address': zaddr2, 'amount': 0.6, 'memo': my_memo}]) + [{'address': zaddr2, 'amount': 0.6}]) txid = wait_and_assert_operationid_status(self.nodes[1], opid) self.sync_all() self.generate_and_sync(height+4) @@ -74,12 +74,12 @@ class ListReceivedTest (BitcoinTestFramework): assert_equal(txid, r[0]['txid']) assert_equal(Decimal('0.4')-fee, r[0]['amount']) assert_true(r[0]['change'], "Note valued at (0.4-fee) should be change") - assert_equal(expected_memo, r[0]['memo']) + assert_equal(no_memo, r[0]['memo']) # The old note still exists (it's immutable), even though it is spent assert_equal(Decimal('1.0'), r[1]['amount']) assert_false(r[1]['change'], "Note valued at 1.0 should not be change") - assert_equal(expected_memo, r[0]['memo']) + assert_equal(my_memo, r[1]['memo']) # zaddr2 should not have change r = self.nodes[1].z_listreceivedbyaddress(zaddr2, 0) @@ -88,11 +88,11 @@ class ListReceivedTest (BitcoinTestFramework): assert_equal(txid, r[0]['txid']) assert_equal(Decimal('0.6'), r[0]['amount']) assert_false(r[0]['change'], "Note valued at 0.6 should not be change") - assert_equal(my_memo, r[0]['memo']) + assert_equal(no_memo, r[0]['memo']) def run_test(self): - self.run_test_release('sprout', no_memo, 200) - self.run_test_release('sapling', no_memo, 204) + self.run_test_release('sprout', 200) + self.run_test_release('sapling', 204) if __name__ == '__main__': ListReceivedTest().main() diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 4e2895675..9062ba73c 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -1366,7 +1366,8 @@ void AsyncRPCOperation_sendmany::add_taddr_change_output_to_tx(CBitcoinAddress * } std::array AsyncRPCOperation_sendmany::get_memo_from_hex_string(std::string s) { - std::array memo = {{0x00}}; + // initialize to default memo (no_memo), see section 5.5 of the protocol spec + std::array memo = {{0xF6}}; std::vector rawMemo = ParseHex(s.c_str()); From e34bb5163a889d15a5063e23eb125196265f54d9 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:14:05 -1100 Subject: [PATCH 69/94] Non-test code from: https://github.com/zcash/zcash/pull/3619 --- .../asyncrpcoperation_mergetoaddress.cpp | 500 +++++++++++------- src/wallet/asyncrpcoperation_mergetoaddress.h | 106 ++-- src/wallet/rpcwallet.cpp | 396 +++++++------- src/wallet/wallet.cpp | 8 +- 4 files changed, 589 insertions(+), 421 deletions(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 04af76211..aa7c64e58 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -34,13 +34,15 @@ using namespace libzcash; +extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); + int mta_find_output(UniValue obj, int n) { UniValue outputMapValue = find_value(obj, "outputmap"); if (!outputMapValue.isArray()) { throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation"); } - + UniValue outputMap = outputMapValue.get_array(); assert(outputMap.size() == ZC_NUM_JS_OUTPUTS); for (size_t i = 0; i < outputMap.size(); i++) { @@ -48,61 +50,73 @@ int mta_find_output(UniValue obj, int n) return i; } } - + throw std::logic_error("n is not present in outputmap"); } AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress( - CMutableTransaction contextualTx, - std::vector utxoInputs, - std::vector noteInputs, - MergeToAddressRecipient recipient, - CAmount fee, - UniValue contextInfo) : - tx_(contextualTx), utxoInputs_(utxoInputs), noteInputs_(noteInputs), - recipient_(recipient), fee_(fee), contextinfo_(contextInfo) + boost::optional builder, + CMutableTransaction contextualTx, + std::vector utxoInputs, + std::vector sproutNoteInputs, + std::vector saplingNoteInputs, + MergeToAddressRecipient recipient, + CAmount fee, + UniValue contextInfo) : +tx_(contextualTx), utxoInputs_(utxoInputs), sproutNoteInputs_(sproutNoteInputs), +saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo) { if (fee < 0 || fee > MAX_MONEY) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range"); } - - if (utxoInputs.empty() && noteInputs.empty()) { + + if (utxoInputs.empty() && sproutNoteInputs.empty() && saplingNoteInputs.empty()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "No inputs"); } - + if (std::get<0>(recipient).size() == 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing"); } - + + if (sproutNoteInputs.size() > 0 && saplingNoteInputs.size() > 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"); + } + + if (sproutNoteInputs.size() > 0 && builder) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Sprout notes are not supported by the TransactionBuilder"); + } + + isUsingBuilder_ = false; + if (builder) { + isUsingBuilder_ = true; + builder_ = builder.get(); + } + toTaddr_ = DecodeDestination(std::get<0>(recipient)); isToTaddr_ = IsValidDestination(toTaddr_); isToZaddr_ = false; - + if (!isToTaddr_) { auto address = DecodePaymentAddress(std::get<0>(recipient)); if (IsValidPaymentAddress(address)) { isToZaddr_ = true; - // TODO: Add Sapling support. For now, return an error to the user. - if (boost::get(&address) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Currently, only Sprout zaddrs are supported"); - } toPaymentAddress_ = address; } else { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address"); } } - + // Log the context info i.e. the call parameters to z_mergetoaddress if (LogAcceptCategory("zrpcunsafe")) { LogPrint("zrpcunsafe", "%s: z_mergetoaddress initialized (params=%s)\n", getId(), contextInfo.write()); } else { LogPrint("zrpc", "%s: z_mergetoaddress initialized\n", getId()); } - + // Lock UTXOs lock_utxos(); lock_notes(); - + // Enable payment disclosure if requested paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); } @@ -118,12 +132,12 @@ void AsyncRPCOperation_mergetoaddress::main() unlock_notes(); return; } - + set_state(OperationStatus::EXECUTING); start_execution_clock(); - + bool success = false; - + #ifdef ENABLE_MINING #ifdef ENABLE_WALLET GenerateBitcoins(false, NULL, 0); @@ -131,7 +145,7 @@ void AsyncRPCOperation_mergetoaddress::main() GenerateBitcoins(false, 0); #endif #endif - + try { success = main_impl(); } catch (const UniValue& objError) { @@ -152,23 +166,23 @@ void AsyncRPCOperation_mergetoaddress::main() set_error_code(-2); set_error_message("unknown error"); } - + #ifdef ENABLE_MINING #ifdef ENABLE_WALLET - GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 0)); + GenerateBitcoins(GetBoolArg("-gen", false), pwalletMain, GetArg("-genproclimit", 1)); #else - GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 0)); + GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1)); #endif #endif - + stop_execution_clock(); - + if (success) { set_state(OperationStatus::SUCCESS); } else { set_state(OperationStatus::FAILED); } - + std::string s = strprintf("%s: z_mergetoaddress finished (status=%s", getId(), getStateAsString()); if (success) { s += strprintf(", txid=%s)\n", tx_.GetHash().ToString()); @@ -176,10 +190,10 @@ void AsyncRPCOperation_mergetoaddress::main() s += strprintf(", error=%s)\n", getErrorMessage()); } LogPrintf("%s", s); - + unlock_utxos(); // clean up unlock_notes(); // clean up - + // !!! Payment disclosure START if (success && paymentDisclosureMode && paymentDisclosureData_.size() > 0) { uint256 txidhash = tx_.GetHash(); @@ -202,12 +216,12 @@ void AsyncRPCOperation_mergetoaddress::main() bool AsyncRPCOperation_mergetoaddress::main_impl() { assert(isToTaddr_ != isToZaddr_); - - bool isPureTaddrOnlyTx = (noteInputs_.empty() && isToTaddr_); + + bool isPureTaddrOnlyTx = (sproutNoteInputs_.empty() && saplingNoteInputs_.empty() && isToTaddr_); CAmount minersFee = fee_; - + size_t numInputs = utxoInputs_.size(); - + // Check mempooltxinputlimit to avoid creating a transaction which the local mempool rejects size_t limit = (size_t)GetArg("-mempooltxinputlimit", 0); { @@ -221,40 +235,46 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() strprintf("Number of transparent inputs %d is greater than mempooltxinputlimit of %d", numInputs, limit)); } - + CAmount t_inputs_total = 0; for (MergeToAddressInputUTXO& t : utxoInputs_) { t_inputs_total += std::get<1>(t); } - + CAmount z_inputs_total = 0; - for (MergeToAddressInputNote& t : noteInputs_) { + for (const MergeToAddressInputSproutNote& t : sproutNoteInputs_) { z_inputs_total += std::get<2>(t); } - + + for (const MergeToAddressInputSaplingNote& t : saplingNoteInputs_) { + z_inputs_total += std::get<2>(t); + } + CAmount targetAmount = z_inputs_total + t_inputs_total; - + if (targetAmount <= minersFee) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strprintf("Insufficient funds, have %s and miners fee is %s", FormatMoney(targetAmount), FormatMoney(minersFee))); } - + CAmount sendAmount = targetAmount - minersFee; - + // update the transaction with the UTXO inputs and output (if any) - CMutableTransaction rawTx(tx_); - for (MergeToAddressInputUTXO& t : utxoInputs_) { - CTxIn in(std::get<0>(t)); - rawTx.vin.push_back(in); + if (!isUsingBuilder_) { + CMutableTransaction rawTx(tx_); + for (const MergeToAddressInputUTXO& t : utxoInputs_) { + CTxIn in(std::get<0>(t)); + rawTx.vin.push_back(in); + } + if (isToTaddr_) { + CScript scriptPubKey = GetScriptForDestination(toTaddr_); + CTxOut out(sendAmount, scriptPubKey); + rawTx.vout.push_back(out); + } + tx_ = CTransaction(rawTx); } - if (isToTaddr_) { - CScript scriptPubKey = GetScriptForDestination(toTaddr_); - CTxOut out(sendAmount, scriptPubKey); - rawTx.vout.push_back(out); - } - tx_ = CTransaction(rawTx); - + LogPrint(isPureTaddrOnlyTx ? "zrpc" : "zrpcunsafe", "%s: spending %s to send %s with fee %s\n", getId(), FormatMoney(targetAmount), FormatMoney(sendAmount), FormatMoney(minersFee)); LogPrint("zrpc", "%s: transparent input: %s\n", getId(), FormatMoney(t_inputs_total)); @@ -265,13 +285,134 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(sendAmount)); } LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee)); - + // Grab the current consensus branch ID { LOCK(cs_main); consensusBranchId_ = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); } - + + /** + * SCENARIO #0 + * + * Sprout not involved, so we just use the TransactionBuilder and we're done. + * + * This is based on code from AsyncRPCOperation_sendmany::main_impl() and should be refactored. + */ + if (isUsingBuilder_) { + builder_.SetFee(minersFee); + + + for (const MergeToAddressInputUTXO& t : utxoInputs_) { + COutPoint outPoint = std::get<0>(t); + CAmount amount = std::get<1>(t); + CScript scriptPubKey = std::get<2>(t); + builder_.AddTransparentInput(outPoint, scriptPubKey, amount); + } + + boost::optional ovk; + // Select Sapling notes + std::vector saplingOPs; + std::vector saplingNotes; + std::vector expsks; + for (const MergeToAddressInputSaplingNote& saplingNoteInput: saplingNoteInputs_) { + saplingOPs.push_back(std::get<0>(saplingNoteInput)); + saplingNotes.push_back(std::get<1>(saplingNoteInput)); + auto expsk = std::get<3>(saplingNoteInput); + expsks.push_back(expsk); + if (!ovk) { + ovk = expsk.full_viewing_key().ovk; + } + } + + // Fetch Sapling anchor and witnesses + uint256 anchor; + std::vector> witnesses; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + pwalletMain->GetSaplingNoteWitnesses(saplingOPs, witnesses, anchor); + } + + // Add Sapling spends + for (size_t i = 0; i < saplingNotes.size(); i++) { + if (!witnesses[i]) { + throw JSONRPCError(RPC_WALLET_ERROR, "Missing witness for Sapling note"); + } + assert(builder_.AddSaplingSpend(expsks[i], saplingNotes[i], anchor, witnesses[i].get())); + } + + if (isToTaddr_) { + if (!builder_.AddTransparentOutput(toTaddr_, sendAmount)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid output address, not a valid taddr."); + } + } else { + std::string zaddr = std::get<0>(recipient_); + std::string memo = std::get<1>(recipient_); + std::array hexMemo = get_memo_from_hex_string(memo); + auto saplingPaymentAddress = boost::get(&toPaymentAddress_); + if (saplingPaymentAddress == nullptr) { + // This should never happen as we have already determined that the payment is to sapling + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Could not get Sapling payment address."); + } + if (saplingNoteInputs_.size() == 0 && utxoInputs_.size() > 0) { + // Sending from t-addresses, which we don't have ovks for. Instead, + // generate a common one from the HD seed. This ensures the data is + // recoverable, while keeping it logically separate from the ZIP 32 + // Sapling key hierarchy, which the user might not be using. + HDSeed seed; + if (!pwalletMain->GetHDSeed(seed)) { + throw JSONRPCError( + RPC_WALLET_ERROR, + "AsyncRPCOperation_sendmany: HD seed not found"); + } + ovk = ovkForShieldingFromTaddr(seed); + } + if (!ovk) { + throw JSONRPCError(RPC_WALLET_ERROR, "Sending to a Sapling address requires an ovk."); + } + builder_.AddSaplingOutput(ovk.get(), *saplingPaymentAddress, sendAmount, hexMemo); + } + + + // Build the transaction + auto maybe_tx = builder_.Build(); + if (!maybe_tx) { + throw JSONRPCError(RPC_WALLET_ERROR, "Failed to build transaction."); + } + tx_ = maybe_tx.get(); + + // Send the transaction + // TODO: Use CWallet::CommitTransaction instead of sendrawtransaction + auto signedtxn = EncodeHexTx(tx_); + if (!testmode) { + UniValue params = UniValue(UniValue::VARR); + params.push_back(signedtxn); + UniValue sendResultValue = sendrawtransaction(params, false); + if (sendResultValue.isNull()) { + throw JSONRPCError(RPC_WALLET_ERROR, "sendrawtransaction did not return an error or a txid."); + } + + auto txid = sendResultValue.get_str(); + + UniValue o(UniValue::VOBJ); + o.push_back(Pair("txid", txid)); + set_result(o); + } else { + // Test mode does not send the transaction to the network. + UniValue o(UniValue::VOBJ); + o.push_back(Pair("test", 1)); + o.push_back(Pair("txid", tx_.GetHash().ToString())); + o.push_back(Pair("hex", signedtxn)); + set_result(o); + } + + return true; + } + /** + * END SCENARIO #0 + */ + + /** * SCENARIO #1 * @@ -288,16 +429,16 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() /** * END SCENARIO #1 */ - - + + // Prepare raw transaction to handle JoinSplits CMutableTransaction mtx(tx_); crypto_sign_keypair(joinSplitPubKey_.begin(), joinSplitPrivKey_); mtx.joinSplitPubKey = joinSplitPubKey_; tx_ = CTransaction(mtx); std::string hexMemo = std::get<1>(recipient_); - - + + /** * SCENARIO #2 * @@ -305,18 +446,18 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() * * We only need a single JoinSplit. */ - if (noteInputs_.empty() && isToZaddr_) { + if (sproutNoteInputs_.empty() && isToZaddr_) { // Create JoinSplit to target z-addr. MergeToAddressJSInfo info; info.vpub_old = sendAmount; info.vpub_new = 0; - + JSOutput jso = JSOutput(boost::get(toPaymentAddress_), sendAmount); if (hexMemo.size() > 0) { jso.memo = get_memo_from_hex_string(hexMemo); } info.vjsout.push_back(jso); - + UniValue obj(UniValue::VOBJ); obj = perform_joinsplit(info); sign_send_raw_transaction(obj); @@ -325,24 +466,20 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() /** * END SCENARIO #2 */ - - + + // Copy zinputs to more flexible containers - std::deque zInputsDeque; - for (auto o : noteInputs_) { - // TODO: Add Sapling support. For now, return an error to the user. - if (boost::get(&std::get<3>(o)) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Currently, only Sprout zaddrs are supported"); - } + std::deque zInputsDeque; + for (const auto& o : sproutNoteInputs_) { zInputsDeque.push_back(o); } - + // When spending notes, take a snapshot of note witnesses and anchors as the treestate will // change upon arrival of new blocks which contain joinsplit transactions. This is likely // to happen as creating a chained joinsplit transaction can take longer than the block interval. { LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto t : noteInputs_) { + for (auto t : sproutNoteInputs_) { JSOutPoint jso = std::get<0>(t); std::vector vOutPoints = {jso}; uint256 inputAnchor; @@ -351,7 +488,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() jsopWitnessAnchorMap[jso.ToString()] = MergeToAddressWitnessAnchorData{vInputWitnesses[0], inputAnchor}; } } - + /** * SCENARIO #3 * @@ -370,12 +507,12 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 bool vpubOldProcessed = false; // updated when vpub_old for taddr inputs is set in first joinsplit bool vpubNewProcessed = false; // updated when vpub_new for miner fee and taddr outputs is set in last joinsplit - + // At this point, we are guaranteed to have at least one input note. // Use address of first input note as the temporary change address. - SproutSpendingKey changeKey = boost::get(std::get<3>(zInputsDeque.front())); + SproutSpendingKey changeKey = std::get<3>(zInputsDeque.front()); SproutPaymentAddress changeAddress = changeKey.address(); - + CAmount vpubOldTarget = 0; CAmount vpubNewTarget = 0; if (isToTaddr_) { @@ -387,16 +524,16 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() vpubOldTarget = t_inputs_total - minersFee; } } - + // Keep track of treestate within this transaction boost::unordered_map intermediates; std::vector previousCommitments; - + while (!vpubNewProcessed) { MergeToAddressJSInfo info; info.vpub_old = 0; info.vpub_new = 0; - + // Set vpub_old in the first joinsplit if (!vpubOldProcessed) { if (t_inputs_total < vpubOldTarget) { @@ -407,30 +544,30 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() info.vpub_old += vpubOldTarget; // funds flowing from public pool vpubOldProcessed = true; } - + CAmount jsInputValue = 0; uint256 jsAnchor; std::vector> witnesses; - + JSDescription prevJoinSplit; - + // Keep track of previous JoinSplit and its commitments if (tx_.vjoinsplit.size() > 0) { prevJoinSplit = tx_.vjoinsplit.back(); } - + // If there is no change, the chain has terminated so we can reset the tracked treestate. if (jsChange == 0 && tx_.vjoinsplit.size() > 0) { intermediates.clear(); previousCommitments.clear(); } - + // // Consume change as the first input of the JoinSplit. // if (jsChange > 0) { LOCK2(cs_main, pwalletMain->cs_wallet); - + // Update tree state with previous joinsplit SproutMerkleTree tree; auto it = intermediates.find(prevJoinSplit.anchor); @@ -439,7 +576,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } else if (!pcoinsTip->GetSproutAnchorAt(prevJoinSplit.anchor, tree)) { throw JSONRPCError(RPC_WALLET_ERROR, "Could not find previous JoinSplit anchor"); } - + assert(changeOutputIndex != -1); boost::optional changeWitness; int n = 0; @@ -457,34 +594,34 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } jsAnchor = tree.root(); intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries) - + // Decrypt the change note's ciphertext to retrieve some data we need ZCNoteDecryption decryptor(changeKey.receiving_key()); auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); try { SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( - decryptor, - prevJoinSplit.ciphertexts[changeOutputIndex], - prevJoinSplit.ephemeralKey, - hSig, - (unsigned char)changeOutputIndex); - + decryptor, + prevJoinSplit.ciphertexts[changeOutputIndex], + prevJoinSplit.ephemeralKey, + hSig, + (unsigned char)changeOutputIndex); + SproutNote note = plaintext.note(changeAddress); info.notes.push_back(note); info.zkeys.push_back(changeKey); - + jsInputValue += plaintext.value(); - + LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", getId(), FormatMoney(plaintext.value())); - + } catch (const std::exception& e) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); } } - - + + // // Consume spendable non-change notes // @@ -495,13 +632,13 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() uint256 inputAnchor; int numInputsNeeded = (jsChange > 0) ? 1 : 0; while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { - MergeToAddressInputNote t = zInputsDeque.front(); + MergeToAddressInputSproutNote t = zInputsDeque.front(); JSOutPoint jso = std::get<0>(t); SproutNote note = std::get<1>(t); CAmount noteFunds = std::get<2>(t); - SproutSpendingKey zkey = boost::get(std::get<3>(t)); + SproutSpendingKey zkey = std::get<3>(t); zInputsDeque.pop_front(); - + MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()]; vInputWitnesses.push_back(wad.witness); if (inputAnchor.IsNull()) { @@ -509,13 +646,13 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } else if (inputAnchor != wad.anchor) { throw JSONRPCError(RPC_WALLET_ERROR, "Selected input notes do not share the same anchor"); } - + vOutPoints.push_back(jso); vInputNotes.push_back(note); vInputZKeys.push_back(zkey); - + jsInputValue += noteFunds; - + int wtxHeight = -1; int wtxDepth = -1; { @@ -525,7 +662,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); } - wtxHeight = mapBlockIndex[wtx.hashBlock]->GetHeight(); + wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; wtxDepth = wtx.GetDepthInMainChain(); } LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", @@ -537,13 +674,13 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() wtxHeight, wtxDepth); } - + // Add history of previous commitments to witness if (vInputNotes.size() > 0) { if (vInputWitnesses.size() == 0) { throw JSONRPCError(RPC_WALLET_ERROR, "Could not find witness for note commitment"); } - + for (auto& optionalWitness : vInputWitnesses) { if (!optionalWitness) { throw JSONRPCError(RPC_WALLET_ERROR, "Witness for note commitment is null"); @@ -559,20 +696,20 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } witnesses.push_back(w); } - + // The jsAnchor is null if this JoinSplit is at the start of a new chain if (jsAnchor.IsNull()) { jsAnchor = inputAnchor; } - + // Add spendable notes as inputs std::copy(vInputNotes.begin(), vInputNotes.end(), std::back_inserter(info.notes)); std::copy(vInputZKeys.begin(), vInputZKeys.end(), std::back_inserter(info.zkeys)); } - + // Accumulate change jsChange = jsInputValue + info.vpub_old; - + // Set vpub_new in the last joinsplit (when there are no more notes to spend) if (zInputsDeque.empty()) { assert(!vpubNewProcessed); @@ -587,10 +724,10 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // If we are merging to a t-addr, there should be no change if (isToTaddr_) assert(jsChange == 0); } - + // create dummy output info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new - + // create output for any change if (jsChange > 0) { std::string outputType = "change"; @@ -604,31 +741,30 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() } } info.vjsout.push_back(jso); - + LogPrint("zrpcunsafe", "%s: generating note for %s (amount=%s)\n", getId(), outputType, FormatMoney(jsChange)); } - + obj = perform_joinsplit(info, witnesses, jsAnchor); - + if (jsChange > 0) { changeOutputIndex = mta_find_output(obj, 1); } } - + // Sanity check in case changes to code block above exits loop by invoking 'break' assert(zInputsDeque.size() == 0); assert(vpubNewProcessed); - + sign_send_raw_transaction(obj); return true; } extern UniValue signrawtransaction(const UniValue& params, bool fHelp); -extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); /** * Sign and send a raw transaction. @@ -642,7 +778,7 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); } std::string rawtxn = rawtxnValue.get_str(); - + UniValue params = UniValue(UniValue::VARR); params.push_back(rawtxn); UniValue signResultValue = signrawtransaction(params, false); @@ -653,13 +789,13 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) // TODO: #1366 Maybe get "errors" and print array vErrors into a string throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); } - + UniValue hexValue = find_value(signResultObject, "hex"); if (hexValue.isNull()) { throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); } std::string signedtxn = hexValue.get_str(); - + // Send the signed transaction if (!testmode) { params.clear(); @@ -669,26 +805,26 @@ void AsyncRPCOperation_mergetoaddress::sign_send_raw_transaction(UniValue obj) if (sendResultValue.isNull()) { throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); } - + std::string txid = sendResultValue.get_str(); - + UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", txid)); set_result(o); } else { // Test mode does not send the transaction to the network. - + CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; stream >> tx; - + UniValue o(UniValue::VOBJ); o.push_back(Pair("test", 1)); o.push_back(Pair("txid", tx.GetHash().ToString())); o.push_back(Pair("hex", signedtxn)); set_result(o); } - + // Keep the signed transaction so we can hash to the same txid CDataStream stream(ParseHex(signedtxn), SER_NETWORK, PROTOCOL_VERSION); CTransaction tx; @@ -721,106 +857,106 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(MergeToAddressJSInf } UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor) + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor) { if (anchor.IsNull()) { throw std::runtime_error("anchor is null"); } - + if (witnesses.size() != info.notes.size()) { throw runtime_error("number of notes and witnesses do not match"); } - + if (info.notes.size() != info.zkeys.size()) { throw runtime_error("number of notes and spending keys do not match"); } - + for (size_t i = 0; i < witnesses.size(); i++) { if (!witnesses[i]) { throw runtime_error("joinsplit input could not be found in tree"); } info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], info.zkeys[i])); } - + // Make sure there are two inputs and two outputs while (info.vjsin.size() < ZC_NUM_JS_INPUTS) { info.vjsin.push_back(JSInput()); } - + while (info.vjsout.size() < ZC_NUM_JS_OUTPUTS) { info.vjsout.push_back(JSOutput()); } - + if (info.vjsout.size() != ZC_NUM_JS_INPUTS || info.vjsin.size() != ZC_NUM_JS_OUTPUTS) { throw runtime_error("unsupported joinsplit input/output counts"); } - + CMutableTransaction mtx(tx_); - + LogPrint("zrpcunsafe", "%s: creating joinsplit at index %d (vpub_old=%s, vpub_new=%s, in[0]=%s, in[1]=%s, out[0]=%s, out[1]=%s)\n", getId(), tx_.vjoinsplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); - + // Generate the proof, this can take over a minute. std::array inputs{info.vjsin[0], info.vjsin[1]}; std::array outputs{info.vjsout[0], info.vjsout[1]}; std::array inputMap; std::array outputMap; - + uint256 esk; // payment disclosure - secret - + JSDescription jsdesc = JSDescription::Randomized( - mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), - *pzcashParams, - joinSplitPubKey_, - anchor, - inputs, - outputs, - inputMap, - outputMap, - info.vpub_old, - info.vpub_new, - !this->testmode, - &esk); // parameter expects pointer to esk, so pass in address + mtx.fOverwintered && (mtx.nVersion >= SAPLING_TX_VERSION), + *pzcashParams, + joinSplitPubKey_, + anchor, + inputs, + outputs, + inputMap, + outputMap, + info.vpub_old, + info.vpub_new, + !this->testmode, + &esk); // parameter expects pointer to esk, so pass in address { auto verifier = libzcash::ProofVerifier::Strict(); if (!(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey_))) { throw std::runtime_error("error verifying joinsplit"); } } - + mtx.vjoinsplit.push_back(jsdesc); - + // Empty output script. CScript scriptCode; CTransaction signTx(mtx); uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_); - + // Add the signature if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, dataToBeSigned.begin(), 32, joinSplitPrivKey_) == 0)) { throw std::runtime_error("crypto_sign_detached failed"); } - + // Sanity check if (!(crypto_sign_verify_detached(&mtx.joinSplitSig[0], dataToBeSigned.begin(), 32, mtx.joinSplitPubKey.begin()) == 0)) { throw std::runtime_error("crypto_sign_verify_detached failed"); } - + CTransaction rawTx(mtx); tx_ = rawTx; - + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << rawTx; - + std::string encryptedNote1; std::string encryptedNote2; { @@ -829,7 +965,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( ss2 << jsdesc.ephemeralKey; ss2 << jsdesc.ciphertexts[0]; ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - + encryptedNote1 = HexStr(ss2.begin(), ss2.end()); } { @@ -838,10 +974,10 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( ss2 << jsdesc.ephemeralKey; ss2 << jsdesc.ciphertexts[1]; ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey_); - + encryptedNote2 = HexStr(ss2.begin(), ss2.end()); } - + UniValue arrInputMap(UniValue::VARR); UniValue arrOutputMap(UniValue::VARR); for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { @@ -850,8 +986,8 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( for (size_t i = 0; i < ZC_NUM_JS_OUTPUTS; i++) { arrOutputMap.push_back(static_cast(outputMap[i])); } - - + + // !!! Payment disclosure START unsigned char buffer[32] = {0}; memcpy(&buffer[0], &joinSplitPrivKey_[0], 32); // private key in first half of 64 byte buffer @@ -867,11 +1003,11 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr}; paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo)); - + LogPrint("paymentdisclosure", "%s: Payment Disclosure: js=%d, n=%d, zaddr=%s\n", getId(), js_index, int(mapped_index), EncodePaymentAddress(zaddr)); } // !!! Payment disclosure END - + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("encryptednote1", encryptedNote1)); obj.push_back(Pair("encryptednote2", encryptedNote2)); @@ -884,19 +1020,19 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( std::array AsyncRPCOperation_mergetoaddress::get_memo_from_hex_string(std::string s) { std::array memo = {{0x00}}; - + std::vector rawMemo = ParseHex(s.c_str()); - + // If ParseHex comes across a non-hex char, it will stop but still return results so far. size_t slen = s.length(); if (slen % 2 != 0 || (slen > 0 && rawMemo.size() != slen / 2)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo must be in hexadecimal format"); } - + if (rawMemo.size() > ZC_MEMO_SIZE) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Memo size of %d is too big, maximum allowed is %d", rawMemo.size(), ZC_MEMO_SIZE)); } - + // copy vector into boost array int lenMemo = rawMemo.size(); for (int i = 0; i < ZC_MEMO_SIZE && i < lenMemo; i++) { @@ -914,7 +1050,7 @@ UniValue AsyncRPCOperation_mergetoaddress::getStatus() const if (contextinfo_.isNull()) { return v; } - + UniValue obj = v.get_obj(); obj.push_back(Pair("method", "z_mergetoaddress")); obj.push_back(Pair("params", contextinfo_)); @@ -924,7 +1060,7 @@ UniValue AsyncRPCOperation_mergetoaddress::getStatus() const /** * Lock input utxos */ - void AsyncRPCOperation_mergetoaddress::lock_utxos() { +void AsyncRPCOperation_mergetoaddress::lock_utxos() { LOCK2(cs_main, pwalletMain->cs_wallet); for (auto utxo : utxoInputs_) { pwalletMain->LockCoin(std::get<0>(utxo)); @@ -945,9 +1081,12 @@ void AsyncRPCOperation_mergetoaddress::unlock_utxos() { /** * Lock input notes */ - void AsyncRPCOperation_mergetoaddress::lock_notes() { +void AsyncRPCOperation_mergetoaddress::lock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto note : noteInputs_) { + for (auto note : sproutNoteInputs_) { + pwalletMain->LockNote(std::get<0>(note)); + } + for (auto note : saplingNoteInputs_) { pwalletMain->LockNote(std::get<0>(note)); } } @@ -957,7 +1096,10 @@ void AsyncRPCOperation_mergetoaddress::unlock_utxos() { */ void AsyncRPCOperation_mergetoaddress::unlock_notes() { LOCK2(cs_main, pwalletMain->cs_wallet); - for (auto note : noteInputs_) { + for (auto note : sproutNoteInputs_) { + pwalletMain->UnlockNote(std::get<0>(note)); + } + for (auto note : saplingNoteInputs_) { pwalletMain->UnlockNote(std::get<0>(note)); } } diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index ef59ba67b..109c0ca07 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -9,6 +9,7 @@ #include "asyncrpcoperation.h" #include "paymentdisclosure.h" #include "primitives/transaction.h" +#include "transaction_builder.h" #include "wallet.h" #include "zcash/Address.hpp" #include "zcash/JoinSplit.hpp" @@ -24,11 +25,13 @@ using namespace libzcash; -// Input UTXO is a tuple of txid, vout, amount -typedef std::tuple MergeToAddressInputUTXO; +// Input UTXO is a tuple of txid, vout, amount, script +typedef std::tuple MergeToAddressInputUTXO; // Input JSOP is a tuple of JSOutpoint, note, amount, spending key -typedef std::tuple MergeToAddressInputNote; +typedef std::tuple MergeToAddressInputSproutNote; + +typedef std::tuple MergeToAddressInputSaplingNote; // A recipient is a tuple of address, memo (optional if zaddr) typedef std::tuple MergeToAddressRecipient; @@ -53,33 +56,36 @@ class AsyncRPCOperation_mergetoaddress : public AsyncRPCOperation { public: AsyncRPCOperation_mergetoaddress( - CMutableTransaction contextualTx, - std::vector utxoInputs, - std::vector noteInputs, - MergeToAddressRecipient recipient, - CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE, - UniValue contextInfo = NullUniValue); + boost::optional builder, + CMutableTransaction contextualTx, + std::vector utxoInputs, + std::vector sproutNoteInputs, + std::vector saplingNoteInputs, + MergeToAddressRecipient recipient, + CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE, + UniValue contextInfo = NullUniValue); virtual ~AsyncRPCOperation_mergetoaddress(); - + // We don't want to be copied or moved around AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy construct AsyncRPCOperation_mergetoaddress(AsyncRPCOperation_mergetoaddress&&) = delete; // Move construct AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress const&) = delete; // Copy assign AsyncRPCOperation_mergetoaddress& operator=(AsyncRPCOperation_mergetoaddress&&) = delete; // Move assign - + virtual void main(); - + virtual UniValue getStatus() const; - + bool testmode = false; // Set to true to disable sending txs and generating proofs - + bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. - + private: friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing - + UniValue contextinfo_; // optional data to include in return value from getStatus() - + + bool isUsingBuilder_; // Indicates that no Sprout addresses are involved uint32_t consensusBranchId_; CAmount fee_; int mindepth_; @@ -88,43 +94,45 @@ private: bool isToZaddr_; CTxDestination toTaddr_; PaymentAddress toPaymentAddress_; - + uint256 joinSplitPubKey_; unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES]; - + // The key is the result string from calling JSOutPoint::ToString() std::unordered_map jsopWitnessAnchorMap; - + std::vector utxoInputs_; - std::vector noteInputs_; - + std::vector sproutNoteInputs_; + std::vector saplingNoteInputs_; + + TransactionBuilder builder_; CTransaction tx_; - + std::array get_memo_from_hex_string(std::string s); bool main_impl(); - + // JoinSplit without any input notes to spend UniValue perform_joinsplit(MergeToAddressJSInfo&); - + // JoinSplit with input notes to spend (JSOutPoints)) UniValue perform_joinsplit(MergeToAddressJSInfo&, std::vector&); - + // JoinSplit where you have the witnesses and anchor UniValue perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor); - + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor); + void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error - + void lock_utxos(); - + void unlock_utxos(); - + void lock_notes(); - + void unlock_notes(); - + // payment disclosure! std::vector paymentDisclosureData_; }; @@ -135,54 +143,54 @@ class TEST_FRIEND_AsyncRPCOperation_mergetoaddress { public: std::shared_ptr delegate; - + TEST_FRIEND_AsyncRPCOperation_mergetoaddress(std::shared_ptr ptr) : delegate(ptr) {} - + CTransaction getTx() { return delegate->tx_; } - + void setTx(CTransaction tx) { delegate->tx_ = tx; } - + // Delegated methods - + std::array get_memo_from_hex_string(std::string s) { return delegate->get_memo_from_hex_string(s); } - + bool main_impl() { return delegate->main_impl(); } - + UniValue perform_joinsplit(MergeToAddressJSInfo& info) { return delegate->perform_joinsplit(info); } - + UniValue perform_joinsplit(MergeToAddressJSInfo& info, std::vector& v) { return delegate->perform_joinsplit(info, v); } - + UniValue perform_joinsplit( - MergeToAddressJSInfo& info, - std::vector> witnesses, - uint256 anchor) + MergeToAddressJSInfo& info, + std::vector> witnesses, + uint256 anchor) { return delegate->perform_joinsplit(info, witnesses, anchor); } - + void sign_send_raw_transaction(UniValue obj) { delegate->sign_send_raw_transaction(obj); } - + void set_state(OperationStatus state) { delegate->state_.store(state); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index cbba7cca9..49b255da6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2849,8 +2849,8 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) "\nExamples\n" + HelpExampleCli("z_listunspent", "") - + HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"") - + HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"") + + HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"") + + HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\",\\\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\\\"]\"") ); RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VBOOL)(UniValue::VARR)); @@ -3686,8 +3686,8 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) " \"change\": true|false, (boolean) true if the address that received the note is also one of the sending addresses\n" "}\n" "\nExamples:\n" - + HelpExampleCli("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") - + HelpExampleRpc("z_listreceivedbyaddress", "\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + + HelpExampleCli("z_listreceivedbyaddress", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") + + HelpExampleRpc("z_listreceivedbyaddress", "\"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -4019,8 +4019,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) "\nResult:\n" "\"operationid\" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" "\nExamples:\n" - + HelpExampleCli("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" '[{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]'") - + HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\" ,\"amount\": 5.0}]") + + HelpExampleCli("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" '[{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]'") + + HelpExampleRpc("z_sendmany", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", [{\"address\": \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\" ,\"amount\": 5.0}]") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -4110,15 +4110,10 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) } // If we are sending from a shielded address, all recipient // shielded addresses must be of the same type. - if (fromSprout && toSapling) { + if ((fromSprout && toSapling) || (fromSapling && toSprout)) { throw JSONRPCError( RPC_INVALID_PARAMETER, - "Cannot send from a Sprout address to a Sapling address using z_sendmany"); - } - if (fromSapling && toSprout) { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - "Cannot send from a Sapling address to a Sprout address using z_sendmany"); + "Cannot send between Sprout and Sapling addresses using z_sendmany"); } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address ); @@ -4330,8 +4325,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" "}\n" "\nExamples:\n" - + HelpExampleCli("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") - + HelpExampleRpc("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") + + HelpExampleCli("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\" \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") + + HelpExampleRpc("z_shieldcoinbase", "\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\", \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") ); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -4519,160 +4514,159 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) return o; } - #define MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT 50 -#define MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT 10 +#define MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT 10 +#define MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT 90 #define JOINSPLIT_SIZE GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define OUTPUTDESCRIPTION_SIZE GetSerializeSize(OutputDescription(), SER_NETWORK, PROTOCOL_VERSION) +#define SPENDDESCRIPTION_SIZE GetSerializeSize(SpendDescription(), SER_NETWORK, PROTOCOL_VERSION) UniValue z_mergetoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - + string enableArg = "zmergetoaddress"; auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, false); std::string strDisabledMsg = ""; if (!fEnableMergeToAddress) { strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg); } - + if (fHelp || params.size() < 2 || params.size() > 6) throw runtime_error( - "z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n" - + strDisabledMsg + - "\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`" - "\nto combine those into a single note." - "\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they" - "\nare unlocked. The RPC call `listlockunspent` can be used to return a list of locked UTXOs." - "\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit" - "\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the" - "\nnumber of UTXOs. Any limit is constrained by the consensus rule defining a maximum transaction size of" - + strprintf("\n%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING) - + HelpRequiringPassphrase() + "\n" - "\nArguments:\n" - "1. fromaddresses (string, required) A JSON array with addresses.\n" - " The following special strings are accepted inside the array:\n" - " - \"*\": Merge both UTXOs and notes from all addresses belonging to the wallet.\n" - " - \"ANY_TADDR\": Merge UTXOs from all t-addrs belonging to the wallet.\n" - " - \"ANY_ZADDR\": Merge notes from all z-addrs belonging to the wallet.\n" - " If a special string is given, any given addresses of that type will be ignored.\n" - " [\n" - " \"address\" (string) Can be a t-addr or a z-addr\n" - " ,...\n" - " ]\n" - "2. \"toaddress\" (string, required) The t-addr or z-addr to send the funds to.\n" - "3. fee (numeric, optional, default=" - + strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" - "4. transparent_limit (numeric, optional, default=" - + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n" - "4. shielded_limit (numeric, optional, default=" - + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" - "5. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n" - "\nResult:\n" - "{\n" - " \"remainingUTXOs\": xxx (numeric) Number of UTXOs still available for merging.\n" - " \"remainingTransparentValue\": xxx (numeric) Value of UTXOs still available for merging.\n" - " \"remainingNotes\": xxx (numeric) Number of notes still available for merging.\n" - " \"remainingShieldedValue\": xxx (numeric) Value of notes still available for merging.\n" - " \"mergingUTXOs\": xxx (numeric) Number of UTXOs being merged.\n" - " \"mergingTransparentValue\": xxx (numeric) Value of UTXOs being merged.\n" - " \"mergingNotes\": xxx (numeric) Number of notes being merged.\n" - " \"mergingShieldedValue\": xxx (numeric) Value of notes being merged.\n" - " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" - "}\n" - "\nExamples:\n" - + HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf") - + HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\"") - ); - + "z_mergetoaddress [\"fromaddress\", ... ] \"toaddress\" ( fee ) ( transparent_limit ) ( shielded_limit ) ( memo )\n" + + strDisabledMsg + + "\nMerge multiple UTXOs and notes into a single UTXO or note. Coinbase UTXOs are ignored; use `z_shieldcoinbase`" + "\nto combine those into a single note." + "\n\nThis is an asynchronous operation, and UTXOs selected for merging will be locked. If there is an error, they" + "\nare unlocked. The RPC call `listlockunspent` can be used to return a list of locked UTXOs." + "\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit" + "\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the" + "\nnumber of UTXOs. Any limit is constrained by the consensus rule defining a maximum transaction size of" + + strprintf("\n%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE_AFTER_SAPLING) + + HelpRequiringPassphrase() + "\n" + "\nArguments:\n" + "1. fromaddresses (string, required) A JSON array with addresses.\n" + " The following special strings are accepted inside the array:\n" + " - \"ANY_TADDR\": Merge UTXOs from any t-addrs belonging to the wallet.\n" + " - \"ANY_SPROUT\": Merge notes from any Sprout z-addrs belonging to the wallet.\n" + " - \"ANY_SAPLING\": Merge notes from any Sapling z-addrs belonging to the wallet.\n" + " If a special string is given, any given addresses of that type will be ignored.\n" + " [\n" + " \"address\" (string) Can be a t-addr or a z-addr\n" + " ,...\n" + " ]\n" + "2. \"toaddress\" (string, required) The t-addr or z-addr to send the funds to.\n" + "3. fee (numeric, optional, default=" + + strprintf("%s", FormatMoney(MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n" + "4. transparent_limit (numeric, optional, default=" + + strprintf("%d", MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT) + ") Limit on the maximum number of UTXOs to merge. Set to 0 to use node option -mempooltxinputlimit (before Overwinter), or as many as will fit in the transaction (after Overwinter).\n" + "4. shielded_limit (numeric, optional, default=" + + strprintf("%d Sprout or %d Sapling Notes", MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT, MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT) + ") Limit on the maximum number of notes to merge. Set to 0 to merge as many as will fit in the transaction.\n" + "5. \"memo\" (string, optional) Encoded as hex. When toaddress is a z-addr, this will be stored in the memo field of the new note.\n" + "\nResult:\n" + "{\n" + " \"remainingUTXOs\": xxx (numeric) Number of UTXOs still available for merging.\n" + " \"remainingTransparentValue\": xxx (numeric) Value of UTXOs still available for merging.\n" + " \"remainingNotes\": xxx (numeric) Number of notes still available for merging.\n" + " \"remainingShieldedValue\": xxx (numeric) Value of notes still available for merging.\n" + " \"mergingUTXOs\": xxx (numeric) Number of UTXOs being merged.\n" + " \"mergingTransparentValue\": xxx (numeric) Value of UTXOs being merged.\n" + " \"mergingNotes\": xxx (numeric) Number of notes being merged.\n" + " \"mergingShieldedValue\": xxx (numeric) Value of notes being merged.\n" + " \"opid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("z_mergetoaddress", "'[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"]' ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf") + + HelpExampleRpc("z_mergetoaddress", "[\"RD6GgnrMpPaTSMn8vai6yiGA7mN4QGPV\"], \"zs14d8tc0hl9q0vg5l28uec5vk6sk34fkj2n8s7jalvw5fxpy6v39yn4s2ga082lymrkjk0x2nqg37\"") + ); + if (!fEnableMergeToAddress) { throw JSONRPCError(RPC_WALLET_ERROR, "Error: z_mergetoaddress is disabled."); } - + LOCK2(cs_main, pwalletMain->cs_wallet); - - bool useAny = false; + bool useAnyUTXO = false; - bool useAnyNote = false; + bool useAnySprout = false; + bool useAnySapling = false; std::set taddrs = {}; std::set zaddrs = {}; - - uint32_t branchId = CurrentEpochBranchId(chainActive.Height(), Params().GetConsensus()); - + UniValue addresses = params[0].get_array(); if (addresses.size()==0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, fromaddresses array is empty."); - + // Keep track of addresses to spot duplicates std::set setAddress; - + // Sources - bool containsSaplingZaddrSource = false; for (const UniValue& o : addresses.getValues()) { if (!o.isStr()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string"); - + std::string address = o.get_str(); - if (address == "*") { - useAny = true; - } else if (address == "ANY_TADDR") { + + if (address == "ANY_TADDR") { useAnyUTXO = true; - } else if (address == "ANY_ZADDR") { - useAnyNote = true; + } else if (address == "ANY_SPROUT") { + useAnySprout = true; + } else if (address == "ANY_SAPLING") { + useAnySapling = true; } else { CTxDestination taddr = DecodeDestination(address); if (IsValidDestination(taddr)) { - // Ignore any listed t-addrs if we are using all of them - if (!(useAny || useAnyUTXO)) { - taddrs.insert(taddr); - } + taddrs.insert(taddr); } else { auto zaddr = DecodePaymentAddress(address); - if (IsValidPaymentAddress(zaddr, branchId)) { - // Ignore listed z-addrs if we are using all of them - if (!(useAny || useAnyNote)) { - zaddrs.insert(zaddr); - } - // Check if z-addr is Sapling - bool isSapling = boost::get(&zaddr) != nullptr; - containsSaplingZaddrSource |= isSapling; + if (IsValidPaymentAddress(zaddr)) { + zaddrs.insert(zaddr); } else { - throw JSONRPCError( - RPC_INVALID_PARAMETER, - string("Invalid parameter, unknown address format: ") + address); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address); } } } - + if (setAddress.count(address)) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address); setAddress.insert(address); } - + + if (useAnyUTXO && taddrs.size() > 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific t-addrs when using \"ANY_TADDR\""); + } + if ((useAnySprout || useAnySapling) && zaddrs.size() > 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SPROUT\" or \"ANY_SAPLING\""); + } + + const int nextBlockHeight = chainActive.Height() + 1; + const bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); + const bool saplingActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING); + // Validate the destination address auto destaddress = params[1].get_str(); - bool isToZaddr = false; + bool isToSproutZaddr = false; bool isToSaplingZaddr = false; CTxDestination taddr = DecodeDestination(destaddress); if (!IsValidDestination(taddr)) { - if (IsValidPaymentAddressString(destaddress, branchId)) { - isToZaddr = true; - - // Is this a Sapling address? - auto res = DecodePaymentAddress(destaddress); - if (IsValidPaymentAddress(res)) { - isToSaplingZaddr = boost::get(&res) != nullptr; + auto decodeAddr = DecodePaymentAddress(destaddress); + if (IsValidPaymentAddress(decodeAddr)) { + if (boost::get(&decodeAddr) != nullptr) { + isToSaplingZaddr = true; + // If Sapling is not active, do not allow sending to a sapling addresses. + if (!saplingActive) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); + } } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); + isToSproutZaddr = true; } } else { throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); } } - else if ( ASSETCHAINS_PRIVATE != 0 ) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "cant use transparent addresses in private chain"); - + // Convert fee from currency format to zatoshis CAmount nFee = SHIELD_COINBASE_DEFAULT_MINERS_FEE; if (params.size() > 2) { @@ -4682,7 +4676,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) nFee = AmountFromValue( params[2] ); } } - + int nUTXOLimit = MERGE_TO_ADDRESS_DEFAULT_TRANSPARENT_LIMIT; if (params.size() > 3) { nUTXOLimit = params[3].get_int(); @@ -4690,19 +4684,22 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of UTXOs cannot be negative"); } } - - int nNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SHIELDED_LIMIT; + + int sproutNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT; + int saplingNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT; if (params.size() > 4) { - nNoteLimit = params[4].get_int(); + int nNoteLimit = params[4].get_int(); if (nNoteLimit < 0) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative"); } + sproutNoteLimit = nNoteLimit; + saplingNoteLimit = nNoteLimit; } - + std::string memo; if (params.size() > 5) { memo = params[5].get_str(); - if (!isToZaddr) { + if (!(isToSproutZaddr || isToSaplingZaddr)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr."); } else if (!IsHex(memo)) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format."); @@ -4711,75 +4708,56 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, size of memo is larger than maximum allowed %d", ZC_MEMO_SIZE )); } } - + MergeToAddressRecipient recipient(destaddress, memo); - - int nextBlockHeight = chainActive.Height() + 1; - bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); - unsigned int max_tx_size = MAX_TX_SIZE_AFTER_SAPLING; - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { - max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; - } - - // This RPC does not support Sapling yet. - if (isToSaplingZaddr || containsSaplingZaddrSource) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling is not supported yet by z_mergetoadress"); - } - - // If this RPC does support Sapling... - // If Sapling is not active, do not allow sending from or sending to Sapling addresses. - if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { - if (isToSaplingZaddr || containsSaplingZaddrSource) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); - } - } - + // Prepare to get UTXOs and notes std::vector utxoInputs; - std::vector noteInputs; + std::vector sproutNoteInputs; + std::vector saplingNoteInputs; CAmount mergedUTXOValue = 0; CAmount mergedNoteValue = 0; CAmount remainingUTXOValue = 0; CAmount remainingNoteValue = 0; - #ifdef __LP64__ - uint64_t utxoCounter = 0; - uint64_t noteCounter = 0; - #else size_t utxoCounter = 0; size_t noteCounter = 0; - #endif bool maxedOutUTXOsFlag = false; bool maxedOutNotesFlag = false; size_t mempoolLimit = (nUTXOLimit != 0) ? nUTXOLimit : (overwinterActive ? 0 : (size_t)GetArg("-mempooltxinputlimit", 0)); - + + unsigned int max_tx_size = saplingActive ? MAX_TX_SIZE_AFTER_SAPLING : MAX_TX_SIZE_BEFORE_SAPLING; size_t estimatedTxSize = 200; // tx overhead + wiggle room - if (isToZaddr) { + if (isToSproutZaddr) { estimatedTxSize += JOINSPLIT_SIZE; + } else if (isToSaplingZaddr) { + estimatedTxSize += OUTPUTDESCRIPTION_SIZE; } - - if (useAny || useAnyUTXO || taddrs.size() > 0) { + + if (useAnyUTXO || taddrs.size() > 0) { // Get available utxos vector vecOutputs; pwalletMain->AvailableCoins(vecOutputs, true, NULL, false, false); - + // Find unspent utxos and update estimated size for (const COutput& out : vecOutputs) { if (!out.fSpendable) { continue; } - + + CScript scriptPubKey = out.tx->vout[out.i].scriptPubKey; + CTxDestination address; - if (!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { + if (!ExtractDestination(scriptPubKey, address)) { continue; } // If taddr is not wildcard "*", filter utxos if (taddrs.size() > 0 && !taddrs.count(address)) { continue; } - + utxoCounter++; CAmount nValue = out.tx->vout[out.i].nValue; - + if (!maxedOutUTXOsFlag) { size_t increase = (boost::get(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE; if (estimatedTxSize + increase >= max_tx_size || @@ -4789,34 +4767,51 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) } else { estimatedTxSize += increase; COutPoint utxo(out.tx->GetHash(), out.i); - utxoInputs.emplace_back(utxo, nValue); + utxoInputs.emplace_back(utxo, nValue, scriptPubKey); mergedUTXOValue += nValue; } } - + if (maxedOutUTXOsFlag) { remainingUTXOValue += nValue; } } } - - if (useAny || useAnyNote || zaddrs.size() > 0) { + + if (useAnySprout || useAnySapling || zaddrs.size() > 0) { // Get available notes std::vector sproutEntries; std::vector saplingEntries; pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs); - + + // If Sapling is not active, do not allow sending from a sapling addresses. + if (!saplingActive && saplingEntries.size() > 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); + } + // Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress + if (sproutEntries.size() > 0 && saplingEntries.size() > 0) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress"); + } + // If sending between shielded addresses, they must be the same type + if ((saplingEntries.size() > 0 && isToSproutZaddr) || (sproutEntries.size() > 0 && isToSaplingZaddr)) { + throw JSONRPCError( + RPC_INVALID_PARAMETER, + "Cannot send between Sprout and Sapling addresses using z_mergetoaddress"); + } + // Find unspent notes and update estimated size - for (CSproutNotePlaintextEntry& entry : sproutEntries) { + for (const CSproutNotePlaintextEntry& entry : sproutEntries) { noteCounter++; CAmount nValue = entry.plaintext.value(); - + if (!maxedOutNotesFlag) { // If we haven't added any notes yet and the merge is to a // z-address, we have already accounted for the first JoinSplit. - size_t increase = (noteInputs.empty() && !isToZaddr) || (noteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; + size_t increase = (sproutNoteInputs.empty() && !isToSproutZaddr) || (sproutNoteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; if (estimatedTxSize + increase >= max_tx_size || - (nNoteLimit > 0 && noteCounter > nNoteLimit)) + (sproutNoteLimit > 0 && noteCounter > sproutNoteLimit)) { maxedOutNotesFlag = true; } else { @@ -4824,31 +4819,49 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) auto zaddr = entry.address; SproutSpendingKey zkey; pwalletMain->GetSproutSpendingKey(zaddr, zkey); - noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); + sproutNoteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey); mergedNoteValue += nValue; } } - + + if (maxedOutNotesFlag) { + remainingNoteValue += nValue; + } + } + + for (const SaplingNoteEntry& entry : saplingEntries) { + noteCounter++; + CAmount nValue = entry.note.value(); + if (!maxedOutNotesFlag) { + size_t increase = SPENDDESCRIPTION_SIZE; + if (estimatedTxSize + increase >= max_tx_size || + (saplingNoteLimit > 0 && noteCounter > saplingNoteLimit)) + { + maxedOutNotesFlag = true; + } else { + estimatedTxSize += increase; + libzcash::SaplingExtendedSpendingKey extsk; + if (!pwalletMain->GetSaplingExtendedSpendingKey(entry.address, extsk)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Could not find spending key for payment address."); + } + saplingNoteInputs.emplace_back(entry.op, entry.note, nValue, extsk.expsk); + mergedNoteValue += nValue; + } + } + if (maxedOutNotesFlag) { remainingNoteValue += nValue; } } - // TODO: Add Sapling support } - - #ifdef __LP64__ - uint64_t numUtxos = utxoInputs.size(); //ca333 - uint64_t numNotes = noteInputs.size(); - #else + size_t numUtxos = utxoInputs.size(); - size_t numNotes = noteInputs.size(); - #endif - - + size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size(); + if (numUtxos == 0 && numNotes == 0) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Could not find any funds to merge."); } - + // Sanity check: Don't do anything if: // - We only have one from address // - It's equal to toaddress @@ -4856,42 +4869,47 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (setAddress.size() == 1 && setAddress.count(destaddress) && (numUtxos + numNotes) == 1) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Destination address is also the only source address, and all its funds are already merged."); } - + CAmount mergedValue = mergedUTXOValue + mergedNoteValue; if (mergedValue < nFee) { throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, - strprintf("Insufficient funds, have %s, which is less than miners fee %s", - FormatMoney(mergedValue), FormatMoney(nFee))); + strprintf("Insufficient funds, have %s, which is less than miners fee %s", + FormatMoney(mergedValue), FormatMoney(nFee))); } - + // Check that the user specified fee is sane (if too high, it can result in error -25 absurd fee) CAmount netAmount = mergedValue - nFee; if (nFee > netAmount) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the net amount to be shielded %s", FormatMoney(nFee), FormatMoney(netAmount))); } - + // Keep record of parameters in context object UniValue contextInfo(UniValue::VOBJ); contextInfo.push_back(Pair("fromaddresses", params[0])); contextInfo.push_back(Pair("toaddress", params[1])); contextInfo.push_back(Pair("fee", ValueFromAmount(nFee))); - + // Contextual transaction we will build on CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction( - Params().GetConsensus(), - nextBlockHeight); - bool isShielded = numNotes > 0 || isToZaddr; - if (contextualTx.nVersion == 1 && isShielded) { + Params().GetConsensus(), + nextBlockHeight); + bool isSproutShielded = sproutNoteInputs.size() > 0 || isToSproutZaddr; + if (contextualTx.nVersion == 1 && isSproutShielded) { contextualTx.nVersion = 2; // Tx format should support vjoinsplit } - + + // Builder (used if Sapling addresses are involved) + boost::optional builder; + if (isToSaplingZaddr || saplingNoteInputs.size() > 0) { + builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain); + } // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); std::shared_ptr operation( - new AsyncRPCOperation_mergetoaddress(contextualTx, utxoInputs, noteInputs, recipient, nFee, contextInfo) ); + new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, sproutNoteInputs, saplingNoteInputs, recipient, nFee, contextInfo) ); q->addOperation(operation); AsyncRPCOperationId operationId = operation->getId(); - + // Return continuation information UniValue o(UniValue::VOBJ); o.push_back(Pair("remainingUTXOs", static_cast(utxoCounter - numUtxos))); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index db994b369..13cd2efd5 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4960,10 +4960,10 @@ void CWallet::GetFilteredNotes( } // skip locked notes - // TODO: Add locking for Sapling notes - // if (ignoreLocked && IsLockedNote(op)) { - // continue; - // } + // TODO: Add locking for Sapling notes -> done + if (ignoreLocked && IsLockedNote(op)) { + continue; + } auto note = notePt.note(nd.ivk).get(); saplingEntries.push_back(SaplingNoteEntry { From 5245f600cd95dd5a25762b64172214bb5364b53f Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:16:00 -1100 Subject: [PATCH 70/94] GetHeight() --- src/wallet/asyncrpcoperation_mergetoaddress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index aa7c64e58..9f55479f8 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -662,7 +662,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() if (mapBlockIndex.find(wtx.hashBlock) == mapBlockIndex.end()) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf("mapBlockIndex does not contain block hash %s", wtx.hashBlock.ToString())); } - wtxHeight = mapBlockIndex[wtx.hashBlock]->nHeight; + wtxHeight = mapBlockIndex[wtx.hashBlock]->GetHeight(); wtxDepth = wtx.GetDepthInMainChain(); } LogPrint("zrpcunsafe", "%s: spending note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, height=%d, confirmations=%d)\n", From 78d607d361fc20f8d9ec9f636ca74ff1125a9fe2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:36:52 -1100 Subject: [PATCH 71/94] Default experimental mode --- src/init.cpp | 2 +- src/main.cpp | 2 +- src/wallet/asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_mergetoaddress.h | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.h | 2 +- src/wallet/asyncrpcoperation_shieldcoinbase.cpp | 2 +- src/wallet/asyncrpcoperation_shieldcoinbase.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index f3d728933..a87eb6170 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -844,7 +844,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) const CChainParams& chainparams = Params(); // Set this early so that experimental features are correctly enabled/disabled - fExperimentalMode = GetBoolArg("-experimentalfeatures", false); + fExperimentalMode = GetBoolArg("-experimentalfeatures", true); // Fail early if user has set experimental options without the global flag if (!fExperimentalMode) { diff --git a/src/main.cpp b/src/main.cpp index b664f3405..62545862a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,7 +77,7 @@ static int64_t nTimeBestReceived = 0; CWaitableCriticalSection csBestBlock; CConditionVariable cvBlockChange; int nScriptCheckThreads = 0; -bool fExperimentalMode = false; +bool fExperimentalMode = true; bool fImporting = false; bool fReindex = false; bool fTxIndex = false; diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 9f55479f8..c77489381 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -118,7 +118,7 @@ saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), context lock_notes(); // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); } AsyncRPCOperation_mergetoaddress::~AsyncRPCOperation_mergetoaddress() diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index 109c0ca07..f7ac81261 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -78,7 +78,7 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs - bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. private: friend class TEST_FRIEND_AsyncRPCOperation_mergetoaddress; // class for unit testing diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 9062ba73c..73288142a 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -123,7 +123,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); } AsyncRPCOperation_sendmany::~AsyncRPCOperation_sendmany() { diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 35bdb9740..a93925874 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -75,7 +75,7 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs - bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. private: friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index dfc51aa3a..37c771dcb 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -93,7 +93,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( lock_utxos(); // Enable payment disclosure if requested - paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", false); + paymentDisclosureMode = fExperimentalMode && GetBoolArg("-paymentdisclosure", true); } AsyncRPCOperation_shieldcoinbase::~AsyncRPCOperation_shieldcoinbase() { diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index 5f22a89fc..e75bb8e82 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -65,7 +65,7 @@ public: bool testmode = false; // Set to true to disable sending txs and generating proofs bool cheatSpend = false; // set when this is shielding a cheating coinbase - bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database. + bool paymentDisclosureMode = true; // Set to true to save esk for encrypted notes in payment disclosure database. private: friend class ShieldToAddress; From db994678909f90bc7a161b957e94c2313c94ee82 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:48:36 -1100 Subject: [PATCH 72/94] Enable z_mergetoaddress --- src/komodo_bitcoind.h | 8 ++++++++ src/main.cpp | 6 +++--- src/wallet/rpcdisclosure.cpp | 4 ++-- src/wallet/rpcwallet.cpp | 6 ++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e7ecf5f77..653bd1456 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1832,6 +1832,14 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) else return(0); } +int32_t komodo_acpublic() +{ + int32_t acpublic = ASSETCHAINS_PUBLIC; + if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) + acpublic = 1; + return(acpublic); +} + int64_t komodo_newcoins(int64_t *zfundsp,int32_t nHeight,CBlock *pblock) { CTxDestination address; int32_t i,j,m,n,vout; uint8_t *script; uint256 txid,hashBlock; int64_t zfunds=0,vinsum=0,voutsum=0; diff --git a/src/main.cpp b/src/main.cpp index 62545862a..a8af7d484 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1259,10 +1259,12 @@ int32_t komodo_isnotaryvout(char *coinaddr) // from ac_private chains only return(0); } +int32_t komodo_acpublic(); + bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context - int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = ASSETCHAINS_PUBLIC; + int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = komodo_acpublic(); /** * Previously: * 1. The consensus rule below was: @@ -1365,8 +1367,6 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio return state.DoS(100, error("CheckTransaction(): tx.valueBalance has no sources or sinks"), REJECT_INVALID, "bad-txns-valuebalance-nonzero"); } - if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) - acpublic = 1; if ( acpublic != 0 && (tx.vShieldedSpend.empty() == 0 || tx.vShieldedOutput.empty() == 0) ) { return state.DoS(100, error("CheckTransaction(): this is a public chain, no sapling allowed"), diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index dd3acab7e..41195cfc8 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -42,7 +42,7 @@ UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "paymentdisclosure"; - auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, false); + auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true); string strPaymentDisclosureDisabledMsg = ""; if (!fEnablePaymentDisclosure) { strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_getpaymentdisclosure", enableArg); @@ -149,7 +149,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "paymentdisclosure"; - auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, false); + auto fEnablePaymentDisclosure = fExperimentalMode && GetBoolArg("-" + enableArg, true); string strPaymentDisclosureDisabledMsg = ""; if (!fEnablePaymentDisclosure) { strPaymentDisclosureDisabledMsg = experimentalDisabledHelpMsg("z_validatepaymentdisclosure", enableArg); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 49b255da6..39a9b8518 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2342,6 +2342,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) return NullUniValue; } +int32_t komodo_acpublic(); UniValue encryptwallet(const UniValue& params, bool fHelp) { @@ -2349,7 +2350,8 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "developerencryptwallet"; - auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, false); + flag = (komodo_acpublic() || ASSETCHAINS_SYMBOL[0] == 0); + auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, flag); std::string strWalletEncryptionDisabledMsg = ""; if (!fEnableWalletEncryption) { @@ -4528,7 +4530,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "zmergetoaddress"; - auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, false); + auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true); std::string strDisabledMsg = ""; if (!fEnableMergeToAddress) { strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg); From ab2c621e639cb4533d09584bb723d0feca7609d6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:51:38 -1100 Subject: [PATCH 73/94] Set tiptime --- src/komodo_bitcoind.h | 16 ++++++++++++---- src/main.cpp | 4 ++-- src/wallet/rpcwallet.cpp | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index 653bd1456..0793a5a7f 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1832,11 +1832,19 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) else return(0); } -int32_t komodo_acpublic() +int32_t komodo_acpublic(uint32_t tiptime) { - int32_t acpublic = ASSETCHAINS_PUBLIC; - if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) - acpublic = 1; + int32_t acpublic = ASSETCHAINS_PUBLIC; CBlockPtr *pindex; + if ( acpublic == 0 ) + { + if ( tiptime == 0 ) + { + if ( (pindex= chainActive.LastTip()) != 0 ) + tiptime = pindex->nTime; + } + if ( (ASSETCHAINS_SYMBOL[0] == 0 || strcmp(ASSETCHAINS_SYMBOL,"ZEX") == 0) && tiptime >= KOMODO_SAPLING_DEADLINE ) + acpublic = 1; + } return(acpublic); } diff --git a/src/main.cpp b/src/main.cpp index a8af7d484..edb8aa0fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1259,12 +1259,12 @@ int32_t komodo_isnotaryvout(char *coinaddr) // from ac_private chains only return(0); } -int32_t komodo_acpublic(); +int32_t komodo_acpublic(uint32_t tiptime); bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransaction& tx, CValidationState &state) { // Basic checks that don't depend on any context - int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = komodo_acpublic(); + int32_t invalid_private_taddr=0,z_z=0,z_t=0,t_z=0,acpublic = komodo_acpublic(tiptime); /** * Previously: * 1. The consensus rule below was: diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 39a9b8518..f269e86f0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2342,7 +2342,7 @@ UniValue walletlock(const UniValue& params, bool fHelp) return NullUniValue; } -int32_t komodo_acpublic(); +int32_t komodo_acpublic(uint32_t tiptime); UniValue encryptwallet(const UniValue& params, bool fHelp) { @@ -2350,7 +2350,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "developerencryptwallet"; - flag = (komodo_acpublic() || ASSETCHAINS_SYMBOL[0] == 0); + flag = (komodo_acpublic(0) || ASSETCHAINS_SYMBOL[0] == 0); auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, flag); std::string strWalletEncryptionDisabledMsg = ""; From 9641503a270cf2f336f4cdb97ba372cbd2377fa6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:52:56 -1100 Subject: [PATCH 74/94] CBlockIndex --- 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 0793a5a7f..c99a5f1a6 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1834,7 +1834,7 @@ int32_t komodo_checkPOW(int32_t slowflag,CBlock *pblock,int32_t height) int32_t komodo_acpublic(uint32_t tiptime) { - int32_t acpublic = ASSETCHAINS_PUBLIC; CBlockPtr *pindex; + int32_t acpublic = ASSETCHAINS_PUBLIC; CBlockIndex *pindex; if ( acpublic == 0 ) { if ( tiptime == 0 ) From b739548812f36008f54cc6f2ef325d1611d8caa2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 01:54:15 -1100 Subject: [PATCH 75/94] Declare flag --- src/wallet/rpcwallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index f269e86f0..9025d4597 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2350,7 +2350,7 @@ UniValue encryptwallet(const UniValue& params, bool fHelp) return NullUniValue; string enableArg = "developerencryptwallet"; - flag = (komodo_acpublic(0) || ASSETCHAINS_SYMBOL[0] == 0); + int32_t flag = (komodo_acpublic(0) || ASSETCHAINS_SYMBOL[0] == 0); auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-" + enableArg, flag); std::string strWalletEncryptionDisabledMsg = ""; From 8e93a31bf395e5546ce733ef8716f14b6c980928 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 02:30:36 -1100 Subject: [PATCH 76/94] Enable coin migration CC --- src/cc/eval.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/eval.cpp b/src/cc/eval.cpp index 4cc7d79b7..4c3ed5ee4 100644 --- a/src/cc/eval.cpp +++ b/src/cc/eval.cpp @@ -74,11 +74,11 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn) switch ( ecode ) { case EVAL_IMPORTPAYOUT: - //return ImportPayout(vparams, txTo, nIn); + return ImportPayout(vparams, txTo, nIn); break; case EVAL_IMPORTCOIN: - //return ImportCoin(vparams, txTo, nIn); + return ImportCoin(vparams, txTo, nIn); break; default: From 3a4366bef41ffc56f781448d10320ca04f865b90 Mon Sep 17 00:00:00 2001 From: Anton Lysakov Date: Wed, 5 Dec 2018 21:42:02 +0600 Subject: [PATCH 77/94] added tests for oracles data publishing --- qa/rpc-tests/cryptoconditions_oracles.py | 165 ++++++++++++++++++++++- 1 file changed, 158 insertions(+), 7 deletions(-) diff --git a/qa/rpc-tests/cryptoconditions_oracles.py b/qa/rpc-tests/cryptoconditions_oracles.py index ded5166ed..31712abbc 100755 --- a/qa/rpc-tests/cryptoconditions_oracles.py +++ b/qa/rpc-tests/cryptoconditions_oracles.py @@ -115,13 +115,163 @@ class CryptoconditionsOraclesTest(BitcoinTestFramework): too_long_description = generate_random_string(4100) result = rpc.oraclescreate("Test", too_long_description, "s") assert_error(result) - # # valid creating oracles of different types - # # using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type) - # valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"] - # for f in valid_formats: - # result = rpc.oraclescreate("Test", "Test", f) - # assert_success(result) - # globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex'], rpc) + # valid creating oracles of different types + # using such naming to re-use it for data publishing / reading (e.g. oracle_s for s type) + valid_formats = ["s", "S", "d", "D", "c", "C", "t", "T", "i", "I", "l", "L", "h", "Ihh"] + for f in valid_formats: + result = rpc.oraclescreate("Test", "Test", f) + assert_success(result) + globals()["oracle_{}".format(f)] = self.send_and_mine(result['hex'], rpc) + + # trying to register with negative datafee + for f in valid_formats: + result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "-100") + assert_error(result) + + # trying to register with zero datafee + for f in valid_formats: + result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "0") + assert_error(result) + + # trying to register with datafee less than txfee + for f in valid_formats: + result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "500") + assert_error(result) + + # trying to register valid + for f in valid_formats: + result = rpc.oraclesregister(globals()["oracle_{}".format(f)], "10000") + assert_success(result) + register_txid = self.send_and_mine(result["hex"], rpc) + assert register_txid, "got txid" + + # TODO: for most of the non valid oraclesregister and oraclessubscribe transactions generating and broadcasting now + # so trying only valid oraclessubscribe atm + for f in valid_formats: + result = rpc.oraclessubscribe(globals()["oracle_{}".format(f)], self.pubkey, "1") + assert_success(result) + subscribe_txid = self.send_and_mine(result["hex"], rpc) + assert register_txid, "got txid" + + # now lets publish and read valid data for each oracle type + + # s type + result = rpc.oraclesdata(globals()["oracle_{}".format("s")], "05416e746f6e") + assert_success(result) + # baton + oraclesdata_s = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("s")], oraclesdata_s, "1") + assert_equal("[u'Anton']", str(result["samples"][0]), "Data match") + + # S type + result = rpc.oraclesdata(globals()["oracle_{}".format("S")], "000161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161") + assert_success(result) + # baton + oraclesdata_S = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("S")], oraclesdata_S, "1") + assert_equal("[u'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa']", str(result["samples"][0]), "Data match") + + # d type + result = rpc.oraclesdata(globals()["oracle_{}".format("d")], "0101") + assert_success(result) + # baton + oraclesdata_d = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("d")], oraclesdata_d, "1") + # TODO: working not correct now! + #assert_equal("[u'01']", str(result["samples"][0]), "Data match") + + # D type + result = rpc.oraclesdata(globals()["oracle_{}".format("D")], "0101") + assert_success(result) + # baton + oraclesdata_D = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("D")], oraclesdata_D, "1") + # TODO: working not correct now! + #assert_equal("[u'01']", str(result["samples"][0]), "Data match") + + # c type + result = rpc.oraclesdata(globals()["oracle_{}".format("c")], "ff") + assert_success(result) + # baton + oraclesdata_c = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("c")], oraclesdata_c, "1") + assert_equal("[u'-1']", str(result["samples"][0]), "Data match") + + # C type + result = rpc.oraclesdata(globals()["oracle_{}".format("C")], "ff") + assert_success(result) + # baton + oraclesdata_C = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("C")], oraclesdata_C, "1") + assert_equal("[u'255']", str(result["samples"][0]), "Data match") + + # t type + result = rpc.oraclesdata(globals()["oracle_{}".format("t")], "ffff") + assert_success(result) + # baton + oraclesdata_t = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("t")], oraclesdata_t, "1") + assert_equal("[u'-1']", str(result["samples"][0]), "Data match") + + # T type + result = rpc.oraclesdata(globals()["oracle_{}".format("T")], "ffff") + assert_success(result) + # baton + oraclesdata_T = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("T")], oraclesdata_T, "1") + assert_equal("[u'65535']", str(result["samples"][0]), "Data match") + + # i type + result = rpc.oraclesdata(globals()["oracle_{}".format("i")], "ffffffff") + assert_success(result) + # baton + oraclesdata_i = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("i")], oraclesdata_i, "1") + assert_equal("[u'-1']", str(result["samples"][0]), "Data match") + + # I type + result = rpc.oraclesdata(globals()["oracle_{}".format("I")], "ffffffff") + assert_success(result) + # baton + oraclesdata_I = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("I")], oraclesdata_I, "1") + assert_equal("[u'4294967295']", str(result["samples"][0]), "Data match") + + # l type + result = rpc.oraclesdata(globals()["oracle_{}".format("l")], "00000000ffffffff") + assert_success(result) + # baton + oraclesdata_l = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("l")], oraclesdata_l, "1") + # TODO: working not correct now! + #assert_equal("[u'-4294967296']", str(result["samples"][0]), "Data match") + + # L type + result = rpc.oraclesdata(globals()["oracle_{}".format("L")], "00000000ffffffff") + assert_success(result) + # baton + oraclesdata_L = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("L")], oraclesdata_L, "1") + assert_equal("[u'18446744069414584320']", str(result["samples"][0]), "Data match") + + # h type + result = rpc.oraclesdata(globals()["oracle_{}".format("h")], "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff") + assert_success(result) + # baton + oraclesdata_h = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("h")], oraclesdata_h, "1") + assert_equal("[u'ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000']", str(result["samples"][0]), "Data match") + + # Ihh type + result = rpc.oraclesdata(globals()["oracle_{}".format("Ihh")], "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff") + assert_success(result) + # baton + oraclesdata_Ihh = self.send_and_mine(result["hex"], rpc) + result = rpc.oraclessamples(globals()["oracle_{}".format("Ihh")], oraclesdata_Ihh, "1") + assert_equal("[u'0']", str(result["samples"][0]), "Data match") + assert_equal("[u'00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff']", str(result["samples"][1]), "Data match") + assert_equal("[u'00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff']", str(result["samples"][2]), "Data match") + def run_test(self): print("Mining blocks...") @@ -138,5 +288,6 @@ class CryptoconditionsOraclesTest(BitcoinTestFramework): rpc1.importprivkey(self.privkey1) self.run_oracles_tests() + if __name__ == '__main__': CryptoconditionsOraclesTest().main() From d3d5fb91420d0760e88dcafedf6571e2596f34a8 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Wed, 5 Dec 2018 20:46:41 +0100 Subject: [PATCH 78/94] Fix z_importkey for sapling addresses --- src/rpc/client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 91b158f45..c4eb16e0e 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -136,7 +136,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "z_shieldcoinbase", 3}, { "z_getoperationstatus", 0}, { "z_getoperationresult", 0}, - { "z_importkey", 1 }, { "paxprice", 4 }, { "paxprices", 3 }, { "paxpending", 0 }, From fcce90b71b4aab8a79562ed218ee54f0c8bc9a99 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 21:05:51 -1100 Subject: [PATCH 79/94] launchmap --- src/coins.cpp | 4 ++-- src/coins.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coins.cpp b/src/coins.cpp index 306e2278f..656f2c92e 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -557,7 +557,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& input) { assert(coins); - if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC")) + /*if (coins->nHeight < 6400 && !strcmp(ASSETCHAINS_SYMBOL, "VRSC")) { std::string hc = input.prevout.hash.ToString(); if (LaunchMap().lmap.count(hc)) @@ -568,7 +568,7 @@ const CScript &CCoinsViewCache::GetSpendFor(const CCoins *coins, const CTxIn& in return txData.scriptPubKey; } } - } + }*/ return coins->vout[input.prevout.n].scriptPubKey; } diff --git a/src/coins.h b/src/coins.h index f35af02f0..5d6b4603a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -456,7 +456,7 @@ class CTransactionExceptionData CTransactionExceptionData() : scriptPubKey(), voutMask() {} }; -class CLaunchMap +/*class CLaunchMap { public: std::unordered_map lmap; @@ -477,7 +477,7 @@ class CLaunchMap } } }; -static CLaunchMap launchMap = CLaunchMap(); +static CLaunchMap launchMap = CLaunchMap();*/ /** CCoinsView that adds a memory cache for transactions to another CCoinsView */ class CCoinsViewCache : public CCoinsViewBacked From 73053ac9d584daf5013f67025a850d94bed94e89 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 21:08:51 -1100 Subject: [PATCH 80/94] Tweak build --- src/Makefile.am | 4 +- src/veruslaunch.cpp | 1424 ------------------------------------------- src/veruslaunch.h | 17 - 3 files changed, 2 insertions(+), 1443 deletions(-) delete mode 100644 src/veruslaunch.cpp delete mode 100644 src/veruslaunch.h diff --git a/src/Makefile.am b/src/Makefile.am index 2f69758d3..19a29b9a3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -261,7 +261,7 @@ BITCOIN_CORE_H = \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ - veruslaunch.h \ +# veruslaunch.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ zmq/zmqnotificationinterface.h \ @@ -483,7 +483,7 @@ libbitcoin_common_a_SOURCES = \ script/script_error.cpp \ script/sign.cpp \ script/standard.cpp \ - veruslaunch.cpp \ +# veruslaunch.cpp \ transaction_builder.cpp \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) diff --git a/src/veruslaunch.cpp b/src/veruslaunch.cpp deleted file mode 100644 index 2268b0200..000000000 --- a/src/veruslaunch.cpp +++ /dev/null @@ -1,1424 +0,0 @@ -// Copyright (c) 2018 The Verus developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include "veruslaunch.h" - -const char *whitelist_address = "RCZyeg6eofQUBKJE5LWuiYkgBPCafheDc8"; - -uint64_t whitelist_masks[WHITELIST_COUNT] = { -0x1, -0x1fff, -0xfbf, -0x1, -0x5f, -0x1, -0x1, -0xfff, -0x7ff, -0x1, -0x1, -0x7ffffff, -0x1ff, -0x3ff, -0x3f, -0x1, -0x7ff, -0x2b, -0x1d, -0x7f, -0xff, -0x3b, -0x3ff, -0xf, -0x1, -0xff, -0x3ff, -0xfff, -0x3ff, -0xffef, -0x3ff, -0x1, -0xffffff, -0x7ff, -0x7fff, -0x7ff, -0x1, -0x1, -0x3f, -0x1, -0x1, -0x7ff, -0xfff, -0x1ff, -0xff, -0x1fff, -0x7ff, -0xfff, -0x7ff, -0x1, -0x3ff, -0x17, -0x3f, -0x1ffff, -0x7ff, -0x3ff, -0x7ff, -0x1f, -0x1f, -0x1fff, -0x1, -0x7ff, -0xff, -0x1ff, -0x7ff, -0x1fff, -0x1fff, -0xff, -0xfff, -0x3ff, -0x7fff, -0x7ff, -0x7ff, -0x1, -0x3ff, -0x1, -0xfff, -0x1ff, -0xfff, -0x1, -0x7df, -0x1fff, -0x1, -0x3ff, -0x1fff, -0x1, -0x1ff, -0x1fff, -0x1fff, -0x1, -0x1ff, -0x1, -0x1, -0x7f, -0x1ff, -0x1ff, -0x1, -0x1f, -0x3ff, -0x5f, -0x1fe, -0x7ff, -0x1, -0xfff, -0x1, -0x7ff, -0x3fff, -0x5fff, -0xff, -0x3f, -0x1fff, -0x1, -0x1, -0x1, -0x1bb, -0x1, -0x7ff, -0x5fffff, -0x1d, -0x1fff, -0x1, -0x3fff, -0x1fff, -0x1, -0x3ffb, -0x1ff, -0x1ff, -0xff, -0x7f, -0x17b, -0x7fff, -0x1, -0x1fef, -0x6, -0x1, -0x7f, -0x1, -0x3ff, -0x1, -0x3ff, -0x3fff, -0xff, -0x1, -0xeff, -0xfff, -0x1, -0xff, -0xff, -0x1fff, -0x1, -0x1fe, -0xbf, -0xfff, -0x1ff, -0xff, -0x1, -0x3ff, -0x1, -0x1ff, -0xfff, -0x7ff, -0x1, -0xff, -0x1fffbff, -0x1f, -0x1c, -0x3ff, -0x3f, -0x1, -0x17f, -0x1, -0x1, -0x5fff, -0x1, -0x1, -0x3ff, -0x7f, -0x3ffff, -0x5d, -0x1, -0x7ff, -0xfff, -0x7fff, -0x1fe, -0x1fff, -0x7f, -0x7ff, -0xfff, -0x1, -0x7f, -0x1, -0xf7f, -0x1, -0x1, -0xff, -0x3fff, -0x1, -0x7f, -0x1, -0x1, -0x1, -0x5ff, -0x6f, -0x1, -0x3f, -0x1fff, -0x7ff, -0x1, -0x1ff, -0x3ff, -0x1, -0xff, -0x3ff, -0x1ff, -0x7f, -0x3ff, -0x1, -0x1, -0x3ff, -0x1ff, -0x1ff, -0x1, -0x6f, -0x3dfdffff, -0x3ff, -0x3fd, -0xfff, -0x3ff, -0x1, -0x1, -0x1, -0x7ff, -0x2fff, -0x1, -0x1, -0x37fff, -0x1ff, -0x1fffffbf, -0x7f, -0x1, -0x1f, -0x1, -0x1, -0x7ff, -0x7ff, -0x3fbf, -0xffd, -0x7ff, -0x17f, -0x1, -0x1, -0x1, -0x3ff, -0x3ff, -0x1, -0x1fff, -0x7fdf, -0x1, -0xfff, -0x1, -0x1f, -0x1, -0x1, -0x1ff, -0x3f, -0x1, -0x1, -0x1, -0x1, -0xff, -0x1, -0x7ffdf, -0x7ff, -0xff, -0x1, -0x1fb, -0x1ff, -0x7c, -0x7f, -0x7ff, -0x1fff, -0x5ff, -0x7d, -0x3ff, -0xffff, -0x1ff, -0x1, -0x1, -0xff, -0xff, -0x3fff, -0x7ff, -0xff, -0x1ffeff, -0xb, -0xfff, -0xffff, -0x3ff, -0x7ff, -0xff, -0x1, -0x1ffffff, -0x1, -0x1, -0xfe, -0xfa, -0xff, -0xfff, -0x1ed, -0x1, -0x1, -0x1ff, -0x7ff, -0xff, -0x7f, -0x3f7, -0xbff, -0x1, -0x1, -0x3fff, -0x7df, -0x1, -0x1, -0x1, -0x7fff, -0x7, -0x7ff, -0x1, -0x1, -0x1, -0x1, -0xb, -0x3ff, -0x1fff, -0x3ff, -0xff, -0x3f, -0x1ffff, -0xfff, -0x1, -0x1, -0xfff, -0x3fff, -0x3ff, -0x1, -0x1ff, -0x1, -0x1, -0x38, -0x3ff, -0x1, -0x1f, -0x1, -0x3ff, -0x7ff, -0x1ff, -0x7ff, -0x3f, -0x1ffffff, -0x3f, -0x2f, -0x1d, -0x1, -0x3ff, -0x7ff, -0x1, -0x1, -0x17f, -0x7fff, -0x1ff, -0x3f, -0x1, -0x1, -0x6f, -0x1, -0x1df, -0x3ff, -0x1, -0x1, -0x1, -0x1fff, -0x1, -0x1, -0x3ffd, -0x1fff, -0xfff, -0x7f, -0x1, -0x1, -0x1, -0x7ff, -0x3f, -0x3ff, -0xff, -0x3ff, -0x1, -0x1fff, -0xff, -0x3f, -0xffff, -0x1f7, -0x7ff, -0xfff, -0x3fff, -0x1, -0xffd, -0x7ff, -0x1, -0x1, -0x1, -0x7ff, -0x3feff, -0x7ff, -0xff, -0x7f, -0x3ff, -0x7f, -0x1, -0x1fff, -0x1, -0x1ff, -0x1, -0x7ff, -0x3f, -0x7ff, -0x7ff, -0x1, -0x7ffffff, -0x3ff, -0x7f, -0x1ff, -0xfff, -0x7ff, -0x1, -0x7f, -0x1ff, -0x3f, -0x7f, -0x5f, -0x1, -0x1fff, -0x3ff, -0x77f, -0x7fffffff, -0xff, -0x7ff, -0xff, -0x3ffdfff, -0x7ff, -0x1, -0xfff, -0x2f, -0x79, -0xfff, -0xf7, -0x1ff, -0x1df, -0x1, -0x1e, -0x1fff, -0x7ff, -0xffff, -0x1ff, -0x3ff, -0x7ff, -0x7ff, -0x7ff, -0x1fff, -0xff, -0x7fff, -0x7ff, -0x1, -0x1, -0xbf, -0x3ff, -0x1fff7ff, -0xfff, -0x1, -0xfff, -0x1, -0xff, -0x3ff, -0x3bf, -0x1, -0x3ff, -0x1ff, -0x1f, -0x1, -0x17b, -0x3ff, -0x1fd, -0x1, -0x1, -0x1, -0x3ff, -0x1fff, -0xfff, -0x1, -0x3ff, -0x3fff, -0x3ff, -0x1, -0xff, -0x3fd, -0x1, -0x1, -0x3ff, -0x7f, -0x1, -0xff, -0x1, -0x1, -0x1, -0x3ff, -0x1fff, -0x1, -0x1, -0x1, -0x7ff, -0x1ff, -0x1, -0x1ef, -0x1, -0x1, -0x1, -0x3fe, -0x1, -0xb, -0x3ff, -0xf, -0x3ff, -0x1bb, -0x1ff, -0x1ff, -0x1, -0x1fd, -0xff, -0x1, -0x3ff, -0x1, -0xfff, -0x1ff, -0xfffff, -0x4f, -0x16f, -0x1ff, -0x1, -0x7fff, -0x7f, -0x7f, -0x1, -0x1ffe, -0x1, -0x1, -0x1, -0x7fff, -0x1, -0x3fff, -0xff, -0x1, -0x7ff, -0x1, -0x1f, -0x3f, -0x1fff, -0xfff, -0x1, -0x1fff, -0x1ff, -0x1, -0xfff, -0x7ff, -0xfff, -0x1, -0xfff, -0x1, -0xfff, -0x1, -0x1, -0x1, -0x1, -0x3fff, -0x3fd, -0x1dff, -0x1, -0x1, -0xf, -0x1d, -0x1, -0x1, -0x1, -0x7f, -0x7ff, -0x1, -0x7ff, -0x1, -0x1f, -0x5ff, -0x1, -0x1, -0x7ff, -0x7f, -0x1df, -0x1, -0x7f, -0x1, -0x1, -0xef, -0x1fbebff, -0x3ff, -0x7ff, -0x3f, -0xfb, -0x1, -0x1, -0x7ff, -0x1ff, -0x1ff, -0xfff, -0x1, -0xff, -0x7f, -0x7f, -0x7ff, -0x1, -0x1, -0x1fff, -0x5, -0x1, -0x1, -0x1f6f, -0x1f, -0x2f, -0x1fff, -0x1, -0x1, -0x3ff, -0xff, -0xfff, -0x1ff, -0xff, -0x7f, -0x1fff, -0x77, -0xfff, -0x7f, -0x1, -0x7f, -0x1ff, -0x1, -0x3b, -0x1f, -0x1, -0x7ff, -0x1, -0x1, -0x1, -0x1, -0x1, -0x17f, -0x1, -0x3ff, -0x1, -0x17f, -0x1, -0x1ff, -0x1, -0x1, -0x3fb, -0x1, -0x7fff, -0x1, -0x1, -0x3fff, -0xfff, -0x7ff, -0xfffff, -0x1, -0x1, -0x1fff, -0x3f, -0xfff, -0x1, -0x37e, -0x3ff, -0x7ff, -0x1ff, -0x1, -0x1df, -0x1, -0x1fbf, -0x3fff, -0x1ffff, -0x1, -0x1ff, -0xff, -0x1, -0x3ff, -0x3ff, -0xffff, -0x1ff, -0x3fff, -0xffd, -0x3ff, -}; - - -const char *whitelist_ids[WHITELIST_COUNT] = { -"002b8879209b8f7d57bd0583a5c2eb36316b9cef74df41d68d920b44519f3024", -"00344e3a597a64613b94f52182ee83c4653c11bad812dd2ff6340f0b53f08459", -"011f023e95c53a7d6a707d26a9867cf15cf2cd737c30001d8bc1b3cf2bdf0edb", -"016b5d58ac29880a6769bf44da913868f9a3aba42bb1c0704923b06a33dcda15", -"016cbcc6d43a6618fff83b640e2d84fc578e946c694182ebad0523e2958b5ffb", -"01ff69289553b84d6a59f6182d5c00b2d17efe24c73a5b05a29e954129c6ccce", -"0275c198543c9c80e5e9d2856389e6de2d422180505925300418b98edc3a0afe", -"0277f1d75d5cfbae4e233b1cb51beec6613977ec8f58ab0c4afa994c8c47a2e6", -"0290c7e50a1449c3cbb6e13e38f866a280288768618acb6cd28c0671983670b8", -"02c80c0e2ef82e8665b15e473378587f17c0e3c249c3981523a5c82a94ebd353", -"02ea58496bf645e82bc3c5bed0074c1eb738e499b76e77d45e1b364e58bd8b76", -"038d31196a2345a613cf50b279bdddde4c1f54af3b0427bef9fad2e592932685", -"0484da59a0de43f198e06196f77296df69226a8cdf77184e884ec167c3532cef", -"056aa35cf3605975ebd975dba51192338b0651031cb1a032e690683e0942a83b", -"05eddc863757ab3a0ad92dc10d08bc68d52af7323c5f2f27e87b5b6a88af96d5", -"06fa4a0211eafc2b442723dee8ebcc4067b8c2a8be403b95224d73692b331203", -"077ac942ae3e4abff86cf6d7816d6a2451ca4173f1129361cc36455b6bbe6134", -"0816537b3bd2716fece38a5c79f7b5aec716ea53e9fa42b0a061faaa401c61b1", -"087c5be47004dfded4922baec550810b4e3a70294b4b69fb9074e30bd1d9a892", -"0883c592722bcee50890559865932e9e79e7fb87f56bd7c0e8d895078ea869f6", -"09eb001bb9b9107863e4850263f91d59c74477b8d89ca57ca625301e9a3fadc5", -"0a461587f0a3fd534dbfd6b505bb30da5b285a7b456bad457a0090799624e6ae", -"0ab8ec4b0f3dd37bfc2ae70bba07526a76339cc45eac861ad36b38b7512699a6", -"0af72ab4c895af9464162ab330c7582d694d9ae27ddf042959edd726ca1b7b14", -"0b1b7dad08224bd5dff990f5d04668f4ee216d637a3e4c49751ec997e3762502", -"0be8634afca5648c45495eb6bb9c853e226ca258e7fb9898916dd64a1a822f04", -"0c033aa83bc0da89d4dab7ba96c8a0ad77114bb49b47da011f84883eed301af5", -"0c4ec5a2fd3c7b1f6b544ee89b7f8dd9bcf867485ee0c59bd587f33968833cf8", -"0c700419bcb1787ba200eb28da5de1512f58906c0e358abfc20157282342962b", -"0cbe8330bf17b9d9b7a7b5d86e13c2b4e4145c8cbd6a602d04e71fa860922391", -"0ddb51dd66a1f556e66c904e2e3bf7b7c6b057f316b33681fade82e703411334", -"0e3d414d58f55e91fda7347bdd343547aa7fc169277e5570a24c76db515ed37b", -"0f057e3315a1b473231cbfa452ba55b408fd9da587fd24bea625e5b707745ea5", -"0f25601c3b6f2da84511262c7491e73ea4ae32b31f9041f6a82918c5c008b6cb", -"0f82140db1c65669331edac3da36b05188178c0a70a79139ea553380f1e87fb1", -"0fb23e7be4dbb0d7b410b74351a9029682bf0021a6d52243c78275cf1f14cab5", -"0fe7db2eae67ef22a0d8cdfff494b160598e9fb85fde16beede19503b88d8f44", -"0fe8709b0b02d2ba1e6bb45188e68306e38286c0a4764a7efa50e0415f897e14", -"1101bcf5fdc44d1e51f8e4d9aa01a86c27d5f790926b5df00cdd049ead4d7fa9", -"11182dd29ee6a40d5aa0f1cc982ace6c2877c47072d551db853115e672448fca", -"11bf1e8898837cec381d6fcb8736b5f9507325bd6fb2c01fc0ecf374b07e0fba", -"120eca38ff7909168915af93cc15c6516dfa942da166744fea26cd2f149c32de", -"1211916bba3c8bea6e71972fca03102ee3555b2da4232f127dbcc4c5017b0825", -"1229657075f7503357e389260c3b74969d37c3be381d435d40078c653ea9f3a7", -"127e36a87665d002c7a92b98ab6fce9a3daf701d472f065d76ecf92f501943e2", -"12922ccdb8a360590cf32546575243665da5d012ae586c331bc353f58923e771", -"12a106f2e625b5a08f9dc2102f8eea180e8975974b41115702dbaf6cfbecc723", -"12ab340a91b6c3e7bf02e8babfe0d1e980eb6503333adf4d41818b7c22d34905", -"12eb374b2a88f53c0d29f7bc612e298eb436f18f5995294722e706a9142bc36d", -"1345450fb4c0378e7980d0a740d0b7144e77ce6ed53577d91b259fc3a42c73f2", -"135e66bf2414e41f735a2dfa8ec35bdeb019f7d2c7c5bf70dec056cc757e0a61", -"1430eda829af2535d4f5dcb2d213fd12b4e1ac207d092f55eb6ad241256dff33", -"149b9ae40c8e4b83693f69e79b1b27398f44bd35c434cefc481a2a61e6f23367", -"14a3ca96180f530efaba5ff3cd9640c2ff1deaadd04c43c7d2c31134eb179bdf", -"14be2ac61b6f7d59c0f5ab9fcd8c243b74c8e410b246c5d731cf5f3e0dec6d3a", -"14dd1f04d04fce2233522d6185203371d6723c10e078f73300caecea522f08cd", -"14fb7b06706c392728c684248e146bf73a89420584c6e5800481867164661425", -"15304ae2ff1375b2c0a45cb031f81509d3dd1f9a1bf8451dba43a997f95f8c1e", -"1547b51f12ee567819ecc3e1550d2a378fd4c98868db51064faf591754b3454f", -"1565d746c24dbe5ce8ee76c7fadff23bb96093a2714a2e43019c40a7a14f27fe", -"15dd7a70f258291b58f6afa56cf89f1b1ab537578110e4ddf770e67abba12f5e", -"16ec17c1ada1da7a2678d208f287b57cd34de3701a28765fa30b1eca1536d6ff", -"171ec86aba7306b3825044f1d2b2f8d3bb642a7f76cd50e048994835f0dbb4f7", -"172d6a1a3f8cf8ff7effdbdec4b91f42bb93e234f7e0c3b4c99105a3b8dd6e12", -"17648a8ada3162bfd6c61dab3a68b6d6a6c416050b5e72186a5f4a0fec1f675e", -"1816c505bf671ff884c1a33758c0617ba5be6c10a64a09b624fdf6052ee9df72", -"1848038400d70b3903d00494b74e699719cc8d7136a23ce1c01678caf9367853", -"18557e2f0976a61d25b00d88306835f19fc98e7b4060c54b1f7fd8af58cb8fe6", -"189d98b261c075e5b8dec117760ddf2f98f13ed7aa135926793cfe01ad26e364", -"18e55215c5bf0bc69dfe1130e61f3cd1b96cde286b3caa873455d3f087dbb549", -"18ed4402e50441c0efe1f0652d0decd8955a3e531fd4026b6b49c40d8377f7b7", -"19165ef3862a34394c8a19acfd6d04817f29c4d15b8c43d9d85efa6a4f012a45", -"1a48faaa69b59d4468eeb12dd348635451ea32f15360676a64a37d62475632cc", -"1a512df86481b517e070482b303c7bd44e2d70f69ee5ce65f0f011e9a7ee6ff2", -"1aa54d1c1eee3cee30416be5544d54f7966ac521b7be80d9c98453755425a825", -"1c2e03b2ed08d3ee273fd20e68174a21485a964a43391c2fc3ec9d119747af29", -"1ccdb80b14a6e34f2280a740247a7ae064511f07c25def71d95f709df20bedac", -"1ccf44427bebd855d79a9361844eb90bcfbcf6f00ab2a2dc1c9aec3bdf8c246d", -"1cf60e92909559165e48f0138cfafe59f480d205554e46df1dcfc4edff200fa4", -"1ddbd47203e47a921784c9c4c568528c3b1b82620d7b550156191fa6ad0cb067", -"1dffb30da463fb43f0fef54f86239ba15fe54d290a7019ce61ebd516de2fab6f", -"202909962c024a6ae2000d4e28f3f6c5e2a2e84b1e23d099a4908580d3962d6e", -"20de587f30726bf08f8c804f165ddea52c01c886bc180d203268e358f87f6484", -"21a8d79d4cb3950c16c76ca1b0c1f3ee45dbd2989f0b9f4d13aee9afbafc3073", -"21def17ab16d3290a33bd7bffdfa940444228804921cf50fa05a668ba1b7f832", -"224996985df9fc62083c27679a6df3f09087168422b0428511f9e9cc082dd408", -"225e665c881fc73df9c1eeabc791dd665784cfd2c06707c22eb47e9f06659e56", -"22740025cb024d92ebbf48ad49629a51cab16f10840cdcc8a937ca14e9c14dd0", -"23f285057e832019f6afc5ec2669461adfaedd1dce145322423c6e19036dd833", -"241710960dc4f4941ee3090154facf70522ff50e036311778305a82635669e84", -"241b848f9419448778f9a938f73ba0cf968670fed00331f3a93721d41b26099c", -"24a3e671772418a897e32c070d04a76387cb7671ee97a21a205885eba1f24587", -"24b9b8737ea244916d18447fad586a7423ff13f96b910e58f18d5e63fbbd9fb3", -"25876e3596b7657dcba55dab807eb018f397fc638583fe6ff56af3373a1906e4", -"2635848f52451f402cf2fba66d330eca44bea0f59830f5cd2fcd0193e39a0aca", -"26a78c19dcea41f1542bd5a154bc5c4aff33ed0520e34483b438633d8f13419a", -"273c4957a1f32a95b305748708828286fbb4c19168b7c5f509a0079949a6a61e", -"274607b0c7e368c335e8109797dbe0cb9a21504ca13dfb06347e1e9f459e3efb", -"274c9913f932cffd8337b7a33e25d838303ef8437c321d964b0e79557840e207", -"2761c2790b9320b6ee3bcb92490e76f8992d2991fcc18e74376cc16c34b32e48", -"27a66b01585f5534badc5e093b11ce9575bb8441c5915866cc504148e4db33cc", -"27cfd5a76495ac5d80a5a98a23790d683c0a1a3341a1217a124d259e216d2065", -"28706d3d00fb09dd0826894d439862a685b1812c403b3971c1c954096ebf0feb", -"2875b37c502b010e5ca5707e5b57d69f5b43b149da56242f63032a63fe0a422b", -"2885423a3b21150833cee9262f1b63e4808fee60c55ad1397d0947a5a072b568", -"28a9995c7b2b0d4e06f1c38f814e68d5f750653c7537735cc496c06b571f38dc", -"28c5309eba71024fee274b81b80d324f7ba6fe49b936c44748bf3e8746949dba", -"28e0f04ab585cc0e008bc64acbcdaf9a3df5b685c24ccf71f893743033d29b19", -"2986d25767030441a966b950fe6bf4216c24faa84c76f523514e69eb9d73ec34", -"2a3ca2ba85f27005c06b0f2b9ef8701d4370aa28bc34b0a76f4839d41924ba14", -"2ae0117cd983f09ad379c1364578e53b6ba2f3b03698c866cc7b9848d67a0b53", -"2b0d21da9d0dd74b6d4ed992cae39794e894d83412c7f43d6d31836d8e1b7d18", -"2b4f7a0b1061d17c6439f401b57eb4a4714b54c3931d8b1940af831c64416c8e", -"2bf36600d99ecf4d04d97b0d6c097aecc73c94d6e7e9a9001c117a8d08e625a4", -"2bfabbce5b1a897b22a75ed730015eb33499abc5e96f22f9349171b8d02957dd", -"2d1782b21aef0877213492483339dd08f874342cd39d19df64de160a799ab4af", -"2dda980b9224698a05649f6cd732e9c20977b02f09eb53d15948a2526e836f56", -"2e207e917e87dd8b39f24255dbcb823f12de3b549b000e3f75e0b966ebbf2b83", -"2e7d3950a49f067a9cb4948b6d2fab3e6fcab33002d5118d7014408283d42cbd", -"2e835b4c84a64bfa706ac9e077a08eb6c2162370799ca90ff7d95290feb353ff", -"2ea286dbfbcac3fb669f83c1f02d78737556e2fba41e03cfb1ae01f01ce2fd59", -"2eb62ae8f3ac85a7d8928a306f28e617fc405d07e2eca4688045156440017cc3", -"2ebd55c901bb94ac0bd165af01c79581e48f5d818691114cd4b1333502ab2b35", -"2f5692f0f88dfb3f3dbb0f4aa4979e55f68f054c092f94947847d4629b047848", -"2fc347f2419255a182421dae97f58b3de020612947692a5b41d15ebae59e8ec1", -"3054bf7cf90248e1991426516b3626544a0c1698905020b1f51641bb37b8b15f", -"310319d2c9782aa1677eb95f1e3b71922cf463da8df12e85de51d9c424793e6e", -"325051a1eb2a4ee5b1fdff9f7b5df042c7cab956df80450a7f6d5518c6947890", -"326dc1fb8b73bd48ed5609020492f339140fd54aef7852370a520afa8f3fee1c", -"32779939ba8ced9ce9f0ed71f40dd07c735d5ad61ce4822c6ff653c78ce54aa9", -"32da5a9ba4ae50c9388f17152d41905fed13f6b45f0bf9fef98916128bb48323", -"33653c6a3f6c6e72843c812eb11a0118399fc059ada8c2fe05a01690ba28d4cb", -"33ec7a535be679d54563c2f4205bd80580b6ad09048e703e2d0fe76faf9c04d8", -"3417683f6d80a564b8ce41a509cfc61b3bf927fc2d412cc48f7c559a632aa20b", -"3455da8af23762bb9c12a718d2df2dc3a6b08222f5a1d837f298530098a12739", -"34703485206f3f629cfab6bf95ddcdfc6db509605d4753d2aa405216db5ccb87", -"34ca230f687e0de838bec71e9f8f07fa30d31e9da3e7c6a36ac3db7370bcf770", -"34e46667cb9070f952c1931705f0213a3af34617e8779f1552cd08d42b6abbac", -"34f2ebd727400ddd81aafa28454490ae7e6fd3ba7f5d01ef4f56c0136a43391a", -"350a3096f337e19a4c8462c18a6aed63bbb6079eff28b9cc32ffe407471dfedc", -"358e2dd41e9ca21b7a4c06e271d314bd2c612888896d39c91862d3d3f80b146a", -"35e1bfe2247a20df0f3504883a65e36ca13d7421893f402201209cd5c4af6c91", -"35f7854642cc0ca565d86f543f5c1995d951479a2877836167b9a05dfbb01453", -"36a89621c47190b0fc03912d62b047c680710ed3a3b9ab7591fd9d4ccf1783fd", -"37028127c214dfe94ec70054bebe79d300fd68e6cdb48d7ee3a8a6e7efc2387f", -"373233f53d7d6fc848a3d1d44d9c94a76a0a9d5cb3a172e00e77e08445f40318", -"379ddfc9cd654c76438e7a98ecfc06466cdce4be178e3ecf1f825a7b8c19c684", -"37c8673f4ebc328693a76dc21017cee31699d480462bd81d9229ee018af56df8", -"38d17a3fd47f8ebf9f6f2b89f0a80af8e252219792c89c40c2923b49855f6dba", -"38e314049e2c927fec6e8dee40b35766c993192b26e87861ede1bcc19201dab9", -"390352708c8ac66b247594f9087cc5a334d63bc96e4c76f6c96169d2a4a893ae", -"3947cc691769d0a07513922d717eb64452a89b679fa784878b2c5183a034c12b", -"3975767f9b45b49cd5693116b5830b0576c20516b50244e2bbf2e13f4fe4284e", -"39a9981213f180db60a44e68a9a7a0ae3feacdc9c4b00039dbfd8718f3091823", -"39f2f86b06fda8c40cbc3b787dd00f21684698431eff462cb392d17f15fc628b", -"3ada7a44cd85dac024517a5f8be890d10ab9c8c1c408ceaa1a6695dc793cf0ba", -"3ae37dd8fd9e8f9adb55abfc13765a1d0c4b95db2775e4b70c0d1c4b9246c13b", -"3ae9e37f0d98637ab40c4f221e2653098eee07ffeafdc612fc308e3057478e3f", -"3b81e3a208a22283e7af9432eb52b262d3cd79ff7c58a00288b3aa6ff5b3ff01", -"3b85c87f57308b00155a27ea8551f5cc1b1df95f866c632e62d801522e937a75", -"3b8fd271479ae55236a0cebff624367d3328aa946e1ebc936f5f2e6975107e35", -"3b9933e8814e274a68f8bd03a7403dddedc9d541541082a892ce70b0c81f2f27", -"3ba5a78d5dfa4c70d547e590b32efa5e99ef8fec2285ff267443b63051ad7be8", -"3bc180238397214448f8119a3a86e41a74c940da99a3af22bb955f463b6ea279", -"3c0e34bca907d376439e4f281439ec78587fc09aa92f13836caa374040589994", -"3c3ef3b2874b8d0be8273e57458616e08fac9c4d446b9eaec8a126bd3a43bc5e", -"3c440ea26ad38cb91895e06ef27ff78c3e3a869d70cd29dafafed465911f0822", -"3ce9e5924fcc25a1569d5cded8e4c78c1edea0a4192e1a05cd3206e37b96d29b", -"3d842670e7e521a6271490056b0389d94db76738cb056deea89e9d19d1f27ddd", -"3d9e80491a81a3b8926c5769d8723a13ac9b408572afb14130cecb50172637e1", -"3dcc7a9ff3383e90bc2d29f4ff6cc03a3b2cb11f614d8faec5b7949d8157cad6", -"3df2e641a404394816e4c069c11720da0a5573724db1499c706ac649d58deb69", -"3e037df06c2f24a9faab67e416cc1b8a5fc185e09bce0bd7c064e08571c030fc", -"3e1e2e18553e703c9a4696d4341f1e7ffe973537af0665c6c61fec6a0d714e1b", -"3e6360c2d6cabe18067e31f77cab4dddce151d408d6fe03a966c774cd11d9045", -"3e8649b328904cb4fad71e4e98953567d405323b4a92ab371a396c4bce0bcb49", -"3e9688b9ca4f83f14df8d5ee1612f336f1534ab466b9cf9ace0d617673113d16", -"3fac933733a58054e968e1d07ffe88dc4a21e3b5f11a73035c5ab112ad420440", -"3ff079ec5f4df2fb44d559ed6b80e6437759baa6ed6a6450dc25b18e29cc108c", -"4028392b3b24f1e6f92588f4aee2aa82d0bbe97d3986bd92970e01a532f002b6", -"41bc2a5ab26754978ddac4f507bf9b7955a233b49fccb7db18fa46903c6b0e6e", -"41beb053cf1e516033316a69ab883584cd42546d1d7613181cf3d948eeaf1e6a", -"4226d7e110ac69cf25c6826fd527c1f2bcd2249cbbfbd5560cffbcc79c9666f4", -"4228d3ce33670ea4708a5a33169db4f972ea218a4f70a2f27dfb704638ccc3ec", -"429497d2ec741a49e76a41b80ab61cfbc2255075f271fae0374294c1907448dd", -"4349b963a367f3c2b8458f07ace2bf918b83737368997be7c1de2e718a85f6b2", -"43b75cd385f801eb9957c11d3e320c2a55a0a017be946d293826ce037b02c8dd", -"44f8351eba509fba2936f43daf4b1880b36200752ae2191a69d7ce560271ff95", -"4552a9594f84966bfd05aea07e119ec3c32664cebe47758e64179269ad4d0cf0", -"458ccf7d7f87f61e37b845b2e70647b3584f9335ff030fc2417340dddd3072bf", -"477bc2b25761d86f3ebe08605e9dccbcffd31557f4566917778fd5a10bd35ee0", -"478d64b89f6388454cb06037bcb2230901c290256e53084ba9c26549b550cf2a", -"479519211e1a6e6c5061d619fc37e9a4b598a8ce13f3ba6f6e585a7ec9195d29", -"47cf75c5a350ef00f1e6f64c1c7273cca9427c81a305b951f796ca1e238ef9b4", -"480059f38193d30b8dfff7fdf9ae4eb40426e500172b87d31b6fe755008eb8bf", -"480d99d7f2dc154c10d36862fe6f0cf4ccb156fbc32ef68082796bc01d606f51", -"4822e004b7301667308daf9f6249a64eac2341dd29f155d543a7a1de4dd2a2cb", -"4834a117960b361433c78b8c2108c02964c25b3f29d8316280fe39a4daf4bb93", -"4847aded4abfdcbe41afd2285f3e563bb2253e391f350e36d075bce29be40894", -"4855a717c06619e0564e8a93841f4c947ce5cb2cb734ee91d2a61c4f4b6e26d0", -"4886da7e6c76875c52fe5b016a6bd9ce139a69fb86b854c9feda45822c4df0ec", -"48b1383edd12162c40b17cb1c8306d857a1b8c6624847efa41f4408611e93c56", -"48e9c3d10d527d78c0f46e6cc7026ab0e0f12572f0712a0a0f9c2c411fdf89e5", -"490262b2407938dd372901ce409f61f7f0fd6612685bd504feef2d0d9a5cfba1", -"49e61bb61ba7065cbce26186cb817ce1e14d078ba6fc1a73e4fc7765ca67e9b1", -"4a4827a59d8f52b8b122678158543dd87af6a76f4ed13dec1b1dbde8f2ac3e87", -"4a757f61d5d5738e2016f44a23f7c27ef14230116eab63944a6f18cf23b439f3", -"4a7643336ef44d156f33fec3d8574976dd33456840231b192c9b437d6783a614", -"4a877ce748cc4aa00244aff9ef2ddc6fa1f05d53456cbe9bfc7629d465e80614", -"4aa038d06c4a3a4ee1a4074931039be85fa1b09dc7a22aa5eb0a468e2e349779", -"4aa7d05381013e1e15fb1bac88c72b0d40586ccee6eb66e7d8ddaebe95b52729", -"4b8daa8cf2a99255249ebcec1b8049854876781bb64cbb57d75563f8fd17a7be", -"4b99c08c5f7deae5b2679dcd4727f486c4c4eafa7c06ec443f46665dd9714077", -"4bf4f2a32190e7fa5988e061cde858f0a0cddcf777d72e6ca1ae1323e13e20a0", -"4c2cecee161b749dc94e45faff5786a8aeb99130bf92998b0da653bb4bf47201", -"4cd6fdfa6e0d862ca4dacd59e39cba11902c8a850301093d63bda6e5b196d019", -"4d51cb80a623dd3c544590dc07e718b37ca896169ef724b88cd80cb8e03c53f3", -"4d5ffc17f03d6332cfee37ca66bda4535bc9b65bbea9d3532658fd6239b2532a", -"4e1b198038c9314842587578a8ecf87a3823fcda894573977b4c09d2649c4083", -"4e87bc9294ae8eaad10879f52a20c53467c7469f5a2e6aa0fb7fa54d39636037", -"4f9711d5c450b59118af298916333272d6661a081f321999b2918d1798dca807", -"4fb4e962c9b883685bcc51b88cca48245cf0f1615853046ee20a0703f049fd4a", -"5017b23489cc1ee276fc17894098059b6af278b5bfe82031e252de837fa3b81d", -"503325a82128678ca5b2f2d5344b4ceea0c46e039c7b1148faf4ec77a33d0d14", -"50c009b404e665ed88d6ccd02ad74d1f2a08df2e91a6a0770c2537739db34f50", -"50d94a6876e6f1dc2961f1b040dd4d973277ec3024d4ed38646487b1f2fcba4b", -"5136ad29fa4969b52b593b3b866a6111bc1f7706fcb46b7cea6945c97396f03c", -"51489a8bf67163c40b795b974bd572483d833e24affda21a13bda2c1b6b62d1b", -"519d37b614c45451bbda2aaad0e11fb10a48d9671ac207fcda1b63901e08f830", -"51b0264cfdefaccbee50e37e3bd1c227349f10739731ad582d1c0a2a392e9f8f", -"523c80b259cefd1100d9af6e9796a168da2bec293060b8cf795b0354835522be", -"526969254e21e98f5865d1a49a4d2331bc2365bcb9532898542d2fff2ec52831", -"5293695fe3e59994840c6ce0e51d566ac2ce27aa30ea1c29fd055622c8ef361d", -"530056bf9c906617501a63d0f3b24e88ec4893722811b129c1c9f0786b0c3444", -"5352088de1900c6167435557913792d61a01b007672d532e2c1d8b81934804f9", -"53d4fe04241d20820b0e7b04b025f0f08d7ab20dfe3c5ec450e210843993bbcc", -"53f6efa1c4986dd02a09098a457f7b77ff88067ce2afa611b6d28755d5a26359", -"5454df4d91845d51f21f5abf678eac76149c168ae1d530a1ad3df0e08d09a186", -"558c91e53ca5516108dcbe9eaf5d4586cea5779f7e73f1bd423d24ac867d384f", -"563a15b286fee767853c184920a3a7de2e3d4b2d0bb69daecfc0028ca26e88b4", -"565434775883c4e3f3d2ae70118d06d7489295ea23e94085763e6442f39e7ce0", -"56e7e6d629eaad53a67d0946404943275583a5d85d3cf8df7d30c9cefb526243", -"574595beb493bc89726f4ba19931c3c5dd4b501a4cddf505e08a403f74fd44b9", -"5848b7bb75c2c0d4ed864d530dcc7353ca96c2737731c835a7ccdf2d4cdf88cc", -"58c67f1b4d96c08657bdbcb64f83d160127410fe88fd4689c90933fd3cd32b5a", -"58f0cc940ce668aaa67a42d067a72bc86e8ed3786e3c02c6603b18b817ef6333", -"59155574b65f7f65ea1fe1da623605d630ca25718637ea450d43f406eee961d5", -"594c3b1b23f80b6d36080579aa87802219f1d8cb99ded9d30562a69b65987196", -"5986e9209c7b2bc866a4bf0501d5cf151dc02025285ea8948fd827d59aca7ea6", -"598aac86b8c43996b4d52c9692a1efd76434b3dd06c48bfee1a3cdac1a793c7c", -"59ec9e01ca0406df4d5fc051c86a3a98cdeac3f37b9fc41dccda40181dd17bf4", -"59fc4efb4dd38196bf2c4d2acfc2d3ecf93ffe517bab66f87457cf2c235f83a0", -"5a6a0dcd93a0fc5d33492eb29c4fb99d41da6703dd01d55b1e388892d88caae9", -"5a6a4bd63a1746dee6c9642a39d32234dd0aa77482bc99addaaadb619bde481c", -"5b7f2adbb0206f573506799de281517d5a6e98f54c6c7f6dd16ca3aa2c4834e7", -"5c20eace178b069b5268d34db73638f5284f1a2590fb5788b4605aa53e6160a6", -"5c97a19e3c961e41c1f91efdef9e4ba5c9a438a727cd52cc3980e0fd08daf30c", -"5d0c8759acac45d455ef377c33835b25f7d119cc45bbb09a881d92065cf037a9", -"5d36807e1ba3e002f4157abc58617a3823df455a1afa68a6ed7a3e76e664c30c", -"5d4cde1601df7be6387da3abd1b4ffe273546008eaf980fbeacff4070759415a", -"5d7243f93ebc262982e627db5290a85b064896bd895aa9b89a66289824cfbcd5", -"5df6f48ebe8e04b26f1876140d83ffce865863b96a25409027408157f9cdf56c", -"5ef2d9aea3429d074c405c7a453aada7d245535e7ce23c493a3757a65fb144e2", -"5f792208b94fdcb1c6f3069ddc3deaf9e87d2142ccb0b4be312d33791f02b363", -"602f5b9cc40f822e33f0eb618ea058713d5355aaf32c2cdb077d84872f044a27", -"6074c6cd27db8aa77bdb726aa1ad515c3095f91aa842598282412c2568bd550c", -"60a40518911a7944460de1d0a50afaefc26f838a723568dbeae8677194dbf92e", -"60b186745b934b508cb91998cdb685956a37984e585e11c98a52c1a6ec462ee0", -"61419905bf433295099cc5bdfabeeec6bb73baa50d60b16ae7ef24265d519ced", -"6152fc2088b9682e71836ce597d883ae65d2aa9fbb74c1c71e27974d32be8f4d", -"6258f1ca6d50cbeaacb647b6712f25e8176c9ec7adc4d839499bc00466d92788", -"6312adaa3b8f57f6c2638cba9fb5f0f7a6882f4bdc9da8ea839d38ce186aba2e", -"634a1cbd2a462e44a969b24e0d6057e3da732add991f300ecc48b1998cf9027d", -"635df27912914ab17f57f0f45984181eac6702e7a1a8b042c8bf706c4349c2b8", -"63ec0f9533037693161235df2ee500f5e6114be8180dbfe983c2d5f1d69e4a7e", -"65806b058a3a233be934f70caa7a4db3a9237b6bfdc6978cbe199a2ffc58e18c", -"65e0c595de9ce22dfe88806e2bd264b47fcdfc80c1d615beabad9d1e0abe2255", -"65fe4c41234a38abd98c743bb7038f07fa7121346087ec9d2c0aca9d7f70485e", -"6615dc1227fdba5b31d23ad9794981e935ee1365a3d4cee7dfb95a07e2634fde", -"665f530b2dd27eb214317e755aaef82f00ae752f6e3edcdf1b292ca81572a86f", -"66f762d39c6e0343cc17a8eb2f74a0983b809f7831a9c338360c570e4e083bf1", -"67003ac1d40dda58a254e61cbfe29336ed45c241284e1550eb18fba2085b8cfc", -"67073776f3e6225f2fe75d7c5f97b266fe3daa120c3de02bb79b1de2d06b9ab9", -"675312a324637a99e591d13f8fd4e63d1d732e9aece4cf3dd548d46f6eef738f", -"676101560b4e33eebfdea9d949412571b9857ee033635adcf7bde60406420625", -"679221a1d7461baed18eb82dd9dd0c24289b9b5633b94a0fe96cdab068db451d", -"681ddabf06ce27b56b7f31e0da00e9fa963365ed094125166ac942a126048a83", -"6897766bbf89cfa79180e7dc648dd8fbad31f1975104741daa292ac37380a560", -"6898e0cac3e181c2cd60a610de790d0b8628005f4aab5ae4206cb5cf5a9d02c1", -"696535905e9e1b9d7d8feaed59e4e669a81293cb0c871933790527a16f974fde", -"6a389805eb874698b0bd86f9c61df2d1ff537c87711e8932d94e9781438cda86", -"6a43a3b88a4863311f1c18a1e416411a46eaa40a5dd6d27e6f985c52c8738b56", -"6a4d5694df3b834d29987093ee6cab05af1fc367f074614a3fc49d4b2a8ac49d", -"6a73d14a0701a760b20fabc3f45f054109c3f171c3aa0a42259108b57605d37c", -"6b89b3aef34fae1db8aca96fa50a1a7da07663cd49e91c1f05e4fc9d02637de3", -"6bb9681c746797fb3b9f3150f0a5ca1a277861a38cfa3114378f0fd45613bd6a", -"6be095e513faa67ac2fa0a55407a46f59b87a13bfc62f1f6274718d745e43031", -"6bf05da357b0acfc9559629edc7c3d86bde021301e7f5cb01ad99199fbf9a9e1", -"6c113531f6121a114dd9c4ccdaf1ac78e5102029100218829321162674b0ad8b", -"6d8ff6492d08c7930ed8e52f656812edbc3a4b57909ab6285af7f19e323e7956", -"6dea9a2e3662f0e22f4b906f9261b9edca66585f22235cebe1a0e8b00e024abc", -"6e2d5adb7b85cccab827414ed111ca7d4f9e4c59a02181bc6dbcf95042ed57ba", -"6e5a73e056ce319d0b84010d072edbb01ccb72e8dfce15c9cdc1e0a9c678c8d4", -"6e8b450f4434b05aafb6cf53bee937897707b8878b1fddaebf9d7fcf4399f83f", -"6e8b5386cf14ff1387e4843fe5fd049872ecdb8b6586575f25921535de63670e", -"6e93f13c541a0be612884e550145a09f72c618478ad01def905fd34acadebbd5", -"6ea13a13ca4aab6dd49dd0f12822ea0aba7bbb47334c464ea5494c28c6c88370", -"6f3d69277e39f7f4392f7015c9d3eae6d905061d5356dc20a473c77a72abcd8b", -"6f6bccf50229982a2bccc8903927b5d2bc960dbe8044b224cb9b1cd03e922b38", -"6fa3a32e70242da9f18fb4cb874c35fbc7c5eb527c245651a3f7074454e4815c", -"703ddfbbb6c464b7f5718e8aadb800430a720d67f18bd7c7262ec9e692025ec5", -"7058c92f50ca3d4ff03f81014450b77b7bca11c00b65a09a84c940b2c4da363c", -"708715ba463cf2e0824f5e5c204fe29143dd5c6ce8e246d765178190aa3e9c5e", -"70aac25fbb04170b0c853e2010a683e255a89713c6450e4bd5ea3f6715aa6131", -"7219fa6e5d01fb8a8193341d0f5274e0d9835263f69180125138e12ee945d58e", -"7225fa07f1acf861b2928060f63f757b04f7d525474e9e49ce7e3ab70a715e70", -"728957480847a0f2226ae210957a833174819005a6def020c6b284bf708988d3", -"729b061e0749c52102cc4654539d865b7de77c0600b67c9b26a1bc67a157e4d0", -"72a4436566a08b41fb272f486409961496a3967ccea554759691032dda0cb639", -"72ab445beb477f16a3e364ebf318e072a05119f1171875fa1c6ca0c72dad8792", -"7340f2e48c9566b5bbe21d019f8c89d45f3e868efe8aad9a34b3c8aba2495c15", -"7405399346d6d301704a03ec37fef4e3fd70b5011f7ec767046e504e67b981a6", -"740a8638fb4f54a0898041bb3aa1b4e479428db8c524f4cb8b6513137d52efdf", -"741e7c539b542bd4bdc5489b150d238a683aa55726c5ef8770805121763f1e0b", -"742e5486aaee55c085d58786a7766f811e5638eab8d09bd936156ffdd02d5d46", -"743d899743c6eff5afcf30145694b3ce8f5f30e9e4dfcc29e49da407e93a2537", -"7454fb35f15239ff0076217cd4eda49bdc05f71978d284883d9e47b35bfb1261", -"74589fcec630662347c382f43a81c7b547eb542703f8c50d60aadd6cee8e4816", -"747f2d88f1dccd6e5bcb136004ec327a811986946ea58f0b188ad2a80af7a0b5", -"7506d8d9d20775dbdcb8dc26e4faf9f2997f8e73c1f20c4cb6a0b9346827b336", -"75cb420f6d0f16a357c23798ba4cbab5b40bf72eb6c5e40d29d263a2c4c8c466", -"761b7761473df6d07ba455267dc9a6efea8321527fcfb459529c7c5e33bc8a4a", -"76327346e3741359a0df51c2df10103416faa53fef8f02858c9fec01cd52c214", -"771b9f4e19b05683a5d7508776178094d1165c632a93d03860a44c00a51b5eb7", -"7766a8179fccb69bd0caf975c5f7ec2f72ba0040e89186bbf0f3ba69852cdd29", -"77881656a0a89d985b19e00f345cd924b4df021693ae1b56265a9b541299cf12", -"7790d8c118a812da34707d98926bc65b8372708ec4141a467c46eb33ada37701", -"7793ee3ccd1f18463be869a1b367bf28eedfabf670b4e9a9fe05c280d64844db", -"779e3193eb795967fc70bb19a88dbe76c026d350887176eef48f48f0162924d7", -"7914f19448af9e56c2ef16257b1bc424342086f8a08eba39040aba9575d906fd", -"79b33fbedb764375cc8f05a6c34ac1e7f013fdec417a54aae828112f919a20ec", -"79bedfd9d39125c45904e1ad0b43110886c6b7cce6296d9335e6bb92fe58dc4d", -"79f46d6465397d7d496c194d93d16b52bb777bc50743f367e5fc729ee922dbd1", -"7a6350960aa4d6936edf2d4ddb45f01a5bc1a23bcca72670ec2205471789c810", -"7ab8f8182d43c43b6813600cee1838d4c9ce65d8a4da841397781362ef0cb728", -"7bea041b46a72b405ac3ef5f5eac137e169cb813d9aeb9b277483640ee872294", -"7bf3bb12c1828809f237d0de8b97b6719f8137f10079758f8d9a1b32de90f1b3", -"7ce7d496dba75a34f72fbd1372adb8e33e207b2e1daf17ce1e41b9ef2d0786b5", -"7d1f1e63a9792b26ba62ad7ad27177e54441c5980ca194f988f7e93d76942b21", -"7d494fb086b1da8bfc47b76fbe13c53f0bf89a90eaa0b4190125dfe8c7737ad3", -"7d7a19d707c59ec2fb43860a60adffc9c711bd89b685677fd4c4509877b76024", -"7d91bf06bb71d4d4c9059af32b979bac68c58830f4291d0f1fedd5bee8d868be", -"7d963c75f3b7c13eb999f1e3dc25ac6e65c683b3bfb9b4e4fc5a8dab8da232c2", -"7da4d7f478c29db68fe28d9f9be7c21a34b96240804911c668e4307b3a4f5e7f", -"7db45ec092d1e5fee7b95f7659f9bd9aceb7ba3287ece8950c1a650abe3a4526", -"7dc63b0e876295e920e9bfd12504b9f7c4b85f1724285d8ac441e3ac642ed7c3", -"7dfd0b3aa6533d91674dd7f44cdabfddf0a5ff7c232495443eea7a2586f4e87c", -"7dff6d716e664b88a7996a7858e246542722f748a6ebe98fc8193af0c876d817", -"7e02137ce984537710aeb12680203628ff0c0bca644d8ab876183c91c3590dd5", -"7e29da8c0c9b569d52090a8a4e05578e841da444f1de80958537b8b0c57ef0f6", -"7e35b9676f6e143929d1d0a7401492ca6b735759298e86842ec937d6a4f9ed00", -"7e9fca684c167611fa73c96ecd90f3d034c289223ffe436a8bb1712b8487739b", -"7f5090a09888f69ebf4f349e52a81c9db5bf3d3480aeea5e3638f27b50c428f9", -"7faa66c9a74e6ecba1d217316348dd26f77a3955ad2b470e90d1f1ad5d252763", -"801477fbb380aae6f1fd021fd63fb5d22d021d745997cea163497a6dbd82712f", -"806dc47f0ee4c87e1494c13c98a9c00d7f781f3f7d8046ebaff8ae1507236270", -"812db712d834f2a859870437215330401ba050b796996bf25b708ac712f4d9e4", -"813e56e269ce416236e351ab98ae5a8da2c2bc24df632529960eb56f4a5f5d8a", -"815c385909692679bf70524f2cfa7b2a29bb600f8641ce450bef34c2850368d1", -"817f28d5c20042dc761f8079bdb0315a3d77805548de1d619117149dbe887890", -"82357c1f55d2b2622848c30661bda420a1ec4b01c20f96b935c3e4c70442ea03", -"82429b61e99c73fd518b4f6e84cb722a1e5b730acbf92449b5e42420b8795670", -"82779c5415b3ae646e588d990d7976c09b8aff1bf2f7468e93c787dceddf508a", -"82b76958ee4cd9de1227e710dd823da40674d081400f79cc827e82b0095f8ae3", -"82d9e277089773ba75b31db62b10233e3f418c383625a1be835a9e6f2ca0c5d3", -"8305ce6302ee2266292eb1165afacc7b79514f222e1b7898853a0ebccda5d70e", -"833eb9d97bfd71f730b6d699e348dfce9cce39051d67006f016b0ea9010b1b19", -"8351cb9acaea335a365bbc13d975a410c9ab77ae5d6a6605ac46ad74a048e71d", -"845707a7e12d0b72a7be59a1bc65ec0a359ab65cb30bdf1b12724b41be36d30a", -"847fa24a6c46c117b89180d579157b4707806c0f7236b4546843df3b86ab531b", -"85025f89bb4adc7b1af3500780d4a96fecbdf7ec92748beb7081c1524e611d23", -"854cccce38d91927b5ecdf7a698032048873a202f83e2e2d07183b7357918cb5", -"8550a81b4a24e1ade6c00311ac2346e71ae1a9dcf61265f21864e1faf03c1df1", -"85583915baf4fd22bd6b29385d754d6a9850969c5fff6cd788ca61ce719a495b", -"8576310a71ea0e72b0033d198a692a778a3c0ed7b6abfffd54e6c76a7785d3f5", -"85bf013948212ffae055cf280c54c511798f13b62bf94db0a3c5aaf83bb0da93", -"85d5d7d63b97c0e27b473c28287600ad07f7c8107369c7a3e32430f5c011bcf9", -"8642ccdd7b07b8e3adab6b49aed4562c6d04bdad63ec47714eefa1d1d65456d0", -"8666a378b1164d068a8d325d9c11692f9a6a79ae7e2ef2f72521e6965f5fd14c", -"86aedcb0dafc2f7fe88c498b49d1ad48eb0366c43d2edb2603ea8ba6d2896cd8", -"86b019b257f8cccef914b22857ef373b175a4e75852ab7336d112cb234b07409", -"8740932f7c611b1a6a64894370c8df37604c8755781a269542b16b1ac4794f2b", -"882a62089c81afbf5ce58a0112744b8814a5aa8be328c158a6d9bf5d0e676b38", -"895d89b8a94921fb1475ff7986a3d0c4def81a01adc505d5cede7990ad497180", -"8a67c36720d61d9acf46798b1a50658cc1807deb1adf5f9c035582c2250986a4", -"8ab2e117de4268dd6351b6f30b25eee184211018e85c362de95ac6d99261eec4", -"8ba968865d5fe5c745b70a739084c95ed44412f19c305f0476060cf1d2e5d3f5", -"8c18ad65dd3f05e26e26d5bfe816c2ff3941f5af269771401947d1d07144953f", -"8c2678c037fc9435cd3b46b47423c814360dcd3f3ba5d4e8383311132911fc13", -"8c2f7105e141e012d2d776d14d01429db6ec0465494527397a65cafbc7e90647", -"8c4160ba8a7be774eabf6001fe9fd225259e37699978666b963e392e64b335e9", -"8c7b33dcd60c9cdf01a942b78bd019d84262d8f4f7168e6348c2d8f82e57e82a", -"8c938d3a1d658bae7131f2da052c83e82ac0e4ad68f33eea14d79e382cdc0b7b", -"8cf837a1f020b9d1d82035726b7cbbc1924065f969771d7f15d0330d5628ea5f", -"8d12ff2d891621e8ec8b40b30133535d33f2f7c772367b6cf6f3a7ca99585c2f", -"8d1ffba86bfd3e2a0edb6b4e9a04c6fb23bc2912588c1f8f501992e5e94d4256", -"8d3adbe56f63ef4d0abc87235f5f07da9c84cc7b6c07dca1134de3ea0eeb464e", -"8d80d27d779a08bad79445995b40cdfc967f6f4cd1a81ce57b8355dd1273493f", -"8d8dc1d563c585f623f9fec12475a6f7aa060bc473e2cd32185c655850d80abf", -"8da0a770826004c4a37a0d74dc8d294e189bceb4dbcdca52d0011331240986d4", -"8da8c66d56a861c6bb52d6e12d2488e4118b93bfca4b60671fd92c12ed3a34c4", -"8dd466842944c2e88ab2eda955695cc6fb7afba3c0c45539aec63255465ef0f7", -"8eb75a8b97ebe66be4c2bb5f5fb526beae9aad85fd4fca6515681763f09d8645", -"8ec82cb5286c7d4536909e1f79afbefc203b4b64a77dc1fb2b9549c43c5af7a9", -"90d611eee19c011390205e9130276fc88164f369aaa57e2dbd1a1c540fc655b5", -"912c97d13bea7423aed6137729e399d3da81889c4ebfa8af6a3689f10517288e", -"9172db355c6a0bfff9d64be62c508e7b7a7a29d1b97e9c223f29e78e50f214bc", -"91ac43125d842ff86c848f1f4e4e3814ec8d1d5a66af5469a6fcc54e80302afe", -"91e9f3514429ea59f417cc0c18de1fb7e8a6c0b42d8a20b19b67d0cd922f2fc9", -"9213a8663230599d67b698c815b805c4ed2afded7e32f3298389112496fe22b6", -"9333f7d5e5f20c8a5e190f5c2d47b8c068b57403471614ea6abdb4cad987736e", -"937a72e54843d3420544a0a1e685c105a72b363fbe50bd441b01bfd2a0596c22", -"93b483d7f8e15f43117ed1148c8c07a05c73a7d5a1d7962dae66458dda8052fb", -"93b7a10ad87b0e0fbaf074318f6bf26bf1a0dcbe851b042ec8c310f13bb2bb27", -"94de72f54c1f35683f9a5953ef50d35241bda08eaf4226374dea7861fe394377", -"950bb380139f2970fef060a4b7cb8cab47ac6e894c17db4847214176d71a8309", -"952e76b8bfbf1bd710fcc776958b35458ebbabcb79d7325709f7ad2c4a8c0474", -"9558f303fda9abbc350eb7bb2e21b080881da5e7f45827a9b4277ca1b3d40ac3", -"956c347527141bdb666781019c595e8550f83a8066c1405aa77bbae43ebfa0a9", -"959e3b906efd636d95871bc29f6a24e9ff529a1afdf061910b719c7c3238a63f", -"95bfc307a4cadd5b53237c38ab89732ecba367fc4047f0b28f3142ee7346d893", -"9628ff7531f4b3a6e438aee7f8150cf2df4ca28d0b9021ba701b8d5f2810c0c1", -"974a90358b73e571aeb70bb116e0312c01c2f25e9d4d8ef44ee5aeafc7f8752e", -"97a7b33f98ee755c106c3d74d7bb43d2e0efabd4c8e43e308675649fd160af1d", -"9812897cb1b3a2f9e5456515cfe1da92d65132b09b77a23d32572fee46666e1f", -"981ceabdf18a036f1b31476db256c35e777c530438dac4eb599857e01bad96f3", -"98a5579e0aafb542718d6f10bd045621cbd3e36e86b4c49db0f16358085a6554", -"9953a1bb578cd7cd0080f5ed72baea76501e3e5bf28d01a5f21fc4ea0e59383e", -"998f1941190afcece028c77541b1d1dadf68a9ecaf1b433e8b038356e09d545f", -"99fb87970b354fac1b3faeeadea2d486727b3eaaaed5085f285d6388b74b550b", -"9aaaf49fb60b08bf0b11adb8fba64d46f300a9552e773d09902d65b2346b4d8b", -"9c15b3d83e171d359141375d1c706ee88ca6e649ba5c52e7f5a32a44ce4e7c59", -"9d5731654cf81fbf4de388c078a706891c672a5f42875d416cff6fbc3fb2c0af", -"9db13d4aae4424db994f9e4571d40af396314ac057b4533f7e28f2697f90f60d", -"9e9421d6bb3e5779cc0e2bfeeb7d277026bda087fef458478226865a466e9f5b", -"9ebf590272e80ddac92c929b0c68639863a5c870f02a21ca4e146c5dd825e4b2", -"9f46111ebf5349117903dcc055773dc8d2a3ca746dd1b6f737ce3d18853b00a1", -"a0207f0aab71c10809cc3334e7fad09fb1b184e94e41b71ac2fdd58bc1f33e2f", -"a0ee59d3cdfcf9df11ae2ab11222827ba54d8bdfca4556e2ddef86b6ebf9bc5b", -"a12ee161a767e55b1e7e1a0c341ccacc6807a336b56c752e68c53e476427bef5", -"a1d341eb7ef5ce3ba356ff0894a981fbb54297aca5b6041adc239e9d584d32f2", -"a1e0149a2896d6c374351853f75765f1497d1cfa589f22399d189d30b85873f7", -"a2369b8d3cc1bac5e71845b21d86cf263faa92a76b1578f61d19dc9961cca224", -"a2aa0f2fe085630ec0ef538641d87f54aafe4e15c806af233ddba19a28c82a60", -"a2cd435677b0a4f04805b2bcc74b17f23c339f04a4087425c1ef08fa16638a1e", -"a2f2baa665e9e93af3b0aff4b9e5875cbfe628044d6013445569bef4666f7150", -"a39bc41a07e47ca93e4c7744841af7c978ac3c00c7a8dbfdc4d0a635b29118ce", -"a3b0aacbd06446c64d71572d8913ad8882a6e7949226f71ed331abb4536309cb", -"a3c7f5ff3b31ed2f071f2c76dac1518d59b893a34154a38bdd798ac836646251", -"a40ea43b055a0c07b3e524f3491afb24f408cfd7c2b1ddbb913c6a76574ff0d1", -"a47e62e4910f3842c004d2aaa5d842fe77dcee04c225e7e7e03a4a6a99326efb", -"a4d662d25f921f0cad3c5c8fe6bd07af3493dad59e94db8e1d2b5a6e6a72242d", -"a57cb6d059beb17e15f13e0d318a9d3b06b60ae8651ba389311fbe2ce8327f58", -"a6268893016711ef88f25f4540f3f529cf7a3b56f1c0b862dc569147d54a6885", -"a6a073ab01defd1a1263add0e8e74a726560828a3efc55ae63ebc2b2bfa96cbe", -"a6b136a0d4ddcca72c0c36e2c33463320be85d45bd029345390462079ce8d06a", -"a7d4d13dfc879383b471f4594907fbc37cc7ca2fd84a7cc7c192627fb60d6ce8", -"a8440171ab018bc8cbbe33fbae4bbce86641137ee747c64c48b8df22928f33d3", -"a8c1a26ddb3caeef57146e17cee325f8113aea94e0f71df48a8d84e07f59c9ad", -"a8f40ef2d66582a95bf1ebea2c3ae0f94f4fb7c4dc6a327905df5a50dc1a048a", -"a9c4acc6d55182353d0a5183a646f63d997d747257cd1d84a7cad903f5c0ad24", -"aa11f48e1202e7bd58d0b966f8d9ac210f6c392cb88c3384409eae5bbeec335c", -"aa6503c37b548c8d1c267923e15ad8ae8a9355fafc75ec0df64d0017661b95e4", -"aace9b30c5c3a109a5cd2f3175225d36b1c669326c1b7b45f50565e84bc12a10", -"ab02e6676f649e898716c33a25d4ff41a2e5a1a40f179cc4aacb33577467c1da", -"abb429a5e938e08f1baf136b951072ea1ceed8009e900c74fc68281eb1035df1", -"abe7af27fdf442f39b5bacbbafe746444f915bc0fed63383b56645ca0b09a3fb", -"ac9e883806ff9b8d81b099162488120a5eb1ecd0e67842a621ec80c2559562cd", -"acc3eb4dc225169a38b2adfda95fe88493a8a6c703899a342ba8477e303a82f5", -"acf61bc2bd263e51909eeefb6aab2436d77fcc538bb67f91152886dcf1b30efa", -"ae3e67bf2ffd63bd789cf63b56770c54de1e4dedc067a22b9cc27928b8368eb6", -"aeb2a4c400d2e8632ceca2a14ddc5f88dfc9ce87eff25d72d7ec586c6ab11fd7", -"af3032f6b7c3d57bd743d9fe8475c839fc7d303b9f5e00475dbbffda8f96f2b5", -"b002598b4517ee50d867b9a363267a10c714860e4d1ff91737241af339cc0932", -"b02aa6cbf26e971c7498a779741b3694854195ae5d7efd7e939e937128074690", -"b06ecbc32518a1c58875c0f27b73873f35990f71ea26e391da1451109cceca75", -"b07e9b5685b0df3fc14e4b5aff3e8de3baa6a8e8301a9ee634feb0d2b71eb900", -"b0c6cda501492e5e27959788980d86232bb30cfdc4d66a32cbc737f2fdefc325", -"b1497c0ed6ce5ac86762092d1c297e5c21bc9f7998fdb9f557cc38214902a7eb", -"b17537bd53af132db28aa6cfd90c580d05f855ae703304cf6fdd5f880a982145", -"b19f31eb7afa92cba51aad46d83ac65b9a85863b859527b7903465bd1372dacd", -"b20ef4b33318ec30c99f9e9c04fb4cdeaa2d5d214040332be89cc008432b5cf7", -"b2612b94807d115b5dde40a5e141f3dd2a37668e70a85fe0d7e337a512f53436", -"b2714917337f13edc80694791c23cc2859ed0cb648300506f1916790c5f5c18e", -"b335f8cb071f918e6e69db7ef2a380869ea64ee18e4aea75b61e09d60bdca471", -"b36bc447d30f483cbc401f883793008898f8d21cd0026caa9ef5011ca092e980", -"b387e1b6aebcbe1013dc635b3bb5538b211f05965897ce6a44f4cd452956de54", -"b3885304d53b923dd5dfd8160fb2d96705d346b1fa259527c9a89cd164d69bc5", -"b398d393b60d32498ed4b47e7f5dc9352d6728d3aa2b6f8dddf16efbe9dbf5ca", -"b3bda99fa07b541ef1a6028431a119280204c92aaf748ef44c9eb33494d40e0b", -"b40826ff1790dcb31ca602854d3e74479d033e6ceabbb26f01c18acbf5d14238", -"b422c62611be24b88203d0fedb1d9aaeb048b8310d6dd7418ed44c79a9c9a2d3", -"b4a32f14a5ef694667ecdb96c38ab9b53b05d72c37c8639bad4308ad3c84a485", -"b5075bd276b3c4284ebddb9b35cde17d3392f5bd2cdb3d94c10a39b7daae29a6", -"b5524d0b748f0ce1456e68ee2b2432d3f75941077a491327712a02187eb1ce97", -"b572bd175b76310e97b125bf15347cdc492279005bbec758fd82dd634c47adb3", -"b5b2c6e15e6dbce0d92e6e1c8421f9e2f1b7435201536a1115046f1a5c24ab0d", -"b6139a32ce0ce918faffaccb81eb0af6b7876eb16c45717b2138068d535b94a9", -"b61c5814d897e82027ee54d72916e62cdc9b68e4d8d86e6eca33341a1c07134f", -"b66682319f8ad024cd3b3c95ac8dcd8c867ac42e34183ec62c050bf551f8caf0", -"b688ce77a6a1a05effc123d310d564965380f8e0b2ae83a498f2f1ef925aafea", -"b6c52f67bbe89a9a034def0179791d6aff9302100c6b906c1ca87854c45f7844", -"b769aaae3513a203755fd86a22d08b86f231bd9d6a7ef747c12d080ecf048ec5", -"b76cff990e2d9f9944fd7ffc8a0a14563f9a09b7336e3d6bc5031c4a2e863e0a", -"b7e79a5bbaeca159428eb488309eecf00d31adaa1018302fff2670d8674537c3", -"b85a58e7dbc835b3d730d17ae598cb50c7cc89b63f592d4c006d7f0915e0d4cd", -"b881a44495a3fb0b7b74a1dbeba7a864aaea3be95caaeb9cbbff7e97c95df5a3", -"b8fc45a4def8389cb37729a365e7587691074f379c1c2a27ff3f0c0dd6119461", -"b91b108fd6328800a8c019ae609e4c721f152d3df027b6728ab9ae31126f046d", -"b941eacda36399b92deef7c2e5bf2ecb7a767a10dc75a864c9c790d262884efa", -"b9b775123a94e3d72b2d6e7b03cb630aaeeb557e68502615cb1c4cc2868915c9", -"ba0f2ecfbdc10784a2e7908191a65e5ce71265656c49db0b6688f416783028aa", -"ba2da2413e58d2a4d516c43fb6e4757045f00454e488d64a77dc3de9ab841a13", -"ba3fb6950678dbd56deceb1d223babdc840ab9029e6ae82fbe1b8d8f17661f49", -"bb2e893fc178553b1bc69cb28641d3cb9c8dca4c62f61ca5674899ce7eae434a", -"bdb1eb23f48773ddfc8539f9274e503cf6d254a38eade9f61c3e31e3f29db140", -"be1802fc8945a1a5b8b9ee733950e1363c43b8bf09a221f8d7b0870d5a72e002", -"be3f40bb9d6956124eb960b86b473f97b6d86b40179cc832865e2bafbd2b16d7", -"be8495504f504a16d1f9aacfce97c88188b196fbe0200c9467f21530b715013d", -"bf789f7903f27e97c0d50fd250ad145ef66a4e49bfdf026cb3ae1037937f0b1e", -"bfec5e5f08608628d76b8507d4826838397c3025ac9d83df252e2562611de4f9", -"c04da726f102e44cca0335a4d8545505a858ddb88024ba02c59b65ce9373aff3", -"c0ac1d3c6046d21b0d19f0b938743c6d0611cd198318216ba4127447e8ca4995", -"c0b7b81da30bf715ec43b70fee354b4767ee49fbdc6bb00035f72fb407c53072", -"c0ea3b2416e056d89dc8d4860ad03ee684629e9b951c98b8030b56be0351242a", -"c0f69054fdd368a45dc9df80833ab41b3821ff10261dd3ffc296c5aaa15df7a8", -"c13ef7b0678ed3b4bd541f133d359111a69cd47adb73a3f213eab02171a480a4", -"c144f305a44d0f6149429927ae40992604d5aa6f1cd9a5291b25d2e5caa00e88", -"c2f46d2ab19a37aaa7ff39f9aac18e6d619aff7621b11f2921b44b8b737e2036", -"c40a8cdd03f316cc6360825f4b99c1f744c58f978bcc7c35e12279d3b2062ba2", -"c40d70d00cc546b7fa3b545ca0573899b6e7b3e260354b18276c0f816a1339aa", -"c458699b9b9b5372c3033398343184d3dfeb4c67902a7dfa8e8f399053a7e920", -"c49ec7dd7563e86e51c750ecb1c25e21aaff726724da25d7d1287d7288798e4d", -"c4b83410c0a7a779aa50f80fbe4f85fa9f735b2f41e2d5874f1c994354650e58", -"c538efa7d740b28165ca6d085628dfb6f14cf3b064721be04ba29c3b7be97135", -"c5ef4d5c58fa2fe03a022f20fd910153aaa5e6b22c60eb2f32da274f6007fa56", -"c61d41eaa53d2eb8432616d618835e2a9103fcabed13be28b65d0991b9e91d2f", -"c6a4029e37012eb65a4834094caeb6cd8059e1769234094a512751fe61ff5bd2", -"c6d6f3b087fc21c04443c2718de3a849740d34da6226276fcac7e79e117616c1", -"c6e9fbda0064ffa2d91cea1c0d414b61b79646f9706724959feb6d9b6885db55", -"c79444b73c2be39d31938dc476dd4ead5474600dc50330d2e00cf1aef0f44d47", -"c8956ee9b4b2f22bffb2e1313b978851a2ba40dfdb7d6a900bee53c0063c8093", -"c89d71a6f659a0690de6c7ae81a2fb7d25aef0b10864e7a1c0401cd79172da23", -"c8f06411299302030dc94df149e12f8db5267efa86572067dca592ef0ae72f97", -"c90e1f2f62b4df1ee054e6fa468d904f144f15d923f1a167ac591bf5215376e3", -"ca1effebd6ceec9fd29af3da34c7b519020fa366f5bb209506659d201649b526", -"ca2a75809bbcc7b11b3106d767c0b5c4e61fad3033abfd80b8c7024f1b50760c", -"cb169159b89b98dcbb1c0be75539be137ca39ed69d7f0c0df03f5b27e062da20", -"cb95970cbb382ab5af8b45c194ee0a386e313566cac0d32ac76d11b2fc5a67e6", -"cbffa46d6d8eff49613e586ed9cefd6d50dca7c632e489fe9a5db5e19c6f8646", -"cd17e0713701812f08ac92c3b43f6cb3ebdb81f07ba1524e81ea668f255f84f5", -"ce2153385a3abd393e48ef7aa9a487ea097af13b6b6f778c198b723bc0f51fae", -"cf17e3c4c9f4985f29abf2bf19222d0531ddafa0ebe18b74d05a89d9028d2eaf", -"cfa473fec3999e51337fed325c6da1df7f027a9f97b1de049fd2c196e97ae755", -"d0f17caa9b401929f9333073e5ab4421e9cd0e39b5946d3894a533fe66256eed", -"d10fcb346876bd804d44f22a3cfd5ebc7ded0ba4f5f0c3d0d50de92c1429b516", -"d1a357079b7ff24706600fdd45eb12f1d6704bcd4281f09de4a9ab41adf3d419", -"d2c006d6ca537749c985e04b830ce17d47fd42e7a2ab1a6123c03d3db2838ea0", -"d2ff7fdbc1cab96ae8a4ade63179a29faef0825ab296615fc353704263281146", -"d332bc97043c94f72604b31cf4509f306cb2f3a6822c68db7985d63e9ae1587a", -"d367a15459b7c4280a9392beb3b3670ebcee1a296e5ef1e14d4acb83af98fff9", -"d37c4b5f657fe98c2e40d22d049163a379ba3697fb6c1e9b27fcd8c2944a5d22", -"d413fe20342df3c8621929fabe4f50fe885b13e719dcb1f12eba54b56fd6ecfb", -"d438996281c527e53bd2ff73faa25462f0191a2bc9fdf3c0e7d4bb5a458da050", -"d4f530b0ad515731c628ecf70aa12919b861de2244607811f9e74902e5891b4b", -"d52cfa54686e2fae7db1c391b754f52e12c2e7eff3b90cf9aed210e188d98a86", -"d5405d840b7d738be0e401d42b9c2d6c6e5a36a7a05357178036c0a3500d7c47", -"d6138be7bd511588f2f3cdeaf37c1fb26f1aa051930170834c37adc8c72204fe", -"d614cecff549b32d73f5fa72139c575f852629cb7c53835d6da831736145b170", -"d6d52bb3c8965a95b8520b5921dfac30a312d8db4c35e7deac679de073549970", -"d6dadd094d818d1aa19078dc418f3c11ac97b36bd857f761d39ffca55c59a98e", -"d73d18497cc888713655ee65b3525a502b9758196b0d6d3f81509f1c78f3d347", -"d78c0329d621cb71cc6a30d3e56bc98a4205c1741fcacc450c264acce9fefee9", -"d8f865a34c5d20d0441ca56df7744bc2f3f86412787f4210c5fe24f36cb22a97", -"d9441a7825585aa7ce4a1db1f52eb0b2e8e06afc53d76c07c5d34c19ff7b3eef", -"d9970b9029331ec5b646bb2c00ab8bf025218b14df46742f1db7184d9a7f639c", -"d9c6622cb19d520d7ed30682c65b82afe1afb02af408159255aa9b28aa003f2b", -"da702f1071941958f446f887e753298b9d5600631abfaa2914ef789fdc0c6b6d", -"da90c6cbf2137cdeb222504b5aab13f5745764e56a2a9dca5bf6335d0ba27653", -"dab55adca8d2e7979a221886216a060389a8c28eb17a4699e924f5175c5a2e8c", -"dafed9f1c7c62859810717b8c39e45c6d38d06f82d526e56eb5686fb461a7420", -"dbe966f0bf291d2f852ebce75b722282f2e78b45be2d4a7ef2475626cd1d5e29", -"dbf0ac3bf82be34f2ab3261eff345c8160f5ba263e5df596f4165ff3f05a476b", -"dbf4defb38fb50f3673df83415855b125656f98ce0b4cbd9ff945eab84544617", -"dc549ae979919af281eaa66e0b77589a54c868640665ca1a7f8e7d6d8b2777d6", -"dc5ae132157f07517d9bbf436f85c7d06d383e67974a0e931126ea6ae6b0604b", -"ddf8fe65ff1bb1471dcf50d9c9582f4d2e45172ac403f795f94c93603d076dfc", -"de17982b2b795a5a76635598fef165bad28b6eddefa953c5eab7c2c58099fb79", -"dec3fd28760fb4371259c11bd6a3c8da74209ed879fcfea85f3c5bbfd90db0c0", -"deeb6289c34666860513c7f766cfd16160e4aee511f7fcfbee44c2e56478517b", -"df3f12c0246146c55fc971b81b34d033ec768f1d1e7e82750cdf8bba7431f246", -"df9059d9f7f24219805a11ea50b73433d8a6ce7cf4af31fdc2d9ad7ab10db80f", -"e09e77de453a208767d35955ef273072743c332d4eadc7a444a31d95d334af29", -"e0cb2e68da5c2a22d1f611050460d27bdf120fcfcfe0b6d0a501ee7d5a599782", -"e0fd6a49a89689b5b7a9ffbb0c024e2e549e827caed6df896b1743cba7931bd1", -"e1571f2032c913fe8d466a05f81141c8a78e63b2c4955f607ff84bb8f3276c8a", -"e1d0595e5c8f2aa948daac642306023db0c34233fb4693f59d87f91f83765ed8", -"e32b41c1f421339238bd8518972651f4b860eaf9d613bde723041ab877c4fbf2", -"e33321c913f6af442dedc4c8f6ccb44286bb4fc1bf3a9ed3e36c3c6fc71ea5bb", -"e342c5f98ddc557fb938d46ac99579e5c927ed2929db4ecc0b7aecf9cc8f1931", -"e350819b29bdbb2a4218fe99b12bcac5ae9afe2504c3586e21627eb497621e1d", -"e37c436163b831cac6284eb3e6cb9848946e756bb639705279f72dc84e4c4ff3", -"e39edf70ec8f6d81b566a6907df63bf8b7ca85e453d71273d3a34f75e717f9e3", -"e3d61a55c9dfc335ca2be1ecc0bac39ffcf17c621b5805505128bcfb44407623", -"e3fb67b8d5d0844433f2306901a26196669e047160cc96d4641e87fadea0c408", -"e47dc8fbf8286a8d1b85769c05d3434950ff59e12c05cf5fe89144513fec2e98", -"e48ed7b1f444c282edce46e373d2c670415d18d798cee113739b094863c9dc56", -"e4c91ad52da7d4b7f582e8772aadbd311499f70098af0ab194fa6053829e7f03", -"e57dbec2d57d240f74308e8b5f59a6301efd74ae081a6a8eaefd0d3bd29a4190", -"e5bf7ba6b543615982d70d8fc785c9c1639220c1de284ab1de43a34f1de3fdc2", -"e5c80a3cf4e56ce81db7c5fa776925d26e8d5a841416d7ed919cfb24c407b158", -"e60d8df101933e7802a456df4eeb45b98f8d7db511dd9975cf6704bb2f30339c", -"e64ba5e7b479b3ad54b7b9333e5053cdd43930ec5adcc8ea37dfc4f42612dc72", -"e6955a326839da77307fe806b976975c9e2c4c93d237f9667abe9b69ce74cabe", -"e695bc41eb0ffa1c2dadb390e5294522bb5d0e42802fb7b47957b0f5aa9789f2", -"e6a132751e0e55e969a5ceab62483fcb85d06380a37e912e4c5953a476ddec40", -"e6abf1b643cb676f6bb587cab4dc04e607c3fb0d4c142758b90946fff137ee7a", -"e6bcbc7f692c3f9c847af822735461d83007f9a09956dc2f71b2af98e1d1d380", -"e7088919ca800eb174780758a6e656712af61bd7b9e4aa39fc276d9696dfcf85", -"e7137a074ac85291ac4ec39bb06103521225fa05d3c2269b4967afd6b81680c1", -"e7f192929ead8728d678cdf4692106b3427812b23a54e0fa8159d4942f08516f", -"e81b838b47cccd2a490884e7d79d2cc2a10cb6be50b90f11dad729a408af107c", -"e8f1bb9ae9d51ee27c1a437ec70e07d1e5d4b85e1b0702f0f1defc2a03b9a815", -"e908a268e0134959707d8d15582b97f9faa86f80c3448972db640665c5f58831", -"e98e80fa5977235c6895b411b6518ab1d084d09a097efa97a72c070bc242d85d", -"e9a9f260d31636451f7c188851bb54c9e7208b413b927a623296791e13dcf8ee", -"ea2882ddc2f7824741671b9b8e703f0011a64137652cdacca940ffe538585755", -"eb16d0c1567c34dc4217e2916bec37c934bf9c7c71f1768960990a563fc273e1", -"eb5a783ff603ae878af092e4b66e0bc22ee10f2768daafa5e4c0a1cfaa0eb547", -"eb96d352e986039713b0ab96c050193006909b1fc96ed10d0828ec84124df621", -"ebb656612ebd8f15df6682db342d57f02409ec9395edc5a39fe01f3c330552e6", -"ec692aab6dff6825a05baf7c90737dc2b66d1b1ce13c25d61258f3702fcc9403", -"ed77a1a1da00c4dfe100a8c656ff1d8336d5982b11a8a0c8236ebc0272fa631d", -"edcff1388f91fd80a2b62ec31cb0492960ffb62206dd9e01d8690dd24ca7cf7b", -"ee194bbbdf6b9ae5405d1e2565427a50c93b2fe7b9ac5c525fa6f2cde67c7e51", -"ee1e01ec7a5e9893fcf8470aea62c03943c795d3b271a7d1f764a255648b4b7b", -"ee717e1a1ce1162ca1bf48a49874ac3a07825c0a131a928d5f647fa80ea19177", -"eea120c9a37cae64352df0b7a0223d8ed1a96561c8c1c6558e5dfe1242969c3b", -"eeb8a491df8df8d1369af7f56e84301abd465a30284b4c9d9b3742faaa21f2a7", -"eed3f14a42ad30a4895ac71dfb66f4152bfea5f6eee2a50097aa28320400915b", -"eef086f911b7483149da38088c50a19208409156074d37f787b86d3f2e1b00da", -"eefd25a321c6c29532a0971af7e28c949c0afdbc2bd005311db2bcb8b7c2c7bf", -"ef1affc22033b8c329eea7de39ae99a4c206ce7cb13a0ae18287d027daf8443d", -"efa335271b61f6468fdeba3e8f84a9909b5d10eed195172368045e05548979c0", -"efd61d23aaa7ccc95a8413373e2c93465a77dd934207fd093e876f9cbbf6527b", -"f02249c03a3d62665d33c54336f647b643fd4e86869dcfd957ea498b5a3bab1f", -"f10193b34fa878cb3828e7df1d56537afc19d20f7c3749b8ef2a3da02335da0d", -"f15cd0e24e9956c7e19f4327b1e162aa41c83442df251382adb7b14403bdbac6", -"f17b282c97be3d57cc033235cb2c36ed993b3a2983561c8790478a146a8d79d2", -"f1cba5c8848c8024f4bcb86f09a6d698349a01a9eb7ccc146ee395e3c34140dd", -"f20d92b13b27733d411c2676486ef7281a72da05f8b29c8c06ff2877eb14c35e", -"f2bd54d61f8b12a7f2305f0df2125c659c71f6b0eecb65911db05a6f4f91a50f", -"f2ca83b3ca7f974607cb5285699b42002bbda937a03bc7d8b76227f5fc0dfb75", -"f2d3624cc81db6dd6a6529f801739066e24ba332e3a85d5af0769f3598338eb6", -"f2f519e3c719d330ddbfba05fdc5368cda0ac65536fc34555cd9615e0c4624db", -"f31fddc0966b0561b2aa5d6436732457252eff51dda4022d83713c4a597b67a6", -"f35daff8db8ff3e286a5b4704c7c24c954dc11ec177aec756c613c3461f51ac2", -"f39428f690c49d3c4dd5f428f710b3608d7e75be2ab316c091c80ed31aad2a5a", -"f3d84962adcbd6a03ac169a004a0aee70e6e49d967ce10c934c693c1babd5e37", -"f45b82f84bb1b477447cc9128cc7a51797f28441a89dfdcbb17df6dd6a0da492", -"f45ef3feae28bb0ff5600cca630ab000acad15e8296d97e4cbfd425b4bce1387", -"f503813b48f51d5712d6bb64828a3e14877b9d5f40b7722df4c2ceac1ef5f9c5", -"f632dd3b7a4e36306ae504ab2dbf2dc4f171c0ec33fa702cc30642ddf6aab789", -"f79256f68b2011712d0d074248876caccf98614ec1d15d84ecd4a5a7f02576ae", -"f79373cbf026b4737dc9a5e69bb71112a91d2fcd602b93b7b9cae3baee4c5804", -"f7e3344ae2b06b8bd3596b54930b6af055c515b4f9dbb839bc63b1bb13e5efd8", -"f8450815db8e2e8695db5da777fa053a80ff80f747175c6653df031211bc6607", -"f87c92566596fff9083a67d6a810575da0b01a63a8c6c6026b1d120f548d6951", -"f890ed99e394d322712db3d9aaeef36710167dbf6c71a31a13e1158efaeee755", -"f8d924bb9bf40a313c2c160894aaa3b75294be55c349198ec380706cd6997b90", -"f91848f4e7fce0036d2bf207f9488ada0c3d0d8a24ff22bbea60e9d331e25f41", -"f987b68f789b31eb610e2552bbfeb1cf6c7b0c962109b3be28bb079c26eea9a9", -"f9adc5269a86f7f5df0bdcd20267bd2723c6f66bf0704879019af4cc85db193f", -"f9b21276c4fc9b6f3de673b2b2c3176dfe0594155f4046e28bbcd83236fce667", -"f9b3968c19691e8db10bde4bd06fde35f0d081e7ee9e10cb0cd320bc20558f96", -"f9dd719319a9bc015d0a80a32589873603808a386df04e5a5372cdb9894704b1", -"fa278d51fc6711b3d14ec7d230cc7f1b2fb57a894d5b1284d1f73b9643b31f87", -"fb284598c4c59f69abd77e0222a5d723e44bb217f34176151b377df92c0bcfe3", -"fb6bbad84d35d47a49eaf3fba088228d299f9efc792e96c8ff6910d4a8fbbb6c", -"fb86bd928ef2b1ecd9918cf427a3a91e24074723922bf8e53e616f698c70c38f", -"fc1d38a9ce46a7fb8b0b0f0cc0ac3a5f802d663ab5f4c2aa5a76ba885f78f6a3", -"fc68a61bbca0c9625be8a30080353cd71fbf6f53b5e02852063c2ecd7c591cd5", -"fcca7e635caa12b17c68ad65b9c666b339232c0a963eb882d4a17ce7a6b7c509", -"fd00432172be122a36bd1fd86a1a200b14cadba9b3f38ffa361b933df9293c10", -"fdad07cf96335392e4b7c8004cfc1f34835c59b66827bb05a735f676218c72b3", -"fdd5a1169ab44e2cfce3a8609d63e88386481f149a198f9e956276e7598ba3f7", -"fe0e2a3d68aec63785b880811ccf19a70893cf9901e48036dcb300f49b2fdb7b", -"fe26826593168d80cc58e86dd22161129f538d65751fbbff81adba425fba4e05", -"feb3400d62fe9a150da8ca8c930f3eae195b3a8f99467d88c5b5a9bf525e8d3a", -"ff82ff74e5cbd2b06468133d88bcc5d260cc7a3de73fb35192dcc87e78cee9f2", -"ff90e9d931b23add9b25c3c4e5b1f4d4623622aca888ccf18e59c96fd43b5a28", -"ffdeaffdaa820f860be1e0d7722c12b8213f93f7b0292f15e835408ac4e45d45", -"fff0ad60c32b99edadf3d327393fec3e5ef0ed476666528d8b86ce587fab4f23", -"fff6592657f29d91d6f9e3fe76de2eec9d461173cd7248a9ff2f065393234bb5", -}; diff --git a/src/veruslaunch.h b/src/veruslaunch.h deleted file mode 100644 index de081e11d..000000000 --- a/src/veruslaunch.h +++ /dev/null @@ -1,17 +0,0 @@ - -// Copyright (c) 2018 The Verus developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef VERUS_LAUNCH_H -#define VERUS_LAUNCH_H - -#include - -#define WHITELIST_COUNT 704 - -extern const char *whitelist_ids[WHITELIST_COUNT]; -extern const char *whitelist_address; -extern uint64_t whitelist_masks[WHITELIST_COUNT]; - -#endif From 93a0ba6287f60c28528a614e0d4845e39caf2cbe Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 21:09:47 -1100 Subject: [PATCH 81/94] Makefile --- src/Makefile.am | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 19a29b9a3..874c3a8b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -261,7 +261,6 @@ BITCOIN_CORE_H = \ wallet/wallet.h \ wallet/wallet_ismine.h \ wallet/walletdb.h \ -# veruslaunch.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ zmq/zmqnotificationinterface.h \ @@ -483,7 +482,6 @@ libbitcoin_common_a_SOURCES = \ script/script_error.cpp \ script/sign.cpp \ script/standard.cpp \ -# veruslaunch.cpp \ transaction_builder.cpp \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) From 4ee39bc49ac001cb74ab823da4ea7dd1132f9eca Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 21:10:20 -1100 Subject: [PATCH 82/94] -include --- src/coins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coins.h b/src/coins.h index 5d6b4603a..7fd5bcdb7 100644 --- a/src/coins.h +++ b/src/coins.h @@ -24,7 +24,7 @@ #include #include #include "zcash/IncrementalMerkleTree.hpp" -#include "veruslaunch.h" +//#include "veruslaunch.h" /** * Pruned version of CTransaction: only retains metadata and unspent transaction outputs From edc6aba6a5af1650d25683208ba8e81f2fd7c30c Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 21:11:35 -1100 Subject: [PATCH 83/94] -launchmap --- src/coins.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coins.h b/src/coins.h index 7fd5bcdb7..39d1e22fc 100644 --- a/src/coins.h +++ b/src/coins.h @@ -507,7 +507,7 @@ public: ~CCoinsViewCache(); // Standard CCoinsView methods - static CLaunchMap &LaunchMap() { return launchMap; } + //static CLaunchMap &LaunchMap() { return launchMap; } bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const; bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const; bool GetNullifier(const uint256 &nullifier, ShieldedType type) const; From 7c089f4865fc6aa1c7507e56b190118e44f1e020 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 5 Dec 2018 22:00:46 -1100 Subject: [PATCH 84/94] Always generate scriptPubKey for create block --- src/miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/miner.cpp b/src/miner.cpp index 981fad63f..9b0a04aaa 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -737,7 +737,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, } else { - if (!isStake) + //if ( !isStake || ASSETCHAINS_STAKED != 0 ) { if (!reservekey.GetReservedKey(pubkey)) { From fb67bac72f6eedfba30f572e896fc35f79e91ab4 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 6 Dec 2018 00:09:13 -1100 Subject: [PATCH 85/94] Squelch missing inputs --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index edb8aa0fb..6c33feb08 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1731,7 +1731,8 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pfMissingInputs) *pfMissingInputs = true; //fprintf(stderr,"missing inputs\n"); - return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing"); + //return state.DoS(0, error("AcceptToMemoryPool: tx inputs not found"),REJECT_INVALID, "bad-txns-inputs-missing"); + return(false); } } From 05908caa14a5db6c9207fad84cb367beace1365d Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 6 Dec 2018 20:26:41 +0800 Subject: [PATCH 86/94] Prevent possible skip of notarisation on KMD --- src/crosschain.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/crosschain.cpp b/src/crosschain.cpp index 250a0e6ca..56c310ce7 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -69,7 +69,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh destNotarisationTxid = nota.first; else if (seenOwnNotarisations == 2) goto end; - break; + //break; } } @@ -97,7 +97,7 @@ int ScanNotarisationsFromHeight(int nHeight, const IsTarget f, Notarisation &fou { int limit = std::min(nHeight + NOTARISATION_SCAN_LIMIT_BLOCKS, chainActive.Height()); int start = std::max(nHeight, 1); - + for (int h=start; hGetHeight(), isTarget, nota)) throw std::runtime_error("backnotarisation not yet confirmed"); - + // index of block in MoM leaves nIndex = nota.second.height - blockIndex->GetHeight(); } @@ -325,7 +325,7 @@ TxProof GetAssetchainProof(uint256 hash) } bool fMutated; BuildMerkleTree(&fMutated, leaves, tree); - branch = GetMerkleBranch(nIndex, leaves.size(), tree); + branch = GetMerkleBranch(nIndex, leaves.size(), tree); // Check branch uint256 ourResult = SafeCheckMerkleBranch(blockIndex->hashMerkleRoot, branch, nIndex); @@ -364,7 +364,7 @@ TxProof GetAssetchainProof(uint256 hash) } // Check the proof - if (nota.second.MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex)) + if (nota.second.MoM != CBlock::CheckMerkleBranch(hash, branch, nIndex)) throw std::runtime_error("Failed validating MoM"); // All done! From d8282c5739260e6f9c3a0dcbe74de98feb9a54f3 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 6 Dec 2018 02:08:39 -1100 Subject: [PATCH 87/94] GetHeight() --- src/crosschain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crosschain.cpp b/src/crosschain.cpp index 56c310ce7..e9444c607 100644 --- a/src/crosschain.cpp +++ b/src/crosschain.cpp @@ -274,7 +274,7 @@ bool CheckMoMoM(uint256 kmdNotarisationHash, uint256 momom) return nota.second.MoMoM == momom; }; - return (bool) ScanNotarisationsFromHeight(block.nHeight-100, checkMoMoM, nota); + return (bool) ScanNotarisationsFromHeight(block.GetHeight()-100, checkMoMoM, nota); } From a9935f76579bdfcd355307bd32b64209ff6f4a00 Mon Sep 17 00:00:00 2001 From: jl777 Date: Thu, 6 Dec 2018 04:53:01 -1100 Subject: [PATCH 88/94] Fix inconsistent CC data --- src/cc/CCtx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index b683a7f51..35cce315e 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -96,8 +96,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran } if ( opret.size() > 0 ) mtx.vout.push_back(CTxOut(0,opret)); - PrecomputedTransactionData txdata(mtx); - n = mtx.vin.size(); + n = mtx.vin.size(); //Reorder vins so that for multiple normal vins all other except vin0 goes to the end //This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation. if (normalvins>1) @@ -108,6 +107,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran mtx.vin.erase(mtx.vin.begin() + 1); } } + PrecomputedTransactionData txdata(mtx); for (i=0; i Date: Thu, 6 Dec 2018 17:30:17 +0100 Subject: [PATCH 89/94] Fix reorder of vins in FinalizeCCTx --- src/cc/CCtx.cpp | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 35cce315e..9315faa9a 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -62,8 +62,26 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran GetCCaddress(cp,myaddr,mypk); mycond = MakeCCcond1(cp->evalcode,mypk); GetCCaddress(cp,unspendable,unspendablepk); - othercond = MakeCCcond1(cp->evalcode,unspendablepk); - //fprintf(stderr,"myCCaddr.(%s) %p vs unspendable.(%s) %p\n",myaddr,mycond,unspendable,othercond); + othercond = MakeCCcond1(cp->evalcode,unspendablepk); + //Reorder vins so that for multiple normal vins all other except vin0 goes to the end + //This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation. + for (i=0; i1 && ccvins) + { + for(i=1;i 0 ) mtx.vout.push_back(CTxOut(0,opret)); - n = mtx.vin.size(); - //Reorder vins so that for multiple normal vins all other except vin0 goes to the end - //This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation. - if (normalvins>1) - { - for(i=1;i Date: Fri, 7 Dec 2018 13:41:45 +0100 Subject: [PATCH 90/94] Fix hanging of oracles --- src/cc/CCtx.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cc/CCtx.cpp b/src/cc/CCtx.cpp index 9315faa9a..27d796ba0 100644 --- a/src/cc/CCtx.cpp +++ b/src/cc/CCtx.cpp @@ -69,8 +69,8 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran { if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 ) { - if ( vintx.vout[utxovout].scriptPubKey.IsPayToCryptoCondition() == 0 ) - if (ccvins==0) normalvins++; + if ( vintx.vout[mtx.vin[i].prevout.n].scriptPubKey.IsPayToCryptoCondition() == 0 && ccvins==0) + normalvins++; else ccvins++; } } From ba6f37bb65dc5473cc4edbf9c5c539fc76a3ef0a Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 8 Dec 2018 00:57:32 -1100 Subject: [PATCH 91/94] Synchronize version number with agama 0.3.0 --- 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 e0bbe86c3..03649b8b1 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -56,7 +56,7 @@ extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN]; uint32_t komodo_segid32(char *coinaddr); int64_t komodo_coinsupply(int64_t *zfundsp,int32_t height); int32_t notarizedtxid_height(char *dest,char *txidstr,int32_t *kmdnotarized_heightp); -#define KOMODO_VERSION "0.3.2" +#define KOMODO_VERSION "0.3.0" #define VERUS_VERSION "0.4.0g" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; From 54431fd74ae77d94af8f8edf6d6994d66d81eae2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sat, 8 Dec 2018 01:33:23 -1100 Subject: [PATCH 92/94] Prevent height -> nLockTime --- src/wallet/wallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 13cd2efd5..be4c8b5a6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3615,7 +3615,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; } - +/* // Discourage fee sniping. // // However because of a off-by-one-error in previous versions we need to @@ -3636,7 +3636,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); - assert(txNew.nLockTime < LOCKTIME_THRESHOLD); + assert(txNew.nLockTime < LOCKTIME_THRESHOLD);*/ { LOCK2(cs_main, cs_wallet); From 5ea3f23ac938061dc1fed9cc87a6e2d772dd85d7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Sun, 9 Dec 2018 08:41:08 -1100 Subject: [PATCH 93/94] Update three --- src/main.cpp | 2 +- src/rpc/rawtransaction.cpp | 2 +- src/wallet/wallet.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6c33feb08..5c4d65f00 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1980,7 +1980,7 @@ bool myAddtomempool(CTransaction &tx, CValidationState *pstate) pstate = &state; CTransaction Ltx; bool fMissingInputs,fOverrideFees = false; if ( mempool.lookup(tx.GetHash(),Ltx) == 0 ) - return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees)); + return(AcceptToMemoryPool(mempool, *pstate, tx, true, &fMissingInputs, !fOverrideFees)); else return(true); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index e6d356f90..1cb913ad1 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1274,7 +1274,7 @@ UniValue sendrawtransaction(const UniValue& params, bool fHelp) // push to local node and sync with wallets CValidationState state; bool fMissingInputs; - if (!AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees)) { + if (!AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, !fOverrideFees)) { if (state.IsInvalid()) { throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); } else { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c5cfedda8..4ec4dd377 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -46,7 +46,7 @@ extern bool fSendFreeTransactions; extern bool fPayAtLeastCustomFee; //! -paytxfee default -static const CAmount DEFAULT_TRANSACTION_FEE = 0; +static const CAmount DEFAULT_TRANSACTION_FEE = 10000; //! -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; //! -maxtxfee default From 01a684cd9592674535bd9a29b162d9d1261a09a5 Mon Sep 17 00:00:00 2001 From: DeckerSU Date: Sun, 9 Dec 2018 23:23:42 +0300 Subject: [PATCH 94/94] genproclimit fix by default when we start komodod only with -gen arg genproclimit automatically become -1. this behaviour derived from VRSC after last merge (as i remember, vrsc has -1 by default, 0 - for staking, and >= 1 - for mining and staking), so we need to set genproclimit=1 if we pass gen and want to actually start mining. --- src/assetchains | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assetchains b/src/assetchains index 57e705d5c..ce6c3aac2 100755 --- a/src/assetchains +++ b/src/assetchains @@ -11,7 +11,7 @@ if [ -z "$delay" ]; then delay=20; fi ./listassetchainparams | while read args; do gen="" if [ $[RANDOM % 10] == 1 ]; then - gen=" -gen" + gen=" -gen -genproclimit=1" fi ./komodod $gen $args $overide_args -pubkey=$pubkey -addnode=$seed_ip &