server.h
1 // Copyright (c) 2010 Satoshi Nakamoto 2 // Copyright (c) 2009-present The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #ifndef BITCOIN_RPC_SERVER_H 7 #define BITCOIN_RPC_SERVER_H 8 9 #include <rpc/request.h> 10 #include <rpc/util.h> 11 12 #include <cstdint> 13 #include <functional> 14 #include <map> 15 #include <string> 16 17 #include <univalue.h> 18 19 class CRPCCommand; 20 21 /** Query whether RPC is running */ 22 bool IsRPCRunning(); 23 24 /** Throw JSONRPCError if RPC is not running */ 25 void RpcInterruptionPoint(); 26 27 /** 28 * Set the RPC warmup status. When this is done, all RPC calls will error out 29 * immediately with RPC_IN_WARMUP. 30 */ 31 void SetRPCWarmupStatus(const std::string& newStatus); 32 void SetRPCWarmupStarting(); 33 /* Mark warmup as done. RPC calls will be processed from now on. */ 34 void SetRPCWarmupFinished(); 35 36 /* returns the current warmup state. */ 37 bool RPCIsInWarmup(std::string *outStatus); 38 39 typedef RPCHelpMan (*RpcMethodFnType)(); 40 41 class CRPCCommand 42 { 43 public: 44 //! RPC method handler reading request and assigning result. Should return 45 //! true if request is fully handled, false if it should be passed on to 46 //! subsequent handlers. 47 using Actor = std::function<bool(const JSONRPCRequest& request, UniValue& result, bool last_handler)>; 48 49 //! Constructor taking Actor callback supporting multiple handlers. 50 CRPCCommand(std::string category, std::string name, Actor actor, std::vector<std::pair<std::string, bool>> args, intptr_t unique_id) 51 : category(std::move(category)), name(std::move(name)), actor(std::move(actor)), argNames(std::move(args)), 52 unique_id(unique_id) 53 { 54 } 55 56 //! Simplified constructor taking plain RpcMethodFnType function pointer. 57 CRPCCommand(std::string category, RpcMethodFnType fn) 58 : CRPCCommand( 59 category, 60 fn().m_name, 61 [fn](const JSONRPCRequest& request, UniValue& result, bool) { result = fn().HandleRequest(request); return true; }, 62 fn().GetArgNames(), 63 intptr_t(fn)) 64 { 65 } 66 67 std::string category; 68 std::string name; 69 Actor actor; 70 //! List of method arguments and whether they are named-only. Incoming RPC 71 //! requests contain a "params" field that can either be an array containing 72 //! unnamed arguments or an object containing named arguments. The 73 //! "argNames" vector is used in the latter case to transform the params 74 //! object into an array. Each argument in "argNames" gets mapped to a 75 //! unique position in the array, based on the order it is listed, unless 76 //! the argument is a named-only argument with argNames[x].second set to 77 //! true. Named-only arguments are combined into a JSON object that is 78 //! appended after other arguments, see transformNamedArguments for details. 79 std::vector<std::pair<std::string, bool>> argNames; 80 intptr_t unique_id; 81 }; 82 83 /** 84 * RPC command dispatcher. 85 */ 86 class CRPCTable 87 { 88 private: 89 std::map<std::string, std::vector<const CRPCCommand*>> mapCommands; 90 public: 91 CRPCTable(); 92 std::string help(std::string_view name, const JSONRPCRequest& helpreq) const; 93 94 /** 95 * Execute a method. 96 * @param request The JSONRPCRequest to execute 97 * @returns Result of the call. 98 * @throws an exception (UniValue) when an error happens. 99 */ 100 UniValue execute(const JSONRPCRequest &request) const; 101 102 /** 103 * Returns a list of registered commands 104 * @returns List of registered commands. 105 */ 106 std::vector<std::string> listCommands() const; 107 108 /** 109 * Return all named arguments that need to be converted by the client from string to another JSON type 110 */ 111 UniValue dumpArgMap(const JSONRPCRequest& request) const; 112 113 /** 114 * Appends a CRPCCommand to the dispatch table. 115 * 116 * Precondition: RPC server is not running 117 * 118 * Commands with different method names but the same unique_id will 119 * be considered aliases, and only the first registered method name will 120 * show up in the help text command listing. Aliased commands do not have 121 * to have the same behavior. Server and client code can distinguish 122 * between calls based on method name, and aliased commands can also 123 * register different names, types, and numbers of parameters. 124 */ 125 void appendCommand(const std::string& name, const CRPCCommand* pcmd); 126 bool removeCommand(const std::string& name, const CRPCCommand* pcmd); 127 }; 128 129 bool IsDeprecatedRPCEnabled(const std::string& method); 130 131 extern CRPCTable tableRPC; 132 133 void StartRPC(); 134 void InterruptRPC(); 135 void StopRPC(); 136 UniValue JSONRPCExec(const JSONRPCRequest& jreq, bool catch_errors); 137 138 #endif // BITCOIN_RPC_SERVER_H