v29.4-roots.4 · Commit 28: [PATCH 28/37] fix(wallet): secure asynchronous sweep cancellation
src/interfaces/wallet.h
Before: src/interfaces/wallet.h · After: src/interfaces/wallet.h
File metadata
index 491aa530362aa8f43762af0446350e25623e6343..e47bb182dd3d333261e7131dbeb1e50337cec1b3 100644
Download original patch · Release notes
Diff rows 1–47 of 47. 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/interfaces/wallet.h
CHANGED
|
@@ -17,6 +17,7 @@
|
|
| 17 |
#include <util/result.h>
|
| 18 |
#include <util/ui_change_type.h>
|
| 19 |
|
|
|
|
| 20 |
#include <cstdint>
|
| 21 |
#include <functional>
|
| 22 |
#include <map>
|
|
@@ -58,6 +59,31 @@ struct WalletTxOut;
|
|
| 58 |
struct WalletTxStatus;
|
| 59 |
struct WalletMigrationResult;
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
//! Result of a transient-private-key sweep. The supplied key is never retained
|
| 62 |
//! by this interface or by the wallet.
|
| 63 |
struct WalletSweepResult {
|
|
@@ -122,7 +148,8 @@ public:
|
|
| 122 |
virtual util::Result<WalletSweepResult> sweepPrivateKey(const SecureString& private_key,
|
| 123 |
const CTxDestination& destination,
|
| 124 |
bool broadcast,
|
| 125 |
-
const std::optional<uint256>& expected_txid = std::nullopt) = 0;
|
|
|
|
| 126 |
|
| 127 |
//! Return whether wallet has watch only keys.
|
| 128 |
virtual bool haveWatchOnly() = 0;
|
|
|
|
| 17 |
#include <util/result.h>
|
| 18 |
#include <util/ui_change_type.h>
|
| 19 |
|
| 20 |
+
#include <atomic>
|
| 21 |
#include <cstdint>
|
| 22 |
#include <functional>
|
| 23 |
#include <map>
|
|
|
|
| 59 |
struct WalletTxStatus;
|
| 60 |
struct WalletMigrationResult;
|
| 61 |
|
| 62 |
+
//! Shared authorization for an asynchronous sweep. Cancellation and the final
|
| 63 |
+
//! transition into broadcast are mutually exclusive, so a successful cancel
|
| 64 |
+
//! guarantees that broadcast cannot start afterwards.
|
| 65 |
+
class SweepAuthorization
|
| 66 |
+
{
|
| 67 |
+
public:
|
| 68 |
+
bool Cancel()
|
| 69 |
+
{
|
| 70 |
+
State expected{State::ACTIVE};
|
| 71 |
+
if (m_state.compare_exchange_strong(expected, State::CANCELLED)) return true;
|
| 72 |
+
return expected == State::CANCELLED;
|
| 73 |
+
}
|
| 74 |
+
bool IsCancelled() const { return m_state.load() == State::CANCELLED; }
|
| 75 |
+
bool BeginBroadcast()
|
| 76 |
+
{
|
| 77 |
+
State expected{State::ACTIVE};
|
| 78 |
+
return m_state.compare_exchange_strong(expected, State::BROADCAST_STARTED);
|
| 79 |
+
}
|
| 80 |
+
bool BroadcastStarted() const { return m_state.load() == State::BROADCAST_STARTED; }
|
| 81 |
+
|
| 82 |
+
private:
|
| 83 |
+
enum class State : uint8_t { ACTIVE, CANCELLED, BROADCAST_STARTED };
|
| 84 |
+
std::atomic<State> m_state{State::ACTIVE};
|
| 85 |
+
};
|
| 86 |
+
|
| 87 |
//! Result of a transient-private-key sweep. The supplied key is never retained
|
| 88 |
//! by this interface or by the wallet.
|
| 89 |
struct WalletSweepResult {
|
|
|
|
| 148 |
virtual util::Result<WalletSweepResult> sweepPrivateKey(const SecureString& private_key,
|
| 149 |
const CTxDestination& destination,
|
| 150 |
bool broadcast,
|
| 151 |
+
const std::optional<uint256>& expected_txid,
|
| 152 |
+
const std::shared_ptr<SweepAuthorization>& authorization) = 0;
|
| 153 |
|
| 154 |
//! Return whether wallet has watch only keys.
|
| 155 |
virtual bool haveWatchOnly() = 0;
|