server.h raw

   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 RPCMethod (*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
 139