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.
1// Copyright (c) 2021-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_NODE_TXORPHANAGE_H6#define BITCOIN_NODE_TXORPHANAGE_H8#include <consensus/validation.h>9#include <net.h>10#include <primitives/block.h>11#include <primitives/transaction.h>12#include <sync.h>13#include <util/time.h>15#include <map>16#include <set>18namespace node {19/** Default value for TxOrphanage::m_reserved_usage_per_peer. Helps limit the total amount of memory used by the orphanage. */20inline constexpr int64_t DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER{404'000};21/** Default value for TxOrphanage::m_max_global_latency_score. Helps limit the maximum latency for operations like22* EraseForBlock and LimitOrphans. */23inline constexpr unsigned int DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE{3'000};25// Keep the connection caps below the default global latency limit to avoid a zero per-peer share.26static_assert(MAX_PEER_CONNECTIONS + MAX_ADDNODE_CONNECTIONS + MAX_PRIVATE_BROADCAST_CONNECTIONS < DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);28/** A class to track orphan transactions (failed on TX_MISSING_INPUTS)29* Since we cannot distinguish orphans from bad transactions with non-existent inputs, we heavily limit the amount of30* announcements (unique (NodeId, wtxid) pairs), the number of inputs, and size of the orphans stored (both individual31* and summed). We also try to prevent adversaries from churning this data structure: once global limits are reached, we32* continuously evict the oldest announcement (sorting non-reconsiderable orphans before reconsiderable ones) from the33* most resource-intensive peer until we are back within limits.34* - Peers can exceed their individual limits (e.g. because they are very useful transaction relay peers) as long as the35* global limits are not exceeded.36* - As long as the orphan has 1 announcer, it remains in the orphanage.37* - No peer can trigger the eviction of another peer's orphans.38* - Peers' orphans are effectively protected from eviction as long as they don't exceed their limits.39* Not thread-safe. Requires external synchronization.40*/41class TxOrphanage {42public:43using Usage = int64_t;44using Count = unsigned int;46/** Allows providing orphan information externally */47struct OrphanInfo {48CTransactionRef tx;49/** Peers added with AddTx or AddAnnouncer. */50std::set<NodeId> announcers;52// Constructor with moved announcers53OrphanInfo(CTransactionRef tx, std::set<NodeId>&& announcers) :54tx(std::move(tx)),55announcers(std::move(announcers))56{}57};59virtual ~TxOrphanage() = default;61/** Add a new orphan transaction */62virtual bool AddTx(const CTransactionRef& tx, NodeId peer) = 0;64/** Add an additional announcer to an orphan if it exists. Otherwise, do nothing. */65virtual bool AddAnnouncer(const Wtxid& wtxid, NodeId peer) = 0;67/** Get a transaction by its witness txid */68virtual CTransactionRef GetTx(const Wtxid& wtxid) const = 0;70/** Check if we already have an orphan transaction (by wtxid only) */71virtual bool HaveTx(const Wtxid& wtxid) const = 0;73/** Check if a {tx, peer} exists in the orphanage.*/74virtual bool HaveTxFromPeer(const Wtxid& wtxid, NodeId peer) const = 0;76/** Extract a transaction from a peer's work set, and flip it back to non-reconsiderable.77* Returns nullptr if there are no transactions to work on.78* Otherwise returns the transaction reference, and removes79* it from the work set.80*/81virtual CTransactionRef GetTxToReconsider(NodeId peer) = 0;83/** Erase an orphan by wtxid, including all announcements if there are multiple.84* Returns true if an orphan was erased, false if no tx with this wtxid exists. */85virtual bool EraseTx(const Wtxid& wtxid) = 0;87/** Maybe erase all orphans announced by a peer (eg, after that peer disconnects). If an orphan88* has been announced by another peer, don't erase, just remove this peer from the list of announcers. */89virtual void EraseForPeer(NodeId peer) = 0;91/** Erase all orphans included in or invalidated by a new block */92virtual void EraseForBlock(const CBlock& block) = 0;94/** Add any orphans that list a particular tx as a parent into the from peer's work set */95virtual std::vector<std::pair<Wtxid, NodeId>> AddChildrenToWorkSet(const CTransaction& tx, FastRandomContext& rng) = 0;97/** Does this peer have any work to do? */98virtual bool HaveTxToReconsider(NodeId peer) = 0;100/** Get all children that spend from this tx and were received from nodeid. Sorted101* reconsiderable before non-reconsiderable, then from most recent to least recent. */102virtual std::vector<CTransactionRef> GetChildrenFromSamePeer(const CTransactionRef& parent, NodeId nodeid) const = 0;104/** Get all orphan transactions */105virtual std::vector<OrphanInfo> GetOrphanTransactions() const = 0;107/** Get the total usage (weight) of all orphans. If an orphan has multiple announcers, its usage is108* only counted once within this total. */109virtual Usage TotalOrphanUsage() const = 0;111/** Total usage (weight) of orphans for which this peer is an announcer. If an orphan has multiple112* announcers, its weight will be accounted for in each PeerOrphanInfo, so the total of all113* peers' UsageByPeer() may be larger than TotalOrphanUsage(). Similarly, UsageByPeer() may be far higher than114* ReservedPeerUsage(), particularly if many peers have provided the same orphans. */115virtual Usage UsageByPeer(NodeId peer) const = 0;117/** Check consistency between PeerOrphanInfo and m_orphans. Recalculate counters and ensure they118* match what is cached. */119virtual void SanityCheck() const = 0;121/** Number of announcements, i.e. total size of m_orphans. Ones for the same wtxid are not de-duplicated.122* Not the same as TotalLatencyScore(). */123virtual Count CountAnnouncements() const = 0;125/** Number of unique orphans (by wtxid). */126virtual Count CountUniqueOrphans() const = 0;128/** Number of orphans stored from this peer. */129virtual Count AnnouncementsFromPeer(NodeId peer) const = 0;131/** Latency score of transactions announced by this peer. */132virtual Count LatencyScoreFromPeer(NodeId peer) const = 0;134/** Get the maximum global latency score allowed */135virtual Count MaxGlobalLatencyScore() const = 0;137/** Get the total latency score of all orphans */138virtual Count TotalLatencyScore() const = 0;140/** Get the reserved usage per peer */141virtual Usage ReservedPeerUsage() const = 0;143/** Get the maximum latency score allowed per peer */144virtual Count MaxPeerLatencyScore() const = 0;146/** Get the maximum global usage allowed */147virtual Usage MaxGlobalUsage() const = 0;148};150/** Create a new TxOrphanage instance */151std::unique_ptr<TxOrphanage> MakeTxOrphanage() noexcept;152std::unique_ptr<TxOrphanage> MakeTxOrphanage(TxOrphanage::Count max_global_latency_score, TxOrphanage::Usage reserved_peer_usage) noexcept;153} // namespace node154#endif // BITCOIN_NODE_TXORPHANAGE_H
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.