Skip to content
Bitcoin Roots

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

src/qt/walletmodel.cpp

Before: src/qt/walletmodel.cpp · After: src/qt/walletmodel.cpp

File metadata
index e051aae59971f7336bbc222bb35552ac293c10b0..268c8f351f0895bbb404115ea7317d9c6f6d69eb 100644

Download original patch · Release notes

Diff rows 1–35 of 35. 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/qt/walletmodel.cpp CHANGED
@@ -67,19 +67,24 @@ WalletModel::~WalletModel()
67
  unsubscribeFromCoreSignals();
68
  }
69
 
70
- uint64_t WalletModel::invalidateSweepRequests()
71
  {
 
72
  ++m_sweep_request_generation;
 
73
  Q_EMIT sweepRequestInvalidated(m_sweep_request_generation);
74
- return m_sweep_request_generation;
75
  }
76
 
77
  uint64_t WalletModel::requestSweep(SecureString private_key, CTxDestination destination, bool broadcast,
78
  std::optional<uint256> expected_txid)
79
  {
 
80
  const uint64_t generation{++m_sweep_request_generation};
81
- QMetaObject::invokeMethod(&m_sweep_context, [this, generation, private_key = std::move(private_key), destination = std::move(destination), broadcast, expected_txid]() mutable {
82
- auto result{m_wallet->sweepPrivateKey(private_key, destination, broadcast, expected_txid)};
 
 
83
  private_key.clear();
84
 
85
  const bool success{result.has_value()};
@@ -92,6 +97,7 @@ uint64_t WalletModel::requestSweep(SecureString private_key, CTxDestination dest
92
  const QString txid{success && result->tx ? QString::fromStdString(result->tx->GetHash().ToString()) : QString{}};
93
  QMetaObject::invokeMethod(this, [this, generation, broadcast, success, error, amount, fee, inputs, vsize, rbf, txid] {
94
  if (generation != m_sweep_request_generation) return;
 
95
  Q_EMIT sweepFinished(generation, broadcast, success, error, amount, fee, inputs, vsize, rbf, txid);
96
  }, Qt::QueuedConnection);
97
  }, Qt::QueuedConnection);
 
67
  unsubscribeFromCoreSignals();
68
  }
69
 
70
+ bool WalletModel::invalidateSweepRequests()
71
  {
72
+ if (m_sweep_authorization && !m_sweep_authorization->Cancel()) return false;
73
  ++m_sweep_request_generation;
74
+ m_sweep_authorization.reset();
75
  Q_EMIT sweepRequestInvalidated(m_sweep_request_generation);
76
+ return true;
77
  }
78
 
79
  uint64_t WalletModel::requestSweep(SecureString private_key, CTxDestination destination, bool broadcast,
80
  std::optional<uint256> expected_txid)
81
  {
82
+ if (m_sweep_authorization && !m_sweep_authorization->Cancel()) return 0;
83
  const uint64_t generation{++m_sweep_request_generation};
84
+ auto authorization{std::make_shared<interfaces::SweepAuthorization>()};
85
+ m_sweep_authorization = authorization;
86
+ QMetaObject::invokeMethod(&m_sweep_context, [this, generation, authorization, private_key = std::move(private_key), destination = std::move(destination), broadcast, expected_txid]() mutable {
87
+ auto result{m_wallet->sweepPrivateKey(private_key, destination, broadcast, expected_txid, authorization)};
88
  private_key.clear();
89
 
90
  const bool success{result.has_value()};
 
97
  const QString txid{success && result->tx ? QString::fromStdString(result->tx->GetHash().ToString()) : QString{}};
98
  QMetaObject::invokeMethod(this, [this, generation, broadcast, success, error, amount, fee, inputs, vsize, rbf, txid] {
99
  if (generation != m_sweep_request_generation) return;
100
+ m_sweep_authorization.reset();
101
  Q_EMIT sweepFinished(generation, broadcast, success, error, amount, fee, inputs, vsize, rbf, txid);
102
  }, Qt::QueuedConnection);
103
  }, Qt::QueuedConnection);