v29.4-roots.3 · Commit 24: [PATCH 24/30] feat(qt): add guarded private key sweep dialog
src/wallet/interfaces.cpp
Before: src/wallet/interfaces.cpp · After: src/wallet/interfaces.cpp
File metadata
index 2880db261732c4bc44da32f644ec13bd1fc32581..10bbd25e6dc0e4eb6401c6b910de9a6db0c0cc6c 100644
Download original patch · Release notes
Diff rows 1–65 of 65. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/wallet/interfaces.cpp
CHANGED
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
#include <wallet/spend.h>
|
|
31
31
|
#include <wallet/wallet.h>
|
|
32
32
|
|
|
33
|
+
#include <key_io.h>
|
|
34
|
+
#include <script/solver.h>
|
|
35
|
+
#include <policy/policy.h>
|
|
36
|
+
|
|
33
37
|
#include <memory>
|
|
34
38
|
#include <string>
|
|
35
39
|
#include <utility>
|
|
@@ -46,6 +50,7 @@ using interfaces::WalletBalances;
|
|
|
46
50
|
using interfaces::WalletLoader;
|
|
47
51
|
using interfaces::WalletMigrationResult;
|
|
48
52
|
using interfaces::WalletOrderForm;
|
|
53
|
+
using interfaces::WalletSweepResult;
|
|
49
54
|
using interfaces::WalletTx;
|
|
50
55
|
using interfaces::WalletTxOut;
|
|
51
56
|
using interfaces::WalletTxStatus;
|
|
@@ -175,6 +180,48 @@ public:
|
|
|
175
180
|
LOCK(m_wallet->cs_wallet);
|
|
176
181
|
return m_wallet->IsMine(dest) & ISMINE_SPENDABLE;
|
|
177
182
|
}
|
|
183
|
+
util::Result<WalletSweepResult> sweepPrivateKey(const SecureString& private_key,
|
|
184
|
+
const CTxDestination& destination,
|
|
185
|
+
bool broadcast,
|
|
186
|
+
const std::optional<uint256>& expected_txid) override
|
|
187
|
+
{
|
|
188
|
+
CKey key{DecodeSecret(std::string{private_key.begin(), private_key.end()})};
|
|
189
|
+
if (!key.IsValid()) return util::Error{Untranslated("Invalid private key or wrong network")};
|
|
190
|
+
const CPubKey pubkey{key.GetPubKey()};
|
|
191
|
+
FlatSigningProvider provider;
|
|
192
|
+
provider.keys.emplace(pubkey.GetID(), key);
|
|
193
|
+
provider.pubkeys.emplace(pubkey.GetID(), pubkey);
|
|
194
|
+
std::set<CScript> scan_objects{GetScriptForDestination(PKHash(pubkey))};
|
|
195
|
+
if (pubkey.IsCompressed()) {
|
|
196
|
+
const CScript witness{GetScriptForDestination(WitnessV0KeyHash(pubkey))};
|
|
197
|
+
scan_objects.insert(witness);
|
|
198
|
+
provider.scripts.emplace(CScriptID(witness), witness);
|
|
199
|
+
scan_objects.insert(GetScriptForDestination(ScriptHash(witness)));
|
|
200
|
+
}
|
|
201
|
+
const CScript destination_script{GetScriptForDestination(destination)};
|
|
202
|
+
{
|
|
203
|
+
LOCK(m_wallet->cs_wallet);
|
|
204
|
+
if (m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) || !(m_wallet->IsMine(destination_script) & ISMINE_SPENDABLE)) {
|
|
205
|
+
return util::Error{Untranslated("Destination is not controlled by this wallet")};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
std::map<COutPoint, Coin> coins;
|
|
209
|
+
switch (m_wallet->chain().findScriptPubKeys(scan_objects, coins)) {
|
|
210
|
+
case interfaces::ScanResult::SUCCESS: break;
|
|
211
|
+
case interfaces::ScanResult::BUSY: return util::Error{Untranslated("UTXO scan already in progress")};
|
|
212
|
+
case interfaces::ScanResult::ABORTED: return util::Error{Untranslated("UTXO scan aborted")};
|
|
213
|
+
case interfaces::ScanResult::UNAVAILABLE: return util::Error{Untranslated("UTXO scan unavailable")};
|
|
214
|
+
}
|
|
215
|
+
auto swept{CreateSweepTransaction(*m_wallet, provider, coins, destination_script, broadcast ? SweepBroadcastFn{[&, expected_txid](const CTransactionRef& tx, std::string& error) {
|
|
216
|
+
if (expected_txid && tx->GetHash() != *expected_txid) {
|
|
217
|
+
error = "Sweep preview is stale; create a fresh preview";
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return m_wallet->chain().broadcastTransaction(tx, m_wallet->m_default_max_tx_fee, /*relay=*/true, error);
|
|
221
|
+
}} : SweepBroadcastFn{})};
|
|
222
|
+
if (!swept) return util::Error{util::ErrorString(swept)};
|
|
223
|
+
return WalletSweepResult{swept->tx, swept->amount, swept->fee, coins.size(), GetVirtualTransactionSize(*swept->tx), broadcast};
|
|
224
|
+
}
|
|
178
225
|
bool haveWatchOnly() override
|
|
179
226
|
{
|
|
180
227
|
auto spk_man = m_wallet->GetLegacyScriptPubKeyMan();
|