Skip to content

Commit 64bf2bb

Browse files
committed
Don't update estimates when we aren't synced.
Pass a flag to the estimation code, using IsInitialBlockDownload as a proxy for when we are still catching up and we shouldn't be counting how many blocks it takes for transactions to be included. Also rearrange HasNoInputs so TxMemPoolEntrys don't need to be aware of TxMempools.
1 parent ff34d78 commit 64bf2bb

File tree

5 files changed

+43
-35
lines changed

5 files changed

+43
-35
lines changed

src/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
974974
CAmount nFees = nValueIn-nValueOut;
975975
double dPriority = view.GetPriority(tx, chainActive.Height());
976976

977-
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height());
977+
CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height(), mempool.HasNoInputsOf(tx));
978978
unsigned int nSize = entry.GetTxSize();
979979

980980
// Don't accept it if it can't get into a block
@@ -1040,7 +1040,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
10401040
}
10411041

10421042
// Store transaction in memory
1043-
pool.addUnchecked(hash, entry);
1043+
pool.addUnchecked(hash, entry, !IsInitialBlockDownload());
10441044
}
10451045

10461046
SyncWithWallets(tx, NULL);
@@ -2042,7 +2042,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
20422042
LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001);
20432043
// Remove conflicting transactions from the mempool.
20442044
list<CTransaction> txConflicted;
2045-
mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted);
2045+
mempool.removeForBlock(pblock->vtx, pindexNew->nHeight, txConflicted, !IsInitialBlockDownload());
20462046
mempool.check(pcoinsTip);
20472047
// Update chainActive & related variables.
20482048
UpdateTip(pindexNew);

src/policyestimator.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ bool CBlockPolicyEstimator::isPriDataPoint(const CFeeRate &fee, double pri)
333333
return false;
334334
}
335335

336-
void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry)
336+
void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate)
337337
{
338338
unsigned int txHeight = entry.GetHeight();
339339
uint256 hash = entry.GetTx().GetHash();
@@ -346,6 +346,11 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry)
346346
return;
347347
}
348348

349+
// Only want to be updating estimates when our blockchain is synced,
350+
// otherwise we'll miscalculate how many blocks its taking to get included.
351+
if (!fCurrentEstimate)
352+
return;
353+
349354
if (!entry.WasClearAtEntry()) {
350355
// This transaction depends on other transactions in the mempool to
351356
// be included in a block before it will be able to be included, so
@@ -415,7 +420,8 @@ void CBlockPolicyEstimator::processBlockTx(unsigned int nBlockHeight, const CTxM
415420
}
416421
}
417422

418-
void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, std::vector<CTxMemPoolEntry>& entries)
423+
void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight,
424+
std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate)
419425
{
420426
if (nBlockHeight <= nBestSeenHeight) {
421427
// Ignore side chains and re-orgs; assuming they are random
@@ -427,6 +433,11 @@ void CBlockPolicyEstimator::processBlock(unsigned int nBlockHeight, std::vector<
427433
}
428434
nBestSeenHeight = nBlockHeight;
429435

436+
// Only want to be updating estimates when our blockchain is synced,
437+
// otherwise we'll miscalculate how many blocks its taking to get included.
438+
if (!fCurrentEstimate)
439+
return;
440+
430441
// Update the dynamic cutoffs
431442
// a fee/priority is "likely" the reason your tx was included in a block if >85% of such tx's
432443
// were confirmed in 2 blocks and is "unlikely" if <50% were confirmed in 10 blocks

src/policyestimator.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,14 @@ class CBlockPolicyEstimator
216216
CBlockPolicyEstimator();
217217

218218
/** Process all the transactions that have been included in a block */
219-
void processBlock(unsigned int nBlockHeight, std::vector<CTxMemPoolEntry>& entries);
219+
void processBlock(unsigned int nBlockHeight,
220+
std::vector<CTxMemPoolEntry>& entries, bool fCurrentEstimate);
220221

221222
/** Process a transaction confirmed in a block*/
222223
void processBlockTx(unsigned int nBlockHeight, const CTxMemPoolEntry& entry);
223224

224225
/** Process a transaction accepted to the mempool*/
225-
void processTransaction(const CTxMemPoolEntry& entry);
226+
void processTransaction(const CTxMemPoolEntry& entry, bool fCurrentEstimate);
226227

227228
/** Remove a transaction from the mempool tracking stats*/
228229
void removeTx(uint256 hash);

src/txmempool.cpp

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ CTxMemPoolEntry::CTxMemPoolEntry():
2323

2424
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
2525
int64_t _nTime, double _dPriority,
26-
unsigned int _nHeight):
27-
tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight)
26+
unsigned int _nHeight, bool poolHasNoInputsOf):
27+
tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight),
28+
hadNoDependencies(poolHasNoInputsOf)
2829
{
2930
nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
30-
3131
nModSize = tx.CalculateModifiedSize(nTxSize);
32-
hadNoDependencies = HasNoInputsInPool(mempool);
3332
}
3433

