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