From 60ac00de854981333656d17c9b2ea2efd1efc436 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 11 Nov 2016 11:17:59 -0500 Subject: Don't track transactions at all during IBD. This was an oversight, where blocks and mempool tracking were ignored during IBD, but transactions that arrived during IBD but were included in blocks after IBD were not ignored. --- src/validation.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/validation.cpp') diff --git a/src/validation.cpp b/src/validation.cpp index bc14c1d8c6..2783a313f7 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -692,7 +692,9 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } } - CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp); + CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, chainActive.Height(), + !IsInitialBlockDownload() && pool.HasNoInputsOf(tx), + inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp); unsigned int nSize = entry.GetTxSize(); // Check that the transaction doesn't have an excessive number of -- cgit v1.2.3 From 84f7ab08d2e8e83a584d72fdf44f68b34baf8165 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 11 Nov 2016 11:57:51 -0500 Subject: Remove member variable hadNoDependencies from CTxMemPoolEntry Fee estimation can just check its own mapMemPoolTxs to determine the same information. Note that now fee estimation for block processing must happen before those transactions are removed, but this shoudl be a speedup. --- src/validation.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/validation.cpp') diff --git a/src/validation.cpp b/src/validation.cpp index 2783a313f7..a68763e489 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -693,7 +693,6 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, chainActive.Height(), - !IsInitialBlockDownload() && pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp); unsigned int nSize = entry.GetTxSize(); @@ -943,7 +942,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C pool.RemoveStaged(allConflicting, false); // Store transaction in memory - pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload()); + pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload() && pool.HasNoInputsOf(tx)); // trim mempool and check if tx was trimmed if (!fOverrideMempoolLimit) { -- cgit v1.2.3 From d825838e6472f73c491f93506cb003472f071602 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 11 Nov 2016 13:14:45 -0500 Subject: Always update fee estimates on new blocks. All decisions about whether the transactions are valid data points are made at the time the transaction arrives. Updating on blocks all the time will now cause stale fee estimates to decay quickly when we restart a node. --- src/validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/validation.cpp') diff --git a/src/validation.cpp b/src/validation.cpp index a68763e489..fb6a902bc9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2204,7 +2204,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; LogPrint("bench", " - Writing chainstate: %.2fms [%.2fs]\n", (nTime5 - nTime4) * 0.001, nTimeChainState * 0.000001); // Remove conflicting transactions from the mempool.; - mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight, !IsInitialBlockDownload()); + mempool.removeForBlock(blockConnecting.vtx, pindexNew->nHeight); // Update chainActive & related variables. UpdateTip(pindexNew, chainparams); -- cgit v1.2.3 From dc008c462f6df84dd444c9646f7ca64ee1c8c841 Mon Sep 17 00:00:00 2001 From: Alex Morcos Date: Fri, 11 Nov 2016 13:29:13 -0500 Subject: Add IsCurrentForFeeEstimatation Make a more conservative notion of whether the node is caught up to the rest of the network and only count transactions as fee estimation data points if the node is caught up. --- src/validation.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/validation.cpp') diff --git a/src/validation.cpp b/src/validation.cpp index fb6a902bc9..264fdd83d6 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -525,6 +525,18 @@ std::string FormatStateMessage(const CValidationState &state) state.GetRejectCode()); } +static bool IsCurrentForFeeEstimation() +{ + AssertLockHeld(cs_main); + if (IsInitialBlockDownload()) + return false; + if (chainActive.Tip()->GetBlockTime() < (GetTime() - MAX_FEE_ESTIMATION_TIP_AGE)) + return false; + if (chainActive.Height() < pindexBestHeader->nHeight - 1) + return false; + return true; +} + bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree, bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector& vHashTxnToUncache) @@ -941,8 +953,13 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } pool.RemoveStaged(allConflicting, false); + // This transaction should only count for fee estimation if + // the node is not behind and it is not dependent on any other + // transactions in the mempool + bool validForFeeEstimation = IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); + // Store transaction in memory - pool.addUnchecked(hash, entry, setAncestors, !IsInitialBlockDownload() && pool.HasNoInputsOf(tx)); + pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation); // trim mempool and check if tx was trimmed if (!fOverrideMempoolLimit) { -- cgit v1.2.3