Line data Source code
1 : // Copyright (c) 2021 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #ifndef BITCOIN_TXORPHANAGE_H 6 : #define BITCOIN_TXORPHANAGE_H 7 : 8 : #include <net.h> 9 : #include <primitives/block.h> 10 : #include <primitives/transaction.h> 11 : #include <sync.h> 12 : 13 : #include <map> 14 : #include <set> 15 : 16 : /** A class to track orphan transactions (failed on TX_MISSING_INPUTS) 17 : * Since we cannot distinguish orphans from bad transactions with 18 : * non-existent inputs, we heavily limit the number of orphans 19 : * we keep and the duration we keep them for. 20 : */ 21 3042 : class TxOrphanage { 22 : public: 23 : /** Add a new orphan transaction */ 24 : bool AddTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 25 : 26 : /** Check if we already have an orphan transaction */ 27 : bool HaveTx(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 28 : 29 : /** Extract a transaction from a peer's work set 30 : * Returns nullptr and sets more to false if there are no transactions 31 : * to work on. Otherwise returns the transaction reference, removes 32 : * the transaction from the work set, and populates its arguments with 33 : * the originating peer, and whether there are more orphans for this peer 34 : * to work on after this tx. 35 : */ 36 : CTransactionRef GetTxToReconsider(NodeId peer, NodeId& originator, bool& more) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 37 : 38 : /** Determine orphan transactions that can be candidates for reconsideration into the mempool based on block */ 39 : void SetCandidatesByBlock(const CBlock& block) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 40 : 41 : /** Erase an orphan by txid */ 42 : int EraseTx(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 43 : 44 : /** Erase all orphans announced by a peer (eg, after that peer disconnects) */ 45 : void EraseForPeer(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 46 : 47 : /** Erase all orphans included in or invalidated by a new block */ 48 : void EraseForBlock(const CBlock& block) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 49 : 50 : /** Check if there are more orphans reported by a peer to work on */ 51 : bool HaveMoreWork(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 52 : 53 : /** Limit the orphanage to the given maximum */ 54 : void LimitOrphans(unsigned int max_orphans_size) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 55 : 56 : /** Add any orphans that list a particular tx as a parent into a peer's work set */ 57 : void AddChildrenToWorkSet(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex); 58 : 59 : /** Return how many entries exist in the orphange */ 60 2286 : size_t Size() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) 61 : { 62 2286 : LOCK(m_mutex); 63 2286 : return m_orphans.size(); 64 2286 : } 65 : 66 : protected: 67 : /** Guards orphan transactions */ 68 : mutable Mutex m_mutex; 69 : 70 : struct OrphanTx { 71 : CTransactionRef tx; 72 : NodeId fromPeer; 73 : int64_t nTimeExpire; 74 : size_t list_pos; 75 : size_t nTxSize; 76 : }; 77 : 78 : /** Map from txid to orphan transaction record. Limited by 79 : * -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS */ 80 : std::map<uint256, OrphanTx> m_orphans GUARDED_BY(m_mutex); 81 : 82 : /** Which peer provided a parent tx of orphans that need to be reconsidered */ 83 : std::map<NodeId, std::set<uint256>> m_peer_work_set GUARDED_BY(m_mutex); 84 : 85 : using OrphanMap = decltype(m_orphans); 86 : 87 : struct IteratorComparator 88 : { 89 : template<typename I> 90 3872 : bool operator()(const I& a, const I& b) const 91 : { 92 3872 : return &(*a) < &(*b); 93 : } 94 : }; 95 : 96 : /** Index from the parents' COutPoint into the m_orphans. Used 97 : * to remove orphan transactions from the m_orphans */ 98 : std::map<COutPoint, std::set<OrphanMap::iterator, IteratorComparator>> m_outpoint_to_orphan_it GUARDED_BY(m_mutex); 99 : 100 : /** Orphan transactions in vector for quick random eviction */ 101 : std::vector<OrphanMap::iterator> m_orphan_list GUARDED_BY(m_mutex); 102 : 103 : /** Cumulative size of all transactions in the orphan map */ 104 3042 : size_t m_orphan_tx_size GUARDED_BY(m_mutex){0}; 105 : 106 : /** Erase an orphan by txid */ 107 : int _EraseTx(const uint256& txid) EXCLUSIVE_LOCKS_REQUIRED(m_mutex); 108 : }; 109 : 110 : #endif // BITCOIN_TXORPHANAGE_H