mining.cpp 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  #include <bitcoin-build-config.h> // IWYU pragma: keep
   7  
   8  #include <interfaces/mining.h>
   9  
  10  #include <addresstype.h>
  11  #include <arith_uint256.h>
  12  #include <chain.h>
  13  #include <chainparams.h>
  14  #include <chainparamsbase.h>
  15  #include <consensus/amount.h>
  16  #include <consensus/consensus.h>
  17  #include <consensus/merkle.h>
  18  #include <consensus/params.h>
  19  #include <consensus/validation.h>
  20  #include <core_io.h>
  21  #include <crypto/hex_base.h>
  22  #include <interfaces/types.h>
  23  #include <key_io.h>
  24  #include <net.h>
  25  #include <netbase.h>
  26  #include <node/blockstorage.h>
  27  #include <node/context.h>
  28  #include <node/miner.h>
  29  #include <node/mining_args.h>
  30  #include <node/mining_types.h>
  31  #include <node/warnings.h>
  32  #include <policy/feerate.h>
  33  #include <policy/policy.h>
  34  #include <pow.h>
  35  #include <primitives/block.h>
  36  #include <primitives/transaction.h>
  37  #include <rpc/blockchain.h>
  38  #include <rpc/mining.h>
  39  #include <rpc/protocol.h>
  40  #include <rpc/request.h>
  41  #include <rpc/server.h>
  42  #include <rpc/server_util.h>
  43  #include <rpc/util.h>
  44  #include <script/descriptor.h>
  45  #include <script/script.h>
  46  #include <script/signingprovider.h>
  47  #include <serialize.h>
  48  #include <streams.h>
  49  #include <sync.h>
  50  #include <tinyformat.h>
  51  #include <txmempool.h>
  52  #include <uint256.h>
  53  #include <univalue.h>
  54  #include <util/chaintype.h>
  55  #include <util/check.h>
  56  #include <util/signalinterrupt.h>
  57  #include <util/strencodings.h>
  58  #include <util/string.h>
  59  #include <util/time.h>
  60  #include <validation.h>
  61  #include <validationinterface.h>
  62  #include <versionbits.h>
  63  
  64  #include <algorithm>
  65  #include <cstddef>
  66  #include <cstdint>
  67  #include <functional>
  68  #include <initializer_list>
  69  #include <limits>
  70  #include <map>
  71  #include <memory>
  72  #include <optional>
  73  #include <set>
  74  #include <span>
  75  #include <string>
  76  #include <string_view>
  77  #include <utility>
  78  #include <vector>
  79  
  80  using interfaces::BlockRef;
  81  using interfaces::BlockTemplate;
  82  using interfaces::Mining;
  83  using node::BlockAssembler;
  84  using node::GetMinimumTime;
  85  using node::NodeContext;
  86  using node::RegenerateCommitments;
  87  using node::UpdateTime;
  88  using util::ToString;
  89  
  90  /**
  91   * Return average network hashes per second based on the last 'lookup' blocks,
  92   * or from the last difficulty change if 'lookup' is -1.
  93   * If 'height' is -1, compute the estimate from current chain tip.
  94   * If 'height' is a valid block height, compute the estimate at the time when a given block was found.
  95   */
  96  static UniValue GetNetworkHashPS(int lookup, int height, const CChain& active_chain) {
  97      if (lookup < -1 || lookup == 0) {
  98          throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid nblocks. Must be a positive number or -1.");
  99      }
 100  
 101      if (height < -1 || height > active_chain.Height()) {
 102          throw JSONRPCError(RPC_INVALID_PARAMETER, "Block does not exist at specified height");
 103      }
 104  
 105      const CBlockIndex* pb = active_chain.Tip();
 106  
 107      if (height >= 0) {
 108          pb = active_chain[height];
 109      }
 110  
 111      if (pb == nullptr || !pb->nHeight)
 112          return 0;
 113  
 114      // If lookup is -1, then use blocks since last difficulty change.
 115      if (lookup == -1)
 116          lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1;
 117  
 118      // If lookup is larger than chain, then set it to chain length.
 119      if (lookup > pb->nHeight)
 120          lookup = pb->nHeight;
 121  
 122      const CBlockIndex* pb0 = pb;
 123      int64_t minTime = pb0->GetBlockTime();
 124      int64_t maxTime = minTime;
 125      for (int i = 0; i < lookup; i++) {
 126          pb0 = pb0->pprev;
 127          int64_t time = pb0->GetBlockTime();
 128          minTime = std::min(time, minTime);
 129          maxTime = std::max(time, maxTime);
 130      }
 131  
 132      // In case there's a situation where minTime == maxTime, we don't want a divide by zero exception.
 133      if (minTime == maxTime)
 134          return 0;
 135  
 136      arith_uint256 workDiff = pb->nChainWork - pb0->nChainWork;
 137      int64_t timeDiff = maxTime - minTime;
 138  
 139      return workDiff.getdouble() / timeDiff;
 140  }
 141  
 142  static RPCMethod getnetworkhashps()
 143  {
 144      return RPCMethod{
 145          "getnetworkhashps",
 146          "Returns the estimated network hashes per second based on the last n blocks.\n"
 147                  "Pass in [blocks] to override # of blocks, -1 specifies since last difficulty change.\n"
 148                  "Pass in [height] to estimate the network speed at the time when a certain block was found.\n",
 149                  {
 150                      {"nblocks", RPCArg::Type::NUM, RPCArg::Default{120}, "The number of previous blocks to calculate estimate from, or -1 for blocks since last difficulty change."},
 151                      {"height", RPCArg::Type::NUM, RPCArg::Default{-1}, "To estimate at the time of the given height."},
 152                  },
 153                  RPCResult{
 154                      RPCResult::Type::NUM, "", "Hashes per second estimated"},
 155                  RPCExamples{
 156                      HelpExampleCli("getnetworkhashps", "")
 157              + HelpExampleRpc("getnetworkhashps", "")
 158                  },
 159          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 160  {
 161      ChainstateManager& chainman = EnsureAnyChainman(request.context);
 162      LOCK(cs_main);
 163      return GetNetworkHashPS(self.Arg<int>("nblocks"), self.Arg<int>("height"), chainman.ActiveChain());
 164  },
 165      };
 166  }
 167  
 168  static bool GenerateBlock(ChainstateManager& chainman, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block)
 169  {
 170      block_out.reset();
 171      block.hashMerkleRoot = BlockMerkleRoot(block);
 172  
 173      while (max_tries > 0 && block.nNonce < std::numeric_limits<uint32_t>::max() && !CheckProofOfWork(block.GetHash(), block.nBits, chainman.GetConsensus()) && !chainman.m_interrupt) {
 174          ++block.nNonce;
 175          --max_tries;
 176      }
 177      if (max_tries == 0 || chainman.m_interrupt) {
 178          return false;
 179      }
 180      if (block.nNonce == std::numeric_limits<uint32_t>::max()) {
 181          return true;
 182      }
 183  
 184      block_out = std::make_shared<const CBlock>(std::move(block));
 185  
 186      if (!process_new_block) return true;
 187  
 188      if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) {
 189          throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
 190      }
 191  
 192      return true;
 193  }
 194  
 195  static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CScript& coinbase_output_script, int nGenerate, uint64_t nMaxTries)
 196  {
 197      UniValue blockHashes(UniValue::VARR);
 198      while (nGenerate > 0 && !chainman.m_interrupt) {
 199          std::unique_ptr<BlockTemplate> block_template(miner.createNewBlock({ .coinbase_output_script = coinbase_output_script }, /*cooldown=*/false));
 200          CHECK_NONFATAL(block_template);
 201  
 202          std::shared_ptr<const CBlock> block_out;
 203          if (!GenerateBlock(chainman, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) {
 204              break;
 205          }
 206  
 207          if (block_out) {
 208              --nGenerate;
 209              blockHashes.push_back(block_out->GetHash().GetHex());
 210          }
 211      }
 212      return blockHashes;
 213  }
 214  
 215  static bool getScriptFromDescriptor(std::string_view descriptor, CScript& script, std::string& error)
 216  {
 217      FlatSigningProvider key_provider;
 218      const auto descs = Parse(descriptor, key_provider, error, /* require_checksum = */ false);
 219      if (descs.empty()) return false;
 220      if (descs.size() > 1) {
 221          throw JSONRPCError(RPC_INVALID_PARAMETER, "Multipath descriptor not accepted");
 222      }
 223      const auto& desc = descs.at(0);
 224      if (desc->IsRange()) {
 225          throw JSONRPCError(RPC_INVALID_PARAMETER, "Ranged descriptor not accepted. Maybe pass through deriveaddresses first?");
 226      }
 227  
 228      FlatSigningProvider provider;
 229      std::vector<CScript> scripts;
 230      if (!desc->Expand(0, key_provider, scripts, provider)) {
 231          throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Cannot derive script without private keys");
 232      }
 233  
 234      // Combo descriptors can have 2 or 4 scripts, so we can't just check scripts.size() == 1
 235      CHECK_NONFATAL(scripts.size() > 0 && scripts.size() <= 4);
 236  
 237      if (scripts.size() == 1) {
 238          script = scripts.at(0);
 239      } else if (scripts.size() == 4) {
 240          // For uncompressed keys, take the 3rd script, since it is p2wpkh
 241          script = scripts.at(2);
 242      } else {
 243          // Else take the 2nd script, since it is p2pkh
 244          script = scripts.at(1);
 245      }
 246  
 247      return true;
 248  }
 249  
 250  static RPCMethod generatetodescriptor()
 251  {
 252      return RPCMethod{
 253          "generatetodescriptor",
 254          "Mine to a specified descriptor and return the block hashes.",
 255          {
 256              {"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
 257              {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."},
 258              {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
 259          },
 260          RPCResult{
 261              RPCResult::Type::ARR, "", "hashes of blocks generated",
 262              {
 263                  {RPCResult::Type::STR_HEX, "", "blockhash"},
 264              }
 265          },
 266          RPCExamples{
 267              "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
 268          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 269  {
 270      const auto num_blocks{self.Arg<int>("num_blocks")};
 271      const auto max_tries{self.Arg<uint64_t>("maxtries")};
 272  
 273      CScript coinbase_output_script;
 274      std::string error;
 275      if (!getScriptFromDescriptor(self.Arg<std::string_view>("descriptor"), coinbase_output_script, error)) {
 276          throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);
 277      }
 278  
 279      NodeContext& node = EnsureAnyNodeContext(request.context);
 280      Mining& miner = EnsureMining(node);
 281      ChainstateManager& chainman = EnsureChainman(node);
 282  
 283      return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
 284  },
 285      };
 286  }
 287  
 288  static RPCMethod generate()
 289  {
 290      return RPCMethod{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {
 291          throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString());
 292      }};
 293  }
 294  
 295  static RPCMethod generatetoaddress()
 296  {
 297      return RPCMethod{"generatetoaddress",
 298          "Mine to a specified address and return the block hashes.",
 299           {
 300               {"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},
 301               {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated bitcoin to."},
 302               {"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},
 303           },
 304           RPCResult{
 305               RPCResult::Type::ARR, "", "hashes of blocks generated",
 306               {
 307                   {RPCResult::Type::STR_HEX, "", "blockhash"},
 308               }},
 309           RPCExamples{
 310              "\nGenerate 11 blocks to myaddress\n"
 311              + HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
 312              + "If you are using the " CLIENT_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"
 313              + HelpExampleCli("getnewaddress", "")
 314                  },
 315          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 316  {
 317      const int num_blocks{request.params[0].getInt<int>()};
 318      const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].getInt<int>()};
 319  
 320      CTxDestination destination = DecodeDestination(request.params[1].get_str());
 321      if (!IsValidDestination(destination)) {
 322          throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");
 323      }
 324  
 325      NodeContext& node = EnsureAnyNodeContext(request.context);
 326      Mining& miner = EnsureMining(node);
 327      ChainstateManager& chainman = EnsureChainman(node);
 328  
 329      CScript coinbase_output_script = GetScriptForDestination(destination);
 330  
 331      return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);
 332  },
 333      };
 334  }
 335  
 336  static RPCMethod generateblock()
 337  {
 338      return RPCMethod{"generateblock",
 339          "Mine a set of ordered transactions to a specified address or descriptor and return the block hash.\n"
 340          "Transaction fees are not collected in the block reward.",
 341          {
 342              {"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated bitcoin to."},
 343              {"transactions", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings which are either txids or raw transactions.\n"
 344                  "Txids must reference transactions currently in the mempool.\n"
 345                  "All transactions must be valid and in valid order, otherwise the block will be rejected.",
 346                  {
 347                      {"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
 348                  },
 349              },
 350              {"submit", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to submit the block before the RPC call returns or to return it as hex."},
 351          },
 352          RPCResult{
 353              RPCResult::Type::OBJ, "", "",
 354              {
 355                  {RPCResult::Type::STR_HEX, "hash", "hash of generated block"},
 356                  {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "hex of generated block, only present when submit=false"},
 357              }
 358          },
 359          RPCExamples{
 360              "\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n"
 361              + HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')")
 362          },
 363          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 364  {
 365      const auto address_or_descriptor = request.params[0].get_str();
 366      CScript coinbase_output_script;
 367      std::string error;
 368  
 369      if (!getScriptFromDescriptor(address_or_descriptor, coinbase_output_script, error)) {
 370          const auto destination = DecodeDestination(address_or_descriptor);
 371          if (!IsValidDestination(destination)) {
 372              throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");
 373          }
 374  
 375          coinbase_output_script = GetScriptForDestination(destination);
 376      }
 377  
 378      NodeContext& node = EnsureAnyNodeContext(request.context);
 379      Mining& miner = EnsureMining(node);
 380      const CTxMemPool& mempool = EnsureMemPool(node);
 381  
 382      std::vector<CTransactionRef> txs;
 383      const auto raw_txs_or_txids = request.params[1].get_array();
 384      for (size_t i = 0; i < raw_txs_or_txids.size(); i++) {
 385          const auto& str{raw_txs_or_txids[i].get_str()};
 386  
 387          CMutableTransaction mtx;
 388          if (auto txid{Txid::FromHex(str)}) {
 389              const auto tx{mempool.get(*txid)};
 390              if (!tx) {
 391                  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str));
 392              }
 393  
 394              txs.emplace_back(tx);
 395  
 396          } else if (DecodeHexTx(mtx, str)) {
 397              txs.push_back(MakeTransactionRef(std::move(mtx)));
 398  
 399          } else {
 400              throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str));
 401          }
 402      }
 403  
 404      const bool process_new_block{request.params[2].isNull() ? true : request.params[2].get_bool()};
 405      CBlock block;
 406  
 407      ChainstateManager& chainman = EnsureChainman(node);
 408      {
 409          LOCK(chainman.GetMutex());
 410          {
 411              std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script}, /*cooldown=*/false)};
 412              CHECK_NONFATAL(block_template);
 413  
 414              block = block_template->getBlock();
 415          }
 416  
 417          CHECK_NONFATAL(block.vtx.size() == 1);
 418  
 419          // Add transactions
 420          block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
 421          RegenerateCommitments(block, chainman);
 422  
 423          if (BlockValidationState state{TestBlockValidity(chainman.ActiveChainstate(), block, /*check_pow=*/false, /*check_merkle_root=*/false)}; !state.IsValid()) {
 424              throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
 425          }
 426      }
 427  
 428      std::shared_ptr<const CBlock> block_out;
 429      uint64_t max_tries{DEFAULT_MAX_TRIES};
 430  
 431      if (!GenerateBlock(chainman, std::move(block), max_tries, block_out, process_new_block) || !block_out) {
 432          throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");
 433      }
 434  
 435      UniValue obj(UniValue::VOBJ);
 436      obj.pushKV("hash", block_out->GetHash().GetHex());
 437      if (!process_new_block) {
 438          DataStream block_ser;
 439          block_ser << TX_WITH_WITNESS(*block_out);
 440          obj.pushKV("hex", HexStr(block_ser));
 441      }
 442      return obj;
 443  },
 444      };
 445  }
 446  
 447  static RPCMethod getmininginfo()
 448  {
 449      return RPCMethod{
 450          "getmininginfo",
 451          "Returns a json object containing mining-related information.",
 452                  {},
 453                  RPCResult{
 454                      RPCResult::Type::OBJ, "", "",
 455                      {
 456                          {RPCResult::Type::NUM, "blocks", "The current block"},
 457                          {RPCResult::Type::NUM, "currentblockweight", /*optional=*/true, "The block weight (including reserved weight for block header, txs count and coinbase tx) of the last assembled block (only present if a block was ever assembled)"},
 458                          {RPCResult::Type::NUM, "currentblocktx", /*optional=*/true, "The number of block transactions (excluding coinbase) of the last assembled block (only present if a block was ever assembled)"},
 459                          {RPCResult::Type::STR_HEX, "bits", "The current nBits, compact representation of the block difficulty target"},
 460                          {RPCResult::Type::NUM, "difficulty", "The current difficulty"},
 461                          {RPCResult::Type::STR_HEX, "target", "The current target"},
 462                          {RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
 463                          {RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
 464                          {RPCResult::Type::STR_AMOUNT, "blockmintxfee", "Minimum feerate of packages selected for block inclusion in " + CURRENCY_UNIT + "/kvB"},
 465                          {RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},
 466                          {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},
 467                          {RPCResult::Type::OBJ, "next", "The next block",
 468                          {
 469                              {RPCResult::Type::NUM, "height", "The next height"},
 470                              {RPCResult::Type::STR_HEX, "bits", "The next target nBits"},
 471                              {RPCResult::Type::NUM, "difficulty", "The next difficulty"},
 472                              {RPCResult::Type::STR_HEX, "target", "The next target"}
 473                          }},
 474                          (IsDeprecatedRPCEnabled("warnings") ?
 475                              RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :
 476                              RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",
 477                              {
 478                                  {RPCResult::Type::STR, "", "warning"},
 479                              }
 480                              }
 481                          ),
 482                      }},
 483                  RPCExamples{
 484                      HelpExampleCli("getmininginfo", "")
 485              + HelpExampleRpc("getmininginfo", "")
 486                  },
 487          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 488  {
 489      NodeContext& node = EnsureAnyNodeContext(request.context);
 490      const CTxMemPool& mempool = EnsureMemPool(node);
 491      ChainstateManager& chainman = EnsureChainman(node);
 492      LOCK(cs_main);
 493      const CChain& active_chain = chainman.ActiveChain();
 494      CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};
 495  
 496      UniValue obj(UniValue::VOBJ);
 497      obj.pushKV("blocks", active_chain.Height());
 498      if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
 499      if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
 500      obj.pushKV("bits", strprintf("%08x", tip.nBits));
 501      obj.pushKV("difficulty", GetDifficulty(tip));
 502      obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
 503      obj.pushKV("networkhashps",    getnetworkhashps().HandleRequest(request));
 504      obj.pushKV("pooledtx", mempool.size());
 505      const auto mining_options{node::FlattenMiningOptions(node.mining_args)};
 506      obj.pushKV("blockmintxfee", ValueFromAmount(CHECK_NONFATAL(mining_options.block_min_fee_rate)->GetFeePerK()));
 507      obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
 508  
 509      UniValue next(UniValue::VOBJ);
 510      CBlockIndex next_index;
 511      NextEmptyBlockIndex(tip, chainman.GetConsensus(), next_index);
 512  
 513      next.pushKV("height", next_index.nHeight);
 514      next.pushKV("bits", strprintf("%08x", next_index.nBits));
 515      next.pushKV("difficulty", GetDifficulty(next_index));
 516      next.pushKV("target", GetTarget(next_index, chainman.GetConsensus().powLimit).GetHex());
 517      obj.pushKV("next", next);
 518  
 519      if (chainman.GetParams().GetChainType() == ChainType::SIGNET) {
 520          const std::vector<uint8_t>& signet_challenge =
 521              chainman.GetConsensus().signet_challenge;
 522          obj.pushKV("signet_challenge", HexStr(signet_challenge));
 523      }
 524      obj.pushKV("warnings", node::GetWarningsForRpc(*CHECK_NONFATAL(node.warnings), IsDeprecatedRPCEnabled("warnings")));
 525      return obj;
 526  },
 527      };
 528  }
 529  
 530  
 531  // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
 532  static RPCMethod prioritisetransaction()
 533  {
 534      return RPCMethod{"prioritisetransaction",
 535                  "Accepts the transaction into mined blocks at a higher (or lower) priority\n",
 536                  {
 537                      {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id."},
 538                      {"dummy", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "API-Compatibility for previous API. Must be zero or null.\n"
 539              "                  DEPRECATED. For forward compatibility use named arguments and omit this parameter."},
 540                      {"fee_delta", RPCArg::Type::NUM, RPCArg::Optional::NO, "The fee value (in satoshis) to add (or subtract, if negative).\n"
 541              "                  Note, that this value is not a fee rate. It is a value to modify absolute fee of the TX.\n"
 542              "                  The fee is not actually paid, only the algorithm for selecting transactions into a block\n"
 543              "                  considers the transaction as it would have paid a higher (or lower) fee."},
 544                  },
 545                  RPCResult{
 546                      RPCResult::Type::BOOL, "", "Returns true"},
 547                  RPCExamples{
 548                      HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
 549              + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
 550                  },
 551          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 552  {
 553      LOCK(cs_main);
 554  
 555      auto txid{Txid::FromUint256(ParseHashV(request.params[0], "txid"))};
 556      const auto dummy{self.MaybeArg<double>("dummy")};
 557      CAmount nAmount = request.params[2].getInt<int64_t>();
 558  
 559      if (dummy && *dummy != 0) {
 560          throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.");
 561      }
 562  
 563      CTxMemPool& mempool = EnsureAnyMemPool(request.context);
 564  
 565      // Non-0 fee dust transactions are not allowed for entry, and modification not allowed afterwards
 566      const auto& tx = mempool.get(txid);
 567      if (mempool.m_opts.require_standard && tx && !GetDust(*tx, mempool.m_opts.dust_relay_feerate).empty()) {
 568          throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is not supported for transactions with dust outputs.");
 569      }
 570  
 571      mempool.PrioritiseTransaction(txid, nAmount);
 572      return true;
 573  },
 574      };
 575  }
 576  
 577  static RPCMethod getprioritisedtransactions()
 578  {
 579      return RPCMethod{"getprioritisedtransactions",
 580          "Returns a map of all user-created (see prioritisetransaction) fee deltas by txid, and whether the tx is present in mempool.",
 581          {},
 582          RPCResult{
 583              RPCResult::Type::OBJ_DYN, "", "prioritisation keyed by txid",
 584              {
 585                  {RPCResult::Type::OBJ, "<transactionid>", "", {
 586                      {RPCResult::Type::NUM, "fee_delta", "transaction fee delta in satoshis"},
 587                      {RPCResult::Type::BOOL, "in_mempool", "whether this transaction is currently in mempool"},
 588                      {RPCResult::Type::NUM, "modified_fee", /*optional=*/true, "modified fee in satoshis. Only returned if in_mempool=true"},
 589                  }}
 590              },
 591          },
 592          RPCExamples{
 593              HelpExampleCli("getprioritisedtransactions", "")
 594              + HelpExampleRpc("getprioritisedtransactions", "")
 595          },
 596          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 597          {
 598              NodeContext& node = EnsureAnyNodeContext(request.context);
 599              CTxMemPool& mempool = EnsureMemPool(node);
 600              UniValue rpc_result{UniValue::VOBJ};
 601              for (const auto& delta_info : mempool.GetPrioritisedTransactions()) {
 602                  UniValue result_inner{UniValue::VOBJ};
 603                  result_inner.pushKV("fee_delta", delta_info.delta);
 604                  result_inner.pushKV("in_mempool", delta_info.in_mempool);
 605                  if (delta_info.in_mempool) {
 606                      result_inner.pushKV("modified_fee", *delta_info.modified_fee);
 607                  }
 608                  rpc_result.pushKV(delta_info.txid.GetHex(), std::move(result_inner));
 609              }
 610              return rpc_result;
 611          },
 612      };
 613  }
 614  
 615  
 616  // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
 617  static UniValue BIP22ValidationResult(const BlockValidationState& state)
 618  {
 619      if (state.IsValid())
 620          return UniValue::VNULL;
 621  
 622      if (state.IsError())
 623          throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
 624      if (state.IsInvalid())
 625      {
 626          std::string strRejectReason = state.GetRejectReason();
 627          if (strRejectReason.empty())
 628              return "rejected";
 629          return strRejectReason;
 630      }
 631      // Should be impossible
 632      return "valid?";
 633  }
 634  
 635  // Prefix rule name with ! if not optional, see BIP9
 636  static std::string gbt_rule_value(const std::string& name, bool gbt_optional_rule)
 637  {
 638      std::string s{name};
 639      if (!gbt_optional_rule) {
 640          s.insert(s.begin(), '!');
 641      }
 642      return s;
 643  }
 644  
 645  static RPCMethod getblocktemplate()
 646  {
 647      return RPCMethod{
 648          "getblocktemplate",
 649          "If the request parameters include a 'mode' key, that is used to explicitly select between the default 'template' request or a 'proposal'.\n"
 650          "It returns data needed to construct a block to work on.\n"
 651          "For full specification, see BIPs 22, 23, 9, and 145:\n"
 652          "    https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki\n"
 653          "    https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki\n"
 654          "    https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki#getblocktemplate_changes\n"
 655          "    https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki\n",
 656          {
 657              {"template_request", RPCArg::Type::OBJ, RPCArg::Optional::NO, "Format of the template",
 658              {
 659                  {"mode", RPCArg::Type::STR, /* treat as named arg */ RPCArg::Optional::OMITTED, "This must be set to \"template\", \"proposal\" (see BIP 23), or omitted"},
 660                  {"capabilities", RPCArg::Type::ARR, /* treat as named arg */ RPCArg::Optional::OMITTED, "A list of strings",
 661                  {
 662                      {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "client side supported feature, 'longpoll', 'coinbasevalue', 'proposal', 'serverlist', 'workid'"},
 663                  }},
 664                  {"rules", RPCArg::Type::ARR, RPCArg::Optional::NO, "A list of strings",
 665                  {
 666                      {"segwit", RPCArg::Type::STR, RPCArg::Optional::NO, "(literal) indicates client side segwit support"},
 667                      {"str", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "other client side supported softfork deployment"},
 668                  }},
 669                  {"longpollid", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "delay processing request until the result would vary significantly from the \"longpollid\" of a prior template"},
 670                  {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "proposed block data to check, encoded in hexadecimal; valid only for mode=\"proposal\""},
 671              },
 672              },
 673          },
 674          {
 675              RPCResult{"If the proposal was accepted with mode=='proposal'", RPCResult::Type::NONE, "", ""},
 676              RPCResult{"If the proposal was not accepted with mode=='proposal'", RPCResult::Type::STR, "", "According to BIP22"},
 677              RPCResult{"Otherwise", RPCResult::Type::OBJ, "", "",
 678              {
 679                  {RPCResult::Type::NUM, "version", "The preferred block version"},
 680                  {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
 681                  {
 682                      {RPCResult::Type::STR, "", "name of a rule the client must understand to some extent; see BIP 9 for format"},
 683                  }},
 684                  {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
 685                  {
 686                      {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
 687                  }},
 688                  {RPCResult::Type::ARR, "capabilities", "",
 689                  {
 690                      {RPCResult::Type::STR, "value", "A supported feature, for example 'proposal'"},
 691                  }},
 692                  {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
 693                  {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
 694                  {RPCResult::Type::ARR, "transactions", "contents of non-coinbase transactions that should be included in the next block",
 695                  {
 696                      {RPCResult::Type::OBJ, "", "",
 697                      {
 698                          {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
 699                          {RPCResult::Type::STR_HEX, "txid", "transaction hash excluding witness data, shown in byte-reversed hex"},
 700                          {RPCResult::Type::STR_HEX, "hash", "transaction hash including witness data, shown in byte-reversed hex"},
 701                          {RPCResult::Type::ARR, "depends", "array of numbers",
 702                          {
 703                              {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
 704                          }},
 705                          {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"},
 706                          {RPCResult::Type::NUM, "sigops", "total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero"},
 707                          {RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
 708                      }},
 709                  }},
 710                  {RPCResult::Type::OBJ_DYN, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
 711                  {
 712                      {RPCResult::Type::STR_HEX, "key", "values must be in the coinbase (keys may be ignored)"},
 713                  }},
 714                  {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
 715                  {RPCResult::Type::STR, "longpollid", "an id to include with a request to longpoll on an update to this template"},
 716                  {RPCResult::Type::STR, "target", "The hash target"},
 717                  {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME + ". Adjusted for the proposed BIP94 timewarp rule."},
 718                  {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
 719                  {
 720                      {RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
 721                  }},
 722                  {RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
 723                  {RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
 724                  {RPCResult::Type::NUM, "sizelimit", "limit of block size"},
 725                  {RPCResult::Type::NUM, "weightlimit", /*optional=*/true, "limit of block weight"},
 726                  {RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME + ". Adjusted for the proposed BIP94 timewarp rule."},
 727                  {RPCResult::Type::STR, "bits", "compressed target of next block"},
 728                  {RPCResult::Type::NUM, "height", "The height of the next block"},
 729                  {RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "Only on signet"},
 730                  {RPCResult::Type::STR_HEX, "default_witness_commitment", /*optional=*/true, "a valid witness commitment for the unmodified block template"},
 731              }},
 732          },
 733          RPCExamples{
 734                      HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'")
 735              + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
 736                  },
 737          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
 738  {
 739      NodeContext& node = EnsureAnyNodeContext(request.context);
 740      ChainstateManager& chainman = EnsureChainman(node);
 741      Mining& miner = EnsureMining(node);
 742  
 743      std::string strMode = "template";
 744      UniValue lpval = NullUniValue;
 745      std::set<std::string> setClientRules;
 746      if (!request.params[0].isNull())
 747      {
 748          const UniValue& oparam = request.params[0].get_obj();
 749          const UniValue& modeval = oparam.find_value("mode");
 750          if (modeval.isStr())
 751              strMode = modeval.get_str();
 752          else if (modeval.isNull())
 753          {
 754              /* Do nothing */
 755          }
 756          else
 757              throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
 758          lpval = oparam.find_value("longpollid");
 759  
 760          if (strMode == "proposal")
 761          {
 762              const UniValue& dataval = oparam.find_value("data");
 763              if (!dataval.isStr())
 764                  throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
 765  
 766              CBlock block;
 767              if (!DecodeHexBlk(block, dataval.get_str()))
 768                  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
 769  
 770              uint256 hash = block.GetHash();
 771              LOCK(cs_main);
 772              const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(hash);
 773              if (pindex) {
 774                  if (pindex->IsValid(BLOCK_VALID_SCRIPTS))
 775                      return "duplicate";
 776                  if (pindex->nStatus & BLOCK_FAILED_VALID)
 777                      return "duplicate-invalid";
 778                  return "duplicate-inconclusive";
 779              }
 780  
 781              return BIP22ValidationResult(TestBlockValidity(chainman.ActiveChainstate(), block, /*check_pow=*/false, /*check_merkle_root=*/true));
 782          }
 783  
 784          const UniValue& aClientRules = oparam.find_value("rules");
 785          if (aClientRules.isArray()) {
 786              for (unsigned int i = 0; i < aClientRules.size(); ++i) {
 787                  const UniValue& v = aClientRules[i];
 788                  setClientRules.insert(v.get_str());
 789              }
 790          }
 791      }
 792  
 793      if (strMode != "template")
 794          throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
 795  
 796      if (!miner.isTestChain()) {
 797          const CConnman& connman = EnsureConnman(node);
 798          if (connman.GetNodeCount(ConnectionDirection::Both) == 0) {
 799              throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, CLIENT_NAME " is not connected!");
 800          }
 801  
 802          if (miner.isInitialBlockDownload()) {
 803              throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, CLIENT_NAME " is in initial sync and waiting for blocks...");
 804          }
 805      }
 806  
 807      static unsigned int nTransactionsUpdatedLast;
 808      const CTxMemPool& mempool = EnsureMemPool(node);
 809  
 810      WAIT_LOCK(cs_main, cs_main_lock);
 811      uint256 tip{CHECK_NONFATAL(miner.getTip()).value().hash};
 812  
 813      // Long Polling (BIP22)
 814      if (!lpval.isNull()) {
 815          /**
 816           * Wait to respond until either the best block changes, OR there are more
 817           * transactions.
 818           *
 819           * The check for new transactions first happens after 1 minute and
 820           * subsequently every 10 seconds. BIP22 does not require this particular interval.
 821           * On mainnet the mempool changes frequently enough that in practice this RPC
 822           * returns after 60 seconds, or sooner if the best block changes.
 823           *
 824           * getblocktemplate is unlikely to be called by bitcoin-cli, so
 825           * -rpcclienttimeout is not a concern. BIP22 recommends a long request timeout.
 826           *
 827           * The longpollid is assumed to be a tip hash if it has the right format.
 828           */
 829          uint256 hashWatchedChain;
 830          unsigned int nTransactionsUpdatedLastLP;
 831  
 832          if (lpval.isStr())
 833          {
 834              // Format: <hashBestChain><nTransactionsUpdatedLast>
 835              const std::string& lpstr = lpval.get_str();
 836  
 837              // Assume the longpollid is a block hash. If it's not then we return
 838              // early below.
 839              hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
 840              nTransactionsUpdatedLastLP = LocaleIndependentAtoi<int64_t>(lpstr.substr(64));
 841          }
 842          else
 843          {
 844              // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
 845              hashWatchedChain = tip;
 846              nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
 847          }
 848  
 849          // Release lock while waiting
 850          {
 851              REVERSE_LOCK(cs_main_lock, cs_main);
 852              MillisecondsDouble checktxtime{std::chrono::minutes(1)};
 853              while (IsRPCRunning()) {
 854                  // If hashWatchedChain is not a real block hash, this will
 855                  // return immediately.
 856                  std::optional<BlockRef> maybe_tip{miner.waitTipChanged(hashWatchedChain, checktxtime)};
 857                  // Node is shutting down
 858                  if (!maybe_tip) break;
 859                  tip = maybe_tip->hash;
 860                  if (tip != hashWatchedChain) break;
 861  
 862                  // Check transactions for update without holding the mempool
 863                  // lock to avoid deadlocks.
 864                  if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) {
 865                      break;
 866                  }
 867                  checktxtime = std::chrono::seconds(10);
 868              }
 869          }
 870          tip = CHECK_NONFATAL(miner.getTip()).value().hash;
 871  
 872          if (!IsRPCRunning())
 873              throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
 874          // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
 875      }
 876  
 877      const Consensus::Params& consensusParams = chainman.GetParams().GetConsensus();
 878  
 879      // GBT must be called with 'signet' set in the rules for signet chains
 880      if (consensusParams.signet_blocks && !setClientRules.contains("signet")) {
 881          throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the signet rule set (call with {\"rules\": [\"segwit\", \"signet\"]})");
 882      }
 883  
 884      // GBT must be called with 'segwit' set in the rules
 885      if (!setClientRules.contains("segwit")) {
 886          throw JSONRPCError(RPC_INVALID_PARAMETER, "getblocktemplate must be called with the segwit rule set (call with {\"rules\": [\"segwit\"]})");
 887      }
 888  
 889      // Update block
 890      static CBlockIndex* pindexPrev;
 891      static int64_t time_start;
 892      static std::unique_ptr<BlockTemplate> block_template;
 893      if (!pindexPrev || pindexPrev->GetBlockHash() != tip ||
 894          (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5))
 895      {
 896          // Clear pindexPrev so future calls make a new block, despite any failures from here on
 897          pindexPrev = nullptr;
 898  
 899          // Store the pindexBest used before createNewBlock, to avoid races
 900          nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
 901          CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip);
 902          time_start = GetTime();
 903  
 904          // Create new block. Opt-out of cooldown mechanism, because it would add
 905          // a delay to each getblocktemplate call. This differs from typical
 906          // long-lived IPC usage, where the overhead is paid only when creating
 907          // the initial template.
 908          block_template = miner.createNewBlock({}, /*cooldown=*/false);
 909          CHECK_NONFATAL(block_template);
 910  
 911  
 912          // Need to update only after we know createNewBlock succeeded
 913          pindexPrev = pindexPrevNew;
 914      }
 915      CHECK_NONFATAL(pindexPrev);
 916      CBlock block{block_template->getBlock()};
 917  
 918      // Update nTime
 919      UpdateTime(&block, consensusParams, pindexPrev);
 920      block.nNonce = 0;
 921  
 922      // NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
 923      const bool fPreSegWit = !DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_SEGWIT);
 924  
 925      UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
 926  
 927      UniValue transactions(UniValue::VARR);
 928      std::map<Txid, int64_t> setTxIndex;
 929      std::vector<CAmount> tx_fees{block_template->getTxFees()};
 930      std::vector<int64_t> tx_sigops{block_template->getTxSigops()};
 931  
 932      int i = 0;
 933      for (const auto& it : block.vtx) {
 934          const CTransaction& tx = *it;
 935          Txid txHash = tx.GetHash();
 936          setTxIndex[txHash] = i++;
 937  
 938          if (tx.IsCoinBase())
 939              continue;
 940  
 941          UniValue entry(UniValue::VOBJ);
 942  
 943          entry.pushKV("data", EncodeHexTx(tx));
 944          entry.pushKV("txid", txHash.GetHex());
 945          entry.pushKV("hash", tx.GetWitnessHash().GetHex());
 946  
 947          UniValue deps(UniValue::VARR);
 948          for (const CTxIn &in : tx.vin)
 949          {
 950              if (setTxIndex.contains(in.prevout.hash))
 951                  deps.push_back(setTxIndex[in.prevout.hash]);
 952          }
 953          entry.pushKV("depends", std::move(deps));
 954  
 955          int index_in_template = i - 2;
 956          entry.pushKV("fee", tx_fees.at(index_in_template));
 957          int64_t nTxSigOps{tx_sigops.at(index_in_template)};
 958          if (fPreSegWit) {
 959              CHECK_NONFATAL(nTxSigOps % WITNESS_SCALE_FACTOR == 0);
 960              nTxSigOps /= WITNESS_SCALE_FACTOR;
 961          }
 962          entry.pushKV("sigops", nTxSigOps);
 963          entry.pushKV("weight", GetTransactionWeight(tx));
 964  
 965          transactions.push_back(std::move(entry));
 966      }
 967  
 968      UniValue aux(UniValue::VOBJ);
 969  
 970      arith_uint256 hashTarget = arith_uint256().SetCompact(block.nBits);
 971  
 972      UniValue aMutable(UniValue::VARR);
 973      aMutable.push_back("time");
 974      aMutable.push_back("transactions");
 975      aMutable.push_back("prevblock");
 976  
 977      UniValue result(UniValue::VOBJ);
 978      result.pushKV("capabilities", std::move(aCaps));
 979  
 980      UniValue aRules(UniValue::VARR);
 981      // See getblocktemplate changes in BIP 9:
 982      // ! indicates a more subtle change to the block structure or generation transaction
 983      // Otherwise clients may assume the rule will not impact usage of the template as-is.
 984      aRules.push_back("csv");
 985      if (!fPreSegWit) {
 986          aRules.push_back("!segwit");
 987          aRules.push_back("taproot");
 988      }
 989      if (consensusParams.signet_blocks) {
 990          // indicate to miner that they must understand signet rules
 991          // when attempting to mine with this template
 992          aRules.push_back("!signet");
 993      }
 994  
 995      UniValue vbavailable(UniValue::VOBJ);
 996      const auto gbtstatus = chainman.m_versionbitscache.GBTStatus(*pindexPrev, consensusParams);
 997  
 998      for (const auto& [name, info] : gbtstatus.signalling) {
 999          vbavailable.pushKV(gbt_rule_value(name, info.gbt_optional_rule), info.bit);
1000          if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1001              // If the client doesn't support this, don't indicate it in the [default] version
1002              block.nVersion &= ~info.mask;
1003          }
1004      }
1005  
1006      for (const auto& [name, info] : gbtstatus.locked_in) {
1007          block.nVersion |= info.mask;
1008          vbavailable.pushKV(gbt_rule_value(name, info.gbt_optional_rule), info.bit);
1009          if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1010              // If the client doesn't support this, don't indicate it in the [default] version
1011              block.nVersion &= ~info.mask;
1012          }
1013      }
1014  
1015      for (const auto& [name, info] : gbtstatus.active) {
1016          aRules.push_back(gbt_rule_value(name, info.gbt_optional_rule));
1017          if (!info.gbt_optional_rule && !setClientRules.contains(name)) {
1018              // Not supported by the client; make sure it's safe to proceed
1019              throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", name));
1020          }
1021      }
1022  
1023      result.pushKV("version", block.nVersion);
1024      result.pushKV("rules", std::move(aRules));
1025      result.pushKV("vbavailable", std::move(vbavailable));
1026      result.pushKV("vbrequired", 0);
1027  
1028      result.pushKV("previousblockhash", block.hashPrevBlock.GetHex());
1029      result.pushKV("transactions", std::move(transactions));
1030      result.pushKV("coinbaseaux", std::move(aux));
1031      result.pushKV("coinbasevalue", block.vtx[0]->vout[0].nValue);
1032      result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast));
1033      result.pushKV("target", hashTarget.GetHex());
1034      result.pushKV("mintime", GetMinimumTime(pindexPrev, consensusParams.DifficultyAdjustmentInterval()));
1035      result.pushKV("mutable", std::move(aMutable));
1036      result.pushKV("noncerange", "00000000ffffffff");
1037      int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;
1038      int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;
1039      if (fPreSegWit) {
1040          CHECK_NONFATAL(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);
1041          nSigOpLimit /= WITNESS_SCALE_FACTOR;
1042          CHECK_NONFATAL(nSizeLimit % WITNESS_SCALE_FACTOR == 0);
1043          nSizeLimit /= WITNESS_SCALE_FACTOR;
1044      }
1045      result.pushKV("sigoplimit", nSigOpLimit);
1046      result.pushKV("sizelimit", nSizeLimit);
1047      if (!fPreSegWit) {
1048          result.pushKV("weightlimit", MAX_BLOCK_WEIGHT);
1049      }
1050      result.pushKV("curtime", block.GetBlockTime());
1051      result.pushKV("bits", strprintf("%08x", block.nBits));
1052      result.pushKV("height", pindexPrev->nHeight + 1);
1053  
1054      if (consensusParams.signet_blocks) {
1055          result.pushKV("signet_challenge", HexStr(consensusParams.signet_challenge));
1056      }
1057  
1058      if (auto coinbase{block_template->getCoinbaseTx()}; coinbase.required_outputs.size() > 0) {
1059          CHECK_NONFATAL(coinbase.required_outputs.size() == 1); // Only one output is currently expected
1060          result.pushKV("default_witness_commitment", HexStr(coinbase.required_outputs[0].scriptPubKey));
1061      }
1062  
1063      return result;
1064  },
1065      };
1066  }
1067  
1068  class submitblock_StateCatcher final : public CValidationInterface
1069  {
1070  public:
1071      uint256 hash;
1072      bool found{false};
1073      BlockValidationState state;
1074  
1075      explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), state() {}
1076  
1077  protected:
1078      void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& stateIn) override
1079      {
1080          if (block->GetHash() != hash) return;
1081          found = true;
1082          state = stateIn;
1083      }
1084  };
1085  
1086  static RPCMethod submitblock()
1087  {
1088      // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
1089      return RPCMethod{
1090          "submitblock",
1091          "Attempts to submit new block to network.\n"
1092          "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",
1093          {
1094              {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},
1095              {"dummy", RPCArg::Type::STR, RPCArg::DefaultHint{"ignored"}, "dummy value, for compatibility with BIP22. This value is ignored."},
1096          },
1097          {
1098              RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""},
1099              RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"},
1100          },
1101          RPCExamples{
1102                      HelpExampleCli("submitblock", "\"mydata\"")
1103              + HelpExampleRpc("submitblock", "\"mydata\"")
1104                  },
1105          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
1106  {
1107      std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
1108      CBlock& block = *blockptr;
1109      if (!DecodeHexBlk(block, request.params[0].get_str())) {
1110          throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
1111      }
1112  
1113      ChainstateManager& chainman = EnsureAnyChainman(request.context);
1114      {
1115          LOCK(cs_main);
1116          const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);
1117          if (pindex) {
1118              chainman.UpdateUncommittedBlockStructures(block, pindex);
1119          }
1120      }
1121  
1122      bool new_block;
1123      auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
1124      CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
1125      bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
1126      CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
1127      if (!new_block && accepted) {
1128          return "duplicate";
1129      }
1130      if (!sc->found) {
1131          return "inconclusive";
1132      }
1133      return BIP22ValidationResult(sc->state);
1134  },
1135      };
1136  }
1137  
1138  static RPCMethod submitheader()
1139  {
1140      return RPCMethod{
1141          "submitheader",
1142          "Decode the given hexdata as a header and submit it as a candidate chain tip if valid."
1143                  "\nThrows when the header is invalid.\n",
1144                  {
1145                      {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"},
1146                  },
1147                  RPCResult{
1148                      RPCResult::Type::NONE, "", "None"},
1149                  RPCExamples{
1150                      HelpExampleCli("submitheader", "\"aabbcc\"") +
1151                      HelpExampleRpc("submitheader", "\"aabbcc\"")
1152                  },
1153          [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
1154  {
1155      CBlockHeader h;
1156      if (!DecodeHexBlockHeader(h, request.params[0].get_str())) {
1157          throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed");
1158      }
1159      ChainstateManager& chainman = EnsureAnyChainman(request.context);
1160      {
1161          LOCK(cs_main);
1162          if (!chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) {
1163              throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first");
1164          }
1165      }
1166  
1167      BlockValidationState state;
1168      chainman.ProcessNewBlockHeaders({{h}}, /*min_pow_checked=*/true, state);
1169      if (state.IsValid()) return UniValue::VNULL;
1170      if (state.IsError()) {
1171          throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());
1172      }
1173      throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());
1174  },
1175      };
1176  }
1177  
1178  void RegisterMiningRPCCommands(CRPCTable& t)
1179  {
1180      static const CRPCCommand commands[]{
1181          {"mining", &getnetworkhashps},
1182          {"mining", &getmininginfo},
1183          {"mining", &prioritisetransaction},
1184          {"mining", &getprioritisedtransactions},
1185          {"mining", &getblocktemplate},
1186          {"mining", &submitblock},
1187          {"mining", &submitheader},
1188  
1189          {"hidden", &generatetoaddress},
1190          {"hidden", &generatetodescriptor},
1191          {"hidden", &generateblock},
1192          {"hidden", &generate},
1193      };
1194      for (const auto& c : commands) {
1195          t.appendCommand(c.name, &c);
1196      }
1197  }
1198