From 2aa376d286f9594c157ad1c1c7df58e2922d26d2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 16:31:54 -0400 Subject: [PATCH 1/6] Add z_getinfo, a place for various shielded details that do not fit other places --- src/init.cpp | 2 +- src/wallet/rpcwallet.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index d513d0a06..495394a4d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1936,7 +1936,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) pwalletMain->GenerateNewSeed(); } - //Set Sapling Consolidation + //Set Sapling Consolidation pwalletMain->fSaplingConsolidationEnabled = GetBoolArg("-consolidation", false); fConsolidationTxFee = GetArg("-consolidationtxfee", DEFAULT_CONSOLIDATION_FEE); fConsolidationMapUsed = !mapMultiArgs["-consolidatesaplingaddress"].empty(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ea4b43a5a..c9a135173 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -79,6 +79,7 @@ int32_t komodo_dpowconfs(int32_t height,int32_t numconfs); int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private chains only CBlockIndex *komodo_getblockindex(uint256 hash); extern string randomSietchZaddr(); +extern CAmount fConsolidationTxFee; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -3479,6 +3480,33 @@ UniValue z_listreceivedaddress(const UniValue& params, bool fHelp,const CPubKey& return ret; } +UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) +{ + if (fHelp || params.size() > 0) { + throw runtime_error( + "z_getinfo\n" + "\nReturns various information about shielded operations, such as sapling consolidation details.\n" + ); + } + UniValue result(UniValue::VOBJ); + result.push_back(Pair("consolidation_enabled",(bool)pwalletMain->fSaplingConsolidationEnabled )); + result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); + result.push_back(Pair("deletetx",(int)fTxDeleteEnabled)); + result.push_back(Pair("delete_interval",(int)fDeleteInterval)); + result.push_back(Pair("keeptxnum",(int)fKeepLastNTransactions)); + result.push_back(Pair("keeptxfornblocks",(int)fDeleteTransactionsAfterNBlocks)); + + std::set saplingzaddrs = {}; + pwalletMain->GetSaplingPaymentAddresses(saplingzaddrs); + result.push_back(Pair("num_sapling_zaddrs",(int)saplingzaddrs.size())); + + std::shared_ptr q = getAsyncRPCQueue(); + std::vector ids = q->getAllOperationIds(); + result.push_back(Pair("num_op_ids",(int)ids.size())); + + return result; +} + UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) { if (!EnsureWalletIsAvailable(fHelp)) @@ -8326,6 +8354,7 @@ static const CRPCCommand commands[] = { "wallet", "z_exportwallet", &z_exportwallet, true }, { "wallet", "z_importwallet", &z_importwallet, true }, { "wallet", "z_viewtransaction", &z_viewtransaction, true }, + { "wallet", "z_getinfo", &z_getinfo, true }, { "wallet", "z_listsentbyaddress", &z_listsentbyaddress, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, true }, // TODO: rearrange into another category From 67f666d5ff25ce82c3a7a13912fb29477343fbb1 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 18:42:13 -0400 Subject: [PATCH 2/6] Tweak z_getinfo data slightly --- src/wallet/rpcwallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c9a135173..4c1564db1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3489,9 +3489,9 @@ UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) ); } UniValue result(UniValue::VOBJ); - result.push_back(Pair("consolidation_enabled",(bool)pwalletMain->fSaplingConsolidationEnabled )); + result.push_back(Pair("consolidation",(bool)pwalletMain->fSaplingConsolidationEnabled )); result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); - result.push_back(Pair("deletetx",(int)fTxDeleteEnabled)); + result.push_back(Pair("deletetx",(bool)fTxDeleteEnabled)); result.push_back(Pair("delete_interval",(int)fDeleteInterval)); result.push_back(Pair("keeptxnum",(int)fKeepLastNTransactions)); result.push_back(Pair("keeptxfornblocks",(int)fDeleteTransactionsAfterNBlocks)); From e4bfafc76cc26ba6af26eb569cab43b7535979ac Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:02:52 -0400 Subject: [PATCH 3/6] Better error checking in consolidation for when CommitTransaction() fails --- .../asyncrpcoperation_saplingconsolidation.cpp | 12 ++++++++---- src/wallet/wallet.cpp | 4 ++-- src/wallet/wallet.h | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index e85ce5861..da0d4b94c 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -209,10 +209,14 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { break; } - pwalletMain->CommitConsolidationTx(tx); - LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); - amountConsolidated += amountToSend - fConsolidationTxFee; - consolidationTxIds.push_back(tx.GetHash().ToString()); + if(pwalletMain->CommitConsolidationTx(tx)) { + LogPrint("zrpcunsafe", "%s: Committed consolidation transaction with txid=%s\n", getId(), tx.GetHash().ToString()); + amountConsolidated += amountToSend - fConsolidationTxFee; + consolidationTxIds.push_back(tx.GetHash().ToString()); + } else { + LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + return false; + } } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f8127e83d..df40a53ff 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -637,10 +637,10 @@ void CWallet::RunSaplingConsolidation(int blockHeight) { } } -void CWallet::CommitConsolidationTx(const CTransaction& tx) { +bool CWallet::CommitConsolidationTx(const CTransaction& tx) { CWalletTx wtx(this, tx); CReserveKey reservekey(pwalletMain); - CommitTransaction(wtx, reservekey); + return CommitTransaction(wtx, reservekey); } void CWallet::SetBestChain(const CBlockLocator& loc) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d9dc9e0a1..3dd658acb 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1258,7 +1258,7 @@ public: const CBlock *pblock, boost::optional> added); void RunSaplingConsolidation(int blockHeight); - void CommitConsolidationTx(const CTransaction& tx); + bool CommitConsolidationTx(const CTransaction& tx); /** Saves witness caches and best block locator to disk. */ void SetBestChain(const CBlockLocator& loc); std::set> GetNullifiersForAddresses(const std::set & addresses); From 744ef344381854cf3f7683fc176e75c80c2211ef Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:04:53 -0400 Subject: [PATCH 4/6] Add zindex to z_getinfo --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4c1564db1..c62a0552e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -80,6 +80,7 @@ int32_t komodo_isnotaryvout(char *coinaddr,uint32_t tiptime); // from ac_private CBlockIndex *komodo_getblockindex(uint256 hash); extern string randomSietchZaddr(); extern CAmount fConsolidationTxFee; +extern bool fZindex; int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; @@ -3489,6 +3490,7 @@ UniValue z_getinfo(const UniValue& params, bool fHelp,const CPubKey&) ); } UniValue result(UniValue::VOBJ); + result.push_back(Pair("zindex",(bool)fZindex)); result.push_back(Pair("consolidation",(bool)pwalletMain->fSaplingConsolidationEnabled )); result.push_back(Pair("consolidationtxfee",(int)fConsolidationTxFee)); result.push_back(Pair("deletetx",(bool)fTxDeleteEnabled)); From 736aa8cfaf8ac14dd59626c14470e92e1054df17 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:27:49 -0400 Subject: [PATCH 5/6] Add more data to failed consolidation ops --- src/wallet/asyncrpcoperation_saplingconsolidation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp index da0d4b94c..3ffb048ae 100644 --- a/src/wallet/asyncrpcoperation_saplingconsolidation.cpp +++ b/src/wallet/asyncrpcoperation_saplingconsolidation.cpp @@ -215,6 +215,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() { consolidationTxIds.push_back(tx.GetHash().ToString()); } else { LogPrint("zrpcunsafe", "%s: Consolidation transaction FAILED in CommitTransaction, txid=%s\n", getId(), tx.GetHash().ToString()); + setConsolidationResult(numTxCreated, amountConsolidated, consolidationTxIds); return false; } From d8477c4d7bae3e619b3c1719f2c7a2a379d3d292 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 9 Mar 2020 21:28:09 -0400 Subject: [PATCH 6/6] Remove some more sprout code, yay --- src/wallet/wallet.cpp | 122 +----------------------------------------- 1 file changed, 1 insertion(+), 121 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index df40a53ff..4c35c16e2 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1173,96 +1173,6 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO auto wtxHash = wtxItem.second.GetHash(); int wtxHeight = mapBlockIndex[wtxItem.second.hashBlock]->GetHeight(); - for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { - - auto op = item.first; - auto* nd = &(item.second); - CBlockIndex* pblockindex; - uint256 blockRoot; - uint256 witnessRoot; - - if (!nd->nullifier) - ::ClearSingleNoteWitnessCache(nd); - - if (!nd->witnesses.empty() && nd->witnessHeight > 0) { - - //Skip all functions for validated witness while witness only = true - if (nd->witnessRootValidated && witnessOnly) - continue; - - //Skip Validation when witness root has been validated - if (nd->witnessRootValidated) { - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - - //Skip Validation when witness height is greater that block height - if (nd->witnessHeight > pindex->GetHeight() - 1) { - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - - //Validate the witness at the witness height - witnessRoot = nd->witnesses.front().root(); - pblockindex = chainActive[nd->witnessHeight]; - blockRoot = pblockindex->hashFinalSproutRoot; - if (witnessRoot == blockRoot) { - nd->witnessRootValidated = true; - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - continue; - } - } - - //Clear witness Cache for all other scenarios - pblockindex = chainActive[wtxHeight]; - ::ClearSingleNoteWitnessCache(nd); - - LogPrintf("Setting Inital Sprout Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); - - SproutMerkleTree sproutTree; - blockRoot = pblockindex->pprev->hashFinalSproutRoot; - pcoinsTip->GetSproutAnchorAt(blockRoot, sproutTree); - - //Cycle through blocks and transactions building sprout tree until the commitment needed is reached - const CBlock* pblock; - CBlock block; - ReadBlockFromDisk(block, pblockindex, 1); - pblock = █ - - for (const CTransaction& tx : block.vtx) { - auto hash = tx.GetHash(); - - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; - for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { - const uint256& note_commitment = jsdesc.commitments[j]; - - // Increment existing witness until the end of the block - if (!nd->witnesses.empty()) { - nd->witnesses.front().append(note_commitment); - } - - //Only needed for intial witness - if (nd->witnesses.empty()) { - sproutTree.append(note_commitment); - - // If this is our note, witness it - if (hash == wtxHash) { - JSOutPoint outPoint {hash, i, j}; - if (op == outPoint) { - nd->witnesses.push_front(sproutTree.witness()); - } - } - } - } - } - } - - nd->witnessHeight = pblockindex->GetHeight(); - UpdateSproutNullifierNoteMapWithTx(wtxItem.second); - nMinimumHeight = SproutWitnessMinimumHeight(*item.second.nullifier, nd->witnessHeight, nMinimumHeight); - } - for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { auto op = item.first; @@ -1307,7 +1217,7 @@ int CWallet::VerifyAndSetInitialWitness(const CBlockIndex* pindex, bool witnessO pblockindex = chainActive[wtxHeight]; ::ClearSingleNoteWitnessCache(nd); - LogPrintf("Setting Inital Sapling Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); + LogPrintf("Setting Initial Sapling Witness for tx %s, %i of %i\n", wtxHash.ToString(), nWitnessTxIncrement, nWitnessTotalTxCount); SaplingMerkleTree saplingTree; blockRoot = pblockindex->pprev->hashFinalSaplingRoot; @@ -1396,31 +1306,6 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) if (wtxItem.second.GetDepthInMainChain() > 0) { - //Sprout - for (mapSproutNoteData_t::value_type& item : wtxItem.second.mapSproutNoteData) { - auto* nd = &(item.second); - if (nd->nullifier && nd->witnessHeight == pblockindex->GetHeight() - 1 - && GetSproutSpendDepth(*item.second.nullifier) <= WITNESS_CACHE_SIZE) { - - - nd->witnesses.push_front(nd->witnesses.front()); - while (nd->witnesses.size() > WITNESS_CACHE_SIZE) { - nd->witnesses.pop_back(); - } - - for (const CTransaction& tx : block.vtx) { - for (size_t i = 0; i < tx.vjoinsplit.size(); i++) { - const JSDescription& jsdesc = tx.vjoinsplit[i]; - for (uint8_t j = 0; j < jsdesc.commitments.size(); j++) { - const uint256& note_commitment = jsdesc.commitments[j]; - nd->witnesses.front().append(note_commitment); - } - } - } - nd->witnessHeight = pblockindex->GetHeight(); - } - } - //Sapling for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { auto* nd = &(item.second); @@ -1639,11 +1524,6 @@ void CWallet::UpdateNullifierNoteMapWithTx(const CWalletTx& wtx) { { LOCK(cs_wallet); - for (const mapSproutNoteData_t::value_type& item : wtx.mapSproutNoteData) { - if (item.second.nullifier) { - mapSproutNullifiersToNotes[*item.second.nullifier] = item.first; - } - } for (const mapSaplingNoteData_t::value_type& item : wtx.mapSaplingNoteData) { if (item.second.nullifier) {