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