Skip to content

Commit e055b70

Browse files
committed
merge bitcoin#19096: Remove g_rpc_chain global
1 parent 0ab4520 commit e055b70

File tree

7 files changed

+90
-26
lines changed

7 files changed

+90
-26
lines changed

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ BITCOIN_CORE_H = \
325325
walletinitinterface.h \
326326
wallet/bdb.h \
327327
wallet/coincontrol.h \
328+
wallet/context.h \
328329
wallet/crypter.h \
329330
wallet/db.h \
330331
wallet/fees.h \
@@ -488,6 +489,7 @@ libdash_wallet_a_SOURCES = \
488489
interfaces/wallet.cpp \
489490
wallet/bdb.cpp \
490491
wallet/coincontrol.cpp \
492+
wallet/context.cpp \
491493
wallet/crypter.cpp \
492494
wallet/db.cpp \
493495
wallet/fees.cpp \

src/interfaces/wallet.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@
1010
#include <interfaces/handler.h>
1111
#include <policy/fees.h>
1212
#include <primitives/transaction.h>
13+
#include <rpc/server.h>
1314
#include <script/standard.h>
1415
#include <support/allocators/secure.h>
1516
#include <sync.h>
1617
#include <ui_interface.h>
1718
#include <uint256.h>
1819
#include <util/system.h>
20+
#include <util/ref.h>
1921
#include <validation.h>
22+
#include <wallet/context.h>
2023
#include <wallet/fees.h>
2124
#include <wallet/ismine.h>
2225
#include <wallet/rpcwallet.h>
@@ -572,16 +575,21 @@ class WalletClientImpl : public ChainClient
572575
{
573576
public:
574577
WalletClientImpl(Chain& chain, std::vector<std::string> wallet_filenames)
575-
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
578+
: m_wallet_filenames(std::move(wallet_filenames))
576579
{
580+
m_context.chain = &chain;
577581
}
578582
void registerRpcs() override
579583
{
580-
g_rpc_chain = &m_chain;
581-
return RegisterWalletRPCCommands(m_chain, m_rpc_handlers);
584+
for (const CRPCCommand& command : GetWalletRPCCommands()) {
585+
m_rpc_commands.emplace_back(command.category, command.name, [this, &command](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
586+
return command.actor({request, m_context}, result, last_handler);
587+
}, command.argNames, command.unique_id);
588+
m_rpc_handlers.emplace_back(m_context.chain->handleRpc(m_rpc_commands.back()));
589+
}
582590
}
583-
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
584-
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
591+
bool verify() override { return VerifyWallets(*m_context.chain, m_wallet_filenames); }
592+
bool load() override { return LoadWallets(*m_context.chain, m_wallet_filenames); }
585593
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }
586594
void flush() override { return FlushWallets(); }
587595
void stop() override { return StopWallets(); }
@@ -596,9 +604,10 @@ class WalletClientImpl : public ChainClient
596604
}
597605
~WalletClientImpl() override { UnloadWallets(); }
598606

599-
Chain& m_chain;
607+
WalletContext m_context;
600608
std::vector<std::string> m_wallet_filenames;
601609
std::vector<std::unique_ptr<Handler>> m_rpc_handlers;
610+
std::list<CRPCCommand> m_rpc_commands;
602611
};
603612

604613
} // 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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@
2222
#include <util/fees.h>
2323
#include <util/system.h>
2424
#include <util/moneystr.h>
25+
#include <util/ref.h>
2526
#include <util/string.h>
2627
#include <util/translation.h>
2728
#include <util/url.h>
2829
#include <util/validation.h>
2930
#include <util/vector.h>
3031
#include <validation.h>
3132
#include <wallet/coincontrol.h>
33+
#include <wallet/context.h>
3234
#include <wallet/psbtwallet.h>
3335
#include <wallet/rpcwallet.h>
3436
#include <wallet/wallet.h>
@@ -94,6 +96,14 @@ void EnsureWalletIsUnlocked(CWallet * const pwallet)
9496
}
9597
}
9698

99+
WalletContext& EnsureWalletContext(const util::Ref& context)
100+
{
101+
if (!context.Has<WalletContext>()) {
102+
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
103+
}
104+
return context.Get<WalletContext>();
105+
}
106+
97107
static void WalletTxToJSON(interfaces::Chain& chain, interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx, UniValue& entry)
98108
{
99109
AssertLockHeld(cs_main); // for mapBlockIndex
@@ -2715,6 +2725,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
27152725
},
27162726
}.ToString());
27172727

2728+
WalletContext& context = EnsureWalletContext(request.context);
27182729
WalletLocation location(request.params[0].get_str());
27192730

27202731
if (!location.Exists()) {
@@ -2729,7 +2740,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
27292740

27302741
bilingual_str error;
27312742
std::vector<bilingual_str> warnings;
2732-
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_chain, location, error, warnings);
2743+
std::shared_ptr<CWallet> const wallet = LoadWallet(*context.chain, location, error, warnings);
27332744
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error.original);
27342745

27352746
UniValue obj(UniValue::VOBJ);
@@ -2767,6 +2778,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
27672778
throw std::runtime_error(help.ToString());
27682779
}
27692780

2781+
WalletContext& context = EnsureWalletContext(request.context);
27702782
uint64_t flags = 0;
27712783
if (!request.params[1].isNull() && request.params[1].get_bool()) {
27722784
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
@@ -2788,7 +2800,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
27882800

27892801
bilingual_str error;
27902802
std::shared_ptr<CWallet> wallet;
2791-
WalletCreationStatus status = CreateWallet(*g_rpc_chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
2803+
WalletCreationStatus status = CreateWallet(*context.chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
27922804
switch (status) {
27932805
case WalletCreationStatus::CREATION_FAILED:
27942806
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
@@ -4051,10 +4063,7 @@ static const CRPCCommand commands[] =
40514063
};
40524064
// clang-format on
40534065

4054-
void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique_ptr<interfaces::Handler>>& handlers)
4066+
Span<const CRPCCommand> GetWalletRPCCommands()
40554067
{
4056-
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
4057-
handlers.emplace_back(chain.handleRpc(commands[vcidx]));
4068+
return MakeSpan(commands);
40584069
}
4059-
4060-
interfaces::Chain* g_rpc_chain = nullptr;

src/wallet/rpcwallet.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,25 @@
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 UniValue;
16-
struct PartiallySignedTransaction;
1718
class CTransaction;
19+
struct PartiallySignedTransaction;
20+
struct WalletContext;
1821

19-
namespace interfaces {
20-
class Chain;
21-
class Handler;
22-
}
2322
namespace util {
2423
class Ref;
2524
} // namespace util
2625

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

3528
/**
3629
* Figures out what wallet, if any, to use for a JSONRPCRequest.
@@ -42,6 +35,7 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques
4235

4336
std::string HelpRequiringPassphrase();
4437
void EnsureWalletIsUnlocked(CWallet *);
38+
WalletContext& EnsureWalletContext(const util::Ref& context);
4539

4640
UniValue getaddressinfo(const JSONRPCRequest& request);
4741
UniValue signrawtransactionwithwallet(const JSONRPCRequest& request);

0 commit comments

Comments
 (0)