Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 284 Lines • ▼ Show 20 Lines | |||||
struct COrphanTx { | struct COrphanTx { | ||||
// When modifying, adapt the copy of this definition in tests/DoS_tests. | // When modifying, adapt the copy of this definition in tests/DoS_tests. | ||||
CTransactionRef tx; | CTransactionRef tx; | ||||
NodeId fromPeer; | NodeId fromPeer; | ||||
int64_t nTimeExpire; | int64_t nTimeExpire; | ||||
size_t list_pos; | size_t list_pos; | ||||
}; | }; | ||||
/** Guards orphan transactions and extra txs for compact blocks */ | |||||
RecursiveMutex g_cs_orphans; | RecursiveMutex g_cs_orphans; | ||||
/** | |||||
* Map from txid to orphan transaction record. Limited by | |||||
* -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS | |||||
*/ | |||||
std::map<TxId, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans); | std::map<TxId, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans); | ||||
void EraseOrphansFor(NodeId peer); | void EraseOrphansFor(NodeId peer); | ||||
// Internal stuff | // Internal stuff | ||||
namespace { | namespace { | ||||
/** Number of nodes with fSyncStarted. */ | /** Number of nodes with fSyncStarted. */ | ||||
int nSyncStarted GUARDED_BY(cs_main) = 0; | int nSyncStarted GUARDED_BY(cs_main) = 0; | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
std::deque<std::pair<int64_t, MapRelay::iterator>> | std::deque<std::pair<int64_t, MapRelay::iterator>> | ||||
vRelayExpiration GUARDED_BY(cs_main); | vRelayExpiration GUARDED_BY(cs_main); | ||||
struct IteratorComparator { | struct IteratorComparator { | ||||
template <typename I> bool operator()(const I &a, const I &b) const { | template <typename I> bool operator()(const I &a, const I &b) const { | ||||
return &(*a) < &(*b); | return &(*a) < &(*b); | ||||
} | } | ||||
}; | }; | ||||
/** | |||||
* Index from the parents' COutPoint into the mapOrphanTransactions. Used | |||||
* to remove orphan transactions from the mapOrphanTransactions | |||||
*/ | |||||
std::map<COutPoint, | std::map<COutPoint, | ||||
std::set<std::map<TxId, COrphanTx>::iterator, IteratorComparator>> | std::set<std::map<TxId, COrphanTx>::iterator, IteratorComparator>> | ||||
mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans); | mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans); | ||||
//! For random eviction | /** Orphan transactions in vector for quick random eviction */ | ||||
std::vector<std::map<TxId, COrphanTx>::iterator> | std::vector<std::map<TxId, COrphanTx>::iterator> | ||||
g_orphan_list GUARDED_BY(g_cs_orphans); | g_orphan_list GUARDED_BY(g_cs_orphans); | ||||
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0; | /** | ||||
* Orphan/conflicted/etc transactions that are kept for compact block | |||||
* reconstruction. | |||||
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN | |||||
* of these are kept in a ring buffer | |||||
*/ | |||||
static std::vector<std::pair<TxHash, CTransactionRef>> | static std::vector<std::pair<TxHash, CTransactionRef>> | ||||
vExtraTxnForCompact GUARDED_BY(g_cs_orphans); | vExtraTxnForCompact GUARDED_BY(g_cs_orphans); | ||||
/** Offset into vExtraTxnForCompact to insert the next tx */ | |||||
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0; | |||||
} // namespace | } // namespace | ||||
namespace { | namespace { | ||||
/** | /** | ||||
* Maintain validation-specific state about nodes, protected by cs_main, instead | * Maintain validation-specific state about nodes, protected by cs_main, instead | ||||
* by CNode's own locks. This simplifies asynchronous operation, where | * by CNode's own locks. This simplifies asynchronous operation, where | ||||
* processing of incoming data is done after the ProcessMessage call returns, | * processing of incoming data is done after the ProcessMessage call returns, | ||||
* and we're no longer holding the node's locks. | * and we're no longer holding the node's locks. | ||||
▲ Show 20 Lines • Show All 2,085 Lines • ▼ Show 20 Lines | if (!m_chainman.ProcessNewBlockHeaders(config, headers, state, | ||||
pfrom.GetId()); | pfrom.GetId()); | ||||
nodestate->m_chain_sync.m_protect = true; | nodestate->m_chain_sync.m_protect = true; | ||||
++g_outbound_peers_with_protect_from_disconnect; | ++g_outbound_peers_with_protect_from_disconnect; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Reconsider orphan transactions after a parent has been accepted to the | |||||
* mempool. | |||||
* | |||||
* @param[in/out] orphan_work_set The set of orphan transactions to | |||||
* reconsider. Generally only one orphan will be reconsidered on each call of | |||||
* this function. This set may be added to if accepting an orphan causes its | |||||
* children to be reconsidered. | |||||
*/ | |||||
void PeerManager::ProcessOrphanTx(const Config &config, | void PeerManager::ProcessOrphanTx(const Config &config, | ||||
std::set<TxId> &orphan_work_set) | std::set<TxId> &orphan_work_set) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
AssertLockHeld(g_cs_orphans); | AssertLockHeld(g_cs_orphans); | ||||
std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | ||||
bool done = false; | bool done = false; | ||||
while (!done && !orphan_work_set.empty()) { | while (!done && !orphan_work_set.empty()) { | ||||
▲ Show 20 Lines • Show All 3,431 Lines • Show Last 20 Lines |