Skip to content

Commit 0644cde

Browse files
MarcoFalkevijaydasmp
authored andcommitted
Merge bitcoin#23640: MOVEONLY: Move helper functions from rpcwallet to wallet/rpc/util
ff945e5 MOVEONLY: Move utility functions from rpcwallet to wallet/rpc/util (Samuel Dobson) 7b04a06 Introduce wallet/rpc/util (Samuel Dobson) Pull request description: This is part one of multiple to split up rpcwallet.cpp into smaller, more logical units. See bitcoin#23622 for context and overall plan. I'll open PRs in stages to hopefully minimise conflicts. Can be reviewed with `--color-moved=dimmed-zebra` The end goal can be seen here: https://github.com/meshcollider/bitcoin/tree/202111_split_walletrpc ACKs for top commit: MarcoFalke: nice, ACK ff945e5 🐰 shaavan: ACK ff945e5 Tree-SHA512: 6e3d1de6db770fe2fca540c8c4f30183ab8258c26e3a1fb46937714d28818a52933eafbfcafe2995f6a6e2551a3f3dd3ec93363b81de7912c0d81f5749d1c86d
1 parent 106172e commit 0644cde

File tree

9 files changed

+167
-126
lines changed

9 files changed

+167
-126
lines changed

src/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ BITCOIN_CORE_H = \
401401
wallet/ismine.h \
402402
wallet/load.h \
403403
wallet/rpcwallet.h \
404+
wallet/rpc/util.h \
404405
wallet/salvage.h \
405406
wallet/scriptpubkeyman.h \
406407
wallet/sqlite.h \
@@ -595,8 +596,8 @@ libbitcoin_wallet_a_SOURCES = \
595596
wallet/hdchain.cpp \
596597
wallet/interfaces.cpp \
597598
wallet/load.cpp \
599+
wallet/rpc/util.cpp \
598600
wallet/rpcdump.cpp \
599-
wallet/rpcwallet.cpp \
600601
wallet/scriptpubkeyman.cpp \
601602
wallet/wallet.cpp \
602603
wallet/walletdb.cpp \

src/rpc/coinjoin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <coinjoin/options.h>
1919
#include <interfaces/coinjoin.h>
2020
#include <wallet/rpcwallet.h>
21+
#include <wallet/rpc/util.h>
2122
#endif // ENABLE_WALLET
2223

2324
#include <univalue.h>

src/rpc/evo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <wallet/coincontrol.h>
3636
#include <wallet/rpcwallet.h>
3737
#include <wallet/wallet.h>
38+
#include <wallet/rpc/util.h>
3839
#endif//ENABLE_WALLET
3940

4041
#ifdef ENABLE_WALLET

src/rpc/masternode.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <wallet/rpcwallet.h>
2828
#ifdef ENABLE_WALLET
2929
#include <wallet/wallet.h>
30+
#include <wallet/rpc/util.h>
3031
#endif // ENABLE_WALLET
3132

3233
#include <fstream>

