diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index edfb608e7..06dc0ded2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3652,6 +3652,92 @@ UniValue z_listsentbyaddress(const UniValue& params, bool fHelp,const CPubKey&) return ret; } +UniValue z_anonsetblockdelta(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "z_anonsetblockdelta\n" + "\nReturns delta (difference) in the anonset for a given block height.\n" + "\nArguments:\n" + "1. \"height\" (number, required) The block height\n" + "\nResult:\n" + "\"delta\" (integer) An integer number.\n" + "\nExamples:\n" + + HelpExampleCli("z_anonsetblockdelta 123", "456") + + HelpExampleRpc("z_anonsetblockdelta 123", "456") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + std::string strHeight = params[0].get_str(); + int nHeight = -1; + try { + nHeight = std::stoi(strHeight); + } catch (const std::exception &e) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block height parameter"); + } + + if (nHeight < 0 || nHeight > chainActive.Height()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); + } + strHash = chainActive[nHeight]->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"); + + int delta = 0; + BOOST_FOREACH(const CTransaction&tx, block.vtx) + { + // delta = shielded outputs - shielded inputs + delta += tx.vShieldedOutput.size() - tx.vShieldedSpend.size(); + } + return delta; +} + +UniValue z_anonsettxdelta(const UniValue& params, bool fHelp, const CPubKey& mypk) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() != 1) + throw runtime_error( + "z_anonsettxdelta\n" + "\nReturns delta (difference) in the anonset for a given txid.\n" + "\nArguments:\n" + "1. \"txid\" (string, required) The transaction id\n" + "\nResult:\n" + "\"delta\" (integer) An integer number.\n" + "\nExamples:\n" + + HelpExampleCli("z_anonsettxdelta txid", "123") + + HelpExampleRpc("z_anonsettxdelta txid", "123") + ); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + uint256 txid; + txid.SetHex(params[0].get_str()); + + if (!pwalletMain->mapWallet.count(hash)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id!"); + const CWalletTx& wtx = pwalletMain->mapWallet[hash]; + + // delta = shielded outputs - shielded inputs + int delta = wtx.vShieldedSpend.size() - wtx.vShieldedOutput.size(); + return delta; +} + UniValue z_getbalances(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -8352,6 +8438,8 @@ static const CRPCCommand commands[] = { "wallet", "z_listunspent", &z_listunspent, false }, { "wallet", "z_getbalance", &z_getbalance, false }, { "wallet", "z_getbalances", &z_getbalances, false }, + { "wallet", "z_anonsettxdelta", &z_anonsettxdelta, true }, + { "wallet", "z_anonsetblockdelta", &z_anonsetblockdelta, true }, { "wallet", "z_gettotalbalance", &z_gettotalbalance, false }, { "wallet", "z_mergetoaddress", &z_mergetoaddress, false }, { "wallet", "z_sendmany", &z_sendmany, false },