diff options
Diffstat (limited to 'src/rpc')
-rw-r--r-- | src/rpc/blockchain.cpp | 66 | ||||
-rw-r--r-- | src/rpc/mempool.cpp | 2 | ||||
-rw-r--r-- | src/rpc/net.cpp | 6 | ||||
-rw-r--r-- | src/rpc/rawtransaction.cpp | 4 | ||||
-rw-r--r-- | src/rpc/server.cpp | 2 | ||||
-rw-r--r-- | src/rpc/txoutproof.cpp | 4 |
6 files changed, 55 insertions, 29 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 027a61ff8b..784fb64d36 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -181,7 +181,8 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn case TxVerbosity::SHOW_DETAILS: case TxVerbosity::SHOW_DETAILS_AND_PREVOUT: CBlockUndo blockUndo; - const bool have_undo{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex) && UndoReadFromDisk(blockUndo, blockindex))}; + const bool is_not_pruned{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex))}; + const bool have_undo{is_not_pruned && UndoReadFromDisk(blockUndo, blockindex)}; for (size_t i = 0; i < block.vtx.size(); ++i) { const CTransactionRef& tx = block.vtx.at(i); @@ -428,7 +429,9 @@ static RPCHelpMan getblockfrompeer() "getblockfrompeer", "Attempt to fetch block from a given peer.\n\n" "We must have the header for this block, e.g. using submitheader.\n" - "Subsequent calls for the same block and a new peer will cause the response from the previous peer to be ignored.\n\n" + "Subsequent calls for the same block and a new peer will cause the response from the previous peer to be ignored.\n" + "Peers generally ignore requests for a stale block that they never fully verified, or one that is more than a month old.\n" + "When a peer does not respond with a block, we will disconnect.\n\n" "Returns an empty JSON object if the request was successfully scheduled.", { {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The block hash to try to fetch"}, @@ -577,30 +580,38 @@ static RPCHelpMan getblockheader() }; } -static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) +static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex* pblockindex) { - AssertLockHeld(::cs_main); CBlock block; - if (blockman.IsBlockPruned(pblockindex)) { - throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); + { + LOCK(cs_main); + if (blockman.IsBlockPruned(pblockindex)) { + throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); + } } if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { // Block not found on disk. This could be because we have the block // header in our index but not yet have the block or did not accept the - // block. + // block. Or if the block was pruned right after we released the lock above. throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); } return block; } -static CBlockUndo GetUndoChecked(BlockManager& blockman, const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +static CBlockUndo GetUndoChecked(BlockManager& blockman, const CBlockIndex* pblockindex) { - AssertLockHeld(::cs_main); CBlockUndo blockUndo; - if (blockman.IsBlockPruned(pblockindex)) { - throw JSONRPCError(RPC_MISC_ERROR, "Undo data not available (pruned data)"); + + // The Genesis block does not have undo data + if (pblockindex->nHeight == 0) return blockUndo; + + { + LOCK(cs_main); + if (blockman.IsBlockPruned(pblockindex)) { + throw JSONRPCError(RPC_MISC_ERROR, "Undo data not available (pruned data)"); + } } if (!UndoReadFromDisk(blockUndo, pblockindex)) { @@ -715,7 +726,6 @@ static RPCHelpMan getblock() } } - CBlock block; const CBlockIndex* pblockindex; const CBlockIndex* tip; ChainstateManager& chainman = EnsureAnyChainman(request.context); @@ -727,10 +737,10 @@ static RPCHelpMan getblock() if (!pblockindex) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); } - - block = GetBlockChecked(chainman.m_blockman, pblockindex); } + const CBlock block{GetBlockChecked(chainman.m_blockman, pblockindex)}; + if (verbosity <= 0) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); @@ -1777,8 +1787,10 @@ static RPCHelpMan getblockstats() {RPCResult::Type::NUM, "total_weight", /*optional=*/true, "Total weight of all non-coinbase transactions"}, {RPCResult::Type::NUM, "totalfee", /*optional=*/true, "The fee total"}, {RPCResult::Type::NUM, "txs", /*optional=*/true, "The number of transactions (including coinbase)"}, - {RPCResult::Type::NUM, "utxo_increase", /*optional=*/true, "The increase/decrease in the number of unspent outputs"}, + {RPCResult::Type::NUM, "utxo_increase", /*optional=*/true, "The increase/decrease in the number of unspent outputs (not discounting op_return and similar)"}, {RPCResult::Type::NUM, "utxo_size_inc", /*optional=*/true, "The increase/decrease in size for the utxo index (not discounting op_return and similar)"}, + {RPCResult::Type::NUM, "utxo_increase_actual", /*optional=*/true, "The increase/decrease in the number of unspent outputs, not counting unspendables"}, + {RPCResult::Type::NUM, "utxo_size_inc_actual", /*optional=*/true, "The increase/decrease in size for the utxo index, not counting unspendables"}, }}, RPCExamples{ HelpExampleCli("getblockstats", R"('"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09"' '["minfeerate","avgfeerate"]')") + @@ -1789,7 +1801,6 @@ static RPCHelpMan getblockstats() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { ChainstateManager& chainman = EnsureAnyChainman(request.context); - LOCK(cs_main); const CBlockIndex& pindex{*CHECK_NONFATAL(ParseHashOrHeight(request.params[0], chainman))}; std::set<std::string> stats; @@ -1809,7 +1820,7 @@ static RPCHelpMan getblockstats() const bool do_medianfee = do_all || stats.count("medianfee") != 0; const bool do_feerate_percentiles = do_all || stats.count("feerate_percentiles") != 0; const bool loop_inputs = do_all || do_medianfee || do_feerate_percentiles || - SetHasKeys(stats, "utxo_size_inc", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate"); + SetHasKeys(stats, "utxo_increase", "utxo_increase_actual", "utxo_size_inc", "utxo_size_inc_actual", "totalfee", "avgfee", "avgfeerate", "minfee", "maxfee", "minfeerate", "maxfeerate"); const bool loop_outputs = do_all || loop_inputs || stats.count("total_out"); const bool do_calculate_size = do_mediantxsize || SetHasKeys(stats, "total_size", "avgtxsize", "mintxsize", "maxtxsize", "swtotal_size"); @@ -1831,7 +1842,9 @@ static RPCHelpMan getblockstats() int64_t swtxs = 0; int64_t total_size = 0; int64_t total_weight = 0; + int64_t utxos = 0; int64_t utxo_size_inc = 0; + int64_t utxo_size_inc_actual = 0; std::vector<CAmount> fee_array; std::vector<std::pair<CAmount, int64_t>> feerate_array; std::vector<int64_t> txsize_array; @@ -1844,7 +1857,18 @@ static RPCHelpMan getblockstats() if (loop_outputs) { for (const CTxOut& out : tx->vout) { tx_total_out += out.nValue; - utxo_size_inc += GetSerializeSize(out, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + + size_t out_size = GetSerializeSize(out, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc += out_size; + + // The Genesis block and the repeated BIP30 block coinbases don't change the UTXO + // set counts, so they have to be excluded from the statistics + if (pindex.nHeight == 0 || (IsBIP30Repeat(pindex) && tx->IsCoinBase())) continue; + // Skip unspendable outputs since they are not included in the UTXO set + if (out.scriptPubKey.IsUnspendable()) continue; + + ++utxos; + utxo_size_inc_actual += out_size; } } @@ -1886,7 +1910,9 @@ static RPCHelpMan getblockstats() const CTxOut& prevoutput = coin.out; tx_total_in += prevoutput.nValue; - utxo_size_inc -= GetSerializeSize(prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + size_t prevout_size = GetSerializeSize(prevoutput, PROTOCOL_VERSION) + PER_UTXO_OVERHEAD; + utxo_size_inc -= prevout_size; + utxo_size_inc_actual -= prevout_size; } CAmount txfee = tx_total_in - tx_total_out; @@ -1946,6 +1972,8 @@ static RPCHelpMan getblockstats() ret_all.pushKV("txs", (int64_t)block.vtx.size()); ret_all.pushKV("utxo_increase", outputs - inputs); ret_all.pushKV("utxo_size_inc", utxo_size_inc); + ret_all.pushKV("utxo_increase_actual", utxos - inputs); + ret_all.pushKV("utxo_size_inc_actual", utxo_size_inc_actual); if (do_all) { return ret_all; diff --git a/src/rpc/mempool.cpp b/src/rpc/mempool.cpp index 039a4328e3..7a0c361ae0 100644 --- a/src/rpc/mempool.cpp +++ b/src/rpc/mempool.cpp @@ -10,6 +10,7 @@ #include <chainparams.h> #include <core_io.h> #include <fs.h> +#include <kernel/mempool_entry.h> #include <node/mempool_persist_args.h> #include <policy/rbf.h> #include <policy/settings.h> @@ -18,7 +19,6 @@ #include <rpc/server_util.h> #include <rpc/util.h> #include <txmempool.h> -#include <txmempool_entry.h> #include <univalue.h> #include <util/moneystr.h> #include <util/time.h> diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 8d7f4e7f5b..1a4cd09284 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -731,9 +731,7 @@ static RPCHelpMan setban() if (!request.params[2].isNull()) banTime = request.params[2].getInt<int64_t>(); - bool absolute = false; - if (request.params[3].isTrue()) - absolute = true; + const bool absolute{request.params[3].isNull() ? false : request.params[3].get_bool()}; if (isSubnet) { node.banman->Ban(subNet, banTime, absolute); @@ -942,7 +940,7 @@ static RPCHelpMan addpeeraddress() const std::string& addr_string{request.params[0].get_str()}; const auto port{request.params[1].getInt<uint16_t>()}; - const bool tried{request.params[2].isTrue()}; + const bool tried{request.params[2].isNull() ? false : request.params[2].get_bool()}; UniValue obj(UniValue::VOBJ); CNetAddr net_addr; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index d654de1862..400f2f1507 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -304,7 +304,7 @@ static RPCHelpMan createrawtransaction() std::optional<bool> rbf; if (!request.params[3].isNull()) { - rbf = request.params[3].isTrue(); + rbf = request.params[3].get_bool(); } CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf); @@ -1449,7 +1449,7 @@ static RPCHelpMan createpsbt() std::optional<bool> rbf; if (!request.params[3].isNull()) { - rbf = request.params[3].isTrue(); + rbf = request.params[3].get_bool(); } CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf); diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 232e2119f1..a026b7adfa 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -103,7 +103,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& { UniValue unused_result; if (setDone.insert(pcmd->unique_id).second) - pcmd->actor(jreq, unused_result, true /* last_handler */); + pcmd->actor(jreq, unused_result, /*last_handler=*/true); } catch (const std::exception& e) { diff --git a/src/rpc/txoutproof.cpp b/src/rpc/txoutproof.cpp index cd8b49bfe1..8c5468634d 100644 --- a/src/rpc/txoutproof.cpp +++ b/src/rpc/txoutproof.cpp @@ -84,13 +84,13 @@ static RPCHelpMan gettxoutproof() g_txindex->BlockUntilSyncedToCurrentChain(); } - LOCK(cs_main); - if (pblockindex == nullptr) { const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, /*mempool=*/nullptr, *setTxids.begin(), chainman.GetConsensus(), hashBlock); if (!tx || hashBlock.IsNull()) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); } + + LOCK(cs_main); pblockindex = chainman.m_blockman.LookupBlockIndex(hashBlock); if (!pblockindex) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); |