Inside Bitcoin
Opening the selected file…
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.
251{252return RPCMethod{253"generatetodescriptor",254"Mine to a specified descriptor and return the block hashes.",255{256{"num_blocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},257{"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor to send the newly generated bitcoin to."},258{"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},259},260RPCResult{261RPCResult::Type::ARR, "", "hashes of blocks generated",262{263{RPCResult::Type::STR_HEX, "", "blockhash"},264}265},266RPCExamples{267"\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},268[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue269{270const auto num_blocks{self.Arg<int>("num_blocks")};271const auto max_tries{self.Arg<uint64_t>("maxtries")};273CScript coinbase_output_script;274std::string error;275if (!getScriptFromDescriptor(self.Arg<std::string_view>("descriptor"), coinbase_output_script, error)) {276throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error);277}279NodeContext& node = EnsureAnyNodeContext(request.context);280Mining& miner = EnsureMining(node);281ChainstateManager& chainman = EnsureChainman(node);283return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);284},285};286}288static RPCMethod generate()289{290return RPCMethod{"generate", "has been replaced by the -generate cli option. Refer to -help for more information.", {}, {}, RPCExamples{""}, [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue {291throw JSONRPCError(RPC_METHOD_NOT_FOUND, self.ToString());292}};293}295static RPCMethod generatetoaddress()296{297return RPCMethod{"generatetoaddress",298"Mine to a specified address and return the block hashes.",299{300{"nblocks", RPCArg::Type::NUM, RPCArg::Optional::NO, "How many blocks are generated."},301{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to send the newly generated bitcoin to."},302{"maxtries", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_MAX_TRIES}, "How many iterations to try."},303},304RPCResult{305RPCResult::Type::ARR, "", "hashes of blocks generated",306{307{RPCResult::Type::STR_HEX, "", "blockhash"},308}},309RPCExamples{310"\nGenerate 11 blocks to myaddress\n"311+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"")312+ "If you are using the " CLIENT_NAME " wallet, you can get a new address to send the newly generated bitcoin to with:\n"313+ HelpExampleCli("getnewaddress", "")314},315[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue316{317const int num_blocks{request.params[0].getInt<int>()};318const uint64_t max_tries{request.params[2].isNull() ? DEFAULT_MAX_TRIES : request.params[2].getInt<int>()};320CTxDestination destination = DecodeDestination(request.params[1].get_str());321if (!IsValidDestination(destination)) {322throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address");323}325NodeContext& node = EnsureAnyNodeContext(request.context);326Mining& miner = EnsureMining(node);327ChainstateManager& chainman = EnsureChainman(node);329CScript coinbase_output_script = GetScriptForDestination(destination);331return generateBlocks(chainman, miner, coinbase_output_script, num_blocks, max_tries);332},333};334}336static RPCMethod generateblock()337{338return RPCMethod{"generateblock",339"Mine a set of ordered transactions to a specified address or descriptor and return the block hash.\n"340"Transaction fees are not collected in the block reward.",341{342{"output", RPCArg::Type::STR, RPCArg::Optional::NO, "The address or descriptor to send the newly generated bitcoin to."},343{"transactions", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of hex strings which are either txids or raw transactions.\n"344"Txids must reference transactions currently in the mempool.\n"345"All transactions must be valid and in valid order, otherwise the block will be rejected.",346{347{"rawtx/txid", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},348},349},350{"submit", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to submit the block before the RPC call returns or to return it as hex."},351},352RPCResult{353RPCResult::Type::OBJ, "", "",354{355{RPCResult::Type::STR_HEX, "hash", "hash of generated block"},356{RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "hex of generated block, only present when submit=false"},357}358},359RPCExamples{360"\nGenerate a block to myaddress, with txs rawtx and mempool_txid\n"361+ HelpExampleCli("generateblock", R"("myaddress" '["rawtx", "mempool_txid"]')")362},363[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue364{365const auto address_or_descriptor = request.params[0].get_str();366CScript coinbase_output_script;367std::string error;369if (!getScriptFromDescriptor(address_or_descriptor, coinbase_output_script, error)) {370const auto destination = DecodeDestination(address_or_descriptor);371if (!IsValidDestination(destination)) {372throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Error: Invalid address or descriptor");373}375coinbase_output_script = GetScriptForDestination(destination);376}378NodeContext& node = EnsureAnyNodeContext(request.context);379Mining& miner = EnsureMining(node);380const CTxMemPool& mempool = EnsureMemPool(node);382std::vector<CTransactionRef> txs;383const auto raw_txs_or_txids = request.params[1].get_array();384for (size_t i = 0; i < raw_txs_or_txids.size(); i++) {385const auto& str{raw_txs_or_txids[i].get_str()};387CMutableTransaction mtx;388if (auto txid{Txid::FromHex(str)}) {389const auto tx{mempool.get(*txid)};390if (!tx) {391throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Transaction %s not in mempool.", str));392}394txs.emplace_back(tx);396} else if (DecodeHexTx(mtx, str)) {397txs.push_back(MakeTransactionRef(std::move(mtx)));399} else {400throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("Transaction decode failed for %s. Make sure the tx has at least one input.", str));401}402}404const bool process_new_block{request.params[2].isNull() ? true : request.params[2].get_bool()};405CBlock block;407ChainstateManager& chainman = EnsureChainman(node);408{409LOCK(chainman.GetMutex());410{411std::unique_ptr<BlockTemplate> block_template{miner.createNewBlock({.use_mempool = false, .coinbase_output_script = coinbase_output_script}, /*cooldown=*/false)};412CHECK_NONFATAL(block_template);414block = block_template->getBlock();415}417CHECK_NONFATAL(block.vtx.size() == 1);419// Add transactions420block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());421RegenerateCommitments(block, chainman);423if (BlockValidationState state{TestBlockValidity(chainman.ActiveChainstate(), block, /*check_pow=*/false, /*check_merkle_root=*/false)}; !state.IsValid()) {424throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));425}426}428std::shared_ptr<const CBlock> block_out;429uint64_t max_tries{DEFAULT_MAX_TRIES};431if (!GenerateBlock(chainman, std::move(block), max_tries, block_out, process_new_block) || !block_out) {432throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block.");433}435UniValue obj(UniValue::VOBJ);436obj.pushKV("hash", block_out->GetHash().GetHex());437if (!process_new_block) {438DataStream block_ser;439block_ser << TX_WITH_WITNESS(*block_out);440obj.pushKV("hex", HexStr(block_ser));441}442return obj;443},444};445}447static RPCMethod getmininginfo()448{449return RPCMethod{450"getmininginfo",451"Returns a json object containing mining-related information.",452{},453RPCResult{454RPCResult::Type::OBJ, "", "",455{456{RPCResult::Type::NUM, "blocks", "The current block"},457{RPCResult::Type::NUM, "currentblockweight", /*optional=*/true, "The block weight (including reserved weight for block header, txs count and coinbase tx) of the last assembled block (only present if a block was ever assembled)"},458{RPCResult::Type::NUM, "currentblocktx", /*optional=*/true, "The number of block transactions (excluding coinbase) of the last assembled block (only present if a block was ever assembled)"},459{RPCResult::Type::STR_HEX, "bits", "The current nBits, compact representation of the block difficulty target"},460{RPCResult::Type::NUM, "difficulty", "The current difficulty"},461{RPCResult::Type::STR_HEX, "target", "The current target"},462{RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},463{RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},464{RPCResult::Type::STR_AMOUNT, "blockmintxfee", "Minimum feerate of packages selected for block inclusion in " + CURRENCY_UNIT + "/kvB"},465{RPCResult::Type::STR, "chain", "current network name (" LIST_CHAIN_NAMES ")"},466{RPCResult::Type::STR_HEX, "signet_challenge", /*optional=*/true, "The block challenge (aka. block script), in hexadecimal (only present if the current network is a signet)"},467{RPCResult::Type::OBJ, "next", "The next block",468{469{RPCResult::Type::NUM, "height", "The next height"},470{RPCResult::Type::STR_HEX, "bits", "The next target nBits"},471{RPCResult::Type::NUM, "difficulty", "The next difficulty"},472{RPCResult::Type::STR_HEX, "target", "The next target"}473}},474(IsDeprecatedRPCEnabled("warnings") ?475RPCResult{RPCResult::Type::STR, "warnings", "any network and blockchain warnings (DEPRECATED)"} :476RPCResult{RPCResult::Type::ARR, "warnings", "any network and blockchain warnings (run with `-deprecatedrpc=warnings` to return the latest warning as a single string)",477{478{RPCResult::Type::STR, "", "warning"},479}480}481),482}},483RPCExamples{484HelpExampleCli("getmininginfo", "")485+ HelpExampleRpc("getmininginfo", "")486},487[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue488{489NodeContext& node = EnsureAnyNodeContext(request.context);490const CTxMemPool& mempool = EnsureMemPool(node);491ChainstateManager& chainman = EnsureChainman(node);492LOCK(cs_main);493const CChain& active_chain = chainman.ActiveChain();494CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};496UniValue obj(UniValue::VOBJ);497obj.pushKV("blocks", active_chain.Height());498if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);499if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);500obj.pushKV("bits", strprintf("%08x", tip.nBits));