@ -100,6 +100,7 @@ struct IteratorComparator
struct COrphanTx {
CTransaction tx ;
NodeId fromPeer ;
int64_t nTimeExpire ;
} ;
map < uint256 , COrphanTx > mapOrphanTransactions GUARDED_BY ( cs_main ) ;
map < COutPoint , set < map < uint256 , COrphanTx > : : iterator , IteratorComparator > > mapOrphanTransactionsByPrev GUARDED_BY ( cs_main ) ;
@ -641,7 +642,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c
return false ;
}
auto ret = mapOrphanTransactions . emplace ( hash , COrphanTx { tx , peer }) ;
auto ret = mapOrphanTransactions . emplace ( hash , COrphanTx { tx , peer , GetTime ( ) + ORPHAN_TX_EXPIRE_TIME }) ;
assert ( ret . second ) ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin ) {
mapOrphanTransactionsByPrev [ txin . prevout ] . insert ( ret . first ) ;
@ -689,6 +690,26 @@ void EraseOrphansFor(NodeId peer)
unsigned int LimitOrphanTxSize ( unsigned int nMaxOrphans ) EXCLUSIVE_LOCKS_REQUIRED ( cs_main )
{
unsigned int nEvicted = 0 ;
static int64_t nNextSweep ;
int64_t nNow = GetTime ( ) ;
if ( nNextSweep < = nNow ) {
// Sweep out expired orphan pool entries:
int nErased = 0 ;
int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL ;
map < uint256 , COrphanTx > : : iterator iter = mapOrphanTransactions . begin ( ) ;
while ( iter ! = mapOrphanTransactions . end ( ) )
{
map < uint256 , COrphanTx > : : iterator maybeErase = iter + + ;
if ( maybeErase - > second . nTimeExpire < = nNow ) {
nErased + = EraseOrphanTx ( maybeErase - > second . tx . GetHash ( ) ) ;
} else {
nMinExpTime = std : : min ( maybeErase - > second . nTimeExpire , nMinExpTime ) ;
}
}
// Sweep again 5 minutes after the next entry that expires in order to batch the linear scan.
nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL ;
if ( nErased > 0 ) LogPrint ( " mempool " , " Erased %d orphan tx due to expiration \n " , nErased ) ;
}
while ( mapOrphanTransactions . size ( ) > nMaxOrphans )
{
// Evict a random orphan: