aboutsummaryrefslogtreecommitdiff
path: root/src/txmempool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/txmempool.cpp')
-rw-r--r--src/txmempool.cpp43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 97a426dd35..164e2741a2 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -80,13 +80,13 @@ public:
// Used as belt-and-suspenders check when reading to detect
// file corruption
- bool AreSane(const std::vector<CFeeRate>& vecFee)
+ bool AreSane(const std::vector<CFeeRate>& vecFee, const CFeeRate& minRelayFee)
{
BOOST_FOREACH(CFeeRate fee, vecFee)
{
if (fee < CFeeRate(0))
return false;
- if (fee.GetFee(1000) > CTransaction::minRelayTxFee.GetFee(1000) * 10000)
+ if (fee.GetFeePerK() > minRelayFee.GetFeePerK() * 10000)
return false;
}
return true;
@@ -109,10 +109,10 @@ public:
fileout << vecPriority;
}
- void Read(CAutoFile& filein) {
+ void Read(CAutoFile& filein, const CFeeRate& minRelayFee) {
std::vector<CFeeRate> vecFee;
filein >> vecFee;
- if (AreSane(vecFee))
+ if (AreSane(vecFee, minRelayFee))
feeSamples.insert(feeSamples.end(), vecFee.begin(), vecFee.end());
else
throw runtime_error("Corrupt fee value in estimates file.");
@@ -141,7 +141,7 @@ private:
// nBlocksAgo is 0 based, i.e. transactions that confirmed in the highest seen block are
// nBlocksAgo == 0, transactions in the block before that are nBlocksAgo == 1 etc.
- void seenTxConfirm(CFeeRate feeRate, double dPriority, int nBlocksAgo)
+ void seenTxConfirm(const CFeeRate& feeRate, const CFeeRate& minRelayFee, double dPriority, int nBlocksAgo)
{
// Last entry records "everything else".
int nBlocksTruncated = min(nBlocksAgo, (int) history.size() - 1);
@@ -149,7 +149,7 @@ private:
// We need to guess why the transaction was included in a block-- either
// because it is high-priority or because it has sufficient fees.
- bool sufficientFee = (feeRate > CTransaction::minRelayTxFee);
+ bool sufficientFee = (feeRate > minRelayFee);
bool sufficientPriority = AllowFree(dPriority);
const char* assignedTo = "unassigned";
if (sufficientFee && !sufficientPriority)
@@ -177,7 +177,7 @@ public:
history.resize(nEntries);
}
- void seenBlock(const std::vector<CTxMemPoolEntry>& entries, int nBlockHeight)
+ void seenBlock(const std::vector<CTxMemPoolEntry>& entries, int nBlockHeight, const CFeeRate minRelayFee)
{
if (nBlockHeight <= nBestSeenHeight)
{
@@ -222,7 +222,7 @@ public:
// Fees are stored and reported as BTC-per-kb:
CFeeRate feeRate(entry->GetFee(), entry->GetTxSize());
double dPriority = entry->GetPriority(entry->GetHeight()); // Want priority when it went IN
- seenTxConfirm(feeRate, dPriority, i);
+ seenTxConfirm(feeRate, minRelayFee, dPriority, i);
}
}
for (size_t i = 0; i < history.size(); i++) {
@@ -251,8 +251,13 @@ public:
std::sort(sortedFeeSamples.begin(), sortedFeeSamples.end(),
std::greater<CFeeRate>());
}
- if (sortedFeeSamples.size() == 0)
+ if (sortedFeeSamples.size() < 11)
+ {
+ // Eleven is Gavin's Favorite Number
+ // ... but we also take a maximum of 10 samples per block so eleven means
+ // we're getting samples from at least two different blocks
return CFeeRate(0);
+ }
int nBucketSize = history.at(nBlocksToConfirm).FeeSamples();
@@ -281,7 +286,7 @@ public:
std::sort(sortedPrioritySamples.begin(), sortedPrioritySamples.end(),
std::greater<double>());
}
- if (sortedPrioritySamples.size() == 0)
+ if (sortedPrioritySamples.size() < 11)
return -1.0;
int nBucketSize = history.at(nBlocksToConfirm).PrioritySamples();
@@ -308,7 +313,7 @@ public:
}
}
- void Read(CAutoFile& filein)
+ void Read(CAutoFile& filein, const CFeeRate& minRelayFee)
{
filein >> nBestSeenHeight;
size_t numEntries;
@@ -317,14 +322,14 @@ public:
for (size_t i = 0; i < numEntries; i++)
{
CBlockAverage entry;
- entry.Read(filein);
+ entry.Read(filein, minRelayFee);
history.push_back(entry);
}
}
};
-CTxMemPool::CTxMemPool()
+CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) : minRelayFee(_minRelayFee)
{
// Sanity checks off by default for performance, because otherwise
// accepting transactions becomes O(N^2) where N is the number
@@ -415,6 +420,7 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed
void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed)
{
// Remove transactions which depend on inputs of tx, recursively
+ list<CTransaction> result;
LOCK(cs);
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
std::map<COutPoint, CInPoint>::iterator it = mapNextTx.find(txin.prevout);
@@ -440,7 +446,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
if (mapTx.count(hash))
entries.push_back(mapTx[hash]);
}
- minerPolicyEstimator->seenBlock(entries, nBlockHeight);
+ minerPolicyEstimator->seenBlock(entries, nBlockHeight, minRelayFee);
BOOST_FOREACH(const CTransaction& tx, vtx)
{
std::list<CTransaction> dummy;
@@ -555,7 +561,7 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein)
return error("CTxMemPool::ReadFeeEstimates() : up-version (%d) fee estimate file", nVersionRequired);
LOCK(cs);
- minerPolicyEstimator->Read(filein);
+ minerPolicyEstimator->Read(filein, minRelayFee);
}
catch (std::exception &e) {
LogPrintf("CTxMemPool::ReadFeeEstimates() : unable to read policy estimator data (non-fatal)");
@@ -596,14 +602,15 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
- if (base->GetCoins(txid, coins))
- return true;
+ // If an entry in the mempool exists, always return that one, as it's guaranteed to never
+ // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
+ // transactions. First checking the underlying cache risks returning a pruned entry instead.
CTransaction tx;
if (mempool.lookup(txid, tx)) {
coins = CCoins(tx, MEMPOOL_HEIGHT);
return true;
}
- return false;
+ return (base->GetCoins(txid, coins) && !coins.IsPruned());
}
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {