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