Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 28: [PATCH 28/68] fix(wallet): secure asynchronous sweep cancellation

src/qt/walletmodel.cpp

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

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