This PR removes the global g_rpc_node and g_rpc_chain pointers from RPC functions and other sources & headers. Instead, a NodeContext const reference, and in some cases a NodeContext pointer, is being forwarded to respective actor callbacks.
Also, this way we avoid changing the JSONRPCRequest that, imo, should remain a plain message transfer object without any knowledge about its environment. I consider the idea of having a void pointer member of JSONRPCRequest problematic because it defeats the compiler type checking. In a way, a globally available, but at least typed, pointer would still be better than a void pointer, in my opinion.
Previously, an RPC function signature looked like this:
0static UniValue getpeerinfo(const JSONRPCRequest& request)
This PR changes it to this:
0static UniValue getpeerinfo(const JSONRPCRequest& request, const NodeContext& node)
For example, a function that previously used g_rpc_node like this:
0if(!g_rpc_node->connman)
1 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED...[snip]...
would get the same object this way:
0if (!node.connman)
1 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED,...[snip]...
The same applies to former g_rpc_chain where functions like loadwallet don’t need it anymore:
0LoadWallet(*node.chain, location, error, warning);
This all is made possible by taking the NodeContext into the tableRPC object at init:
0/* Register RPC commands regardless of -server setting so they will be
1 * available in the GUI RPC console even if external calls are disabled.
2 */
3 RegisterAllCoreRPCCommands(tableRPC);
4 for (const auto& client : node.chain_clients) {
5 client->registerRpcs();
6 }
7 tableRPC.addNodeContext(&node); <=== RPC's are available, now take NodeContext to forward it later to them.
Each time an RPC is being called, tableRPC will forward the NodeContext argument:
0static bool ExecuteCommand(const CRPCCommand& command, const JSONRPCRequest& request, UniValue& result, bool last_handler, const NodeContext& node)
1{
2 try
3 {
4 RPCCommandExecution execution(request.strMethod);
5 // Execute, convert arguments to array if necessary
6 if (request.params.isObject()) {
7 return command.actor(transformNamedArguments(request, command.argNames), result, last_handler, node);
8 } else {
9 return command.actor(request, result, last_handler, node);
Fixes #17548