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.
1501case PackageValidationResult::PCKG_POLICY:1502case PackageValidationResult::PCKG_TX:1503{1504// Package-wide error we want to return, but we also want to return individual responses1505package_msg = package_result.m_state.ToString();1506CHECK_NONFATAL(package_result.m_tx_results.size() == txns.size() ||1507package_result.m_tx_results.empty());1508break;1509}1510}1512size_t num_broadcast{0};1513for (const auto& tx : txns) {1514// We don't want to re-submit the txn for validation in BroadcastTransaction1515if (!mempool.exists(tx->GetHash())) {1516continue;1517}1519// We do not expect an error here; we are only broadcasting things already/still in mempool1520std::string err_string;1521const auto err = BroadcastTransaction(node,1522tx,1523err_string,1524/*max_tx_fee=*/0,1525node::TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL,1526/*wait_callback=*/true);1527if (err != TransactionError::OK) {1528throw JSONRPCTransactionError(err,1529strprintf("transaction broadcast failed: %s (%d transactions were broadcast successfully)",1530err_string, num_broadcast));1531}1532num_broadcast++;1533}1535UniValue rpc_result{UniValue::VOBJ};1536rpc_result.pushKV("package_msg", package_msg);1537UniValue tx_result_map{UniValue::VOBJ};1538std::set<Txid> replaced_txids;1539for (const auto& tx : txns) {1540UniValue result_inner{UniValue::VOBJ};1541result_inner.pushKV("txid", tx->GetHash().GetHex());1542const auto wtxid_hex = tx->GetWitnessHash().GetHex();1543auto it = package_result.m_tx_results.find(tx->GetWitnessHash());1544if (it == package_result.m_tx_results.end()) {1545// No per-tx result for this wtxid1546// Current invariant: per-tx results are all-or-none (every member or empty on package abort).1547// If any exist yet this one is missing, it's an unexpected partial map.1548CHECK_NONFATAL(package_result.m_tx_results.empty());1549result_inner.pushKV("error", "package-not-validated");1550tx_result_map.pushKV(wtxid_hex, std::move(result_inner));1551continue;1552}1553const auto& tx_result = it->second;1554switch(it->second.m_result_type) {1555case MempoolAcceptResult::ResultType::DIFFERENT_WITNESS:1556result_inner.pushKV("other-wtxid", it->second.m_other_wtxid.value().GetHex());1557break;1558case MempoolAcceptResult::ResultType::INVALID:1559result_inner.pushKV("error", it->second.m_state.ToString());1560break;1561case MempoolAcceptResult::ResultType::VALID:1562case MempoolAcceptResult::ResultType::MEMPOOL_ENTRY:1563result_inner.pushKV("vsize_adjusted", it->second.m_vsize.value());1564result_inner.pushKV("vsize", it->second.m_vsize.value());1565result_inner.pushKV("vsize_bip141", GetVirtualTransactionSize(*tx));1566UniValue fees(UniValue::VOBJ);1567fees.pushKV("base", ValueFromAmount(it->second.m_base_fees.value()));1568if (tx_result.m_result_type == MempoolAcceptResult::ResultType::VALID) {1569// Effective feerate is not provided for MEMPOOL_ENTRY transactions even1570// though modified fees is known, because it is unknown whether package1571// feerate was used when it was originally submitted.1572fees.pushKV("effective-feerate", ValueFromAmount(tx_result.m_effective_feerate.value().GetFeePerK()));1573UniValue effective_includes_res(UniValue::VARR);1574for (const auto& wtxid : tx_result.m_wtxids_fee_calculations.value()) {1575effective_includes_res.push_back(wtxid.ToString());1576}1577fees.pushKV("effective-includes", std::move(effective_includes_res));1578}1579result_inner.pushKV("fees", std::move(fees));1580for (const auto& ptx : it->second.m_replaced_transactions) {1581replaced_txids.insert(ptx->GetHash());1582}1583break;1584}1585tx_result_map.pushKV(wtxid_hex, std::move(result_inner));1586}1587rpc_result.pushKV("tx-results", std::move(tx_result_map));1588UniValue replaced_list(UniValue::VARR);1589for (const auto& txid : replaced_txids) replaced_list.push_back(txid.ToString());1590rpc_result.pushKV("replaced-transactions", std::move(replaced_list));1591return rpc_result;1592},1593};1594}1596void RegisterMempoolRPCCommands(CRPCTable& t)1597{1598static const CRPCCommand commands[]{1599{"rawtransactions", &sendrawtransaction},1600{"rawtransactions", &getprivatebroadcastinfo},1601{"rawtransactions", &abortprivatebroadcast},1602{"rawtransactions", &testmempoolaccept},1603{"blockchain", &getmempoolancestors},1604{"blockchain", &getmempooldescendants},1605{"blockchain", &getmempoolentry},1606{"blockchain", &getmempoolcluster},1607{"blockchain", &gettxspendingprevout},1608{"blockchain", &getmempoolinfo},1609{"hidden", &getmempoolfeeratediagram},1610{"blockchain", &getrawmempool},1611{"blockchain", &importmempool},1612{"blockchain", &savemempool},1613{"hidden", &getorphantxs},1614{"rawtransactions", &submitpackage},1615};1616for (const auto& c : commands) {1617t.appendCommand(c.name, &c);1618}1619}