Skip to content
Bitcoin Roots

v29.4-roots.3 · Commit 28: [PATCH 28/30] fix(wallet): secure asynchronous sweep cancellation

src/wallet/interfaces.cpp

Before: src/wallet/interfaces.cpp · After: src/wallet/interfaces.cpp

File metadata
index 8294d1a3cc1534031a41b2ef3332c300dec02f33..b6b22fe11ff25ba0f3a22a23ff91de0f004b24d8 100644

Download original patch · Release notes

Diff rows 1–29 of 29. 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/wallet/interfaces.cpp CHANGED
@@ -217,9 +217,11 @@ public:
217
  util::Result<WalletSweepResult> sweepPrivateKey(const SecureString& private_key,
218
  const CTxDestination& destination,
219
  bool broadcast,
220
- const std::optional<uint256>& expected_txid) override
 
221
  {
222
- CKey key{DecodeSecret(std::string{private_key.begin(), private_key.end()})};
 
223
  if (!key.IsValid()) return util::Error{Untranslated("Invalid private key or wrong network")};
224
  const CPubKey pubkey{key.GetPubKey()};
225
  FlatSigningProvider provider;
@@ -240,7 +242,7 @@ public:
240
  }
241
  }
242
  std::map<COutPoint, Coin> coins;
243
- switch (m_wallet->chain().findScriptPubKeys(scan_objects, coins)) {
244
  case interfaces::ScanResult::SUCCESS: break;
245
  case interfaces::ScanResult::BUSY: return util::Error{Untranslated("UTXO scan already in progress")};
246
  case interfaces::ScanResult::ABORTED: return util::Error{Untranslated("UTXO scan aborted")};
@@ -252,7 +254,7 @@ public:
252
  return false;
253
  }
254
  return m_wallet->chain().broadcastTransaction(tx, m_wallet->m_default_max_tx_fee, /*relay=*/true, error);
255
- }} : SweepBroadcastFn{})};
256
  if (!swept) return util::Error{util::ErrorString(swept)};
257
  return WalletSweepResult{swept->tx, swept->amount, swept->fee, coins.size(), GetVirtualTransactionSize(*swept->tx), broadcast};
258
  }
 
217
  util::Result<WalletSweepResult> sweepPrivateKey(const SecureString& private_key,
218
  const CTxDestination& destination,
219
  bool broadcast,
220
+ const std::optional<uint256>& expected_txid,
221
+ const std::shared_ptr<interfaces::SweepAuthorization>& authorization) override
222
  {
223
+ if (!authorization || authorization->IsCancelled()) return util::Error{Untranslated("Sweep cancelled")};
224
+ CKey key{DecodeSecret(private_key)};
225
  if (!key.IsValid()) return util::Error{Untranslated("Invalid private key or wrong network")};
226
  const CPubKey pubkey{key.GetPubKey()};
227
  FlatSigningProvider provider;
 
242
  }
243
  }
244
  std::map<COutPoint, Coin> coins;
245
+ switch (m_wallet->chain().findScriptPubKeys(scan_objects, coins, [&] { return authorization->IsCancelled(); })) {
246
  case interfaces::ScanResult::SUCCESS: break;
247
  case interfaces::ScanResult::BUSY: return util::Error{Untranslated("UTXO scan already in progress")};
248
  case interfaces::ScanResult::ABORTED: return util::Error{Untranslated("UTXO scan aborted")};
 
254
  return false;
255
  }
256
  return m_wallet->chain().broadcastTransaction(tx, m_wallet->m_default_max_tx_fee, /*relay=*/true, error);
257
+ }} : SweepBroadcastFn{}, *authorization)};
258
  if (!swept) return util::Error{util::ErrorString(swept)};
259
  return WalletSweepResult{swept->tx, swept->amount, swept->fee, coins.size(), GetVirtualTransactionSize(*swept->tx), broadcast};
260
  }