Bitcoin Core 32.99.0
P2P Digital Currency
backup.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-present The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <chain.h>
6#include <clientversion.h>
7#include <core_io.h>
8#include <hash.h>
9#include <interfaces/chain.h>
10#include <key_io.h>
11#include <merkleblock.h>
12#include <node/types.h>
13#include <rpc/util.h>
14#include <script/descriptor.h>
15#include <script/script.h>
16#include <script/solver.h>
17#include <sync.h>
18#include <uint256.h>
19#include <util/bip32.h>
20#include <util/check.h>
21#include <util/fs.h>
22#include <util/time.h>
23#include <util/translation.h>
24#include <wallet/export.h>
25#include <wallet/imports.h>
26#include <wallet/rpc/util.h>
27#include <wallet/scan.h>
28#include <wallet/wallet.h>
29
30#include <cstdint>
31#include <fstream>
32#include <tuple>
33#include <string>
34
35#include <univalue.h>
36
37
38
40
41namespace wallet {
43{
44 return RPCMethod{
45 "importprunedfunds",
46 "Imports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n",
47 {
48 {"rawtransaction", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A raw transaction in hex funding an already-existing address in wallet"},
49 {"txoutproof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex output from gettxoutproof that contains the transaction"},
50 },
52 RPCExamples{""},
53 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
54{
55 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
56 if (!pwallet) return UniValue::VNULL;
57
59 if (!DecodeHexTx(tx, request.params[0].get_str())) {
60 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
61 }
62
63 CMerkleBlock merkleBlock;
64 SpanReader{ParseHexV(request.params[1], "proof")} >> merkleBlock;
65
66 //Search partial merkle tree in proof for our transaction and index in valid block
67 std::vector<Txid> vMatch;
68 std::vector<unsigned int> vIndex;
69 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) {
70 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Something wrong with merkleblock");
71 }
72
73 LOCK(pwallet->cs_wallet);
74 int height;
75 if (!pwallet->chain().findAncestorByHash(pwallet->GetLastBlockHash(), merkleBlock.header.GetHash(), FoundBlock().height(height))) {
76 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found in chain");
77 }
78
79 std::vector<Txid>::const_iterator it;
80 if ((it = std::find(vMatch.begin(), vMatch.end(), tx.GetHash())) == vMatch.end()) {
81 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction given doesn't exist in proof");
82 }
83
84 unsigned int txnIndex = vIndex[it - vMatch.begin()];
85
87 if (pwallet->IsMine(*tx_ref)) {
88 pwallet->AddToWallet(std::move(tx_ref), TxStateConfirmed{merkleBlock.header.GetHash(), height, static_cast<int>(txnIndex)});
89 return UniValue::VNULL;
90 }
91
92 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No addresses in wallet correspond to included transaction");
93},
94 };
95}
96
98{
99 return RPCMethod{
100 "removeprunedfunds",
101 "(DEPRECATED) This feature will be removed in the next major release. Start bitcoind with the `-deprecatedrpc=removeprunedfunds` option in order to use this.\n"
102 "Deletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.\n",
103 {
104 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded id of the transaction you are deleting"},
105 },
108 HelpExampleCli("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
109 "\nAs a JSON-RPC call\n"
110 + HelpExampleRpc("removeprunedfunds", "\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
111 },
112 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
113{
114 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
115 if (!pwallet) return UniValue::VNULL;
116
117 if (!pwallet->chain().rpcEnableDeprecated("removeprunedfunds")) {
118 throw JSONRPCError(RPC_METHOD_DEPRECATED, "DEPRECATION WARNING: This feature will be removed in the next major release. Start bitcoind with the `-deprecatedrpc=removeprunedfunds` option in order to use this.");
119 }
120
121 LOCK(pwallet->cs_wallet);
122
123 Txid hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
124 std::vector<Txid> vHash;
125 vHash.push_back(hash);
126 if (auto res = pwallet->RemoveTxs(vHash); !res) {
127 throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original);
128 }
129
130 return UniValue::VNULL;
131},
132 };
133}
134
135
141static std::optional<int64_t> GetImportTimestamp(const UniValue& data)
142{
143 if (data.exists("timestamp")) {
144 const UniValue& timestamp = data["timestamp"];
145 if (timestamp.isNum()) {
146 const int64_t value{timestamp.getInt<int64_t>()};
147 if (value < 0) {
148 throw JSONRPCError(RPC_INVALID_PARAMETER, "Timestamp must not be negative");
149 }
150 return value;
151 } else if (timestamp.isStr() && timestamp.get_str() == "now") {
152 return std::nullopt; // std::nullopt means use the current best block's MTP time
153 }
154 throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type())));
155 }
156 throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key");
157}
158
159static ImportDescriptorRequest ProcessUniValueDescriptor(const UniValue& data, std::optional<int64_t> timestamp)
160{
162 if (!data.exists("desc")) {
163 throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor not found.");
164 }
165 request.descriptor = data["desc"].get_str();
166 request.label = LabelFromValue(data["label"]);
167 request.timestamp = timestamp;
168 if (data.exists("active")) request.active = data["active"].get_bool();
169 if (data.exists("internal")) request.internal = data["internal"].get_bool();
170 if (data.exists("range")) request.range = ParseDescriptorRange(data["range"]);
171 if (data.exists("next_index")) request.next_index = data["next_index"].getInt<int64_t>();
172 return request;
173}
174
176{
177 return RPCMethod{
178 "importdescriptors",
179 "Import descriptors. This will trigger a rescan of the blockchain based on the earliest timestamp of all descriptors being imported. Requires a new wallet backup.\n"
180 "When importing descriptors with multipath key expressions, if the multipath specifier contains exactly two elements, the descriptor produced from the second element will be imported as an internal descriptor.\n"
181 "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n"
182 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n"
183 "The rescan is significantly faster if block filters are available (using startup option \"-blockfilterindex=1\").\n",
184 {
185 {"requests", RPCArg::Type::ARR, RPCArg::Optional::NO, "Data to be imported",
186 {
188 {
189 {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "Descriptor to import."},
190 {"active", RPCArg::Type::BOOL, RPCArg::Default{false}, "Set this descriptor to be the active descriptor for the corresponding output type/externality"},
191 {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED, "If a ranged descriptor is used, this specifies the end or the range (in the form [begin,end]) to import"},
192 {"next_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If a ranged descriptor is set to active, this specifies the next index to generate addresses from"},
193 {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, "Time from which to start rescanning the blockchain for this descriptor, in " + UNIX_EPOCH_TIME + "\n"
194 "Use the string \"now\" to substitute the current synced blockchain time.\n"
195 "\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
196 "0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
197 "of all descriptors being imported will be scanned as well as the mempool.",
198 RPCArgOptions{.type_str={"timestamp | \"now\"", "integer / string"}}
199 },
200 {"internal", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether matching outputs should be treated as not incoming payments (e.g. change)"},
201 {"label", RPCArg::Type::STR, RPCArg::Default{""}, "Label to assign to the address, only allowed with internal=false. Disabled for ranged descriptors"},
202 },
203 },
204 },
206 },
207 RPCResult{
208 RPCResult::Type::ARR, "", "Response is an array with the same size as the input that has the execution result",
209 {
210 {RPCResult::Type::OBJ, "", "",
211 {
212 {RPCResult::Type::BOOL, "success", ""},
213 {RPCResult::Type::ARR, "warnings", /*optional=*/true, "",
214 {
215 {RPCResult::Type::STR, "", ""},
216 }},
217 {RPCResult::Type::OBJ, "error", /*optional=*/true, "",
218 {
219 {RPCResult::Type::NUM, "code", "JSONRPC error code"},
220 {RPCResult::Type::STR, "message", "JSONRPC error message"},
221 }},
222 }},
223 }
224 },
226 HelpExampleCli("importdescriptors", "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"internal\": true }, "
227 "{ \"desc\": \"<my descriptor 2>\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
228 HelpExampleCli("importdescriptors", "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"<my bech32 wallet>\" }]'")
229 },
230 [](const RPCMethod& self, const JSONRPCRequest& main_request) -> UniValue
231{
232 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(main_request);
233 if (!pwallet) return UniValue::VNULL;
234 CWallet& wallet{*pwallet};
235
236 const UniValue& univalue_requests = main_request.params[0];
237 // One result per input, in input order.
238 std::vector<UniValue> results(univalue_requests.size());
239 // Successfully parsed requests, each with the index of the input it came from.
240 struct ParsedRequest {
241 size_t input_index;
243 };
244 std::vector<ParsedRequest> requests;
245
246 // Malformed inputs (e.g. invalid label) are returned as per-item failures.
247 for (size_t i = 0; i < univalue_requests.size(); ++i) {
248 // Throws a top-level RPC error if "timestamp" is missing or invalid
249 std::optional<int64_t> timestamp = GetImportTimestamp(univalue_requests[i]);
250 try {
251 requests.push_back({i, ProcessUniValueDescriptor(univalue_requests[i], timestamp)});
252 } catch (const UniValue& e) {
253 results[i] = UniValue(UniValue::VOBJ);
254 results[i].pushKV("success", UniValue(false));
255 results[i].pushKV("error", e);
256 }
257 }
258
259 // Hand off the successfully parsed requests to the batch importer, which
260 // handles wallet locking, rescanning and rescan-failure error composition.
261 std::vector<ImportDescriptorRequest> descriptor_requests;
262 descriptor_requests.reserve(requests.size());
263 for (auto& parsed : requests) {
264 descriptor_requests.push_back(std::move(parsed.request));
265 }
266
267 std::vector<ImportResult> import_results{ProcessDescriptorsImport(wallet, descriptor_requests)};
268
269 // Wallet-wide precondition failure (e.g. already rescanning, or locked):
270 // surface as a top-level RPC error.
271 if (import_results.size() == 1 && import_results[0].has_error() && import_results[0].error->is_general_error) {
272 const ImportError& import_error = import_results[0].error.value();
273 RPCErrorCode rpc_error_code{HandleWalletErrorCode(import_error.wallet_error.code)};
274 throw JSONRPCError(rpc_error_code, import_error.wallet_error.message.original);
275 }
276
277 // Translate each ImportResult into the per-input UniValue result. Inputs
278 // that failed to parse already hold an error in results[] and are not
279 // part of `requests`, so use input_index to map each import_results[k]
280 // back to its slot.
281 CHECK_NONFATAL(import_results.size() == requests.size());
282 for (size_t k = 0; k < requests.size(); ++k) {
283 UniValue& result = results[requests[k].input_index];
284 const ImportResult& import_result = import_results[k];
285 result = UniValue(UniValue::VOBJ);
286 UniValue warnings(UniValue::VARR);
287 if (import_result.has_error()) {
288 const WalletError& error = import_result.error.value().wallet_error;
289 auto write_error = [&result, &error](int code) {
290 result.pushKV("success", false);
291 result.pushKV("error", JSONRPCError(code, error.message.original));
292 };
294 write_error(HandleWalletErrorCode(error.code));
295 } else {
296 result.pushKV("success", true);
297 }
298 for (const auto& w : import_result.warnings) {
299 warnings.push_back(w);
300 }
301 PushWarnings(warnings, result);
302 }
303
304 UniValue response(UniValue::VARR);
305 for (UniValue& result : results) {
306 response.push_back(std::move(result));
307 }
308 return response;
309},
310 };
311}
312
314{
315 return RPCMethod{
316 "listdescriptors",
317 "List all descriptors present in a wallet.\n",
318 {
319 {"private", RPCArg::Type::BOOL, RPCArg::Default{false}, "Show private descriptors."}
320 },
322 {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
323 {RPCResult::Type::ARR, "descriptors", "Array of descriptor objects (sorted by descriptor string representation)",
324 {
325 {RPCResult::Type::OBJ, "", "", {
326 {RPCResult::Type::STR, "desc", "Descriptor string representation"},
327 {RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
328 {RPCResult::Type::BOOL, "active", "Whether this descriptor is currently used to generate new addresses"},
329 {RPCResult::Type::BOOL, "internal", /*optional=*/true, "True if this descriptor is used to generate change addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
330 {RPCResult::Type::ARR_FIXED, "range", /*optional=*/true, "Defined only for ranged descriptors", {
331 {RPCResult::Type::NUM, "", "Range start inclusive"},
332 {RPCResult::Type::NUM, "", "Range end inclusive"},
333 }},
334 {RPCResult::Type::NUM, "next", /*optional=*/true, "Same as next_index field. Kept for compatibility reason."},
335 {RPCResult::Type::NUM, "next_index", /*optional=*/true, "The next index to generate addresses from; defined only for ranged descriptors"},
336 }},
337 }}
338 }},
340 HelpExampleCli("listdescriptors", "") + HelpExampleRpc("listdescriptors", "")
341 + HelpExampleCli("listdescriptors", "true") + HelpExampleRpc("listdescriptors", "true")
342 },
343 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
344{
345 const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request);
346 if (!wallet) return UniValue::VNULL;
347
348 const bool priv = !request.params[0].isNull() && request.params[0].get_bool();
349 if (wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && priv) {
350 throw JSONRPCError(RPC_WALLET_ERROR, "Can't get private descriptor string for watch-only wallets");
351 }
352 if (priv) {
354 }
355
356 LOCK(wallet->cs_wallet);
358 if (!exported) {
359 throw JSONRPCError(RPC_WALLET_ERROR, exported.error());
360 }
361 std::vector<WalletDescInfo> wallet_descriptors = *exported;
362
363 std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](const auto& a, const auto& b) {
364 return a.descriptor < b.descriptor;
365 });
366
367 UniValue descriptors(UniValue::VARR);
368 for (const WalletDescInfo& info : wallet_descriptors) {
370 spk.pushKV("desc", info.descriptor);
371 spk.pushKV("timestamp", info.creation_time);
372 spk.pushKV("active", info.active);
373 if (info.internal.has_value()) {
374 spk.pushKV("internal", info.internal.value());
375 }
376 if (info.range.has_value()) {
378 range.push_back(info.range->first);
379 range.push_back(info.range->second - 1);
380 spk.pushKV("range", std::move(range));
381 spk.pushKV("next", info.next_index);
382 spk.pushKV("next_index", info.next_index);
383 }
384 descriptors.push_back(std::move(spk));
385 }
386
387 UniValue response(UniValue::VOBJ);
388 response.pushKV("wallet_name", wallet->GetName());
389 response.pushKV("descriptors", std::move(descriptors));
390
391 return response;
392},
393 };
394}
395
397{
398 return RPCMethod{
399 "backupwallet",
400 "Safely copies the current wallet file to the specified destination, which can either be a directory or a path with a filename.\n",
401 {
402 {"destination", RPCArg::Type::STR, RPCArg::Optional::NO, "The destination directory or file"},
403 },
406 HelpExampleCli("backupwallet", "\"backup.dat\"")
407 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
408 },
409 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
410{
411 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
412 if (!pwallet) return UniValue::VNULL;
413
414 // Make sure the results are valid at least up to the most recent block
415 // the user could have gotten from another RPC command prior to now
416 pwallet->BlockUntilSyncedToCurrentChain();
417
418 LOCK(pwallet->cs_wallet);
419
420 std::string strDest = request.params[0].get_str();
421 if (!pwallet->BackupWallet(strDest)) {
422 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
423 }
424
425 return UniValue::VNULL;
426},
427 };
428}
429
430
432{
433 return RPCMethod{
434 "restorewallet",
435 "Restores and loads a wallet from backup.\n"
436 "\nThe rescan is significantly faster if block filters are available"
437 "\n(using startup option \"-blockfilterindex=1\").\n",
438 {
439 {"wallet_name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name that will be applied to the restored wallet"},
440 {"backup_file", RPCArg::Type::STR, RPCArg::Optional::NO, "The backup file that will be used to restore the wallet."},
441 {"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
442 },
443 RPCResult{
444 RPCResult::Type::OBJ, "", "",
445 {
446 {RPCResult::Type::STR, "name", "The wallet name if restored successfully."},
447 {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to restoring and loading the wallet.",
448 {
449 {RPCResult::Type::STR, "", ""},
450 }},
451 }
452 },
454 HelpExampleCli("restorewallet", "\"testwallet\" \"home\\backups\\backup-file.bak\"")
455 + HelpExampleRpc("restorewallet", R"("testwallet", "home\\backups\\backup-file.bak")")
456 + HelpExampleCliNamed("restorewallet", {{"wallet_name", "testwallet"}, {"backup_file", "home\\backups\\backup-file.bak"}, {"load_on_startup", true}})
457 + HelpExampleRpcNamed("restorewallet", {{"wallet_name", "testwallet"}, {"backup_file", "home\\backups\\backup-file.bak"}, {"load_on_startup", true}})
458 },
459 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
460{
461
462 WalletContext& context = EnsureWalletContext(request.context);
463
464 auto backup_file = fs::u8path(request.params[1].get_str());
465
466 std::string wallet_name = request.params[0].get_str();
467
468 std::optional<bool> load_on_start = request.params[2].isNull() ? std::nullopt : std::optional<bool>(request.params[2].get_bool());
469
470 DatabaseStatus status;
471 bilingual_str error;
472 std::vector<bilingual_str> warnings;
473
474 const std::shared_ptr<CWallet> wallet = RestoreWallet(context, backup_file, wallet_name, load_on_start, status, error, warnings);
475
476 HandleWalletError(wallet, status, error);
477
479 obj.pushKV("name", wallet->GetName());
480 PushWarnings(warnings, obj);
481
482 return obj;
483
484},
485 };
486}
487} // namespace wallet
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:112
#define NONFATAL_UNREACHABLE()
NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code.
Definition: check.h:133
uint256 hashMerkleRoot
Definition: block.h:32
uint256 GetHash() const
Definition: block.cpp:14
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
Definition: merkleblock.h:127
CBlockHeader header
Public only for unit testing.
Definition: merkleblock.h:130
CPartialMerkleTree txn
Definition: merkleblock.h:131
uint256 ExtractMatches(std::vector< Txid > &vMatch, std::vector< unsigned int > &vnIndex)
extract the matching txid's represented by this partial merkle tree and their respective indices with...
Minimal stream for reading from an existing byte array by std::span.
Definition: streams.h:83
void push_back(UniValue val)
Definition: univalue.cpp:103
const std::string & get_str() const
@ VNULL
Definition: univalue.h:24
@ VOBJ
Definition: univalue.h:24
@ VARR
Definition: univalue.h:24
size_t size() const
Definition: univalue.h:71
enum VType type() const
Definition: univalue.h:131
bool isStr() const
Definition: univalue.h:85
Int getInt() const
Definition: univalue.h:143
bool isNum() const
Definition: univalue.h:86
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:125
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:52
static transaction_identifier FromUint256(const uint256 &id)
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
constexpr const E & error() const &noexcept LIFETIMEBOUND
Definition: expected.h:86
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:313
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness, bool try_witness)
Definition: core_io.cpp:225
static path u8path(std::string_view utf8_str)
Definition: fs.h:80
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:93
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: util.cpp:62
void HandleWalletError(const std::shared_ptr< CWallet > &wallet, DatabaseStatus &status, bilingual_str &error)
Definition: util.cpp:124
RPCMethod importdescriptors()
Definition: backup.cpp:175
static ImportDescriptorRequest ProcessUniValueDescriptor(const UniValue &data, std::optional< int64_t > timestamp)
Definition: backup.cpp:159
void EnsureWalletIsUnlocked(const CWallet &wallet)
Definition: util.cpp:85
std::vector< ImportResult > ProcessDescriptorsImport(CWallet &wallet, std::vector< ImportDescriptorRequest > &requests)
Definition: imports.cpp:222
@ UnlockNeeded
The wallet is locked and the operation requires access to private keys.
RPCErrorCode HandleWalletErrorCode(const WalletErrorCode code)
Definition: util.cpp:156
WalletContext & EnsureWalletContext(const std::any &context)
Definition: util.cpp:92
RPCMethod removeprunedfunds()
Definition: backup.cpp:97
RPCMethod importprunedfunds()
Definition: backup.cpp:42
std::string LabelFromValue(const UniValue &value)
Definition: util.cpp:101
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings, bool load_after_restore, bool allow_unnamed)
Definition: wallet.cpp:406
RPCMethod listdescriptors()
Definition: backup.cpp:313
RPCMethod backupwallet()
Definition: backup.cpp:396
util::Expected< std::vector< WalletDescInfo >, std::string > ExportDescriptors(const CWallet &wallet, bool export_private)
Export the descriptors from a wallet so that they can be imported elsewhere.
Definition: export.cpp:18
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:30
RPCMethod restorewallet()
Definition: backup.cpp:431
DatabaseStatus
Definition: db.h:180
static std::optional< int64_t > GetImportTimestamp(const UniValue &data)
Converts the timestamp from UniValue data to an int64_t.
Definition: backup.cpp:141
is a home for public enum and struct type definitions that are used internally by node code,...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:418
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:417
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:75
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:50
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
Definition: protocol.h:66
@ RPC_METHOD_DEPRECATED
RPC method is deprecated.
Definition: protocol.h:76
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:69
@ RPC_WALLET_ERROR
Wallet errors.
Definition: protocol.h:97
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
Definition: protocol.h:71
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:67
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
Definition: util.cpp:1328
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:189
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:213
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string_view name)
Definition: util.cpp:136
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
Definition: util.cpp:1401
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:207
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
Definition: util.cpp:49
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:194
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:123
A mutable version of CTransaction.
Definition: transaction.h:372
Txid GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:69
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ STR_HEX
Special type that is a STR with only hex chars.
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
@ NO
Required arg.
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings....
Definition: util.h:171
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Definition: util.h:170
@ ARR_FIXED
Special array that has a fixed number of entries.
Bilingual messages:
Definition: translation.h:24
std::string original
Definition: translation.h:25
Information about a descriptor to be imported.
Definition: imports.h:49
std::optional< int64_t > timestamp
Definition: imports.h:52
std::optional< int64_t > next_index
Definition: imports.h:56
std::optional< bool > internal
Definition: imports.h:54
std::optional< std::pair< int64_t, int64_t > > range
Definition: imports.h:55
WalletError wallet_error
Definition: imports.h:20
std::optional< ImportError > error
Definition: imports.h:35
bool has_error() const
Definition: imports.h:37
std::vector< std::string > warnings
Definition: imports.h:34
State of transaction confirmed in a block.
Definition: transaction.h:34
WalletContext struct containing references to state shared between CWallet instances,...
Definition: context.h:36
Wallet-layer error with both programmatic and user-facing information.
Definition: types.h:87
bilingual_str message
User-facing translated error message.
Definition: types.h:91
WalletErrorCode code
Machine-readable error code for callers that need programmatic handling.
Definition: types.h:89
#define LOCK(cs)
Definition: sync.h:268
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
const char * uvTypeName(UniValue::VType t)
Definition: univalue.cpp:217