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