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.
1// Copyright (c) 2024-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.4#ifndef BITCOIN_NODE_TXDOWNLOADMAN_IMPL_H5#define BITCOIN_NODE_TXDOWNLOADMAN_IMPL_H7#include <node/txdownloadman.h>9#include <common/bloom.h>10#include <consensus/validation.h>11#include <kernel/chain.h>12#include <net.h>13#include <node/txorphanage.h>14#include <primitives/transaction.h>15#include <policy/packages.h>16#include <random.h>17#include <txrequest.h>19class CTxMemPool;20namespace node {21class TxDownloadManagerImpl {22public:23const CTxMemPool& m_mempool;24FastRandomContext m_rng;26/** Manages unvalidated tx data (orphan transactions for which we are downloading ancestors). */27std::unique_ptr<TxOrphanage> m_orphanage;28/** Tracks candidates for requesting and downloading transaction data. */29TxRequestTracker m_txrequest;31/**32* Filter for transactions that were recently rejected by the mempool.33* These are not rerequested until the chain tip changes, at which point34* the entire filter is reset.35*36* Without this filter we'd be re-requesting txs from each of our peers,37* increasing bandwidth consumption considerably. For instance, with 10038* peers, half of which relay a tx we don't accept, that might be a 50x39* bandwidth increase. A flooding attacker attempting to roll-over the40* filter using minimum-sized, 60byte, transactions might manage to send41* 1000/sec if we have fast peers, so we pick 120,000 to give our peers a42* two minute window to send invs to us.43*44* Decreasing the false positive rate is fairly cheap, so we pick one in a45* million to make it highly unlikely for users to have issues with this46* filter.47*48* We typically only add wtxids to this filter. For non-segwit49* transactions, the txid == wtxid, so this only prevents us from50* re-downloading non-segwit transactions when communicating with51* non-wtxidrelay peers -- which is important for avoiding malleation52* attacks that could otherwise interfere with transaction relay from53* non-wtxidrelay peers. For communicating with wtxidrelay peers, having54* the reject filter store wtxids is exactly what we want to avoid55* redownload of a rejected transaction.56*57* In cases where we can tell that a segwit transaction will fail58* validation no matter the witness, we may add the txid of such59* transaction to the filter as well. This can be helpful when60* communicating with txid-relay peers or if we were to otherwise fetch a61* transaction via txid (eg in our orphan handling).62*63* Memory used: 1.3 MB64*/65std::unique_ptr<CRollingBloomFilter> m_lazy_recent_rejects{nullptr};67CRollingBloomFilter& RecentRejectsFilter()68{69if (!m_lazy_recent_rejects) {70m_lazy_recent_rejects = std::make_unique<CRollingBloomFilter>(120'000, 0.000'001);71}73return *m_lazy_recent_rejects;74}76/**77* Filter for:78* (1) wtxids of transactions that were recently rejected by the mempool but are79* eligible for reconsideration if submitted with other transactions.80* (2) packages (see GetPackageHash) we have already rejected before and should not retry.81*82* Similar to m_lazy_recent_rejects, this filter is used to save bandwidth when e.g. all of our peers83* have larger mempools and thus lower minimum feerates than us.84*85* When a transaction's error is TxValidationResult::TX_RECONSIDERABLE (in a package or by86* itself), add its wtxid to this filter. When a package fails for any reason, add the combined87* hash to this filter.88*89* Upon receiving an announcement for a transaction, if it exists in this filter, do not90* download the txdata. When considering packages, if it exists in this filter, drop it.91*92* Reset this filter when the chain tip changes.93*94* Parameters are picked to be the same as m_lazy_recent_rejects, with the same rationale.95*/96std::unique_ptr<CRollingBloomFilter> m_lazy_recent_rejects_reconsiderable{nullptr};98CRollingBloomFilter& RecentRejectsReconsiderableFilter()99{100if (!m_lazy_recent_rejects_reconsiderable) {101m_lazy_recent_rejects_reconsiderable = std::make_unique<CRollingBloomFilter>(120'000, 0.000'001);102}104return *m_lazy_recent_rejects_reconsiderable;105}107/*108* Filter for transactions that have been recently confirmed.109* We use this to avoid requesting transactions that have already been110* confirmed.111*112* Blocks don't typically have more than 4000 transactions, so this should113* be at least six blocks (~1 hr) worth of transactions that we can store,114* inserting both a txid and wtxid for every observed transaction.115* If the number of transactions appearing in a block goes up, or if we are116* seeing getdata requests more than an hour after initial announcement, we117* can increase this number.118* The false positive rate of 1/1M should come out to less than 1119* transaction per day that would be inadvertently ignored (which is the120* same probability that we have in the reject filter).121*/122std::unique_ptr<CRollingBloomFilter> m_lazy_recent_confirmed_transactions{nullptr};124CRollingBloomFilter& RecentConfirmedTransactionsFilter()125{126if (!m_lazy_recent_confirmed_transactions) {127m_lazy_recent_confirmed_transactions = std::make_unique<CRollingBloomFilter>(48'000, 0.000'001);128}130return *m_lazy_recent_confirmed_transactions;131}133TxDownloadManagerImpl(const TxDownloadOptions& options)134: m_mempool{options.m_mempool},135m_rng{options.m_deterministic_txrequest},136m_orphanage{MakeTxOrphanage()},137m_txrequest{options.m_deterministic_txrequest}138{}140struct PeerInfo {141/** Information relevant to scheduling tx requests. */142const TxDownloadConnectionInfo m_connection_info;144PeerInfo(const TxDownloadConnectionInfo& info) : m_connection_info{info} {}145};147/** Information for all of the peers we may download transactions from. This is not necessarily148* all peers we are connected to (no block-relay-only and temporary connections). */149std::map<NodeId, PeerInfo> m_peer_info;151/** Number of wtxid relay peers we have in m_peer_info. */152uint32_t m_num_wtxid_peers{0};154void ActiveTipChange();155void BlockConnected(const std::shared_ptr<const CBlock>& pblock);156void BlockDisconnected();158/** Check whether we already have this gtxid in:159* - mempool160* - orphanage161* - m_recent_rejects162* - m_recent_rejects_reconsiderable (if include_reconsiderable = true)163* - m_recent_confirmed_transactions164* */165bool AlreadyHaveTx(const GenTxid& gtxid, bool include_reconsiderable);167void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo& info);168void DisconnectedPeer(NodeId nodeid);170/** Consider adding this tx hash to txrequest. Should be called whenever a new inv has been received.171* Also called internally when a transaction is missing parents so that we can request them.172*/173bool AddTxAnnouncement(NodeId peer, const GenTxid& gtxid, std::chrono::microseconds now);175/** Get getdata requests to send. */176std::vector<GenTxid> GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time);178/** Marks a tx as ReceivedResponse in txrequest. */179void ReceivedNotFound(NodeId nodeid, const std::vector<GenTxid>& gtxids);181/** Look for a child of this transaction in the orphanage to form a 1-parent-1-child package,182* skipping any combinations that have already been tried. Return the resulting package along with183* the senders of its respective transactions, or std::nullopt if no package is found. */184std::optional<PackageToValidate> Find1P1CPackage(const CTransactionRef& ptx, NodeId nodeid);186void MempoolAcceptedTx(const CTransactionRef& tx);187RejectedTxTodo MempoolRejectedTx(const CTransactionRef& ptx, const TxValidationState& state, NodeId nodeid, bool first_time_failure);188void MempoolRejectedPackage(const Package& package);190std::pair<bool, std::optional<PackageToValidate>> ReceivedTx(NodeId nodeid, const CTransactionRef& ptx);192bool HaveMoreWork(NodeId nodeid);193CTransactionRef GetTxToReconsider(NodeId nodeid);195void CheckIsEmpty();196void CheckIsEmpty(NodeId nodeid);198std::vector<TxOrphanage::OrphanInfo> GetOrphanTransactions() const;200protected:201/** Helper for getting deduplicated vector of Txids in vin. */202std::vector<Txid> GetUniqueParents(const CTransaction& tx);204/** If this peer is an orphan resolution candidate for this transaction, treat the unique_parents as announced by205* this peer; add them as new invs to m_txrequest.206* @returns whether this transaction was a valid orphan resolution candidate.207* */208bool MaybeAddOrphanResolutionCandidate(const std::vector<Txid>& unique_parents, const Wtxid& wtxid, NodeId nodeid, std::chrono::microseconds now);209};210} // namespace node211#endif // BITCOIN_NODE_TXDOWNLOADMAN_IMPL_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.