Bitcoin ABC 0.30.7
P2P Digital Currency
util.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2021 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 <wallet/rpc/util.h>
6
7#include <rpc/util.h>
8#include <util/any.h>
9#include <util/translation.h>
10#include <util/url.h>
11#include <wallet/context.h>
12#include <wallet/wallet.h>
13
14#include <univalue.h>
15
16static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
17const std::string HELP_REQUIRING_PASSPHRASE{
18 "\nRequires wallet passphrase to be set with walletpassphrase call if "
19 "wallet is encrypted.\n"};
20
21bool GetAvoidReuseFlag(const CWallet *const pwallet, const UniValue &param) {
22 bool can_avoid_reuse = pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
23 bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool();
24
25 if (avoid_reuse && !can_avoid_reuse) {
26 throw JSONRPCError(
28 "wallet does not have the \"avoid reuse\" feature enabled");
29 }
30
31 return avoid_reuse;
32}
33
38bool ParseIncludeWatchonly(const UniValue &include_watchonly,
39 const CWallet &pwallet) {
40 if (include_watchonly.isNull()) {
41 // if include_watchonly isn't explicitly set, then check if we have a
42 // watchonly wallet
44 }
45
46 // otherwise return whatever include_watchonly was set to
47 return include_watchonly.get_bool();
48}
49
51 std::string &wallet_name) {
52 if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) ==
54 // wallet endpoint was used
55 wallet_name =
56 urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
57 return true;
58 }
59 return false;
60}
61
62std::shared_ptr<CWallet>
65 std::string wallet_name;
66 if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
67 std::shared_ptr<CWallet> pwallet = GetWallet(wallet_name);
68 if (!pwallet) {
69 throw JSONRPCError(
71 "Requested wallet does not exist or is not loaded");
72 }
73 return pwallet;
74 }
75
76 std::vector<std::shared_ptr<CWallet>> wallets = GetWallets();
77 if (wallets.size() == 1) {
78 return wallets[0];
79 }
80
81 if (wallets.empty()) {
82 throw JSONRPCError(
84 "No wallet is loaded. Load a wallet using loadwallet or create a "
85 "new one with createwallet. (Note: A default wallet is no longer "
86 "automatically created)");
87 }
88
90 "Wallet file not specified (must request wallet RPC "
91 "through /wallet/<filename> uri-path).");
92}
93
94void EnsureWalletIsUnlocked(const CWallet *pwallet) {
95 if (pwallet->IsLocked()) {
97 "Error: Please enter the wallet passphrase with "
98 "walletpassphrase first.");
99 }
100}
101
102WalletContext &EnsureWalletContext(const std::any &context) {
103 auto wallet_context = util::AnyPtr<WalletContext>(context);
104 if (!wallet_context) {
105 throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
106 }
107 return *wallet_context;
108}
109
110// also_create should only be set to true only when the RPC is expected to add
111// things to a blank wallet and make it no longer blank
113 bool also_create) {
114 LegacyScriptPubKeyMan *spk_man = wallet.GetLegacyScriptPubKeyMan();
115 if (!spk_man && also_create) {
116 spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan();
117 }
118 if (!spk_man) {
120 "This type of wallet does not support this command");
121 }
122 return *spk_man;
123}
124
125std::string LabelFromValue(const UniValue &value) {
126 std::string label = value.get_str();
127 if (label == "*") {
128 throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, "Invalid label name");
129 }
130 return label;
131}
132
133std::tuple<std::shared_ptr<CWallet>, std::vector<bilingual_str>>
134LoadWalletHelper(WalletContext &context, UniValue load_on_start_param,
135 const std::string wallet_name) {
136 DatabaseOptions options;
137 DatabaseStatus status;
138 options.require_existing = true;
140 std::vector<bilingual_str> warnings;
141 std::optional<bool> load_on_start =
142 load_on_start_param.isNull()
143 ? std::nullopt
144 : std::make_optional<bool>(load_on_start_param.get_bool());
145 std::shared_ptr<CWallet> const wallet =
146 LoadWallet(*context.chain, wallet_name, load_on_start, options, status,
147 error, warnings);
148 if (!wallet) {
149 // Map bad format to not found, since bad format is returned
150 // when the wallet directory exists, but doesn't contain a data
151 // file.
156 throw JSONRPCError(code, error.original);
157 }
158
159 return {wallet, warnings};
160}
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:53
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:254
bool IsLocked() const override
Definition: wallet.cpp:3147
enum JSONRPCRequest::Mode mode
std::string URI
Definition: request.h:36
const std::string & get_str() const
bool isNull() const
Definition: univalue.h:104
bool get_bool() const
bool IsWalletFlagSet(uint64_t flag) const override
Check if a certain wallet flag is set.
Definition: wallet.cpp:1517
bool error(const char *fmt, const Args &...args)
Definition: logging.h:263
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:58
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:22
@ RPC_WALLET_NOT_SPECIFIED
No wallet specified (error when there are multiple wallets loaded)
Definition: protocol.h:111
@ RPC_WALLET_INVALID_LABEL_NAME
Invalid label name.
Definition: protocol.h:94
@ RPC_WALLET_UNLOCK_NEEDED
Enter the wallet passphrase with walletpassphrase first.
Definition: protocol.h:98
@ RPC_WALLET_ERROR
Wallet errors Unspecified problem with wallet (key not found etc.)
Definition: protocol.h:90
@ RPC_WALLET_NOT_FOUND
Invalid wallet specified.
Definition: protocol.h:109
@ RPC_INTERNAL_ERROR
Definition: protocol.h:33
bool require_existing
Definition: db.h:222
WalletContext struct containing references to state shared between CWallet instances,...
Definition: context.h:23
interfaces::Chain * chain
Definition: context.h:24
Bilingual messages:
Definition: translation.h:17
std::string urlDecode(const std::string &urlEncoded)
Definition: url.cpp:10
DatabaseStatus
Definition: db.h:229
void EnsureWalletIsUnlocked(const CWallet *pwallet)
Definition: util.cpp:94
static const std::string WALLET_ENDPOINT_BASE
Definition: util.cpp:16
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: util.cpp:63
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
Definition: util.cpp:112
bool GetAvoidReuseFlag(const CWallet *const pwallet, const UniValue &param)
Definition: util.cpp:21
bool ParseIncludeWatchonly(const UniValue &include_watchonly, const CWallet &pwallet)
Used by RPC commands that have an include_watchonly parameter.
Definition: util.cpp:38
WalletContext & EnsureWalletContext(const std::any &context)
Definition: util.cpp:102
const std::string HELP_REQUIRING_PASSPHRASE
Definition: util.cpp:17
std::string LabelFromValue(const UniValue &value)
Definition: util.cpp:125
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest &request, std::string &wallet_name)
Definition: util.cpp:50
std::tuple< std::shared_ptr< CWallet >, std::vector< bilingual_str > > LoadWalletHelper(WalletContext &context, UniValue load_on_start_param, const std::string wallet_name)
Definition: util.cpp:134
std::shared_ptr< CWallet > GetWallet(const std::string &name)
Definition: wallet.cpp:156
std::vector< std::shared_ptr< CWallet > > GetWallets()
Definition: wallet.cpp:151
std::shared_ptr< CWallet > LoadWallet(interfaces::Chain &chain, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:265
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:55
@ WALLET_FLAG_AVOID_REUSE
Definition: walletutil.h:47