/ src / rpc / server_util.cpp
server_util.cpp
  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  }