aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorGregory Maxwell <[email protected]>2016-06-11 00:26:16 +0000
committerGregory Maxwell <[email protected]>2016-06-15 09:56:28 +0000
commit11cc143895e730002749f0881c4c95635fa54bd5 (patch)
treee0e9ad81dbaba5081304341cb49d44a7d0602c92 /src/main.cpp
parentThis eliminates the primary leak that causes the orphan map to (diff)
downloaddiscoin-11cc143895e730002749f0881c4c95635fa54bd5.tar.xz
discoin-11cc143895e730002749f0881c4c95635fa54bd5.zip
Adds an expiration time for orphan tx.
This prevents higher order orphans and other junk from holding positions in the orphan map. Parents delayed twenty minutes are more are unlikely to ever arrive. The freed space will improve the orphan matching success rate for other transactions.
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/main.cpp b/src/main.cpp
index c80a4ac92..44d96d614 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -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: