server_util.cpp raw

   1  // Copyright (c) 2021-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <rpc/server_util.h>
   6  
   7  #include <chain.h>
   8  #include <common/args.h>
   9  #include <net_processing.h>
  10  #include <node/context.h>
  11  #include <node/miner.h>
  12  #include <policy/fees/block_policy_estimator.h>
  13  #include <pow.h>
  14  #include <rpc/protocol.h>
  15  #include <rpc/request.h>
  16  #include <txmempool.h>
  17  #include <util/any.h>
  18  #include <validation.h>
  19  
  20  #include <any>
  21  
  22  using node::NodeContext;
  23  using node::UpdateTime;
  24  
  25  NodeContext& EnsureAnyNodeContext(const std::any& context)
  26  {
  27      auto node_context = util::AnyPtr<NodeContext>(context);
  28      if (!node_context) {
  29          throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found");
  30      }
  31      return *node_context;
  32  }
  33  
  34  CTxMemPool& EnsureMemPool(const NodeContext& node)
  35  {
  36      if (!node.mempool) {
  37          throw JSONRPCError(RPC_CLIENT_MEMPOOL_DISABLED, "Mempool disabled or instance not found");
  38      }
  39      return *node.mempool;
  40  }
  41  
  42  CTxMemPool& EnsureAnyMemPool(const std::any& context)
  43  {
  44      return EnsureMemPool(EnsureAnyNodeContext(context));
  45  }
  46  
  47  
  48  BanMan& EnsureBanman(const NodeContext& node)
  49  {
  50      if (!node.banman) {
  51          throw JSONRPCError(RPC_DATABASE_ERROR, "Error: Ban database not loaded");
  52      }
  53      return *node.banman;
  54  }
  55  
  56  BanMan& EnsureAnyBanman(const std::any& context)
  57  {
  58      return EnsureBanman(EnsureAnyNodeContext(context));
  59  }
  60  
  61  ArgsManager& EnsureArgsman(const NodeContext& node)
  62  {
  63      if (!node.args) {
  64          throw JSONRPCError(RPC_INTERNAL_ERROR, "Node args not found");
  65      }
  66      return *node.args;
  67  }
  68  
  69  ArgsManager& EnsureAnyArgsman(const std::any& context)
  70  {
  71      return EnsureArgsman(EnsureAnyNodeContext(context));
  72  }
  73  
  74  ChainstateManager& EnsureChainman(const NodeContext& node)
  75  {
  76      if (!node.chainman) {
  77          throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
  78      }
  79      return *node.chainman;
  80  }
  81  
  82  ChainstateManager& EnsureAnyChainman(const std::any& context)
  83  {
  84      return EnsureChainman(EnsureAnyNodeContext(context));
  85  }
  86  
  87  CBlockPolicyEstimator& EnsureFeeEstimator(const NodeContext& node)
  88  {
  89      if (!node.fee_estimator) {
  90          throw JSONRPCError(RPC_INTERNAL_ERROR, "Fee estimation disabled");
  91      }
  92      return *node.fee_estimator;
  93  }
  94  
  95  CBlockPolicyEstimator& EnsureAnyFeeEstimator(const std::any& context)
  96  {
  97      return EnsureFeeEstimator(EnsureAnyNodeContext(context));
  98  }
  99  
 100  CConnman& EnsureConnman(const NodeContext& node)
 101  {
 102      if (!node.connman) {
 103          throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
 104      }
 105      return *node.connman;
 106  }
 107  
 108  interfaces::Mining& EnsureMining(const NodeContext& node)
 109  {
 110      if (!node.mining) {
 111          throw JSONRPCError(RPC_INTERNAL_ERROR, "Node miner not found");
 112      }
 113      return *node.mining;
 114  }
 115  
 116  PeerManager& EnsurePeerman(const NodeContext& node)
 117  {
 118      if (!node.peerman) {
 119          throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
 120      }
 121      return *node.peerman;
 122  }
 123  
 124  AddrMan& EnsureAddrman(const NodeContext& node)
 125  {
 126      if (!node.addrman) {
 127          throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Address manager functionality missing or disabled");
 128      }
 129      return *node.addrman;
 130  }
 131  
 132  AddrMan& EnsureAnyAddrman(const std::any& context)
 133  {
 134      return EnsureAddrman(EnsureAnyNodeContext(context));
 135  }
 136  
 137  void NextEmptyBlockIndex(CBlockIndex& tip, const Consensus::Params& consensusParams, CBlockIndex& next_index)
 138  {
 139      CBlockHeader next_header{};
 140      next_header.hashPrevBlock  = tip.GetBlockHash();
 141      UpdateTime(&next_header, consensusParams, &tip);
 142      next_header.nBits = GetNextWorkRequired(&tip, &next_header, consensusParams);
 143      next_header.nNonce = 0;
 144  
 145      next_index.pprev = &tip;
 146      next_index.nTime = next_header.nTime;
 147      next_index.nBits = next_header.nBits;
 148      next_index.nNonce = next_header.nNonce;
 149      next_index.nHeight = tip.nHeight + 1;
 150  }
 151