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.
This commit is contained in:
1 parent
8922d7f6b7
commit
362ded410b
10 files changed
+28
-12
No files matched your search
@@ -489,7 +489,11 @@ public:
|
|||||||
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
|
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void registerRpcs() override { return RegisterWalletRPCCommands(m_chain, m_rpc_handlers); }
|
void registerRpcs() override
|
||||||
|
{
|
||||||
|
g_rpc_chain = &m_chain;
|
||||||
|
return RegisterWalletRPCCommands(m_chain, m_rpc_handlers);
|
||||||
|
}
|
||||||
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
|
bool verify() override { return VerifyWallets(m_chain, m_wallet_filenames); }
|
||||||
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
|
bool load() override { return LoadWallets(m_chain, m_wallet_filenames); }
|
||||||
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }
|
void start(CScheduler& scheduler) override { return StartWallets(scheduler); }
|
||||||
|
|||||||
@@ -2289,3 +2289,5 @@ void RegisterBlockchainRPCCommands(CRPCTable &t)
|
|||||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||||
t.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
t.appendCommand(commands[vcidx].name, &commands[vcidx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeContext* g_rpc_node = nullptr;
|
||||||
@@ -17,6 +17,7 @@ class CBlock;
|
|||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CTxMemPool;
|
class CTxMemPool;
|
||||||
class UniValue;
|
class UniValue;
|
||||||
|
struct NodeContext;
|
||||||
|
|
||||||
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
|
||||||
|
|
||||||
@@ -46,4 +47,9 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
|
|||||||
/** Used by getblockstats to get feerates at different percentiles by weight */
|
/** Used by getblockstats to get feerates at different percentiles by weight */
|
||||||
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
|
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
|
||||||
|
|
||||||
|
//! Pointer to node state that needs to be declared as a global to be accessible
|
||||||
|
//! RPC methods. Due to limitations of the RPC framework, there's currently no
|
||||||
|
//! direct way to pass in state to RPC methods without globals.
|
||||||
|
extern NodeContext* g_rpc_node;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <policy/settings.h>
|
#include <policy/settings.h>
|
||||||
|
#include <rpc/blockchain.h>
|
||||||
#include <rpc/protocol.h>
|
#include <rpc/protocol.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <index/txindex.h>
|
#include <index/txindex.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <merkleblock.h>
|
#include <merkleblock.h>
|
||||||
#include <net.h>
|
|
||||||
#include <node/coin.h>
|
#include <node/coin.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/psbt.h>
|
#include <node/psbt.h>
|
||||||
@@ -20,6 +19,7 @@
|
|||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <psbt.h>
|
#include <psbt.h>
|
||||||
#include <random.h>
|
#include <random.h>
|
||||||
|
#include <rpc/blockchain.h>
|
||||||
#include <rpc/rawtransaction_util.h>
|
#include <rpc/rawtransaction_util.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
NodeContext* g_rpc_node = nullptr;
|
|
||||||
|
|
||||||
void RPCTypeCheck(const UniValue& params,
|
void RPCTypeCheck(const UniValue& params,
|
||||||
const std::list<UniValueType>& typesExpected,
|
const std::list<UniValueType>& typesExpected,
|
||||||
bool fAllowNull)
|
bool fAllowNull)
|
||||||
|
|||||||
@@ -25,12 +25,6 @@
|
|||||||
class FillableSigningProvider;
|
class FillableSigningProvider;
|
||||||
class CPubKey;
|
class CPubKey;
|
||||||
class CScript;
|
class CScript;
|
||||||
struct NodeContext;
|
|
||||||
|
|
||||||
//! Pointers to interfaces that need to be accessible from RPC methods. Due to
|
|
||||||
//! limitations of the RPC framework, there's currently no direct way to pass in
|
|
||||||
//! state to RPC method implementations.
|
|
||||||
extern NodeContext* g_rpc_node;
|
|
||||||
|
|
||||||
/** Wrapper for UniValue::VType, which includes typeAny:
|
/** Wrapper for UniValue::VType, which includes typeAny:
|
||||||
* Used to denote don't care type. */
|
* Used to denote don't care type. */
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <net.h>
|
#include <net.h>
|
||||||
#include <noui.h>
|
#include <noui.h>
|
||||||
#include <pow.h>
|
#include <pow.h>
|
||||||
|
#include <rpc/blockchain.h>
|
||||||
#include <rpc/register.h>
|
#include <rpc/register.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <script/sigcache.h>
|
#include <script/sigcache.h>
|
||||||
@@ -76,6 +77,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
|||||||
const CChainParams& chainparams = Params();
|
const CChainParams& chainparams = Params();
|
||||||
// Ideally we'd move all the RPC tests to the functional testing framework
|
// Ideally we'd move all the RPC tests to the functional testing framework
|
||||||
// instead of unit tests, but for now we need these here.
|
// instead of unit tests, but for now we need these here.
|
||||||
|
g_rpc_node = &m_node;
|
||||||
RegisterAllCoreRPCCommands(tableRPC);
|
RegisterAllCoreRPCCommands(tableRPC);
|
||||||
|
|
||||||
// We have to run a scheduler thread to prevent ActivateBestChain
|
// We have to run a scheduler thread to prevent ActivateBestChain
|
||||||
@@ -114,6 +116,7 @@ TestingSetup::~TestingSetup()
|
|||||||
threadGroup.join_all();
|
threadGroup.join_all();
|
||||||
GetMainSignals().FlushBackgroundCallbacks();
|
GetMainSignals().FlushBackgroundCallbacks();
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
||||||
|
g_rpc_node = nullptr;
|
||||||
m_node.connman.reset();
|
m_node.connman.reset();
|
||||||
m_node.banman.reset();
|
m_node.banman.reset();
|
||||||
UnloadBlockIndex();
|
UnloadBlockIndex();
|
||||||
|
|||||||
@@ -2574,7 +2574,7 @@ static UniValue loadwallet(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
std::string error;
|
std::string error;
|
||||||
std::vector<std::string> warning;
|
std::vector<std::string> warning;
|
||||||
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_node->chain, location, error, warning);
|
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_chain, location, error, warning);
|
||||||
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error);
|
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error);
|
||||||
|
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
@@ -2700,7 +2700,7 @@ static UniValue createwallet(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
std::string error;
|
std::string error;
|
||||||
std::shared_ptr<CWallet> wallet;
|
std::shared_ptr<CWallet> wallet;
|
||||||
WalletCreationStatus status = CreateWallet(*g_rpc_node->chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
|
WalletCreationStatus status = CreateWallet(*g_rpc_chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case WalletCreationStatus::CREATION_FAILED:
|
case WalletCreationStatus::CREATION_FAILED:
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, error);
|
throw JSONRPCError(RPC_WALLET_ERROR, error);
|
||||||
@@ -4231,3 +4231,5 @@ void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique
|
|||||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
|
||||||
handlers.emplace_back(chain.handleRpc(commands[vcidx]));
|
handlers.emplace_back(chain.handleRpc(commands[vcidx]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interfaces::Chain* g_rpc_chain = nullptr;
|
||||||
@@ -21,6 +21,12 @@ class Chain;
|
|||||||
class Handler;
|
class Handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Pointer to chain interface that needs to be declared as a global to be
|
||||||
|
//! accessible loadwallet and createwallet methods. Due to limitations of the
|
||||||
|
//! RPC framework, there's currently no direct way to pass in state to RPC
|
||||||
|
//! methods without globals.
|
||||||
|
extern interfaces::Chain* g_rpc_chain;
|
||||||
|
|
||||||
void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique_ptr<interfaces::Handler>>& handlers);
|
void RegisterWalletRPCCommands(interfaces::Chain& chain, std::vector<std::unique_ptr<interfaces::Handler>>& handlers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user