Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1001if (!info.gbt_optional_rule && !setClientRules.contains(name)) {1002// If the client doesn't support this, don't indicate it in the [default] version1003block.nVersion &= ~info.mask;1004}1005}1007for (const auto& [name, info] : gbtstatus.locked_in) {1008block.nVersion |= info.mask;1009vbavailable.pushKV(gbt_rule_value(name, info.gbt_optional_rule), info.bit);1010if (!info.gbt_optional_rule && !setClientRules.contains(name)) {1011// If the client doesn't support this, don't indicate it in the [default] version1012block.nVersion &= ~info.mask;1013}1014}1016for (const auto& [name, info] : gbtstatus.active) {1017aRules.push_back(gbt_rule_value(name, info.gbt_optional_rule));1018if (!info.gbt_optional_rule && !setClientRules.contains(name)) {1019// Not supported by the client; make sure it's safe to proceed1020throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Support for '%s' rule requires explicit client support", name));1021}1022}1024result.pushKV("version", block.nVersion);1025result.pushKV("rules", std::move(aRules));1026result.pushKV("vbavailable", std::move(vbavailable));1027result.pushKV("vbrequired", 0);1029result.pushKV("previousblockhash", block.hashPrevBlock.GetHex());1030result.pushKV("transactions", std::move(transactions));1031result.pushKV("coinbaseaux", std::move(aux));1032result.pushKV("coinbasevalue", block.vtx[0]->vout[0].nValue);1033result.pushKV("longpollid", tip.GetHex() + ToString(nTransactionsUpdatedLast));1034result.pushKV("target", hashTarget.GetHex());1035result.pushKV("mintime", GetMinimumTime(pindexPrev, consensusParams.DifficultyAdjustmentInterval()));1036result.pushKV("mutable", std::move(aMutable));1037result.pushKV("noncerange", "00000000ffffffff");1038int64_t nSigOpLimit = MAX_BLOCK_SIGOPS_COST;1039int64_t nSizeLimit = MAX_BLOCK_SERIALIZED_SIZE;1040if (fPreSegWit) {1041CHECK_NONFATAL(nSigOpLimit % WITNESS_SCALE_FACTOR == 0);1042nSigOpLimit /= WITNESS_SCALE_FACTOR;1043CHECK_NONFATAL(nSizeLimit % WITNESS_SCALE_FACTOR == 0);1044nSizeLimit /= WITNESS_SCALE_FACTOR;1045}1046result.pushKV("sigoplimit", nSigOpLimit);1047result.pushKV("sizelimit", nSizeLimit);1048if (!fPreSegWit) {1049result.pushKV("weightlimit", MAX_BLOCK_WEIGHT);1050}1051result.pushKV("curtime", block.GetBlockTime());1052result.pushKV("bits", strprintf("%08x", block.nBits));1053result.pushKV("height", pindexPrev->nHeight + 1);1055if (consensusParams.signet_blocks) {1056result.pushKV("signet_challenge", HexStr(consensusParams.signet_challenge));1057}1059if (auto coinbase{block_template->getCoinbaseTx()}; coinbase.required_outputs.size() > 0) {1060CHECK_NONFATAL(coinbase.required_outputs.size() == 1); // Only one output is currently expected1061result.pushKV("default_witness_commitment", HexStr(coinbase.required_outputs[0].scriptPubKey));1062}1064return result;1065},1066};1067}1069class submitblock_StateCatcher final : public CValidationInterface1070{1071public:1072uint256 hash;1073bool found{false};1074BlockValidationState state;1076explicit submitblock_StateCatcher(const uint256 &hashIn) : hash(hashIn), state() {}1078protected:1079void BlockChecked(const std::shared_ptr<const CBlock>& block, const BlockValidationState& stateIn) override1080{1081if (block->GetHash() != hash) return;1082found = true;1083state = stateIn;1084}1085};1087static RPCMethod submitblock()1088{1089// We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.1090return RPCMethod{1091"submitblock",1092"Attempts to submit new block to network.\n"1093"See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n",1094{1095{"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block data to submit"},1096{"dummy", RPCArg::Type::STR, RPCArg::DefaultHint{"ignored"}, "dummy value, for compatibility with BIP22. This value is ignored.",1097RPCArgOptions{.placeholder = true}},1098},1099{1100RPCResult{"If the block was accepted", RPCResult::Type::NONE, "", ""},1101RPCResult{"Otherwise", RPCResult::Type::STR, "", "According to BIP22"},1102},1103RPCExamples{1104HelpExampleCli("submitblock", "\"mydata\"")1105+ HelpExampleRpc("submitblock", "\"mydata\"")1106},1107[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue1108{1109std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();1110CBlock& block = *blockptr;1111if (!DecodeHexBlk(block, request.params[0].get_str())) {1112throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");1113}1115ChainstateManager& chainman = EnsureAnyChainman(request.context);1116{1117LOCK(cs_main);1118const CBlockIndex* pindex = chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock);1119if (pindex) {1120chainman.UpdateUncommittedBlockStructures(block, pindex);1121}1122}1124bool new_block;1125auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());1126CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);1127bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);1128CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);1129if (!new_block && accepted) {1130return "duplicate";1131}1132if (!sc->found) {1133return "inconclusive";1134}1135return BIP22ValidationResult(sc->state);1136},1137};1138}1140static RPCMethod submitheader()1141{1142return RPCMethod{1143"submitheader",1144"Decode the given hexdata as a header and submit it as a candidate chain tip if valid."1145"\nThrows when the header is invalid.\n",1146{1147{"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"},1148},1149RPCResult{1150RPCResult::Type::NONE, "", "None"},1151RPCExamples{1152HelpExampleCli("submitheader", "\"aabbcc\"") +1153HelpExampleRpc("submitheader", "\"aabbcc\"")1154},1155[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue1156{1157CBlockHeader h;1158if (!DecodeHexBlockHeader(h, request.params[0].get_str())) {1159throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block header decode failed");1160}1161ChainstateManager& chainman = EnsureAnyChainman(request.context);1162{1163LOCK(cs_main);1164if (!chainman.m_blockman.LookupBlockIndex(h.hashPrevBlock)) {1165throw JSONRPCError(RPC_VERIFY_ERROR, "Must submit previous header (" + h.hashPrevBlock.GetHex() + ") first");1166}1167}1169BlockValidationState state;1170chainman.ProcessNewBlockHeaders({{h}}, /*min_pow_checked=*/true, state);1171if (state.IsValid()) return UniValue::VNULL;1172if (state.IsError()) {1173throw JSONRPCError(RPC_VERIFY_ERROR, state.ToString());1174}1175throw JSONRPCError(RPC_VERIFY_ERROR, state.GetRejectReason());1176},1177};1178}1180void RegisterMiningRPCCommands(CRPCTable& t)1181{1182static const CRPCCommand commands[]{1183{"mining", &getnetworkhashps},1184{"mining", &getmininginfo},1185{"mining", &prioritisetransaction},1186{"mining", &getprioritisedtransactions},1187{"mining", &getblocktemplate},1188{"mining", &submitblock},1189{"mining", &submitheader},1191{"hidden", &generatetoaddress},1192{"hidden", &generatetodescriptor},1193{"hidden", &generateblock},1194{"hidden", &generate},1195};1196for (const auto& c : commands) {1197t.appendCommand(c.name, &c);1198}1199}