From 35ee0b4b8909132c051b9faca07cbd28f72ccdd9 Mon Sep 17 00:00:00 2001 From: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com> Date: Thu, 18 Jun 2020 22:19:26 +0300 Subject: [PATCH] merge bitcoin#19323: Fix regression in *txoutset* in GUI console --- src/init.cpp | 5 +++-- src/node/context.h | 2 ++ src/rpc/blockchain.cpp | 18 ++++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 92080701ee..bf1245794d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1056,13 +1056,14 @@ static bool InitSanityCheck() return true; } -static bool AppInitServers(const util::Ref& context) +static bool AppInitServers(const util::Ref& context, NodeContext& node) { RPCServer::OnStarted(&OnRPCStarted); RPCServer::OnStopped(&OnRPCStopped); if (!InitHTTPServer()) return false; StartRPC(); + node.rpc_interruption_point = RpcInterruptionPoint; if (!StartHTTPRPC(context)) return false; if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context); @@ -1748,7 +1749,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA if (gArgs.GetBoolArg("-server", false)) { uiInterface.InitMessage_connect(SetRPCWarmupStatus); - if (!AppInitServers(context)) + if (!AppInitServers(context, node)) return InitError(_("Unable to start HTTP server. See debug log for details.")); } diff --git a/src/node/context.h b/src/node/context.h index 31a59f2403..7cbd4ab24f 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -6,6 +6,7 @@ #define BITCOIN_NODE_CONTEXT_H #include +#include #include #include @@ -39,6 +40,7 @@ struct NodeContext { std::unique_ptr chain; std::vector> chain_clients; std::unique_ptr scheduler; + std::function rpc_interruption_point = [] {}; //! Declare default constructor and destructor that are not inline, so code //! instantiating the NodeContext struct doesn't need to #include class diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index fef7183a02..3eceeb919e 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1254,7 +1254,8 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request) const CoinStatsHashType hash_type{request.params[0].isNull() ? CoinStatsHashType::HASH_SERIALIZED : ParseHashType(request.params[0].get_str())}; CCoinsView* coins_view = WITH_LOCK(cs_main, return &ChainstateActive().CoinsDB()); - if (GetUTXOStats(coins_view, stats, hash_type, RpcInterruptionPoint)) { + NodeContext& node = EnsureNodeContext(request.context); + if (GetUTXOStats(coins_view, stats, hash_type, node.rpc_interruption_point)) { ret.pushKV("height", (int64_t)stats.nHeight); ret.pushKV("bestblock", stats.hashBlock.GetHex()); ret.pushKV("transactions", (int64_t)stats.nTransactions); @@ -2358,8 +2359,10 @@ static UniValue savemempool(const JSONRPCRequest& request) return NullUniValue; } +namespace { //! Search for a given set of pubkey scripts -bool FindScriptPubKey(std::atomic& scan_progress, const std::atomic& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set& needles, std::map& out_results) { +bool FindScriptPubKey(std::atomic& scan_progress, const std::atomic& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set& needles, std::map& out_results, std::function& interruption_point) +{ scan_progress = 0; count = 0; while (cursor->Valid()) { @@ -2367,7 +2370,7 @@ bool FindScriptPubKey(std::atomic& scan_progress, const std::atomic& Coin coin; if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false; if (++count % 8192 == 0) { - RpcInterruptionPoint(); + interruption_point(); if (should_abort) { // allow to abort the scan via the abort reference return false; @@ -2386,6 +2389,7 @@ bool FindScriptPubKey(std::atomic& scan_progress, const std::atomic& scan_progress = 100; return true; } +} // namespace /** RAII object to prevent concurrency issue when scanning the txout set */ static std::mutex g_utxosetscan; @@ -2568,7 +2572,8 @@ UniValue scantxoutset(const JSONRPCRequest& request) tip = ::ChainActive().Tip(); CHECK_NONFATAL(tip); } - bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins); + NodeContext& node = EnsureNodeContext(request.context); + bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point); result.pushKV("success", res); result.pushKV("txouts", count); result.pushKV("height", tip->nHeight); @@ -2722,6 +2727,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request) std::unique_ptr pcursor; CCoinsStats stats; CBlockIndex* tip; + NodeContext& node = EnsureNodeContext(request.context); { // We need to lock cs_main to ensure that the coinsdb isn't written to @@ -2740,7 +2746,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request) ::ChainstateActive().ForceFlushStateToDisk(); - if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats, CoinStatsHashType::NONE, RpcInterruptionPoint)) { + if (!GetUTXOStats(&::ChainstateActive().CoinsDB(), stats, CoinStatsHashType::NONE, node.rpc_interruption_point)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set"); } @@ -2758,7 +2764,7 @@ UniValue dumptxoutset(const JSONRPCRequest& request) unsigned int iter{0}; while (pcursor->Valid()) { - if (iter % 5000 == 0) RpcInterruptionPoint(); + if (iter % 5000 == 0) node.rpc_interruption_point(); ++iter; if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { afile << key;