Bitcoin Core 32.99.0
P2P Digital Currency
Loading...
Searching...
No Matches
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
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 auto tx_state = TxStateConfirmed{merkleBlock.header.GetHash(), height, static_cast<int>(txnIndex)};
88 if (pwallet->AddToWalletIfInvolvingMe(tx_ref, tx_state, /*rescanning_old_block=*/false)) {
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
102static std::optional<int64_t> GetImportTimestamp(const UniValue& data)
103{
104 if (data.exists("timestamp")) {
105 const UniValue& timestamp = data["timestamp"];
106 if (timestamp.isNum()) {
107 const int64_t value{timestamp.getInt<int64_t>()};
108 if (value < 0) {
109 throw JSONRPCError(RPC_INVALID_PARAMETER, "Timestamp must not be negative");
110 }
111 return value;
112 } else if (timestamp.isStr() && timestamp.get_str() == "now") {
113 return std::nullopt; // std::nullopt means use the current best block's MTP time
114 }
115 throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Expected number or \"now\" timestamp value for key. got type %s", uvTypeName(timestamp.type())));
116 }
117 throw JSONRPCError(RPC_TYPE_ERROR, "Missing required timestamp field for key");
118}
119
120static ImportDescriptorRequest ProcessUniValueDescriptor(const UniValue& data, std::optional<int64_t> timestamp)
121{
123 if (!data.exists("desc")) {
124 throw JSONRPCError(RPC_INVALID_PARAMETER, "Descriptor not found.");
125 }
126 request.descriptor = data["desc"].get_str();
127 request.label = LabelFromValue(data["label"]);
128 request.timestamp = timestamp;
129 if (data.exists("active")) request.active = data["active"].get_bool();
130 if (data.exists("internal")) request.internal = data["internal"].get_bool();
131 if (data.exists("range")) request.range = ParseDescriptorRange(data["range"]);
132 if (data.exists("next_index")) request.next_index = data["next_index"].getInt<int64_t>();
133 return request;
134}
135
137{
138 return RPCMethod{
139 "importdescriptors",
140 "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"
141 "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"
142 "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n"
143 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n"
144 "The rescan is significantly faster if block filters are available (using startup option \"-blockfilterindex=1\").\n",
145 {
146 {"requests", RPCArg::Type::ARR, RPCArg::Optional::NO, "Data to be imported",
147 {
149 {
150 {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "Descriptor to import."},
151 {"active", RPCArg::Type::BOOL, RPCArg::Default{false}, "Set this descriptor to be the active descriptor for the corresponding output type/externality"},
152 {"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"},
153 {"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"},
154 {"timestamp", RPCArg::Type::NUM, RPCArg::Optional::NO, "Time from which to start rescanning the blockchain for this descriptor, in " + UNIX_EPOCH_TIME + "\n"
155 "Use the string \"now\" to substitute the current synced blockchain time.\n"
156 "\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
157 "0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
158 "of all descriptors being imported will be scanned as well as the mempool.",
159 RPCArgOptions{.type_str={"timestamp | \"now\"", "integer / string"}}
160 },
161 {"internal", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether matching outputs should be treated as not incoming payments (e.g. change)"},
162 {"label", RPCArg::Type::STR, RPCArg::Default{""}, "Label to assign to the address, only allowed with internal=false. Disabled for ranged descriptors"},
163 },
164 },
165 },
167 },
168 RPCResult{
169 RPCResult::Type::ARR, "", "Response is an array with the same size as the input that has the execution result",
170 {
171 {RPCResult::Type::OBJ, "", "",
172 {
173 {RPCResult::Type::BOOL, "success", ""},
174 {RPCResult::Type::ARR, "warnings", /*optional=*/true, "",
175 {
176 {RPCResult::Type::STR, "", ""},
177 }},
178 {RPCResult::Type::OBJ, "error", /*optional=*/true, "",
179 {
180 {RPCResult::Type::NUM, "code", "JSONRPC error code"},
181 {RPCResult::Type::STR, "message", "JSONRPC error message"},
182 }},
183 }},
184 }
185 },
187 HelpExampleCli("importdescriptors", "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"internal\": true }, "
188 "{ \"desc\": \"<my descriptor 2>\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
189 HelpExampleCli("importdescriptors", "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"<my bech32 wallet>\" }]'")
190 },
192{
193 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(main_request);
194 if (!pwallet) return UniValue::VNULL;
195 CWallet& wallet{*pwallet};
196
197 const UniValue& univalue_requests = main_request.params[0];
198 // One result per input, in input order.
199 std::vector<UniValue> results(univalue_requests.size());
200 // Successfully parsed requests, each with the index of the input it came from.
201 struct ParsedRequest {
202 size_t input_index;
204 };
205 std::vector<ParsedRequest> requests;
206
207 // Malformed inputs (e.g. invalid label) are returned as per-item failures.
208 for (size_t i = 0; i < univalue_requests.size(); ++i) {
209 // Throws a top-level RPC error if "timestamp" is missing or invalid
210 std::optional<int64_t> timestamp = GetImportTimestamp(univalue_requests[i]);
211 try {
212 requests.push_back({i, ProcessUniValueDescriptor(univalue_requests[i], timestamp)});
213 } catch (const UniValue& e) {
215 results[i].pushKV("success", UniValue(false));
216 results[i].pushKV("error", e);
217 }
218 }
219
220 // Hand off the successfully parsed requests to the batch importer, which
221 // handles wallet locking, rescanning and rescan-failure error composition.
222 std::vector<ImportDescriptorRequest> descriptor_requests;
223 descriptor_requests.reserve(requests.size());
224 for (auto& parsed : requests) {
225 descriptor_requests.push_back(std::move(parsed.request));
226 }
227
229
230 // Wallet-wide precondition failure (e.g. already rescanning, or locked):
231 // surface as a top-level RPC error.
232 if (import_results.size() == 1 && import_results[0].has_error() && import_results[0].error->is_general_error) {
233 const ImportError& import_error = import_results[0].error.value();
235 throw JSONRPCError(rpc_error_code, import_error.wallet_error.message.original);
236 }
237
238 // Translate each ImportResult into the per-input UniValue result. Inputs
239 // that failed to parse already hold an error in results[] and are not
240 // part of `requests`, so use input_index to map each import_results[k]
241 // back to its slot.
242 CHECK_NONFATAL(import_results.size() == requests.size());
243 for (size_t k = 0; k < requests.size(); ++k) {
244 UniValue& result = results[requests[k].input_index];
246 result = UniValue(UniValue::VOBJ);
247 UniValue warnings(UniValue::VARR);
248 if (import_result.has_error()) {
249 const WalletError& error = import_result.error.value().wallet_error;
250 auto write_error = [&result, &error](int code) {
251 result.pushKV("success", false);
252 result.pushKV("error", JSONRPCError(code, error.message.original));
253 };
256 } else {
257 result.pushKV("success", true);
258 }
259 for (const auto& w : import_result.warnings) {
260 warnings.push_back(w);
261 }
262 PushWarnings(warnings, result);
263 }
264
266 for (UniValue& result : results) {
267 response.push_back(std::move(result));
268 }
269 return response;
270},
271 };
272}
273
275{
276 return RPCMethod{
277 "listdescriptors",
278 "List all descriptors present in a wallet.\n",
279 {
280 {"private", RPCArg::Type::BOOL, RPCArg::Default{false}, "Show private descriptors."}
281 },
283 {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
284 {RPCResult::Type::ARR, "descriptors", "Array of descriptor objects (sorted by descriptor string representation)",
285 {
286 {RPCResult::Type::OBJ, "", "", {
287 {RPCResult::Type::STR, "desc", "Descriptor string representation"},
288 {RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"},
289 {RPCResult::Type::BOOL, "active", "Whether this descriptor is currently used to generate new addresses"},
290 {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"},
291 {RPCResult::Type::ARR_FIXED, "range", /*optional=*/true, "Defined only for ranged descriptors", {
292 {RPCResult::Type::NUM, "", "Range start inclusive"},
293 {RPCResult::Type::NUM, "", "Range end inclusive"},
294 }},
295 {RPCResult::Type::NUM, "next", /*optional=*/true, "Same as next_index field. Kept for compatibility reason."},
296 {RPCResult::Type::NUM, "next_index", /*optional=*/true, "The next index to generate addresses from; defined only for ranged descriptors"},
297 }},
298 }}
299 }},
301 HelpExampleCli("listdescriptors", "") + HelpExampleRpc("listdescriptors", "")
302 + HelpExampleCli("listdescriptors", "true") + HelpExampleRpc("listdescriptors", "true")
303 },
304 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
305{
306 const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request);
307 if (!wallet) return UniValue::VNULL;
308
309 const bool priv{self.Arg<bool>("private")};
310 if (wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && priv) {
311 throw JSONRPCError(RPC_WALLET_ERROR, "Can't get private descriptor string for watch-only wallets");
312 }
313 if (priv) {
315 }
316
317 LOCK(wallet->cs_wallet);
319 if (!exported) {
320 throw JSONRPCError(RPC_WALLET_ERROR, exported.error());
321 }
322 std::vector<WalletDescInfo> wallet_descriptors = *exported;
323
324 std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](const auto& a, const auto& b) {
325 return a.descriptor < b.descriptor;
326 });
327
329 for (const WalletDescInfo& info : wallet_descriptors) {
331 spk.pushKV("desc", info.descriptor);
332 spk.pushKV("timestamp", info.creation_time);
333 spk.pushKV("active", info.active);
334 if (info.internal.has_value()) {
335 spk.pushKV("internal", info.internal.value());
336 }
337 if (info.range.has_value()) {
339 range.push_back(info.range->first);
340 range.push_back(info.range->second - 1);
341 spk.pushKV("range", std::move(range));
342 spk.pushKV("next", info.next_index);
343 spk.pushKV("next_index", info.next_index);
344 }
345 descriptors.push_back(std::move(spk));
346 }
347
349 response.pushKV("wallet_name", wallet->GetName());
350 response.pushKV("descriptors", std::move(descriptors));
351
352 return response;
353},
354 };
355}
356
358{
359 return RPCMethod{
360 "backupwallet",
361 "Safely copies the current wallet file to the specified destination, which can either be a directory or a path with a filename.\n",
362 {
363 {"destination", RPCArg::Type::STR, RPCArg::Optional::NO, "The destination directory or file"},
364 },
367 HelpExampleCli("backupwallet", "\"backup.dat\"")
368 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
369 },
370 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
371{
372 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
373 if (!pwallet) return UniValue::VNULL;
374
375 // Make sure the results are valid at least up to the most recent block
376 // the user could have gotten from another RPC command prior to now
377 pwallet->BlockUntilSyncedToCurrentChain();
378
379 LOCK(pwallet->cs_wallet);
380
381 std::string strDest = request.params[0].get_str();
382 if (!pwallet->BackupWallet(strDest)) {
383 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
384 }
385
386 return UniValue::VNULL;
387},
388 };
389}
390
391
393{
394 return RPCMethod{
395 "restorewallet",
396 "Restores and loads a wallet from backup.\n"
397 "\nThe rescan is significantly faster if block filters are available"
398 "\n(using startup option \"-blockfilterindex=1\").\n",
399 {
400 {"wallet_name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name that will be applied to the restored wallet"},
401 {"backup_file", RPCArg::Type::STR, RPCArg::Optional::NO, "The backup file that will be used to restore the wallet."},
402 {"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."},
403 },
404 RPCResult{
405 RPCResult::Type::OBJ, "", "",
406 {
407 {RPCResult::Type::STR, "name", "The wallet name if restored successfully."},
408 {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to restoring and loading the wallet.",
409 {
410 {RPCResult::Type::STR, "", ""},
411 }},
412 }
413 },
415 HelpExampleCli("restorewallet", "\"testwallet\" \"home\\backups\\backup-file.bak\"")
416 + HelpExampleRpc("restorewallet", R"("testwallet", "home\\backups\\backup-file.bak")")
417 + HelpExampleCliNamed("restorewallet", {{"wallet_name", "testwallet"}, {"backup_file", "home\\backups\\backup-file.bak"}, {"load_on_startup", true}})
418 + HelpExampleRpcNamed("restorewallet", {{"wallet_name", "testwallet"}, {"backup_file", "home\\backups\\backup-file.bak"}, {"load_on_startup", true}})
419 },
420 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
421{
422
423 WalletContext& context = EnsureWalletContext(request.context);
424
425 auto backup_file = fs::u8path(request.params[1].get_str());
426
427 std::string wallet_name = request.params[0].get_str();
428
429 std::optional<bool> load_on_start = request.params[2].isNull() ? std::nullopt : std::optional<bool>(request.params[2].get_bool());
430
431 DatabaseStatus status;
432 bilingual_str error;
433 std::vector<bilingual_str> warnings;
434
435 const std::shared_ptr<CWallet> wallet = RestoreWallet(context, backup_file, wallet_name, load_on_start, status, error, warnings);
436
437 HandleWalletError(wallet, status, error);
438
440 obj.pushKV("name", wallet->GetName());
441 PushWarnings(warnings, obj);
442
443 return obj;
444
445},
446 };
447}
448} // namespace wallet
#define CHECK_NONFATAL(condition)
Identity function.
Definition check.h:115
#define NONFATAL_UNREACHABLE()
NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code.
Definition check.h:139
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
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
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
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition expected.h:44
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition wallet.h:318
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
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:136
static ImportDescriptorRequest ProcessUniValueDescriptor(const UniValue &data, std::optional< int64_t > timestamp)
Definition backup.cpp:120
void EnsureWalletIsUnlocked(const CWallet &wallet)
Definition util.cpp:85
std::vector< ImportResult > ProcessDescriptorsImport(CWallet &wallet, std::vector< ImportDescriptorRequest > &requests)
Definition imports.cpp:230
@ 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 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:274
RPCMethod backupwallet()
Definition backup.cpp:357
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:392
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:102
is a home for public enum and struct type definitions that are used internally by node code,...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
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_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:1329
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:1402
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
A mutable version of CTransaction.
Txid GetHash() const
Compute the hash of this CMutableTransaction.
@ 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
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:90
bilingual_str message
User-facing translated error message.
Definition types.h:94
WalletErrorCode code
Machine-readable error code for callers that need programmatic handling.
Definition types.h:92
#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...
const char * uvTypeName(UniValue::VType t)
Definition univalue.cpp:217
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:82
WalletContext context