Skip to content

Commit 0fc6ea2

Browse files
author
MarcoFalke
committed
Merge #19096: Remove g_rpc_chain global
4a7253a Remove g_rpc_chain global (Russell Yanofsky) e783197 refactor: replace RegisterWalletRPCCommands with GetWalletRPCCommands (Russell Yanofsky) Pull request description: Replace with RPC request reference to new WalletContext struct similar to the existing NodeContext struct and reference. This PR is a followup to #18740 removing the g_rpc_node global. Some later PRs will follow this up and move more wallet globals to the WalletContext struct. ACKs for top commit: MarcoFalke: ACK 4a7253a 🎋 ariard: Code Review ACK 4a7253a, feel free to ignore comment it's super nit. Tree-SHA512: 5bb5561c89f81811ca5232a58bf450e230d4218e62471c03227d142395fd36131672e99cb88329b33b9680a235db01e8b9d1c1e2a18288349e57205528deabab
2 parents aa35ea5 + 4a7253a commit 0fc6ea2

File tree

7 files changed

+90
-28
lines changed

7 files changed

+90
-28
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ BITCOIN_CORE_H = \
241241
versionbitsinfo.h \
242242
walletinitinterface.h \
243243
wallet/coincontrol.h \
244+
wallet/context.h \
244245
wallet/crypter.h \
245246
wallet/db.h \
246247
wallet/feebumper.h \
@@ -350,6 +351,7 @@ libbitcoin_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
350351
libbitcoin_wallet_a_SOURCES = \
351352
interfaces/wallet.cpp \
352353
wallet/coincontrol.cpp \
354+
wallet/context.cpp \
353355
wallet/crypter.cpp \
354356
wallet/db.cpp \
355357
wallet/feebumper.cpp \

src/interfaces/wallet.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
#include <interfaces/handler.h>
1010
#include <policy/fees.h>
1111
#include <primitives/transaction.h>
12+
#include <rpc/server.h>
1213
#include <script/standard.h>
1314
#include <support/allocators/secure.h>
1415
#include <sync.h>
1516
#include <ui_interface.h>
1617
#include <uint256.h>
1718
#include <util/check.h>
19+
#include <util/ref.h>
1820
#include <util/system.h>
21+
#include <wallet/context.h>
1922
#include <wallet/feebumper.h>
2023
#include <wallet/fees.h>
2124
#include <wallet/ismine.h>
@@ -481,16 +484,21 @@ class WalletClientImpl : public ChainClient
481484
{
482485
public:
483486
WalletClientImpl(Chain& chain, std::vector<std::string> wallet_filenames)
484-
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
487+
: m_wallet_filenames(std::move(wallet_filenames))
485488
{
489+
m_context.chain = &chain;
486490
}
487491
void registerRpcs() override
488492
{
489-
g_rpc_chain = &m_chain;
490-
return RegisterWalletRPCCommands(m_chain, m_rpc_handlers);
493+
for (const CRPCCommand& command : GetWalletRPCCommands()) {
494+
m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
495+
return command.actor({request, m_context}, result, last_handler);
496+
}, command.argNames, command.unique_id);
497+
m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
498+
}
491499
}
492-
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
493-
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
500+
bool verify() override { return VerifyWallets(*m_context.chain, m_wallet_filenames); }
501+
bool load() override { return LoadWallets(*m_context.chain, m_wallet_filenames); }
494502
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }
495503
void flush() override { return FlushWallets(); }
496504
void stop() override { return StopWallets(); }
@@ -505,9 +513,10 @@ class WalletClientImpl : public ChainClient
505513
}
506514
~WalletClientImpl() override { UnloadWallets(); }
507515

508-
Chain& m_chain;
516+
WalletContext m_context;
509517
std::vector<std::string> m_wallet_filenames;
510518
std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
519+
std::list<CRPCCommand> m_rpc_commands;
511520
};
512521

513522
} // namespace

src/rpc/request.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ class JSONRPCRequest
4141
const util::Ref& context;
4242

4343
JSONRPCRequest(const util::Ref& context) : id(NullUniValue), params(NullUniValue), fHelp(false), context(context) {}
44+
45+
//! Initializes request information from another request object and the
46+
//! given context. The implementation should be updated if any members are
47+
//! added or removed above.
48+
JSONRPCRequest(const JSONRPCRequest& other, const util::Ref& context)
49+
: id(other.id), strMethod(other.strMethod), params(other.params), fHelp(other.fHelp), URI(other.URI),
50+
authUser(other.authUser), peerAddr(other.peerAddr), context(context)
51+
{
52+
}
53+
4454
void parse(const UniValue& valRequest);
4555
};
4656

src/wallet/context.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright (c) 2020 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/context.h>
6+
7+
WalletContext::WalletContext() {}
8+
WalletContext::~WalletContext() {}

src/wallet/context.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2020 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_CONTEXT_H
6+
#define BITCOIN_WALLET_CONTEXT_H
7+
8+
namespace interfaces {
9+
class Chain;
10+
} // namespace interfaces
11+
12+
//! WalletContext struct containing references to state shared between CWallet
13+
//! instances, like the reference to the chain interface, and the list of opened
14+
//! wallets.
15+
//!
16+
//! Future shared state can be added here as an alternative to adding global
17+
//! variables.
18+
//!
19+
//! The struct isn't intended to have any member functions. It should just be a
20+
//! collection of state pointers that doesn't pull in dependencies or implement
21+
//! behavior.
22+
struct WalletContext {
23+
interfaces::Chain* chain{nullptr};
24+
25+
//! Declare default constructor and destructor that are not inline, so code
26+
//! instantiating the WalletContext struct doesn't need to #include class
27+
//! definitions for smart pointer and container members.
28+
WalletContext();
29+
~WalletContext();
30+
};
31+
32+
#endif // BITCOIN_WALLET_CONTEXT_H

