Skip to content

Commit 362ded4

Browse files
committed
Avoid using g_rpc_node global in wallet code
Wallet code should use interfaces::Chain and not directly access to node state. Add a g_rpc_chain replacement global for wallet code to use, and move g_rpc_node definition to a libbitcoin_server source file so there are link errors if wallet code tries to access it.
1 parent 8922d7f commit 362ded4

File tree

10 files changed

+28
-12
lines changed

10 files changed

+28
-12
lines changed

src/interfaces/wallet.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,11 @@ class WalletClientImpl : public ChainClient
489489
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
490490
{
491491
}
492-
void registerRpcs() override { return RegisterWalletRPCCommands(m_chain, m_rpc_handlers); }
492+
void registerRpcs() override
493+
{
494+
g_rpc_chain = &m_chain;
495+
return RegisterWalletRPCCommands(m_chain, m_rpc_handlers);
496+
}
493497
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
494498
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
495499
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }

src/rpc/blockchain.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2289,3 +2289,5 @@ void RegisterBlockchainRPCCommands(CRPCTable &t)
22892289
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
22902290
t.appendCommand(commands[vcidx].name, &commands[vcidx]);
22912291
}
2292+
2293+
NodeContext* g_rpc_node = nullptr;

src/rpc/blockchain.h

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class CBlock;
1717
class CBlockIndex;
1818
class CTxMemPool;
1919
class UniValue;
20+
struct NodeContext;
2021

2122
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
2223

@@ -46,4 +47,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
4647
/** Used by getblockstats to get feerates at different percentiles by weight */
4748
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
4849

50+
//! Pointer to node state that needs to be declared as a global to be accessible
51+
//! RPC methods. Due to limitations of the RPC framework, there's currently no
52+
//! direct way to pass in state to RPC methods without globals.
53+
extern NodeContext* g_rpc_node;
54+
4955
#endif

src/rpc/net.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <netbase.h>
1414
#include <node/context.h>
1515
#include <policy/settings.h>
16+
#include <rpc/blockchain.h>
1617
#include <rpc/protocol.h>
1718
#include <rpc/util.h>
1819
#include <sync.h>

src/rpc/rawtransaction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <index/txindex.h>
1111
#include <key_io.h>
1212
#include <merkleblock.h>
13-
#include <net.h>
1413
#include <node/coin.h>
1514
#include <node/context.h>
1615
#include <node/psbt.h>
@@ -20,6 +19,7 @@
2019
#include <primitives/transaction.h>
2120
#include <psbt.h>
2221
#include <random.h>
22+
#include <rpc/blockchain.h>
2323
#include <rpc/rawtransaction_util.h>
2424
#include <rpc/server.h>
2525
#include <rpc/util.h>

src/rpc/util.cpp

-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
#include <tuple>
1515

16-
NodeContext* g_rpc_node = nullptr;
17-
1816
void RPCTypeCheck(const UniValue& params,
1917
const std::list<UniValueType>& typesExpected,
2018
bool fAllowNull)

src/rpc/util.h

-6
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@
2525
class FillableSigningProvider;
2626
class CPubKey;
2727
class CScript;
28-
struct NodeContext;
29-
30-
//! Pointers to interfaces that need to be accessible from RPC methods. Due to
31-
//! limitations of the RPC framework, there's currently no direct way to pass in
32-
//! state to RPC method implementations.
33-
extern NodeContext* g_rpc_node;
3428

3529
/** Wrapper for UniValue::VType, which includes typeAny:
3630
* Used to denote don't care type. */

src/test/setup_common.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <net.h>
1616
#include <noui.h>
1717
#include <pow.h>
18+
#include <rpc/blockchain.h>
1819
#include <rpc/register.h>
1920
#include <rpc/server.h>
2021
#include <script/sigcache.h>
@@ -76,6 +77,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
7677
const CChainParams& chainparams = Params();
7778
// Ideally we'd move all the RPC tests to the functional testing framework
7879
// instead of unit tests, but for now we need these here.
80+
g_rpc_node = &m_node;
7981
RegisterAllCoreRPCCommands(tableRPC);
8082

8183
// We have to run a scheduler thread to prevent ActivateBestChain
@@ -114,6 +116,7 @@ TestingSetup::~TestingSetup()
114116
threadGroup.join_all();
115117
GetMainSignals().FlushBackgroundCallbacks();
116118
GetMainSignals().UnregisterBackgroundSignalScheduler();
119+
g_rpc_node = nullptr;
117120
m_node.connman.reset();
118121
m_node.banman.reset();
119122
UnloadBlockIndex();

src/wallet/rpcwallet.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -2574,7 +2574,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
25742574

25752575
std::string error;
25762576
std::vector<std::string> warning;
2577-
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_node->chain, location, error, warning);
2577+
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_chain, location, error, warning);
25782578
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error);
25792579

25802580
UniValue obj(UniValue::VOBJ);
@@ -2700,7 +2700,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
27002700

27012701
std::string error;
27022702
std::shared_ptr<CWallet> wallet;
2703-
WalletCreationStatus status = CreateWallet(*g_rpc_node->chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
2703+
WalletCreationStatus status = CreateWallet(*g_rpc_chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
27042704
switch (status) {
27052705
case WalletCreationStatus::CREATION_FAILED:
27062706
throw JSONRPCError(RPC_WALLET_ERROR, error);
@@ -4231,3 +4231,5 @@ void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique
42314231
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
42324232
handlers.emplace_back(chain.handleRpc(commands[vcidx]));
42334233
}
4234+
4235+
interfaces::Chain* g_rpc_chain = nullptr;

src/wallet/rpcwallet.h

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ class Chain;
2121
class Handler;
2222
}
2323

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

2632
/**

0 commit comments

Comments
 (0)