v29.4-roots.3 · Commit 28: [PATCH 28/30] fix(wallet): secure asynchronous sweep cancellation
src/rpc/blockchain.cpp
Before: src/rpc/blockchain.cpp · After: src/rpc/blockchain.cpp
File metadata
index bb3b92d552625562bb4012691070fc1c4753897f..7a0c927921f45fc8763eedbfb4f49e704215b177 100644
Download original patch · Release notes
Diff rows 1–37 of 37. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/rpc/blockchain.cpp
CHANGED
|
@@ -2108,7 +2108,7 @@ static RPCHelpMan getblockstats()
|
|
| 2108 |
|
| 2109 |
namespace {
|
| 2110 |
//! Search for a given set of pubkey scripts
|
| 2111 |
-
bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set<CScript>& needles, std::map<COutPoint, Coin>& out_results, std::function<void()>& interruption_point)
|
| 2112 |
{
|
| 2113 |
scan_progress = 0;
|
| 2114 |
count = 0;
|
|
@@ -2117,7 +2117,7 @@ bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>&
|
|
| 2117 |
Coin coin;
|
| 2118 |
if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false;
|
| 2119 |
if (rpc::scan::CheckInterruption(++count, interruption_point)) {
|
| 2120 |
-
if (should_abort) {
|
| 2121 |
// allow to abort the scan via the abort reference
|
| 2122 |
return false;
|
| 2123 |
}
|
|
@@ -2152,7 +2152,8 @@ rpc::scan::Reserver::~Reserver() { if (m_reserved) { g_in_progress = false; g_pr
|
|
| 2152 |
bool rpc::scan::CheckInterruption(int64_t count, const std::function<void()>& interruption) { if (count % 8192 != 0) return false; interruption(); return true; }
|
| 2153 |
using rpc::scan::Reserver;
|
| 2154 |
|
| 2155 |
-
interfaces::ScanResult ScanUTXOSet(NodeContext& node, const std::set<CScript>& needles, std::map<COutPoint, Coin>& coins)
|
|
|
|
| 2156 |
{
|
| 2157 |
Reserver reserver;
|
| 2158 |
if (!reserver.reserve()) return interfaces::ScanResult::BUSY;
|
|
@@ -2167,10 +2168,10 @@ interfaces::ScanResult ScanUTXOSet(NodeContext& node, const std::set<CScript>& n
|
|
| 2167 |
rpc::scan::g_should_abort = false;
|
| 2168 |
std::atomic<int> progress;
|
| 2169 |
int64_t count;
|
| 2170 |
-
if (FindScriptPubKey(progress, rpc::scan::g_should_abort, count, cursor.get(), needles, coins, node.rpc_interruption_point)) {
|
| 2171 |
return interfaces::ScanResult::SUCCESS;
|
| 2172 |
}
|
| 2173 |
-
return rpc::scan::g_should_abort ? interfaces::ScanResult::ABORTED : interfaces::ScanResult::UNAVAILABLE;
|
| 2174 |
}
|
| 2175 |
|
| 2176 |
static const auto scan_action_arg_desc = RPCArg{
|
|
|
|
| 2108 |
|
| 2109 |
namespace {
|
| 2110 |
//! Search for a given set of pubkey scripts
|
| 2111 |
+
bool FindScriptPubKey(std::atomic<int>& scan_progress, const std::atomic<bool>& should_abort, int64_t& count, CCoinsViewCursor* cursor, const std::set<CScript>& needles, std::map<COutPoint, Coin>& out_results, std::function<void()>& interruption_point, const std::function<bool()>& local_should_abort = {})
|
| 2112 |
{
|
| 2113 |
scan_progress = 0;
|
| 2114 |
count = 0;
|
|
|
|
| 2117 |
Coin coin;
|
| 2118 |
if (!cursor->GetKey(key) || !cursor->GetValue(coin)) return false;
|
| 2119 |
if (rpc::scan::CheckInterruption(++count, interruption_point)) {
|
| 2120 |
+
if (should_abort || (local_should_abort && local_should_abort())) {
|
| 2121 |
// allow to abort the scan via the abort reference
|
| 2122 |
return false;
|
| 2123 |
}
|
|
|
|
| 2152 |
bool rpc::scan::CheckInterruption(int64_t count, const std::function<void()>& interruption) { if (count % 8192 != 0) return false; interruption(); return true; }
|
| 2153 |
using rpc::scan::Reserver;
|
| 2154 |
|
| 2155 |
+
interfaces::ScanResult ScanUTXOSet(NodeContext& node, const std::set<CScript>& needles, std::map<COutPoint, Coin>& coins,
|
| 2156 |
+
const std::function<bool()>& should_abort)
|
| 2157 |
{
|
| 2158 |
Reserver reserver;
|
| 2159 |
if (!reserver.reserve()) return interfaces::ScanResult::BUSY;
|
|
|
|
| 2168 |
rpc::scan::g_should_abort = false;
|
| 2169 |
std::atomic<int> progress;
|
| 2170 |
int64_t count;
|
| 2171 |
+
if (FindScriptPubKey(progress, rpc::scan::g_should_abort, count, cursor.get(), needles, coins, node.rpc_interruption_point, should_abort)) {
|
| 2172 |
return interfaces::ScanResult::SUCCESS;
|
| 2173 |
}
|
| 2174 |
+
return rpc::scan::g_should_abort || (should_abort && should_abort()) ? interfaces::ScanResult::ABORTED : interfaces::ScanResult::UNAVAILABLE;
|
| 2175 |
}
|
| 2176 |
|
| 2177 |
static const auto scan_action_arg_desc = RPCArg{
|