From e0d22ee170f8af9542f2c7dcb5d1eb0c28c1e72c Mon Sep 17 00:00:00 2001 From: "Jonathan \"Duke\" Leto" Date: Thu, 9 Jun 2022 03:00:50 -0700 Subject: [PATCH] Enable z_anonsetblockdelta to calculate a delta for a block range; ignore coinbase txs as optimization --- src/wallet/rpcwallet.cpp | 63 +++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 189d668f3..3a5498f19 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3657,12 +3657,15 @@ UniValue z_anonsetblockdelta(const UniValue& params, bool fHelp, const CPubKey& if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (fHelp || params.size() != 1) + if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( "z_anonsetblockdelta\n" - "\nReturns delta (difference) in the anonset for a given block height.\n" + "\nReturns delta (difference) in the anonset for a given block height. A delta > 0 increases the anonset,\n" + "\na delta < 0 reduces the anonset and a delta=0 leaves the anonset the same. Given a single block height\n" + "\nwe calculate the delta for that block. Given two block heights, we calculate the delta for that range of blocks.\n" "\nArguments:\n" "1. \"height\" (number, required) The block height\n" + "1. \"end_height\" (number, optional) The ending block height\n" "\nResult:\n" "\"delta\" (integer) An integer number.\n" "\nExamples:\n" @@ -3698,10 +3701,55 @@ UniValue z_anonsetblockdelta(const UniValue& params, bool fHelp, const CPubKey& throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); int delta = 0; - BOOST_FOREACH(const CTransaction&tx, block.vtx) - { - // delta = shielded outputs - shielded inputs - delta += tx.vShieldedOutput.size() - tx.vShieldedSpend.size(); + + // given a single block height, we calculate delta for that height + if (params.size() == 1) { + BOOST_FOREACH(const CTransaction&tx, block.vtx) + { + // delta = shielded outputs - shielded inputs + if(!tx.IsCoinBase()) { + delta += tx.vShieldedOutput.size() - tx.vShieldedSpend.size(); + } + } + } else { + // given two blocks, we calculate delta for that range + std::string strHeight2 = params[1].get_str(); + int nHeight2 = -1; + try { + nHeight = std::stoi(strHeight2); + } catch (const std::exception &e) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid ending block height parameter"); + } + + if (nHeight2 < 0 || nHeight2 > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Ending block height out of range"); + } + + // get the delta for every block in the range + for(int currentHeight = nHeight; currentHeight <= nHeight2; currentHeight++) { + auto strHash = chainActive[currentHeight]->GetBlockHash().GetHex(); + uint256 hash(uint256S(strHash)); + + if (mapBlockIndex.count(hash) == 0) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); + + if(!ReadBlockFromDisk(block, pblockindex,1)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); + + BOOST_FOREACH(const CTransaction&tx, block.vtx) + { + // delta = shielded outputs - shielded inputs + if(!tx.IsCoinBase()) { + delta += tx.vShieldedOutput.size() - tx.vShieldedSpend.size(); + } + } + } } return delta; } @@ -3714,7 +3762,8 @@ UniValue z_anonsettxdelta(const UniValue& params, bool fHelp, const CPubKey& myp if (fHelp || params.size() != 1) throw runtime_error( "z_anonsettxdelta\n" - "\nReturns delta (difference) in the anonset for a given txid.\n" + "\nReturns delta (difference) in the anonset for a given txid. A delta > 0 increases the anonset,\n" + "\na delta < 0 reduces the anonset and a delta=0 leaves the anonset the same.\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "\nResult:\n"