aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/init.cpp10
-rw-r--r--src/kernel/mempool_options.h4
-rw-r--r--src/policy/fees.cpp40
-rw-r--r--src/policy/fees.h22
-rw-r--r--src/test/fuzz/package_eval.cpp1
-rw-r--r--src/test/fuzz/policy_estimator.cpp13
-rw-r--r--src/test/fuzz/tx_pool.cpp1
-rw-r--r--src/test/policyestimator_tests.cpp97
-rw-r--r--src/test/util/txmempool.cpp1
-rw-r--r--src/txmempool.cpp24
-rw-r--r--src/txmempool.h7
-rw-r--r--src/validation.cpp11
13 files changed, 158 insertions, 74 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 99b2184cf2..b746a931c1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -954,7 +954,6 @@ libbitcoinkernel_la_SOURCES = \
node/chainstate.cpp \
node/utxo_snapshot.cpp \
policy/feerate.cpp \
- policy/fees.cpp \
policy/packages.cpp \
policy/policy.cpp \
policy/rbf.cpp \
diff --git a/src/init.cpp b/src/init.cpp
index d6dc62f707..92aa187626 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -285,8 +285,12 @@ void Shutdown(NodeContext& node)
DumpMempool(*node.mempool, MempoolPath(*node.args));
}
- // Drop transactions we were still watching, and record fee estimations.
- if (node.fee_estimator) node.fee_estimator->Flush();
+ // Drop transactions we were still watching, record fee estimations and Unregister
+ // fee estimator from validation interface.
+ if (node.fee_estimator) {
+ node.fee_estimator->Flush();
+ UnregisterValidationInterface(node.fee_estimator.get());
+ }
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
if (node.chainman) {
@@ -1258,6 +1262,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Flush estimates to disk periodically
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
node.scheduler->scheduleEvery([fee_estimator] { fee_estimator->FlushFeeEstimates(); }, FEE_FLUSH_INTERVAL);
+ RegisterValidationInterface(fee_estimator);
}
// Check port numbers
@@ -1471,7 +1476,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
assert(!node.chainman);
CTxMemPool::Options mempool_opts{
- .estimator = node.fee_estimator.get(),
.check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
};
auto result{ApplyArgsManOptions(args, chainparams, mempool_opts)};
diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h
index d09fd2ba35..753aebd455 100644
--- a/src/kernel/mempool_options.h
+++ b/src/kernel/mempool_options.h
@@ -13,8 +13,6 @@
#include <cstdint>
#include <optional>
-class CBlockPolicyEstimator;
-
/** Default for -maxmempool, maximum megabytes of mempool memory usage */
static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300};
/** Default for -maxmempool when blocksonly is set */
@@ -37,8 +35,6 @@ namespace kernel {
* Most of the time, this struct should be referenced as CTxMemPool::Options.
*/
struct MemPoolOptions {
- /* Used to estimate appropriate transaction fees. */
- CBlockPolicyEstimator* estimator{nullptr};
/* The ratio used to determine how often sanity checks will run. */
int check_ratio{0};
int64_t max_size_bytes{DEFAULT_MAX_MEMPOOL_SIZE_MB * 1'000'000};
diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp
index 6d550b1d5a..74c688060d 100644
--- a/src/policy/fees.cpp
+++ b/src/policy/fees.cpp
@@ -515,15 +515,10 @@ void TxConfirmStats::removeTx(unsigned int entryHeight, unsigned int nBestSeenHe
}
}
-// This function is called from CTxMemPool::removeUnchecked to ensure
-// txs removed from the mempool for any reason are no longer
-// tracked. Txs that were part of a block have already been removed in
-// processBlockTx to ensure they are never double tracked, but it is
-// of no harm to try to remove them again.
-bool CBlockPolicyEstimator::removeTx(uint256 hash, bool inBlock)
+bool CBlockPolicyEstimator::removeTx(uint256 hash)
{
LOCK(m_cs_fee_estimator);
- return _removeTx(hash, inBlock);
+ return _removeTx(hash, /*inBlock=*/false);
}
bool CBlockPolicyEstimator::_removeTx(const uint256& hash, bool inBlock)
@@ -579,11 +574,26 @@ CBlockPolicyEstimator::CBlockPolicyEstimator(const fs::path& estimation_filepath
CBlockPolicyEstimator::~CBlockPolicyEstimator() = default;
-void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
+void CBlockPolicyEstimator::TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t /*unused*/)
+{
+ processTransaction(tx);
+}
+
+void CBlockPolicyEstimator::TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason /*unused*/, uint64_t /*unused*/)
+{
+ removeTx(tx->GetHash());
+}
+
+void CBlockPolicyEstimator::MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight)
+{
+ processBlock(txs_removed_for_block, nBlockHeight);
+}
+
+void CBlockPolicyEstimator::processTransaction(const NewMempoolTransactionInfo& tx)
{
LOCK(m_cs_fee_estimator);
- unsigned int txHeight = entry.GetHeight();
- uint256 hash = entry.GetTx().GetHash();
+ const unsigned int txHeight = tx.info.txHeight;
+ const auto& hash = tx.info.m_tx->GetHash();
if (mapMemPoolTxs.count(hash)) {
LogPrint(BCLog::ESTIMATEFEE, "Blockpolicy error mempool tx %s already being tracked\n",
hash.ToString());
@@ -597,17 +607,23 @@ void CBlockPolicyEstimator::processTransaction(const CTxMemPoolEntry& entry, boo
// It will be synced next time a block is processed.
return;
}
+ // This transaction should only count for fee estimation if:
+ // - it's not being re-added during a reorg which bypasses typical mempool fee limits
+ // - the node is not behind
+ // - the transaction is not dependent on any other transactions in the mempool
+ // - it's not part of a package.
+ const bool validForFeeEstimation = !tx.m_from_disconnected_block && !tx.m_submitted_in_package && tx.m_chainstate_is_current && tx.m_has_no_mempool_parents;
// Only want to be updating estimates when our blockchain is synced,
// otherwise we'll miscalculate how many blocks its taking to get included.
- if (!validFeeEstimate) {
+ if (!validForFeeEstimation) {
untrackedTxs++;
return;
}
trackedTxs++;
// Feerates are stored and reported as BTC-per-kb:
- CFeeRate feeRate(entry.GetFee(), entry.GetTxSize());
+ const CFeeRate feeRate(tx.info.m_fee, tx.info.m_virtual_transaction_size);
mapMemPoolTxs[hash].blockHeight = txHeight;
unsigned int bucketIndex = feeStats->NewTx(txHeight, static_cast<double>(feeRate.GetFeePerK()));
diff --git a/src/policy/fees.h b/src/policy/fees.h
index cff0c4dbe2..f34f66d3f0 100644
--- a/src/policy/fees.h
+++ b/src/policy/fees.h
@@ -12,6 +12,7 @@
#include <threadsafety.h>
#include <uint256.h>
#include <util/fs.h>
+#include <validationinterface.h>
#include <array>
#include <chrono>
@@ -35,9 +36,9 @@ static constexpr std::chrono::hours MAX_FILE_AGE{60};
static constexpr bool DEFAULT_ACCEPT_STALE_FEE_ESTIMATES{false};
class AutoFile;
-class CTxMemPoolEntry;
class TxConfirmStats;
struct RemovedMempoolTransactionInfo;
+struct NewMempoolTransactionInfo;
/* Identifier for each of the 3 different TxConfirmStats which will track
* history over different time horizons. */
@@ -144,7 +145,7 @@ struct FeeCalculation
* a certain number of blocks. Every time a block is added to the best chain, this class records
* stats on the transactions included in that block
*/
-class CBlockPolicyEstimator
+class CBlockPolicyEstimator : public CValidationInterface
{
private:
/** Track confirm delays up to 12 blocks for short horizon */
@@ -199,7 +200,7 @@ private:
public:
/** Create new BlockPolicyEstimator and initialize stats tracking classes with default values */
CBlockPolicyEstimator(const fs::path& estimation_filepath, const bool read_stale_estimates);
- ~CBlockPolicyEstimator();
+ virtual ~CBlockPolicyEstimator();
/** Process all the transactions that have been included in a block */
void processBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block,
@@ -207,11 +208,11 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
/** Process a transaction accepted to the mempool*/
- void processTransaction(const CTxMemPoolEntry& entry, bool validFeeEstimate)
+ void processTransaction(const NewMempoolTransactionInfo& tx)
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
- /** Remove a transaction from the mempool tracking stats*/
- bool removeTx(uint256 hash, bool inBlock)
+ /** Remove a transaction from the mempool tracking stats for non BLOCK removal reasons*/
+ bool removeTx(uint256 hash)
EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
/** DEPRECATED. Return a feerate estimate */
@@ -261,6 +262,15 @@ public:
/** Calculates the age of the file, since last modified */
std::chrono::hours GetFeeEstimatorFileAge();
+protected:
+ /** Overridden from CValidationInterface. */
+ void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t /*unused*/) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
+ void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason /*unused*/, uint64_t /*unused*/) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
+ void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight) override
+ EXCLUSIVE_LOCKS_REQUIRED(!m_cs_fee_estimator);
+
private:
mutable Mutex m_cs_fee_estimator;
diff --git a/src/test/fuzz/package_eval.cpp b/src/test/fuzz/package_eval.cpp
index 021acc02f2..08b8be26e7 100644
--- a/src/test/fuzz/package_eval.cpp
+++ b/src/test/fuzz/package_eval.cpp
@@ -121,7 +121,6 @@ CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeConte
mempool_opts.expiry = std::chrono::hours{fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 999)};
nBytesPerSigOp = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(1, 999);
- mempool_opts.estimator = nullptr;
mempool_opts.check_ratio = 1;
mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool();
diff --git a/src/test/fuzz/policy_estimator.cpp b/src/test/fuzz/policy_estimator.cpp
index e5e0b0d8da..4a41707edf 100644
--- a/src/test/fuzz/policy_estimator.cpp
+++ b/src/test/fuzz/policy_estimator.cpp
@@ -44,9 +44,16 @@ FUZZ_TARGET(policy_estimator, .init = initialize_policy_estimator)
return;
}
const CTransaction tx{*mtx};
- block_policy_estimator.processTransaction(ConsumeTxMemPoolEntry(fuzzed_data_provider, tx), fuzzed_data_provider.ConsumeBool());
+ const CTxMemPoolEntry& entry = ConsumeTxMemPoolEntry(fuzzed_data_provider, tx);
+ const auto tx_info = NewMempoolTransactionInfo(entry.GetSharedTx(), entry.GetFee(),
+ entry.GetTxSize(), entry.GetHeight(),
+ /* m_from_disconnected_block */ false,
+ /* m_submitted_in_package */ false,
+ /* m_chainstate_is_current */ true,
+ /* m_has_no_mempool_parents */ fuzzed_data_provider.ConsumeBool());
+ block_policy_estimator.processTransaction(tx_info);
if (fuzzed_data_provider.ConsumeBool()) {
- (void)block_policy_estimator.removeTx(tx.GetHash(), /*inBlock=*/fuzzed_data_provider.ConsumeBool());
+ (void)block_policy_estimator.removeTx(tx.GetHash());
}
},
[&] {
@@ -69,7 +76,7 @@ FUZZ_TARGET(policy_estimator, .init = initialize_policy_estimator)
block_policy_estimator.processBlock(txs, fuzzed_data_provider.ConsumeIntegral<unsigned int>());
},
[&] {
- (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider), /*inBlock=*/fuzzed_data_provider.ConsumeBool());
+ (void)block_policy_estimator.removeTx(ConsumeUInt256(fuzzed_data_provider));
},
[&] {
block_policy_estimator.FlushUnconfirmed();
diff --git a/src/test/fuzz/tx_pool.cpp b/src/test/fuzz/tx_pool.cpp
index 001b452722..cc816f213b 100644
--- a/src/test/fuzz/tx_pool.cpp
+++ b/src/test/fuzz/tx_pool.cpp
@@ -123,7 +123,6 @@ CTxMemPool MakeMempool(FuzzedDataProvider& fuzzed_data_provider, const NodeConte
CTxMemPool::Options mempool_opts{MemPoolOptionsForTest(node)};
// ...override specific options for this specific fuzz suite
- mempool_opts.estimator = nullptr;
mempool_opts.check_ratio = 1;
mempool_opts.require_standard = fuzzed_data_provider.ConsumeBool();
diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp
index bc9c672560..13ec89663a 100644
--- a/src/test/policyestimator_tests.cpp
+++ b/src/test/policyestimator_tests.cpp
@@ -8,6 +8,7 @@
#include <txmempool.h>
#include <uint256.h>
#include <util/time.h>
+#include <validationinterface.h>
#include <test/util/setup_common.h>
@@ -19,7 +20,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
{
CBlockPolicyEstimator& feeEst = *Assert(m_node.fee_estimator);
CTxMemPool& mpool = *Assert(m_node.mempool);
- LOCK2(cs_main, mpool.cs);
+ RegisterValidationInterface(&feeEst);
TestMemPoolEntryHelper entry;
CAmount basefee(2000);
CAmount deltaFee(100);
@@ -59,8 +60,23 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
for (int j = 0; j < 10; j++) { // For each fee
for (int k = 0; k < 4; k++) { // add 4 fee txs
tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique
+ {
+ LOCK2(cs_main, mpool.cs);
+ mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
+ // Since TransactionAddedToMempool callbacks are generated in ATMP,
+ // not addUnchecked, we cheat and create one manually here
+ const int64_t virtual_size = GetVirtualTransactionSize(*MakeTransactionRef(tx));
+ const NewMempoolTransactionInfo tx_info{NewMempoolTransactionInfo(MakeTransactionRef(tx),
+ feeV[j],
+ virtual_size,
+ entry.nHeight,
+ /* m_from_disconnected_block */ false,
+ /* m_submitted_in_package */ false,
+ /* m_chainstate_is_current */ true,
+ /* m_has_no_mempool_parents */ true)};
+ GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
+ }
uint256 hash = tx.GetHash();
- mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
txHashes[j].push_back(hash);
}
}
@@ -76,10 +92,17 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
txHashes[9-h].pop_back();
}
}
- mpool.removeForBlock(block, ++blocknum);
+
+ {
+ LOCK(mpool.cs);
+ mpool.removeForBlock(block, ++blocknum);
+ }
+
block.clear();
// Check after just a few txs that combining buckets works as expected
if (blocknum == 3) {
+ // Wait for fee estimator to catch up
+ SyncWithValidationInterfaceQueue();
// At this point we should need to combine 3 buckets to get enough data points
// So estimateFee(1) should fail and estimateFee(2) should return somewhere around
// 9*baserate. estimateFee(2) %'s are 100,100,90 = average 97%
@@ -114,8 +137,13 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// Mine 50 more blocks with no transactions happening, estimates shouldn't change
// We haven't decayed the moving average enough so we still have enough data points in every bucket
- while (blocknum < 250)
+ while (blocknum < 250) {
+ LOCK(mpool.cs);
mpool.removeForBlock(block, ++blocknum);
+ }
+
+ // Wait for fee estimator to catch up
+ SyncWithValidationInterfaceQueue();
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
for (int i = 2; i < 10;i++) {
@@ -130,14 +158,35 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
for (int j = 0; j < 10; j++) { // For each fee multiple
for (int k = 0; k < 4; k++) { // add 4 fee txs
tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
+ {
+ LOCK2(cs_main, mpool.cs);
+ mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
+ // Since TransactionAddedToMempool callbacks are generated in ATMP,
+ // not addUnchecked, we cheat and create one manually here
+ const int64_t virtual_size = GetVirtualTransactionSize(*MakeTransactionRef(tx));
+ const NewMempoolTransactionInfo tx_info{NewMempoolTransactionInfo(MakeTransactionRef(tx),
+ feeV[j],
+ virtual_size,
+ entry.nHeight,
+ /* m_from_disconnected_block */ false,
+ /* m_submitted_in_package */ false,
+ /* m_chainstate_is_current */ true,
+ /* m_has_no_mempool_parents */ true)};
+ GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
+ }
uint256 hash = tx.GetHash();
- mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
txHashes[j].push_back(hash);
}
}
- mpool.removeForBlock(block, ++blocknum);
+ {
+ LOCK(mpool.cs);
+ mpool.removeForBlock(block, ++blocknum);
+ }
}
+ // Wait for fee estimator to catch up
+ SyncWithValidationInterfaceQueue();
+
for (int i = 1; i < 10;i++) {
BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
}
@@ -152,8 +201,16 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
txHashes[j].pop_back();
}
}
- mpool.removeForBlock(block, 266);
+
+ {
+ LOCK(mpool.cs);
+ mpool.removeForBlock(block, 266);
+ }
block.clear();
+
+ // Wait for fee estimator to catch up
+ SyncWithValidationInterfaceQueue();
+
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
for (int i = 2; i < 10;i++) {
BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
@@ -165,17 +222,39 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
for (int j = 0; j < 10; j++) { // For each fee multiple
for (int k = 0; k < 4; k++) { // add 4 fee txs
tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
+ {
+ LOCK2(cs_main, mpool.cs);
+ mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
+ // Since TransactionAddedToMempool callbacks are generated in ATMP,
+ // not addUnchecked, we cheat and create one manually here
+ const int64_t virtual_size = GetVirtualTransactionSize(*MakeTransactionRef(tx));
+ const NewMempoolTransactionInfo tx_info{NewMempoolTransactionInfo(MakeTransactionRef(tx),
+ feeV[j],
+ virtual_size,
+ entry.nHeight,
+ /* m_from_disconnected_block */ false,
+ /* m_submitted_in_package */ false,
+ /* m_chainstate_is_current */ true,
+ /* m_has_no_mempool_parents */ true)};
+ GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
+ }
uint256 hash = tx.GetHash();
- mpool.addUnchecked(entry.Fee(feeV[j]).Time(Now<NodeSeconds>()).Height(blocknum).FromTx(tx));
CTransactionRef ptx = mpool.get(hash);
if (ptx)
block.push_back(ptx);
}
}
- mpool.removeForBlock(block, ++blocknum);
+
+ {
+ LOCK(mpool.cs);
+ mpool.removeForBlock(block, ++blocknum);
+ }
+
block.clear();
}
+ // Wait for fee estimator to catch up
+ SyncWithValidationInterfaceQueue();
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
for (int i = 2; i < 9; i++) { // At 9, the original estimate was already at the bottom (b/c scale = 2)
BOOST_CHECK(feeEst.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee);
diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp
index 6d3bb01be8..379c3c9329 100644
--- a/src/test/util/txmempool.cpp
+++ b/src/test/util/txmempool.cpp
@@ -18,7 +18,6 @@ using node::NodeContext;
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext& node)
{
CTxMemPool::Options mempool_opts{
- .estimator = node.fee_estimator.get(),
// Default to always checking mempool regardless of
// chainparams.DefaultConsistencyChecks for tests
.check_ratio = 1,
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index f5036a9301..8a2af807df 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -12,9 +12,9 @@
#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <logging.h>
-#include <policy/fees.h>
#include <policy/policy.h>
#include <policy/settings.h>
+#include <random.h>
#include <reverse_iterator.h>
#include <util/check.h>
#include <util/moneystr.h>
@@ -402,7 +402,6 @@ void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee,
CTxMemPool::CTxMemPool(const Options& opts)
: m_check_ratio{opts.check_ratio},
- minerPolicyEstimator{opts.estimator},
m_max_size_bytes{opts.max_size_bytes},
m_expiry{opts.expiry},
m_incremental_relay_feerate{opts.incremental_relay_feerate},
@@ -433,7 +432,7 @@ void CTxMemPool::AddTransactionsUpdated(unsigned int n)
nTransactionsUpdated += n;
}
-void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
+void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors)
{
// Add to memory pool without checking anything.
// Used by AcceptToMemoryPool(), which DOES do
@@ -477,9 +476,6 @@ void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAnces
nTransactionsUpdated++;
totalTxSize += entry.GetTxSize();
m_total_fee += entry.GetFee();
- if (minerPolicyEstimator) {
- minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
- }
txns_randomized.emplace_back(newit->GetSharedTx());
newit->idx_randomized = txns_randomized.size() - 1;
@@ -497,16 +493,12 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
// even if not directly reported below.
uint64_t mempool_sequence = GetAndIncrementSequence();
- const auto& hash = it->GetTx().GetHash();
if (reason != MemPoolRemovalReason::BLOCK) {
// Notify clients that a transaction has been removed from the mempool
// for any reason except being included in a block. Clients interested
// in transactions included in blocks can subscribe to the BlockConnected
// notification.
GetMainSignals().TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
- if (minerPolicyEstimator) {
- minerPolicyEstimator->removeTx(hash, false);
- }
}
TRACE5(mempool, removed,
it->GetTx().GetHash().data(),
@@ -519,7 +511,7 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
for (const CTxIn& txin : it->GetTx().vin)
mapNextTx.erase(txin.prevout);
- RemoveUnbroadcastTx(hash, true /* add logging because unchecked */ );
+ RemoveUnbroadcastTx(it->GetTx().GetHash(), true /* add logging because unchecked */);
if (txns_randomized.size() > 1) {
// Update idx_randomized of the to-be-moved entry.
@@ -638,7 +630,7 @@ void CTxMemPool::removeConflicts(const CTransaction &tx)
}
/**
- * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
+ * Called when a block is connected. Removes from mempool.
*/
void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight)
{
@@ -657,10 +649,6 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
removeConflicts(*tx);
ClearPrioritisation(tx->GetHash());
}
- // Update policy estimates
- if (minerPolicyEstimator) {
- minerPolicyEstimator->processBlock(txs_removed_for_block, nBlockHeight);
- }
GetMainSignals().MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight);
lastRollingFeeUpdate = GetTime();
blockSinceLastRollingFeeBump = true;
@@ -1091,10 +1079,10 @@ int CTxMemPool::Expire(std::chrono::seconds time)
return stage.size();
}
-void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate)
+void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry)
{
auto ancestors{AssumeCalculateMemPoolAncestors(__func__, entry, Limits::NoLimits())};
- return addUnchecked(entry, ancestors, validFeeEstimate);
+ return addUnchecked(entry, ancestors);
}
void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
diff --git a/src/txmempool.h b/src/txmempool.h
index aed6acd9da..bac7a445d6 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -202,8 +202,6 @@ struct entry_time {};
struct ancestor_score {};
struct index_by_wtxid {};
-class CBlockPolicyEstimator;
-
/**
* Information about a mempool transaction.
*/
@@ -303,7 +301,6 @@ class CTxMemPool
protected:
const int m_check_ratio; //!< Value n means that 1 times in n we check.
std::atomic<unsigned int> nTransactionsUpdated{0}; //!< Used by getblocktemplate to trigger CreateNewBlock() invocation
- CBlockPolicyEstimator* const minerPolicyEstimator;
uint64_t totalTxSize GUARDED_BY(cs){0}; //!< sum of all mempool tx's virtual sizes. Differs from serialized tx size since witness data is discounted. Defined in BIP 141.
CAmount m_total_fee GUARDED_BY(cs){0}; //!< sum of all mempool tx's fees (NOT modified fee)
@@ -472,8 +469,8 @@ public:
// Note that addUnchecked is ONLY called from ATMP outside of tests
// and any other callers may break wallet's in-mempool tracking (due to
// lack of CValidationInterface::TransactionAddedToMempool callbacks).
- void addUnchecked(const CTxMemPoolEntry& entry, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
- void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors, bool validFeeEstimate = true) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
+ void addUnchecked(const CTxMemPoolEntry& entry) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
+ void addUnchecked(const CTxMemPoolEntry& entry, setEntries& setAncestors) EXCLUSIVE_LOCKS_REQUIRED(cs, cs_main);
void removeRecursive(const CTransaction& tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs);
/** After reorg, filter the entries that would no longer be valid in the next block, and update
diff --git a/src/validation.cpp b/src/validation.cpp
index 1c95ba08c5..f9e5d1db82 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -1126,17 +1126,8 @@ bool MemPoolAccept::Finalize(const ATMPArgs& args, Workspace& ws)
ws.m_replaced_transactions.push_back(it->GetSharedTx());
}
m_pool.RemoveStaged(ws.m_all_conflicting, false, MemPoolRemovalReason::REPLACED);
-
- // This transaction should only count for fee estimation if:
- // - it's not being re-added during a reorg which bypasses typical mempool fee limits
- // - the node is not behind
- // - the transaction is not dependent on any other transactions in the mempool
- // - it's not part of a package. Since package relay is not currently supported, this
- // transaction has not necessarily been accepted to miners' mempools.
- bool validForFeeEstimation = !bypass_limits && !args.m_package_submission && IsCurrentForFeeEstimation(m_active_chainstate) && m_pool.HasNoInputsOf(tx);
-
// Store transaction in memory
- m_pool.addUnchecked(*entry, ws.m_ancestors, validForFeeEstimation);
+ m_pool.addUnchecked(*entry, ws.m_ancestors);
// trim mempool and check if tx was trimmed
// If we are validating a package, don't trim here because we could evict a previous transaction