src/wallet/rpc/util.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
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/url.h>
9+
#include <wallet/context.h>
10+
#include <wallet/wallet.h>
11+
12+
#include <univalue.h>
13+
14+
static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
15+
const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
16+
17+
bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
18+
bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
19+
bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool();
20+
21+
if (avoid_reuse && !can_avoid_reuse) {
22+
throw JSONRPCError(RPC_WALLET_ERROR, "wallet does not have the \"avoid reuse\" feature enabled");
23+
}
24+
25+
return avoid_reuse;
26+
}
27+
28+
/** Used by RPC commands that have an include_watchonly parameter.
29+
* We default to true for watchonly wallets if include_watchonly isn't
30+
* explicitly set.
31+
*/
32+
bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wallet)
33+
{
34+
if (include_watchonly.isNull()) {
35+
// if include_watchonly isn't explicitly set, then check if we have a watchonly wallet
36+
return wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
37+
}
38+
39+
// otherwise return whatever include_watchonly was set to
40+
return include_watchonly.get_bool();
41+
}
42+
43+
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name)
44+
{
45+
if (URL_DECODE && request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
46+
// wallet endpoint was used
47+
wallet_name = URL_DECODE(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
48+
return true;
49+
}
50+
return false;
51+
}
52+
53+
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
54+
{
55+
CHECK_NONFATAL(request.mode == JSONRPCRequest::EXECUTE);
56+
WalletContext& context = EnsureWalletContext(request.context);
57+
58+
std::string wallet_name;
59+
if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
60+
const std::shared_ptr<CWallet> pwallet = GetWallet(context, wallet_name);
61+
if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
62+
return pwallet;
63+
}
64+
65+
std::vector<std::shared_ptr<CWallet>> wallets = GetWallets(context);
66+
if (wallets.size() == 1) {
67+
return wallets[0];
68+
}
69+
70+
if (wallets.empty()) {
71+
throw JSONRPCError(
72+
RPC_WALLET_NOT_FOUND, "No wallet is loaded. Load a wallet using loadwallet or create a new one with createwallet. (Note: A default wallet is no longer automatically created)");
73+
}
74+
throw JSONRPCError(RPC_WALLET_NOT_SPECIFIED,
75+
"Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
76+
}
77+
78+
void EnsureWalletIsUnlocked(const CWallet& wallet)
79+
{
80+
if (wallet.IsLocked()) {
81+
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
82+
}
83+
}
84+
85+
WalletContext& EnsureWalletContext(const std::any& context)
86+
{
87+
auto wallet_context = util::AnyPtr<WalletContext>(context);
88+
if (!wallet_context) {
89+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
90+
}
91+
return *wallet_context;
92+
}
93+
94+
// also_create should only be set to true only when the RPC is expected to add things to a blank wallet and make it no longer blank
95+
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create)
96+
{
97+
LegacyScriptPubKeyMan* spk_man = wallet.GetLegacyScriptPubKeyMan();
98+
if (!spk_man && also_create) {
99+
spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan();
100+
}
101+
if (!spk_man) {
102+
throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command");
103+
}
104+
return *spk_man;
105+
}
106+
107+
const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet)
108+
{
109+
const LegacyScriptPubKeyMan* spk_man = wallet.GetLegacyScriptPubKeyMan();
110+
if (!spk_man) {
111+
throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command");
112+
}
113+
return *spk_man;
114+
}
115+
116+
std::string LabelFromValue(const UniValue& value)
117+
{
118+
std::string label = value.get_str();
119+
if (label == "*")
120+
throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, "Invalid label name");
121+
return label;
122+
}

src/wallet/rpc/util.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) 2017-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+
#ifndef BITCOIN_WALLET_RPC_UTIL_H
6+
#define BITCOIN_WALLET_RPC_UTIL_H
7+
8+
#include <any>
9+
#include <memory>
10+
#include <string>
11+
12+
class CWallet;
13+
class JSONRPCRequest;
14+
class LegacyScriptPubKeyMan;
15+
class UniValue;
16+
struct WalletContext;
17+
18+
extern const std::string HELP_REQUIRING_PASSPHRASE;
19+
20+
/**
21+
* Figures out what wallet, if any, to use for a JSONRPCRequest.
22+
*
23+
* @param[in] request JSONRPCRequest that wishes to access a wallet
24+
* @return nullptr if no wallet should be used, or a pointer to the CWallet
25+
*/
26+
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
27+
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name);
28+
29+
void EnsureWalletIsUnlocked(const CWallet&);
30+
WalletContext& EnsureWalletContext(const std::any& context);
31+
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
32+
const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet);
33+
34+
bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param);
35+
bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wallet);
36+
std::string LabelFromValue(const UniValue& value);
37+
38+
#endif // BITCOIN_WALLET_RPC_UTIL_H

src/wallet/rpcdump.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <validation.h>
2424
#include <wallet/wallet.h>
2525
#include <wallet/rpcwallet.h>
26+
#include <wallet/rpc/util.h>
2627

2728
#include <cstdint>
2829
#include <fstream>

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <wallet/load.h>
3333
#include <wallet/rpcwallet.h>
3434
#include <wallet/scriptpubkeyman.h>
35+
#include <wallet/rpc/util.h>
3536
#include <wallet/wallet.h>
3637
#include <wallet/walletdb.h>
3738
#include <wallet/walletutil.h>
@@ -49,35 +50,6 @@
4950

5051
using interfaces::FoundBlock;
5152

52-
static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
53-
54-
static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) {
55-
bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE);
56-
bool avoid_reuse = param.isNull() ? can_avoid_reuse : param.get_bool();
57-
58-
if (avoid_reuse && !can_avoid_reuse) {
59-
throw JSONRPCError(RPC_WALLET_ERROR, "wallet does not have the \"avoid reuse\" feature enabled");
60-
}
61-
62-
return avoid_reuse;
63-
}
64-
65-
66-
/** Used by RPC commands that have an include_watchonly parameter.
67-
* We default to true for watchonly wallets if include_watchonly isn't
68-
* explicitly set.
69-
*/
70-
static bool ParseIncludeWatchonly(const UniValue& include_watchonly, const CWallet& wallet)
71-
{
72-
if (include_watchonly.isNull()) {
73-
// if include_watchonly isn't explicitly set, then check if we have a watchonly wallet
74-
return wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
75-
}
76-
77-
// otherwise return whatever include_watchonly was set to
78-
return include_watchonly.get_bool();
79-
}
80-
8153