3534
CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other)
@@ -46,22 +45,6 @@ CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const
4645
return dResult;
4746
}
4847

49-
// Check whether all of this transactions inputs are available and the tx is clear
50-
// to be added to a block (not dependent on other mempool transactions)
51-
// This relies on the fact that if the transaction gets accepted to the mempool
52-
// each of its inputs is either in the mempool XOR in the blockchain.
53-
bool CTxMemPoolEntry::HasNoInputsInPool(const CTxMemPool &pool) const
54-
{
55-
BOOST_FOREACH(const CTxIn &txin, tx.vin)
56-
{
57-
if (pool.exists(txin.prevout.hash)) {
58-
return false;
59-
}
60-
}
61-
62-
return true;
63-
}
64-
6548
CTxMemPool::CTxMemPool(const CFeeRate& _minRelayFee) :
6649
nTransactionsUpdated(0),
6750
minRelayFee(_minRelayFee)
@@ -110,7 +93,7 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n)
11093
}
11194

11295

113-
bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry)
96+
bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate)
11497
{
11598
// Add to memory pool without checking anything.
11699
// Used by main.cpp AcceptToMemoryPool(), which DOES do
@@ -124,7 +107,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry)
124107
nTransactionsUpdated++;
125108
totalTxSize += entry.GetTxSize();
126109
}
127-
minerPolicyEstimator->processTransaction(entry);
110+
minerPolicyEstimator->processTransaction(entry, fCurrentEstimate);
128111
return true;
129112
}
130113

@@ -221,7 +204,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::list<CTransaction>
221204
* Called when a block is connected. Removes from mempool and updates the miner fee estimator.
222205
*/
223206
void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
224-
std::list<CTransaction>& conflicts)
207+
std::list<CTransaction>& conflicts, bool fCurrentEstimate)
225208
{
226209
LOCK(cs);
227210
std::vector<CTxMemPoolEntry> entries;
@@ -239,7 +222,7 @@ void CTxMemPool::removeForBlock(const std::vector<CTransaction>& vtx, unsigned i
239222
ClearPrioritisation(tx.GetHash());
240223
}
241224
// After the txs in the new block have been removed from the mempool, update policy estimates
242-
minerPolicyEstimator->processBlock(nBlockHeight, entries);
225+
minerPolicyEstimator->processBlock(nBlockHeight, entries, fCurrentEstimate);
243226
}
244227

245228
void CTxMemPool::clear()
@@ -416,6 +399,19 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
416399
mapDeltas.erase(hash);
417400
}
418401

402+
// Check that none of this transactions inputs are in the mempool, and thus
403+
// the tx is not dependent on other mempool transactions to be included in a block.
404+
bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
405+
{
406+
BOOST_FOREACH(const CTxIn &txin, tx.vin)
407+
{
408+
if (exists(txin.prevout.hash)) {
409+
return false;
410+
}
411+
}
412+
413+
return true;
414+
}
419415

420416
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView *baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
421417

src/txmempool.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class CTxMemPoolEntry
4949

5050
public:
5151
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee,
52-
int64_t _nTime, double _dPriority, unsigned int _nHeight);
52+
int64_t _nTime, double _dPriority, unsigned int _nHeight, bool poolHasNoInputsOf = false);
5353
CTxMemPoolEntry();
5454
CTxMemPoolEntry(const CTxMemPoolEntry& other);
5555

@@ -60,7 +60,6 @@ class CTxMemPoolEntry
6060
int64_t GetTime() const { return nTime; }
6161
unsigned int GetHeight() const { return nHeight; }
6262
bool WasClearAtEntry() const { return hadNoDependencies; }
63-
bool HasNoInputsInPool(const CTxMemPool& pool) const;
6463
};
6564

6665
class CBlockPolicyEstimator;
@@ -116,17 +115,18 @@ class CTxMemPool
116115
void check(const CCoinsViewCache *pcoins) const;
117116
void setSanityCheck(bool _fSanityCheck) { fSanityCheck = _fSanityCheck; }
118117

119-
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry);
118+
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
120119
void remove(const CTransaction &tx, std::list<CTransaction>& removed, bool fRecursive = false);
121120
void removeCoinbaseSpends(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight);
122121
void removeConflicts(const CTransaction &tx, std::list<CTransaction>& removed);
123122
void removeForBlock(const std::vector<CTransaction>& vtx, unsigned int nBlockHeight,
124-
std::list<CTransaction>& conflicts);
123+
std::list<CTransaction>& conflicts, bool fCurrentEstimate = true);
125124
void clear();
126125
void queryHashes(std::vector<uint256>& vtxid);
127126
void pruneSpent(const uint256& hash, CCoins &coins);
128127
unsigned int GetTransactionsUpdated() const;
129128
void AddTransactionsUpdated(unsigned int n);
129+
bool HasNoInputsOf(const CTransaction& tx) const;
130130

131131
/** Affect CreateNewBlock prioritisation of transactions */
132132
void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta);

0 commit comments

Comments
 (0)