Skip to content
Bitcoin Roots

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{