8254
/** Checks if a CKey is in the given CWallet compressed or otherwise*/
8355
bool HaveKey(const SigningProvider& wallet, const CKey& key)
@@ -87,69 +59,6 @@ bool HaveKey(const SigningProvider& wallet, const CKey& key)
8759
return wallet.HaveKey(key.GetPubKey().GetID()) || wallet.HaveKey(key2.GetPubKey().GetID());
8860
}
8961

90-
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string& wallet_name)
91-
{
92-
if (URL_DECODE && request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
93-
// wallet endpoint was used
94-
wallet_name = URL_DECODE(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
95-
return true;
96-
}
97-
return false;
98-
}
99-
100-
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
101-
{
102-
CHECK_NONFATAL(request.mode == JSONRPCRequest::EXECUTE);
103-
104-
std::string wallet_name;
105-
if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
106-
std::shared_ptr<CWallet> pwallet = GetWallet(wallet_name);
107-
if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
108-
return pwallet;
109-
}
110-
111-
std::vector<std::shared_ptr<CWallet>> wallets = GetWallets();
112-
if (wallets.size() == 1) {
113-
return wallets[0];
114-
}
115-
116-
if (wallets.empty()) {
117-
throw JSONRPCError(
118-
RPC_WALLET_NOT_FOUND, "No wallet is loaded. Load a wallet using loadwallet or create a new one with createwallet. (Note: A default wallet is no longer automatically created)");
119-
}
120-
throw JSONRPCError(RPC_WALLET_NOT_SPECIFIED,
121-
"Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
122-
}
123-
124-
void EnsureWalletIsUnlocked(const CWallet& wallet)
125-
{
126-
if (wallet.IsLocked()) {
127-
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
128-
}
129-
}
130-
131-
// also_create should only be set to true only when the RPC is expected to add things to a blank wallet and make it no longer blank
132-
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create)
133-
{
134-
LegacyScriptPubKeyMan* spk_man = wallet.GetLegacyScriptPubKeyMan();
135-
if (!spk_man && also_create) {
136-
spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan();
137-
}
138-
if (!spk_man) {
139-
throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command");
140-
}
141-
return *spk_man;
142-
}
143-
144-
WalletContext& EnsureWalletContext(const CoreContext& context)
145-
{
146-
auto* wallet_context = GetContext<WalletContext>(context);
147-
if (!wallet_context) {
148-
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
149-
}
150-
return *wallet_context;
151-
}
152-
15362
static void WalletTxToJSON(interfaces::Chain& chain, const CWalletTx& wtx, UniValue& entry)
15463
{
15564
int confirms = wtx.GetDepthInMainChain();
@@ -191,14 +100,6 @@ static void WalletTxToJSON(interfaces::Chain& chain, const CWalletTx& wtx, UniVa
191100
}
192101

193102

194-
static std::string LabelFromValue(const UniValue& value)
195-
{
196-
std::string label = value.get_str();
197-
if (label == "*")
198-
throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, "Invalid label name");
199-
return label;
200-
}
201-
202103
/**
203104
* Update coin control with fee estimation based on the given parameters
204105
*

src/wallet/rpcwallet.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,10 @@
88
#include <context.h>
99
#include <span.h>
1010

11-
#include <memory>
12-
#include <string>
13-
#include <vector>
14-
1511
class CRPCCommand;
16-
class CWallet;
17-
class JSONRPCRequest;
18-
class LegacyScriptPubKeyMan;
19-
class UniValue;
20-
class CTransaction;
21-
struct PartiallySignedTransaction;
22-
struct WalletContext;
23-
24-
static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
2512

2613
Span<const CRPCCommand> GetWalletRPCCommands();
2714

28-
/**
29-
* Figures out what wallet, if any, to use for a JSONRPCRequest.
30-
*
31-
* @param[in] request JSONRPCRequest that wishes to access a wallet
32-
* @return nullptr if no wallet should be used, or a pointer to the CWallet
33-
*/
34-
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
35-
36-
void EnsureWalletIsUnlocked(const CWallet&);
37-
WalletContext& EnsureWalletContext(const CoreContext& context);
38-
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
39-
4015
RPCHelpMan getaddressinfo();
4116
RPCHelpMan getrawchangeaddress();
4217
RPCHelpMan addmultisigaddress();

0 commit comments

Comments
 (0)