From 63cadcf444b9be1f9c3208469ffdf0283fa240db Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 24 Sep 2018 05:45:38 -1100 Subject: [PATCH 01/66] 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 02/66] 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 03/66] 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 04/66] 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 05/66] 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 06/66] 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 07/66] 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 4b3228fccfa1d4f9777f3ceb486959117f567d91 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 6 Nov 2018 22:55:29 -1100 Subject: [PATCH 08/66] 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 09/66] 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 10/66] 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 d1e8c8c8fc68f7338bf7a41df4d5f092d7c02911 Mon Sep 17 00:00:00 2001 From: SHossain Date: Sun, 2 Dec 2018 17:44:05 +0000 Subject: [PATCH 11/66] 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 12/66] 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 a5be135052a98e7c096c883483d74a4502764b82 Mon Sep 17 00:00:00 2001 From: jl777 Date: Tue, 4 Dec 2018 23:51:14 -1100 Subject: [PATCH 13/66] 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 14/66] 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 15/66] 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 16/66] 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 17/66] 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 18/66] 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 19/66] 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 20/66] 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 21/66] 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 22/66] 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 23/66] 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 24/66] 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 25/66] 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 26/66] 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 27/66] 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 28/66] 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 29/66] -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 30/66] -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 31/66] 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 32/66] 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 33/66] 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 34/66] 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 35/66] 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 36/66] 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 37/66] 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 38/66] 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 39/66] 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 40/66] 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 41/66] 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 & From a2ea9de06f90c88c0cc0e9c68f018a03eb0df9fb Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 05:45:59 -1100 Subject: [PATCH 42/66] Revert txfee changes --- 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 5c4d65f00..6c33feb08 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, true, &fMissingInputs, !fOverrideFees)); + return(AcceptToMemoryPool(mempool, *pstate, tx, false, &fMissingInputs, !fOverrideFees)); else return(true); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1cb913ad1..e6d356f90 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, true, &fMissingInputs, !fOverrideFees)) { + if (!AcceptToMemoryPool(mempool, state, tx, false, &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 4ec4dd377..c5cfedda8 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 = 10000; +static const CAmount DEFAULT_TRANSACTION_FEE = 0; //! -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 27606f3e0ba1cfae50321e2701716c4fd331cc40 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 09:44:50 -1100 Subject: [PATCH 43/66] Fix typow == 0 --- src/rpc/rawtransaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index e6d356f90..21a6e26cd 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1167,12 +1167,12 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) if ( txConst.IsCoinBase() != 0 ) { if ( (txpow & 2) == 0 ) - txpow == 0; + txpow = 0; } else { if ( (txpow & 1) == 0 ) - txpow == 0; + txpow = 0; } } while ( 1 ) From fcb709c5e80e5e42047894abd7be42e752a7feea Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 09:56:26 -1100 Subject: [PATCH 44/66] +print --- src/wallet/rpcwallet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1f4c2c59b..3eeed58a4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1665,6 +1665,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; + fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex()); if (pwalletMain->mapAddressBook.count(r.destination)) account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) From 80198244d4701a3be42876f8475e7a36a463cd48 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:18:42 -1100 Subject: [PATCH 45/66] New prints --- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3eeed58a4..cbda7ea20 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1665,7 +1665,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; - fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex()); + //fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex()); if (pwalletMain->mapAddressBook.count(r.destination)) account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index be4c8b5a6..d98c0ff78 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,6 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); + fprintf(stderr,"ordered iter %s\n",wtx.GetHash().GetHex()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From fe0671145e6d6c7925a698ce7fefd40571cfdbdf Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:19:12 -1100 Subject: [PATCH 46/66] Fix --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d98c0ff78..ae072d503 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - fprintf(stderr,"ordered iter %s\n",wtx.GetHash().GetHex()); + fprintf(stderr,"ordered iter %s\n",wtx.GetHash().GetHex().ToString()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From 755e64a9af9980caeeeb63238224395577d36a0a Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:25:07 -1100 Subject: [PATCH 47/66] -> --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ae072d503..aa0ed6a57 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - fprintf(stderr,"ordered iter %s\n",wtx.GetHash().GetHex().ToString()); + fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().ToString()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From 7c8828545253368b6cae0dcc0073c902f9e4ba97 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:26:19 -1100 Subject: [PATCH 48/66] Fix --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index aa0ed6a57..3b57744af 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().ToString()); + fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().c_str()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From 2b66bcf2479b971b5eb907b1a5be6f7ce2663407 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:37:13 -1100 Subject: [PATCH 49/66] Move prints --- src/wallet/rpcwallet.cpp | 3 ++- src/wallet/wallet.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index cbda7ea20..335682b60 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1665,7 +1665,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; - //fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex()); + fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex().c_str()); if (pwalletMain->mapAddressBook.count(r.destination)) account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) @@ -1817,6 +1817,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + else fprintf(stderr,"null pwtx\n"); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3b57744af..9097740c9 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().c_str()); + //fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().c_str()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From 7883afa7fec29ff964d73d8451fc8723750f4f33 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 10:43:21 -1100 Subject: [PATCH 50/66] Print orderpos --- src/wallet/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 9097740c9..82b52b901 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - //fprintf(stderr,"ordered iter %s\n",wtx->GetHash().GetHex().c_str()); + fprintf(stderr,"ordered iter.%d %s\n",(int32_t)wtx->nOrderPos,wtx->GetHash().GetHex().c_str()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); From 181d6b33f37ce4453d0f32aa870f705d61632499 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:35:11 -1100 Subject: [PATCH 51/66] +prints --- src/wallet/rpcwallet.cpp | 2 +- src/wallet/wallet.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 335682b60..e52a2503b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1817,7 +1817,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - else fprintf(stderr,"null pwtx\n"); + //else fprintf(stderr,"null pwtx\n"); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 82b52b901..b5d5b01af 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2533,11 +2533,16 @@ void CWalletTx::GetAmounts(list& listReceived, { // Don't report 'change' txouts if (!(filter & ISMINE_CHANGE) && pwallet->IsChange(txout)) + { + fprintf(stderr,"skip change vout\n"); continue; + } } else if (!(fIsMine & filter)) + { + fprintf(stderr,"skip filtered vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); continue; - + } // In either case, we need to get the destination address CTxDestination address; if (!ExtractDestination(txout.scriptPubKey, address)) @@ -2551,10 +2556,12 @@ void CWalletTx::GetAmounts(list& listReceived, // If we are debited by the transaction, add the output as a "sent" entry if (nDebit > 0) listSent.push_back(output); + else fprintf(stderr,"not sent vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); // If we are receiving the output, add it as a "received" entry if (fIsMine & filter) listReceived.push_back(output); + else fprintf(stderr,"not received vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); } } From 0615c21df0bbcc4f72ac4eff741965001e37287e Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:38:07 -1100 Subject: [PATCH 52/66] +print --- src/wallet/rpcwallet.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e52a2503b..f94f07199 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1816,7 +1816,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) { CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) + { + fprintf(stderr,"pwtx iter %s\n",pwtx->GetHash().GetHex().c_str()); ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + } //else fprintf(stderr,"null pwtx\n"); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) From 5f162b1a9de3ada4a000005d04dfc30bd37eefda Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:39:51 -1100 Subject: [PATCH 53/66] +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 f94f07199..52e92ceb9 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1817,7 +1817,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) { - fprintf(stderr,"pwtx iter %s\n",pwtx->GetHash().GetHex().c_str()); + fprintf(stderr,"pwtx iter.%d %s\n",(int32_t)pwtx->nOrderPos,pwtx->GetHash().GetHex().c_str()); ListTransactions(*pwtx, strAccount, 0, true, ret, filter); } //else fprintf(stderr,"null pwtx\n"); From 3b4ee13f944392492c22bc1ebc061224b278a83d Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:46:51 -1100 Subject: [PATCH 54/66] Allow one change out in list transactions --- src/wallet/wallet.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b5d5b01af..b72ee14f3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1304,7 +1304,7 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, { CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); - fprintf(stderr,"ordered iter.%d %s\n",(int32_t)wtx->nOrderPos,wtx->GetHash().GetHex().c_str()); + //fprintf(stderr,"ordered iter.%d %s\n",(int32_t)wtx->nOrderPos,wtx->GetHash().GetHex().c_str()); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); @@ -2522,6 +2522,7 @@ void CWalletTx::GetAmounts(list& listReceived, } // Sent/received. + int32_t oneshot = 0; for (unsigned int i = 0; i < vout.size(); ++i) { const CTxOut& txout = vout[i]; @@ -2534,8 +2535,11 @@ void CWalletTx::GetAmounts(list& listReceived, // Don't report 'change' txouts if (!(filter & ISMINE_CHANGE) && pwallet->IsChange(txout)) { - fprintf(stderr,"skip change vout\n"); - continue; + if ( oneshot++ > 1 ) + { + fprintf(stderr,"skip change vout\n"); + continue; + } } } else if (!(fIsMine & filter)) From 80be59463871910ff88c1449855a254196a56244 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:47:18 -1100 Subject: [PATCH 55/66] -print --- 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 b72ee14f3..b8587a943 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2560,12 +2560,12 @@ void CWalletTx::GetAmounts(list& listReceived, // If we are debited by the transaction, add the output as a "sent" entry if (nDebit > 0) listSent.push_back(output); - else fprintf(stderr,"not sent vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); + //else fprintf(stderr,"not sent vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); // If we are receiving the output, add it as a "received" entry if (fIsMine & filter) listReceived.push_back(output); - else fprintf(stderr,"not received vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); + //else fprintf(stderr,"not received vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); } } From 9742bb74db0fb99de068fe1f99f5ab4ad0deba7f Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:48:48 -1100 Subject: [PATCH 56/66] -prints --- src/wallet/rpcwallet.cpp | 4 ++-- src/wallet/wallet.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 52e92ceb9..fc8269008 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1665,7 +1665,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe BOOST_FOREACH(const COutputEntry& r, listReceived) { string account; - fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex().c_str()); + //fprintf(stderr,"recv iter %s\n",wtx.GetHash().GetHex().c_str()); if (pwalletMain->mapAddressBook.count(r.destination)) account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) @@ -1817,7 +1817,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) CWalletTx *const pwtx = (*it).second.first; if (pwtx != 0) { - fprintf(stderr,"pwtx iter.%d %s\n",(int32_t)pwtx->nOrderPos,pwtx->GetHash().GetHex().c_str()); + //fprintf(stderr,"pwtx iter.%d %s\n",(int32_t)pwtx->nOrderPos,pwtx->GetHash().GetHex().c_str()); ListTransactions(*pwtx, strAccount, 0, true, ret, filter); } //else fprintf(stderr,"null pwtx\n"); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b8587a943..3857f7090 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2537,14 +2537,14 @@ void CWalletTx::GetAmounts(list& listReceived, { if ( oneshot++ > 1 ) { - fprintf(stderr,"skip change vout\n"); + //fprintf(stderr,"skip change vout\n"); continue; } } } else if (!(fIsMine & filter)) { - fprintf(stderr,"skip filtered vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); + //fprintf(stderr,"skip filtered vout %d %d\n",(int32_t)fIsMine,(int32_t)filter); continue; } // In either case, we need to get the destination address From 3958b39ead8f32d58534494b3290b759f503c371 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 11:53:34 -1100 Subject: [PATCH 57/66] Fix rewards claim txid not appearing in list transactions --- src/wallet/rpcwallet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fc8269008..c34466a39 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1819,8 +1819,7 @@ UniValue listtransactions(const UniValue& params, bool fHelp) { //fprintf(stderr,"pwtx iter.%d %s\n",(int32_t)pwtx->nOrderPos,pwtx->GetHash().GetHex().c_str()); ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - } - //else fprintf(stderr,"null pwtx\n"); + } //else fprintf(stderr,"null pwtx\n"); CAccountingEntry *const pacentry = (*it).second.second; if (pacentry != 0) AcentryToJSON(*pacentry, strAccount, ret); From 5215b63f6a5d8e33a812afd6c4ab7e4ea62826a7 Mon Sep 17 00:00:00 2001 From: jl777 Date: Mon, 10 Dec 2018 12:19:17 -1100 Subject: [PATCH 58/66] 0.3.1 --- 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 03649b8b1..26c273236 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.0" +#define KOMODO_VERSION "0.3.1" #define VERUS_VERSION "0.4.0g" extern uint16_t ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT; extern uint32_t ASSETCHAINS_CC; From ab6374c07942a97c6cb17986216c36c1749168c2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 06:09:59 -1100 Subject: [PATCH 59/66] Restore mempool, instead of adding back --- src/main.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6c33feb08..bc8455279 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,7 +103,6 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CTxMemPool mempool(::minRelayTxFee); -CTxMemPool tmpmempool(::minRelayTxFee); struct COrphanTx { CTransaction tx; @@ -4675,12 +4674,15 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // Check transactions CTransaction sTx; CTransaction *ptx = NULL; + CTxMemPool savedmempool(::minRelayTxFee); if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order { int32_t i,j,rejects=0,lastrejects=0; //fprintf(stderr,"put block's tx into mempool\n"); // Copy all non Z-txs in mempool to temporary mempool because there can be tx in local mempool that make the block invalid. LOCK(mempool.cs); + CTxMemPool tmpmempool(::minRelayTxFee); + savedmempool = mempool; list transactionsToRemove; BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) { const CTransaction &tx = e.GetTx(); @@ -4764,9 +4766,9 @@ 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; + //int invalidtxs = 0; LOCK(mempool.cs); - BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) { + /*BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) { CTransaction tx = e.GetTx(); CValidationState state; bool fMissingInputs,fOverrideFees = false; @@ -4777,7 +4779,8 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C if ( 0 && invalidtxs > 0 ) fprintf(stderr, "number of invalid txs: %d\n",invalidtxs ); // empty the temp mempool for next time. - tmpmempool.clear(); + tmpmempool.clear();*/ + mempool = savedmempool; } return true; } From 0d02463df6a92c5d43f6536340a0eb71eb6fd938 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 06:20:52 -1100 Subject: [PATCH 60/66] Iteratively add back to mempool --- src/main.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bc8455279..15023734d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,6 +103,7 @@ unsigned int expiryDelta = DEFAULT_TX_EXPIRY_DELTA; CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CTxMemPool mempool(::minRelayTxFee); +CTxMemPool tmpmempool(::minRelayTxFee); struct COrphanTx { CTransaction tx; @@ -4674,15 +4675,12 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C // Check transactions CTransaction sTx; CTransaction *ptx = NULL; - CTxMemPool savedmempool(::minRelayTxFee); if ( ASSETCHAINS_CC != 0 ) // CC contracts might refer to transactions in the current block, from a CC spend within the same block and out of order { int32_t i,j,rejects=0,lastrejects=0; //fprintf(stderr,"put block's tx into mempool\n"); // Copy all non Z-txs in mempool to temporary mempool because there can be tx in local mempool that make the block invalid. LOCK(mempool.cs); - CTxMemPool tmpmempool(::minRelayTxFee); - savedmempool = mempool; list transactionsToRemove; BOOST_FOREACH(const CTxMemPoolEntry& e, mempool.mapTx) { const CTransaction &tx = e.GetTx(); @@ -4697,6 +4695,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C mempool.remove(tx, removed, false); } // add all the txs in the block to the empty mempool. + // CC validation shouldnt (cant) depend on the state of mempool! while ( 1 ) { for (i=0; i removed; LOCK(mempool.cs); - /*BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) { - CTransaction tx = e.GetTx(); - CValidationState state; bool fMissingInputs,fOverrideFees = false; - - if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees) == false ) - invalidtxs++; - //else fprintf(stderr, "added mempool tx back to mempool\n"); + while ( 1 ) + { + numiters++; + numadded = 0; + BOOST_FOREACH(const CTxMemPoolEntry& e, tmpmempool.mapTx) + { + CTransaction tx = e.GetTx(); + if (AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, !fOverrideFees) == true ) + { + numadded++; + tmpmempool.remove(tx, removed, false); + } + } + if ( numadded == 0 ) + break; } - if ( 0 && invalidtxs > 0 ) - fprintf(stderr, "number of invalid txs: %d\n",invalidtxs ); + if ( numadded > 0 ) + fprintf(stderr, "CC mempool add: numiters.%d numadded.%d remains.%d\n",numiters,numadded,(int32_t)tmpmempool.size()); // empty the temp mempool for next time. - tmpmempool.clear();*/ - mempool = savedmempool; + tmpmempool.clear(); } return true; } From dc63bc8d260c8c2d405005b0c029c99082b00bfb Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 06:21:55 -1100 Subject: [PATCH 61/66] Numbers --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 15023734d..01857e8b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4765,7 +4765,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 numadded,numadded = 0; + int numadded,numiters = 0; CValidationState state; bool fMissingInputs,fOverrideFees = false; list removed; LOCK(mempool.cs); From b90b38255634369b1201d4c7d1e924b80bc732ad Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 06:39:20 -1100 Subject: [PATCH 62/66] -print --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 01857e8b8..788ee95b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4785,7 +4785,7 @@ bool CheckBlock(int32_t *futureblockp,int32_t height,CBlockIndex *pindex,const C if ( numadded == 0 ) break; } - if ( numadded > 0 ) + if ( 0 && numadded > 0 ) fprintf(stderr, "CC mempool add: numiters.%d numadded.%d remains.%d\n",numiters,numadded,(int32_t)tmpmempool.size()); // empty the temp mempool for next time. tmpmempool.clear(); From 659b3af80e8f36a3973ab14811dda82c9b62ee87 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 09:06:30 -1100 Subject: [PATCH 63/66] +prints --- 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 6faaa1f0c..4233e8928 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -431,7 +431,7 @@ void *dicefinish(void *_ptr) utxos = (struct dicefinish_utxo *)calloc(vin0_needed,sizeof(*utxos)); if ( (n= dicefinish_utxosget(num,utxos,vin0_needed,coinaddr)) > 0 ) { - //fprintf(stderr,"iter.%d vin0_needed.%d got %d, num 0.0002 %d\n",iter,vin0_needed,n,num); +fprintf(stderr,"iter.%d vin0_needed.%d got %d, num 0.0002 %d\n",iter,vin0_needed,n,num); m = 0; DL_FOREACH_SAFE(DICEFINISH_LIST,ptr,tmp) { @@ -533,7 +533,7 @@ void DiceQueue(int32_t iswin,uint64_t sbits,uint256 fundingtxid,uint256 bettxid, else { //fprintf(stderr,"DiceQueue status bettxid.%s already in list\n",bettxid.GetHex().c_str()); - _dicehash_clear(bettxid); + //_dicehash_clear(bettxid); } pthread_mutex_unlock(&DICE_MUTEX); } From f18e92f0932615673d6b5f5e0f05b0cacca3011a Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 09:12:26 -1100 Subject: [PATCH 64/66] +print --- 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 4233e8928..32674a51d 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -427,7 +427,7 @@ void *dicefinish(void *_ptr) if ( vin0_needed > 0 ) { num = 0; - //fprintf(stderr,"iter.%d vin0_needed.%d\n",iter,vin0_needed); +fprintf(stderr,"iter.%d vin0_needed.%d\n",iter,vin0_needed); utxos = (struct dicefinish_utxo *)calloc(vin0_needed,sizeof(*utxos)); if ( (n= dicefinish_utxosget(num,utxos,vin0_needed,coinaddr)) > 0 ) { From 527ccd4e2e4efe4bb79db170489f1129606e00b6 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 09:28:35 -1100 Subject: [PATCH 65/66] Autocreate 0.0002 for kmdice dealer --- src/cc/dice.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cc/dice.cpp b/src/cc/dice.cpp index 32674a51d..45e101e9c 100644 --- a/src/cc/dice.cpp +++ b/src/cc/dice.cpp @@ -427,11 +427,11 @@ void *dicefinish(void *_ptr) if ( vin0_needed > 0 ) { num = 0; -fprintf(stderr,"iter.%d vin0_needed.%d\n",iter,vin0_needed); +//fprintf(stderr,"iter.%d vin0_needed.%d\n",iter,vin0_needed); utxos = (struct dicefinish_utxo *)calloc(vin0_needed,sizeof(*utxos)); if ( (n= dicefinish_utxosget(num,utxos,vin0_needed,coinaddr)) > 0 ) { -fprintf(stderr,"iter.%d vin0_needed.%d got %d, num 0.0002 %d\n",iter,vin0_needed,n,num); +//fprintf(stderr,"iter.%d vin0_needed.%d got %d, num 0.0002 %d\n",iter,vin0_needed,n,num); m = 0; DL_FOREACH_SAFE(DICEFINISH_LIST,ptr,tmp) { @@ -484,7 +484,8 @@ fprintf(stderr,"iter.%d vin0_needed.%d got %d, num 0.0002 %d\n",iter,vin0_needed //fprintf(stderr,"error ready.%d dicefinish %d of %d process %s %s using need %.8f finish.%s size.%d betspent.%d\n",ptr->bettxid_ready,m,n,iter<0?"loss":"win",ptr->bettxid.GetHex().c_str(),(double)(iter<0 ? 0 : ptr->winamount)/COIN,ptr->txid.GetHex().c_str(),(int32_t)ptr->rawtx.size(),dice_betspent((char *)"dicefinish",ptr->bettxid)); } } - } + } else if ( system("cc/dapps/sendmany100") != 0 ) + fprintf(stderr,"error issing cc/dapps/sendmany100\n"); free(utxos); } } From 5e1c3d1e32e0d4efea059cbcf593b94c229c3fc2 Mon Sep 17 00:00:00 2001 From: jl777 Date: Wed, 12 Dec 2018 11:33:20 -1100 Subject: [PATCH 66/66] zMigrate cap at 1000 --- src/cc/dapps/zmigrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cc/dapps/zmigrate.c b/src/cc/dapps/zmigrate.c index 81de2c13d..a86b529ad 100644 --- a/src/cc/dapps/zmigrate.c +++ b/src/cc/dapps/zmigrate.c @@ -906,7 +906,7 @@ int32_t main(int32_t argc,char **argv) zsaddr = clonestr(argv[2]); printf("%s: %s %s\n",REFCOIN_CLI,coinstr,zsaddr); uint32_t lastopid; char coinaddr[64],zcaddr[128],opidstr[128]; int32_t finished; int64_t amount,stdamount,txfee; - stdamount = 10000 * SATOSHIDEN; + stdamount = 1000 * SATOSHIDEN; txfee = 10000; again: printf("start processing zmigrate\n");