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.
251result.pushKV("coinbase_tx", coinbaseTxToJSON(*block.vtx[0]));253UniValue txs(UniValue::VARR);254txs.reserve(block.vtx.size());256switch (verbosity) {257case TxVerbosity::SHOW_TXID:258for (const CTransactionRef& tx : block.vtx) {259txs.push_back(tx->GetHash().GetHex());260}261break;263case TxVerbosity::SHOW_DETAILS:264case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:265CBlockUndo blockUndo;266const bool is_not_pruned{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex))};267bool have_undo{is_not_pruned && WITH_LOCK(::cs_main, return blockindex.nStatus & BLOCK_HAVE_UNDO)};268if (have_undo && !blockman.ReadBlockUndo(blockUndo, blockindex)) {269throw JSONRPCError(RPC_INTERNAL_ERROR, "Undo data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");270}271for (size_t i = 0; i < block.vtx.size(); ++i) {272const CTransactionRef& tx = block.vtx.at(i);273// coinbase transaction (i.e. i == 0) doesn't have undo data274const CTxUndo* txundo = (have_undo && i > 0) ? &blockUndo.vtxundo.at(i - 1) : nullptr;275UniValue objTx(UniValue::VOBJ);276TxToUniv(*tx, /*block_hash=*/uint256(), /*entry=*/objTx, /*include_hex=*/true, txundo, verbosity);277txs.push_back(std::move(objTx));278}279break;280}282result.pushKV("tx", std::move(txs));284return result;285}287static RPCMethod getblockcount()288{289return RPCMethod{290"getblockcount",291"Returns the height of the most-work fully-validated chain.\n"292"The genesis block has height 0.\n",293{},294RPCResult{295RPCResult::Type::NUM, "", "The current block count"},296RPCExamples{297HelpExampleCli("getblockcount", "")298+ HelpExampleRpc("getblockcount", "")299},300[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue301{302ChainstateManager& chainman = EnsureAnyChainman(request.context);303LOCK(cs_main);304return chainman.ActiveChain().Height();305},306};307}309static RPCMethod getbestblockhash()310{311return RPCMethod{312"getbestblockhash",313"Returns the hash of the best (tip) block in the most-work fully-validated chain.\n",314{},315RPCResult{316RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"},317RPCExamples{318HelpExampleCli("getbestblockhash", "")319+ HelpExampleRpc("getbestblockhash", "")320},321[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue322{323ChainstateManager& chainman = EnsureAnyChainman(request.context);324LOCK(cs_main);325return chainman.ActiveChain().Tip()->GetBlockHash().GetHex();326},327};328}330static RPCMethod waitfornewblock()331{332return RPCMethod{333"waitfornewblock",334"Waits for any new block and returns useful info about it.\n"335"\nReturns the current block on timeout or exit.\n"336"\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",337{338{"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},339{"current_tip", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "Method waits for the chain tip to differ from this."},340},341RPCResult{342RPCResult::Type::OBJ, "", "",343{344{RPCResult::Type::STR_HEX, "hash", "The blockhash"},345{RPCResult::Type::NUM, "height", "Block height"},346}},347RPCExamples{348HelpExampleCli("waitfornewblock", "1000")349+ HelpExampleRpc("waitfornewblock", "1000")350},351[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue352{353int timeout = 0;354if (!request.params[0].isNull())355timeout = request.params[0].getInt<int>();356if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");358NodeContext& node = EnsureAnyNodeContext(request.context);359Mining& miner = EnsureMining(node);361// If the caller provided a current_tip value, pass it to waitTipChanged().362//363// If the caller did not provide a current tip hash, call getTip() to get364// one and wait for the tip to be different from this value. This mode is365// less reliable because if the tip changed between waitfornewblock calls,366// it will need to change a second time before this call returns.367BlockRef current_block{CHECK_NONFATAL(miner.getTip()).value()};369uint256 tip_hash{request.params[1].isNull()370? current_block.hash371: ParseHashV(request.params[1], "current_tip")};373// If the user provided an invalid current_tip then this call immediately374// returns the current tip.375std::optional<BlockRef> block = timeout ? miner.waitTipChanged(tip_hash, std::chrono::milliseconds(timeout)) :376miner.waitTipChanged(tip_hash);378// Return current block upon shutdown379if (block) current_block = *block;381UniValue ret(UniValue::VOBJ);382ret.pushKV("hash", current_block.hash.GetHex());383ret.pushKV("height", current_block.height);384return ret;385},386};387}389static RPCMethod waitforblock()390{391return RPCMethod{392"waitforblock",393"Waits for a specific new block and returns useful info about it.\n"394"\nReturns the current block on timeout or exit.\n"395"\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",396{397{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "Block hash to wait for."},398{"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},399},400RPCResult{401RPCResult::Type::OBJ, "", "",402{403{RPCResult::Type::STR_HEX, "hash", "The blockhash"},404{RPCResult::Type::NUM, "height", "Block height"},405}},406RPCExamples{407HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\" 1000")408+ HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")409},410[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue411{412int timeout = 0;414uint256 hash(ParseHashV(request.params[0], "blockhash"));416if (!request.params[1].isNull())417timeout = request.params[1].getInt<int>();418if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");420NodeContext& node = EnsureAnyNodeContext(request.context);421Mining& miner = EnsureMining(node);423// Abort if RPC came out of warmup too early424BlockRef current_block{CHECK_NONFATAL(miner.getTip()).value()};426const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};427while (current_block.hash != hash) {428std::optional<BlockRef> block;429if (timeout) {430auto now{std::chrono::steady_clock::now()};431if (now >= deadline) break;432const MillisecondsDouble remaining{deadline - now};433block = miner.waitTipChanged(current_block.hash, remaining);434} else {435block = miner.waitTipChanged(current_block.hash);436}437// Return current block upon shutdown438if (!block) break;439current_block = *block;440}442UniValue ret(UniValue::VOBJ);443ret.pushKV("hash", current_block.hash.GetHex());444ret.pushKV("height", current_block.height);445return ret;446},447};448}450static RPCMethod waitforblockheight()451{452return RPCMethod{453"waitforblockheight",454"Waits for (at least) block height and returns the height and hash\n"455"of the current tip.\n"456"\nReturns the current block on timeout or exit.\n"457"\nMake sure to use no RPC timeout (bitcoin-cli -rpcclienttimeout=0)",458{459{"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "Block height to wait for."},460{"timeout", RPCArg::Type::NUM, RPCArg::Default{0}, "Time in milliseconds to wait for a response. 0 indicates no timeout."},461},462RPCResult{463RPCResult::Type::OBJ, "", "",464{465{RPCResult::Type::STR_HEX, "hash", "The blockhash"},466{RPCResult::Type::NUM, "height", "Block height"},467}},468RPCExamples{469HelpExampleCli("waitforblockheight", "100 1000")470+ HelpExampleRpc("waitforblockheight", "100, 1000")471},472[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue473{474int timeout = 0;476int height = request.params[0].getInt<int>();478if (!request.params[1].isNull())479timeout = request.params[1].getInt<int>();480if (timeout < 0) throw JSONRPCError(RPC_MISC_ERROR, "Negative timeout");482NodeContext& node = EnsureAnyNodeContext(request.context);483Mining& miner = EnsureMining(node);485// Abort if RPC came out of warmup too early486BlockRef current_block{CHECK_NONFATAL(miner.getTip()).value()};488const auto deadline{std::chrono::steady_clock::now() + 1ms * timeout};490while (current_block.height < height) {491std::optional<BlockRef> block;492if (timeout) {493auto now{std::chrono::steady_clock::now()};494if (now >= deadline) break;495const MillisecondsDouble remaining{deadline - now};496block = miner.waitTipChanged(current_block.hash, remaining);497} else {498block = miner.waitTipChanged(current_block.hash);499}500// Return current block on shutdown