From 4c9dc4bbe6b23ae7dba7badbdb6dd6c3d0f74e08 Mon Sep 17 00:00:00 2001 From: tdb3 <106488469+tdb3@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:11:09 -0400 Subject: [PATCH 1/2] rpc: add relevant_blocks to scanblocks status Provides relevant block hashes to status output. Enables a user to start looking through matching blocks without having to wait on scan completion. Co-Authored-By: Luke Dashjr --- src/rpc/blockchain.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 3ba89d08d98..c2733094101 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2365,9 +2365,17 @@ public: return true; } + void release() { + if (!m_could_reserve) { + throw std::runtime_error("Attempt to release unreserved BlockFiltersScanReserver"); + } + g_scanfilter_in_progress = false; + m_could_reserve = false; + } + ~BlockFiltersScanReserver() { if (m_could_reserve) { - g_scanfilter_in_progress = false; + release(); } } }; @@ -2427,6 +2435,9 @@ static RPCHelpMan scanblocks() RPCResult{"when action=='status' and a scan is currently in progress", RPCResult::Type::OBJ, "", "", { {RPCResult::Type::NUM, "progress", "Approximate percent complete"}, {RPCResult::Type::NUM, "current_height", "Height of the block currently being scanned"}, + {RPCResult::Type::ARR, "relevant_blocks", "Blocks that may have matched a scanobject.", { + {RPCResult::Type::STR_HEX, "blockhash", "A relevant blockhash"}, + }}, }, }, scan_result_abort, @@ -2441,15 +2452,20 @@ static RPCHelpMan scanblocks() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + static GlobalMutex cs_relevant_blocks; + static UniValue relevant_blocks GUARDED_BY(cs_relevant_blocks); + UniValue ret(UniValue::VOBJ); if (request.params[0].get_str() == "status") { BlockFiltersScanReserver reserver; + LOCK(cs_relevant_blocks); if (reserver.reserve()) { // no scan in progress return NullUniValue; } ret.pushKV("progress", g_scanfilter_progress.load()); ret.pushKV("current_height", g_scanfilter_progress_height.load()); + ret.pushKV("relevant_blocks", relevant_blocks); return ret; } else if (request.params[0].get_str() == "abort") { BlockFiltersScanReserver reserver; @@ -2461,6 +2477,11 @@ static RPCHelpMan scanblocks() g_scanfilter_should_abort_scan = true; return true; } else if (request.params[0].get_str() == "start") { + { + LOCK(cs_relevant_blocks); + relevant_blocks = UniValue(UniValue::VARR); + } + BlockFiltersScanReserver reserver; if (!reserver.reserve()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Scan already in progress, use action \"abort\" or \"status\""); @@ -2516,7 +2537,7 @@ static RPCHelpMan scanblocks() needle_set.emplace(script.begin(), script.end()); } } - UniValue blocks(UniValue::VARR); + const int amount_per_chunk = 10000; std::vector filters; int start_block_height = start_index->nHeight; // for progress reporting @@ -2554,7 +2575,8 @@ static RPCHelpMan scanblocks() } } - blocks.push_back(filter.GetBlockHash().GetHex()); + LOCK(cs_relevant_blocks); + relevant_blocks.push_back(filter.GetBlockHash().GetHex()); } } } @@ -2574,8 +2596,10 @@ static RPCHelpMan scanblocks() ret.pushKV("from_height", start_block_height); ret.pushKV("to_height", start_index->nHeight); // start_index is always the last scanned block here - ret.pushKV("relevant_blocks", std::move(blocks)); + LOCK(cs_relevant_blocks); + ret.pushKV("relevant_blocks", std::move(relevant_blocks)); ret.pushKV("completed", completed); + reserver.release(); // ensure this is before cs_relevant_blocks is released, so status doesn't try to use moved relevant_blocks } else { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid action '%s'", request.params[0].get_str())); From 5b2d0216d871bd481f733506a2e8f80b8a34eca0 Mon Sep 17 00:00:00 2001 From: tdb3 <106488469+tdb3@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:26:18 -0400 Subject: [PATCH 2/2] doc: add release notes for 30713 --- doc/release-notes-30713.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 doc/release-notes-30713.md diff --git a/doc/release-notes-30713.md b/doc/release-notes-30713.md new file mode 100644 index 00000000000..97ef16841de --- /dev/null +++ b/doc/release-notes-30713.md @@ -0,0 +1,5 @@ +Updated RPCs +------------ + +- The `status` action of the`scanblocks` RPC now returns an additional array `relevant_blocks` containing + the matching block hashes found so far during a scan.