aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <[email protected]>2015-10-21 08:49:25 +0200
committerWladimir J. van der Laan <[email protected]>2015-10-21 08:50:16 +0200
commit3b20e239c602dd7d3ab85935ef9d1f6c5e1907d2 (patch)
tree2705a5810ce71e9f382fc2bf073dccd6d8cd6e8c /src/txmempool.cpp
parentMerge pull request #6796 (diff)
parentFix stale comment in CTxMemPool::TrimToSize. (diff)
downloaddiscoin-3b20e239c602dd7d3ab85935ef9d1f6c5e1907d2.tar.xz
discoin-3b20e239c602dd7d3ab85935ef9d1f6c5e1907d2.zip
Merge pull request #6722
58254aa Fix stale comment in CTxMemPool::TrimToSize. (Matt Corallo) 2bc5018 Fix comment formatting tabs (Matt Corallo) 8abe0f5 Undo GetMinFee-requires-extra-call-to-hit-0 (Matt Corallo) 9e93640 Drop minRelayTxFee to 1000 (Matt Corallo) 074cb15 Add reasonable test case for mempool trimming (Matt Corallo) d355cf4 Only call TrimToSize once per reorg/blocks disconnect (Matt Corallo) 794a8ce Implement on-the-fly mempool size limitation. (Matt Corallo) e6c7b36 Print mempool size in KB when adding txn (Matt Corallo) 241d607 Add CFeeRate += operator (Matt Corallo) e8bcdce Track (and define) ::minRelayTxFee in CTxMemPool (Matt Corallo) 9c9b66f Fix calling mempool directly, instead of pool, in ATMP (Matt Corallo) 49b6fd5 Add Mempool Expire function to remove old transactions (Pieter Wuille) 78b82f4 Reverse the sort on the mempool's feerate index (Suhas Daftuar)
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp92
1 files changed, 88 insertions, 4 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 1370cab0c..bb148005c 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -13,6 +13,7 @@
#include "streams.h"
#include "util.h"
#include "utilmoneystr.h"
+#include "utiltime.h"
#include "version.h"
using namespace std;
@@ -305,15 +306,18 @@ void CTxMemPoolEntry::UpdateState(int64_t modifySize, CAmount modifyFee, int64_t
}
}
-CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
+CTxMemPool::CTxMemPool(const CFeeRate& _minReasonableRelayFee) :
nTransactionsUpdated(0)
{
+ clear();
+
// Sanity checks off by default for performance, because otherwise
// accepting transactions becomes O(N^2) where N is the number
// of transactions in the pool
fSanityCheck = false;
- minerPolicyEstimator = new CBlockPolicyEstimator(_minRelayFee);
+ minerPolicyEstimator = new CBlockPolicyEstimator(_minReasonableRelayFee);
+ minReasonableRelayFee = _minReasonableRelayFee;
}
CTxMemPool::~CTxMemPool()
@@ -538,6 +542,8 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
}
// After the txs in the new block have been removed from the mempool, update policy estimates
minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
+ lastRollingFeeUpdate = GetTime();
+ blockSinceLastRollingFeeBump = true;
}
void CTxMemPool::clear()
@@ -548,6 +554,9 @@ void CTxMemPool::clear()
mapNextTx.clear();
totalTxSize = 0;
cachedInnerUsage = 0;
+ lastRollingFeeUpdate = GetTime();
+ blockSinceLastRollingFeeBump = false;
+ rollingMinimumFeeRate = 0;
++nTransactionsUpdated;
}
@@ -735,10 +744,10 @@ void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash,
LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta));
}
-void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta)
+void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const
{
LOCK(cs);
- std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash);
+ std::map<uint256, std::pair<double, CAmount> >::const_iterator pos = mapDeltas.find(hash);
if (pos == mapDeltas.end())
return;
const std::pair<double, CAmount> &deltas = pos->second;
@@ -792,6 +801,22 @@ void CTxMemPool::RemoveStaged(setEntries &stage) {
}
}
+int CTxMemPool::Expire(int64_t time) {
+ LOCK(cs);
+ indexed_transaction_set::nth_index<2>::type::iterator it = mapTx.get<2>().begin();
+ setEntries toremove;
+ while (it != mapTx.get<2>().end() && it->GetTime() < time) {
+ toremove.insert(mapTx.project<0>(it));
+ it++;
+ }
+ setEntries stage;
+ BOOST_FOREACH(txiter removeit, toremove) {
+ CalculateDescendants(removeit, stage);
+ }
+ RemoveStaged(stage);
+ return stage.size();
+}
+
bool CTxMemPool::addUnchecked(const uint256&hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
{
LOCK(cs);
@@ -837,3 +862,62 @@ const CTxMemPool::setEntries & CTxMemPool::GetMemPoolChildren(txiter entry) cons
assert(it != mapLinks.end());
return it->second.children;
}
+
+CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
+ LOCK(cs);
+ if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
+ return CFeeRate(rollingMinimumFeeRate);
+
+ int64_t time = GetTime();
+ if (time > lastRollingFeeUpdate + 10) {
+ double halflife = ROLLING_FEE_HALFLIFE;
+ if (DynamicMemoryUsage() < sizelimit / 4)
+ halflife /= 4;
+ else if (DynamicMemoryUsage() < sizelimit / 2)
+ halflife /= 2;
+
+ rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
+ lastRollingFeeUpdate = time;
+
+ if (rollingMinimumFeeRate < minReasonableRelayFee.GetFeePerK() / 2) {
+ rollingMinimumFeeRate = 0;
+ return CFeeRate(0);
+ }
+ }
+ return std::max(CFeeRate(rollingMinimumFeeRate), minReasonableRelayFee);
+}
+
+void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
+ AssertLockHeld(cs);
+ if (rate.GetFeePerK() > rollingMinimumFeeRate) {
+ rollingMinimumFeeRate = rate.GetFeePerK();
+ blockSinceLastRollingFeeBump = false;
+ }
+}
+
+void CTxMemPool::TrimToSize(size_t sizelimit) {
+ LOCK(cs);
+
+ unsigned nTxnRemoved = 0;
+ CFeeRate maxFeeRateRemoved(0);
+ while (DynamicMemoryUsage() > sizelimit) {
+ indexed_transaction_set::nth_index<1>::type::iterator it = mapTx.get<1>().begin();
+
+ // We set the new mempool min fee to the feerate of the removed set, plus the
+ // "minimum reasonable fee rate" (ie some value under which we consider txn
+ // to have 0 fee). This way, we don't allow txn to enter mempool with feerate
+ // equal to txn which were removed with no block in between.
+ CFeeRate removed(it->GetFeesWithDescendants(), it->GetSizeWithDescendants());
+ removed += minReasonableRelayFee;
+ trackPackageRemoved(removed);
+ maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
+
+ setEntries stage;
+ CalculateDescendants(mapTx.project<0>(it), stage);
+ RemoveStaged(stage);
+ nTxnRemoved += stage.size();
+ }
+
+ if (maxFeeRateRemoved > CFeeRate(0))
+ LogPrint("mempool", "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString());
+}