src/wallet/rpcwallet.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
#include <util/fees.h>
2222
#include <util/message.h> // For MessageSign()
2323
#include <util/moneystr.h>
24+
#include <util/ref.h>
2425
#include <util/string.h>
2526
#include <util/system.h>
2627
#include <util/translation.h>
2728
#include <util/url.h>
2829
#include <util/vector.h>
2930
#include <wallet/coincontrol.h>
31+
#include <wallet/context.h>
3032
#include <wallet/feebumper.h>
3133
#include <wallet/rpcwallet.h>
3234
#include <wallet/wallet.h>
@@ -121,6 +123,14 @@ void EnsureWalletIsUnlocked(const CWallet* pwallet)
121123
}
122124
}
123125

126+
WalletContext& EnsureWalletContext(const util::Ref& context)
127+
{
128+
if (!context.Has<WalletContext>()) {
129+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
130+
}
131+
return context.Get<WalletContext>();
132+
}
133+
124134
// 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
125135
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create)
126136
{
@@ -2584,6 +2594,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
25842594
},
25852595
}.Check(request);
25862596

2597+
WalletContext& context = EnsureWalletContext(request.context);
25872598
WalletLocation location(request.params[0].get_str());
25882599

25892600
if (!location.Exists()) {
@@ -2598,7 +2609,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
25982609

25992610
bilingual_str error;
26002611
std::vector<bilingual_str> warnings;
2601-
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_chain, location, error, warnings);
2612+
std::shared_ptr<CWallet> const wallet = LoadWallet(*context.chain, location, error, warnings);
26022613
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error.original);
26032614

26042615
UniValue obj(UniValue::VOBJ);
@@ -2702,6 +2713,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
27022713
},
27032714
}.Check(request);
27042715

2716+
WalletContext& context = EnsureWalletContext(request.context);
27052717
uint64_t flags = 0;
27062718
if (!request.params[1].isNull() && request.params[1].get_bool()) {
27072719
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
@@ -2731,7 +2743,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
27312743

27322744
bilingual_str error;
27332745
std::shared_ptr<CWallet> wallet;
2734-
WalletCreationStatus status = CreateWallet(*g_rpc_chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
2746+
WalletCreationStatus status = CreateWallet(*context.chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
27352747
switch (status) {
27362748
case WalletCreationStatus::CREATION_FAILED:
27372749
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
@@ -4263,7 +4275,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request);
42634275
UniValue importmulti(const JSONRPCRequest& request);
42644276
UniValue importdescriptors(const JSONRPCRequest& request);
42654277

4266-
void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique_ptr<interfaces::Handler>>& handlers)
4278+
Span<const CRPCCommand> GetWalletRPCCommands()
42674279
{
42684280
// clang-format off
42694281
static const CRPCCommand commands[] =
@@ -4329,9 +4341,5 @@ static const CRPCCommand commands[] =
43294341
{ "wallet", "walletprocesspsbt", &walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} },
43304342
};
43314343
// clang-format on
4332-
4333-
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
4334-
handlers.emplace_back(chain.handleRpc(commands[vcidx]));
4344+
return MakeSpan(commands);
43354345
}
4336-
4337-
interfaces::Chain* g_rpc_chain = nullptr;

src/wallet/rpcwallet.h

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,22 @@
55
#ifndef BITCOIN_WALLET_RPCWALLET_H
66
#define BITCOIN_WALLET_RPCWALLET_H
77

8+
#include <span.h>
9+
810
#include <memory>
911
#include <string>
1012
#include <vector>
1113

12-
class CRPCTable;
14+
class CRPCCommand;
1315
class CWallet;
1416
class JSONRPCRequest;
1517
class LegacyScriptPubKeyMan;
1618
class UniValue;
17-
struct PartiallySignedTransaction;
1819
class CTransaction;
20+
struct PartiallySignedTransaction;
21+
struct WalletContext;
1922

20-
namespace interfaces {
21-
class Chain;
22-
class Handler;
23-
}
24-
25-
//! Pointer to chain interface that needs to be declared as a global to be
26-
//! accessible loadwallet and createwallet methods. Due to limitations of the
27-
//! RPC framework, there's currently no direct way to pass in state to RPC
28-
//! methods without globals.
29-
extern interfaces::Chain* g_rpc_chain;
30-
31-
void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique_ptr<interfaces::Handler>>& handlers);
23+
Span<const CRPCCommand> GetWalletRPCCommands();
3224

3325
/**
3426
* Figures out what wallet, if any, to use for a JSONRPCRequest.
@@ -40,6 +32,7 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques
4032

4133
void EnsureWalletIsUnlocked(const CWallet*);
4234
bool EnsureWalletIsAvailable(const CWallet*, bool avoidException);
35+
WalletContext& EnsureWalletContext(const util::Ref& context);
4336
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
4437

4538
UniValue getaddressinfo(const JSONRPCRequest& request);

0 commit comments

Comments
 (0)