Skip to content

Commit

Permalink
Merge #29086: refactor: Simply include CTxMemPool::Options in CTxMemP…
Browse files Browse the repository at this point in the history
…ool directly rather than duplicating definition

cc67d33 refactor: Simply include CTxMemPool::Options in CTxMemPool directly rather than duplicating definition (Luke Dashjr)

Pull request description:

  Instead of duplicating mempool options two places, just include the Options struct directly on the CTxMemPool

ACKs for top commit:
  achow101:
    ACK cc67d33
  kristapsk:
    cr utACK cc67d33
  jonatack:
    ACK cc67d33

Tree-SHA512: 9deb5ea6f85eeb1c7e04536cded65303b0ec459936a97e4f257aff2c50b0984a4ddbf69a4651f48455b9c80200a1fd24e9c74926874fdd9be436bbbe406251ce
  • Loading branch information
achow101 committed May 15, 2024
2 parents dbb3113 + cc67d33 commit f5fc319
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 92 deletions.
6 changes: 3 additions & 3 deletions src/kernel/mempool_persist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, Chainstate& active
if (amountdelta && opts.apply_fee_delta_priority) {
pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
}
if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_expiry)) {
if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_opts.expiry)) {
LOCK(cs_main);
const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false);
if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) {
Expand Down Expand Up @@ -174,11 +174,11 @@ bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mock
}

try {
const uint64_t version{pool.m_persist_v1_dat ? MEMPOOL_DUMP_VERSION_NO_XOR_KEY : MEMPOOL_DUMP_VERSION};
const uint64_t version{pool.m_opts.persist_v1_dat ? MEMPOOL_DUMP_VERSION_NO_XOR_KEY : MEMPOOL_DUMP_VERSION};
file << version;

std::vector<std::byte> xor_key(8);
if (!pool.m_persist_v1_dat) {
if (!pool.m_opts.persist_v1_dat) {
FastRandomContext{}.fillrand(xor_key);
file << xor_key;
}
Expand Down
2 changes: 1 addition & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5775,7 +5775,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
if (current_time > peer.m_next_send_feefilter) {
CAmount filterToSend = m_fee_filter_rounder.round(currentFilter);
// We always have a fee filter of at least the min relay fee
filterToSend = std::max(filterToSend, m_mempool.m_min_relay_feerate.GetFeePerK());
filterToSend = std::max(filterToSend, m_mempool.m_opts.min_relay_feerate.GetFeePerK());
if (filterToSend != peer.m_fee_filter_sent) {
MakeAndPushMessage(pto, NetMsgType::FEEFILTER, filterToSend);
peer.m_fee_filter_sent = filterToSend;
Expand Down
10 changes: 5 additions & 5 deletions src/node/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class NodeImpl : public Node
CFeeRate getDustRelayFee() override
{
if (!m_context->mempool) return CFeeRate{DUST_RELAY_TX_FEE};
return m_context->mempool->m_dust_relay_feerate;
return m_context->mempool->m_opts.dust_relay_feerate;
}
UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
{
Expand Down Expand Up @@ -701,7 +701,7 @@ class ChainImpl : public Chain
{
const CTxMemPool::Limits default_limits{};

const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_limits : default_limits};
const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_opts.limits : default_limits};

limit_ancestor_count = limits.ancestor_count;
limit_descendant_count = limits.descendant_count;
Expand Down Expand Up @@ -732,17 +732,17 @@ class ChainImpl : public Chain
CFeeRate relayMinFee() override
{
if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE};
return m_node.mempool->m_min_relay_feerate;
return m_node.mempool->m_opts.min_relay_feerate;
}
CFeeRate relayIncrementalFee() override
{
if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE};
return m_node.mempool->m_incremental_relay_feerate;
return m_node.mempool->m_opts.incremental_relay_feerate;
}
CFeeRate relayDustFee() override
{
if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE};
return m_node.mempool->m_dust_relay_feerate;
return m_node.mempool->m_opts.dust_relay_feerate;
}
bool havePruned() override
{
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static RPCHelpMan estimatesmartfee()
const NodeContext& node = EnsureAnyNodeContext(request.context);
const CTxMemPool& mempool = EnsureMemPool(node);

CHECK_NONFATAL(mempool.m_signals)->SyncWithValidationInterfaceQueue();
CHECK_NONFATAL(mempool.m_opts.signals)->SyncWithValidationInterfaceQueue();
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
bool conservative = true;
Expand All @@ -83,7 +83,7 @@ static RPCHelpMan estimatesmartfee()
CFeeRate feeRate{fee_estimator.estimateSmartFee(conf_target, &feeCalc, conservative)};
if (feeRate != CFeeRate(0)) {
CFeeRate min_mempool_feerate{mempool.GetMinFee()};
CFeeRate min_relay_feerate{mempool.m_min_relay_feerate};
CFeeRate min_relay_feerate{mempool.m_opts.min_relay_feerate};
feeRate = std::max({feeRate, min_mempool_feerate, min_relay_feerate});
result.pushKV("feerate", ValueFromAmount(feeRate.GetFeePerK()));
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/rpc/mempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,12 +671,12 @@ UniValue MempoolInfoToJSON(const CTxMemPool& pool)
ret.pushKV("bytes", (int64_t)pool.GetTotalTxSize());
ret.pushKV("usage", (int64_t)pool.DynamicMemoryUsage());
ret.pushKV("total_fee", ValueFromAmount(pool.GetTotalFee()));
ret.pushKV("maxmempool", pool.m_max_size_bytes);
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_min_relay_feerate).GetFeePerK()));
ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_min_relay_feerate.GetFeePerK()));
ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_incremental_relay_feerate.GetFeePerK()));
ret.pushKV("maxmempool", pool.m_opts.max_size_bytes);
ret.pushKV("mempoolminfee", ValueFromAmount(std::max(pool.GetMinFee(), pool.m_opts.min_relay_feerate).GetFeePerK()));
ret.pushKV("minrelaytxfee", ValueFromAmount(pool.m_opts.min_relay_feerate.GetFeePerK()));
ret.pushKV("incrementalrelayfee", ValueFromAmount(pool.m_opts.incremental_relay_feerate.GetFeePerK()));
ret.pushKV("unbroadcastcount", uint64_t{pool.GetUnbroadcastTxs().size()});
ret.pushKV("fullrbf", pool.m_full_rbf);
ret.pushKV("fullrbf", pool.m_opts.full_rbf);
return ret;
}

Expand Down
4 changes: 2 additions & 2 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,8 @@ static RPCHelpMan getnetworkinfo()
obj.pushKV("networks", GetNetworksInfo());
if (node.mempool) {
// Those fields can be deprecated, to be replaced by the getmempoolinfo fields
obj.pushKV("relayfee", ValueFromAmount(node.mempool->m_min_relay_feerate.GetFeePerK()));
obj.pushKV("incrementalfee", ValueFromAmount(node.mempool->m_incremental_relay_feerate.GetFeePerK()));
obj.pushKV("relayfee", ValueFromAmount(node.mempool->m_opts.min_relay_feerate.GetFeePerK()));
obj.pushKV("incrementalfee", ValueFromAmount(node.mempool->m_opts.incremental_relay_feerate.GetFeePerK()));
}
UniValue localAddresses(UniValue::VARR);
{
Expand Down
4 changes: 2 additions & 2 deletions src/test/txpackage_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ BOOST_FIXTURE_TEST_CASE(package_witness_swap_tests, TestChain100Setup)
CTransactionRef ptx_parent3 = MakeTransactionRef(mtx_parent3);
package_mixed.push_back(ptx_parent3);
BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*ptx_parent3)) > low_fee_amt);
BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt);
BOOST_CHECK(m_node.mempool->m_opts.min_relay_feerate.GetFee(GetVirtualTransactionSize(*ptx_parent3)) <= low_fee_amt);

// child spends parent1, parent2, and parent3
CKey mixed_grandchild_key = GenerateRandomKey();
Expand Down Expand Up @@ -825,7 +825,7 @@ BOOST_FIXTURE_TEST_CASE(package_cpfp_tests, TestChain100Setup)
CTransactionRef tx_parent_cheap = MakeTransactionRef(mtx_parent_cheap);
package_still_too_low.push_back(tx_parent_cheap);
BOOST_CHECK(m_node.mempool->GetMinFee().GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) > parent_fee);
BOOST_CHECK(m_node.mempool->m_min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee);
BOOST_CHECK(m_node.mempool->m_opts.min_relay_feerate.GetFee(GetVirtualTransactionSize(*tx_parent_cheap)) <= parent_fee);

auto mtx_child_cheap = CreateValidMempoolTransaction(/*input_transaction=*/tx_parent_cheap, /*input_vout=*/0,
/*input_height=*/101, /*input_signing_key=*/child_key,
Expand Down
6 changes: 3 additions & 3 deletions src/test/util/setup_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,9 +552,9 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
assert(m_node.mempool->size() == 0);
// The target feerate cannot be too low...
// ...otherwise the transaction's feerate will need to be negative.
assert(target_feerate > m_node.mempool->m_incremental_relay_feerate);
assert(target_feerate > m_node.mempool->m_opts.incremental_relay_feerate);
// ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
assert(target_feerate > m_node.mempool->m_min_relay_feerate);
assert(target_feerate > m_node.mempool->m_opts.min_relay_feerate);

// Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
// achieve the exact target feerate.
Expand All @@ -565,7 +565,7 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
LockPoints lp;
// The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
m_node.mempool->m_opts.incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee,
/*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
/*spends_coinbase=*/true, /*sigops_cost=*/1, lp));
Expand Down
56 changes: 22 additions & 34 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendan
// Don't directly remove the transaction here -- doing so would
// invalidate iterators in cachedDescendants. Mark it for removal
// by inserting into descendants_to_remove.
if (descendant.GetCountWithAncestors() > uint64_t(m_limits.ancestor_count) || descendant.GetSizeWithAncestors() > m_limits.ancestor_size_vbytes) {
if (descendant.GetCountWithAncestors() > uint64_t(m_opts.limits.ancestor_count) || descendant.GetSizeWithAncestors() > m_opts.limits.ancestor_size_vbytes) {
descendants_to_remove.insert(descendant.GetTx().GetHash());
}
}
Expand Down Expand Up @@ -203,14 +203,14 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
size_t pack_count = package.size();

// Package itself is busting mempool limits; should be rejected even if no staged_ancestors exist
if (pack_count > static_cast<uint64_t>(m_limits.ancestor_count)) {
return util::Error{Untranslated(strprintf("package count %u exceeds ancestor count limit [limit: %u]", pack_count, m_limits.ancestor_count))};
} else if (pack_count > static_cast<uint64_t>(m_limits.descendant_count)) {
return util::Error{Untranslated(strprintf("package count %u exceeds descendant count limit [limit: %u]", pack_count, m_limits.descendant_count))};
} else if (total_vsize > m_limits.ancestor_size_vbytes) {
return util::Error{Untranslated(strprintf("package size %u exceeds ancestor size limit [limit: %u]", total_vsize, m_limits.ancestor_size_vbytes))};
} else if (total_vsize > m_limits.descendant_size_vbytes) {
return util::Error{Untranslated(strprintf("package size %u exceeds descendant size limit [limit: %u]", total_vsize, m_limits.descendant_size_vbytes))};
if (pack_count > static_cast<uint64_t>(m_opts.limits.ancestor_count)) {
return util::Error{Untranslated(strprintf("package count %u exceeds ancestor count limit [limit: %u]", pack_count, m_opts.limits.ancestor_count))};
} else if (pack_count > static_cast<uint64_t>(m_opts.limits.descendant_count)) {
return util::Error{Untranslated(strprintf("package count %u exceeds descendant count limit [limit: %u]", pack_count, m_opts.limits.descendant_count))};
} else if (total_vsize > m_opts.limits.ancestor_size_vbytes) {
return util::Error{Untranslated(strprintf("package size %u exceeds ancestor size limit [limit: %u]", total_vsize, m_opts.limits.ancestor_size_vbytes))};
} else if (total_vsize > m_opts.limits.descendant_size_vbytes) {
return util::Error{Untranslated(strprintf("package size %u exceeds descendant size limit [limit: %u]", total_vsize, m_opts.limits.descendant_size_vbytes))};
}

CTxMemPoolEntry::Parents staged_ancestors;
Expand All @@ -219,8 +219,8 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
std::optional<txiter> piter = GetIter(input.prevout.hash);
if (piter) {
staged_ancestors.insert(**piter);
if (staged_ancestors.size() + package.size() > static_cast<uint64_t>(m_limits.ancestor_count)) {
return util::Error{Untranslated(strprintf("too many unconfirmed parents [limit: %u]", m_limits.ancestor_count))};
if (staged_ancestors.size() + package.size() > static_cast<uint64_t>(m_opts.limits.ancestor_count)) {
return util::Error{Untranslated(strprintf("too many unconfirmed parents [limit: %u]", m_opts.limits.ancestor_count))};
}
}
}
Expand All @@ -229,7 +229,7 @@ util::Result<void> CTxMemPool::CheckPackageLimits(const Package& package,
// considered together must be within limits even if they are not interdependent. This may be
// stricter than the limits for each individual transaction.
const auto ancestors{CalculateAncestorsAndCheckLimits(total_vsize, package.size(),
staged_ancestors, m_limits)};
staged_ancestors, m_opts.limits)};
// It's possible to overestimate the ancestor/descendant totals.
if (!ancestors.has_value()) return util::Error{Untranslated("possibly " + util::ErrorString(ancestors).original)};
return {};
Expand Down Expand Up @@ -396,19 +396,7 @@ void CTxMemPoolEntry::UpdateAncestorState(int32_t modifySize, CAmount modifyFee,
}

CTxMemPool::CTxMemPool(const Options& opts)
: m_check_ratio{opts.check_ratio},
m_max_size_bytes{opts.max_size_bytes},
m_expiry{opts.expiry},
m_incremental_relay_feerate{opts.incremental_relay_feerate},
m_min_relay_feerate{opts.min_relay_feerate},
m_dust_relay_feerate{opts.dust_relay_feerate},
m_permit_bare_multisig{opts.permit_bare_multisig},
m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
m_require_standard{opts.require_standard},
m_full_rbf{opts.full_rbf},
m_persist_v1_dat{opts.persist_v1_dat},
m_limits{opts.limits},
m_signals{opts.signals}
: m_opts{opts}
{
}

Expand Down Expand Up @@ -489,12 +477,12 @@ void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
// even if not directly reported below.
uint64_t mempool_sequence = GetAndIncrementSequence();

if (reason != MemPoolRemovalReason::BLOCK && m_signals) {
if (reason != MemPoolRemovalReason::BLOCK && m_opts.signals) {
// 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.
m_signals->TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
m_opts.signals->TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
}
TRACE5(mempool, removed,
it->GetTx().GetHash().data(),
Expand Down Expand Up @@ -645,18 +633,18 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
removeConflicts(*tx);
ClearPrioritisation(tx->GetHash());
}
if (m_signals) {
m_signals->MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight);
if (m_opts.signals) {
m_opts.signals->MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight);
}
lastRollingFeeUpdate = GetTime();
blockSinceLastRollingFeeBump = true;
}

void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const
{
if (m_check_ratio == 0) return;
if (m_opts.check_ratio == 0) return;

if (GetRand(m_check_ratio) >= 1) return;
if (GetRand(m_opts.check_ratio) >= 1) return;

AssertLockHeld(::cs_main);
LOCK(cs);
Expand Down Expand Up @@ -1108,12 +1096,12 @@ CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
lastRollingFeeUpdate = time;

if (rollingMinimumFeeRate < (double)m_incremental_relay_feerate.GetFeePerK() / 2) {
if (rollingMinimumFeeRate < (double)m_opts.incremental_relay_feerate.GetFeePerK() / 2) {
rollingMinimumFeeRate = 0;
return CFeeRate(0);
}
}
return std::max(CFeeRate(llround(rollingMinimumFeeRate)), m_incremental_relay_feerate);
return std::max(CFeeRate(llround(rollingMinimumFeeRate)), m_opts.incremental_relay_feerate);
}

void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
Expand All @@ -1137,7 +1125,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpends
// 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->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
removed += m_incremental_relay_feerate;
removed += m_opts.incremental_relay_feerate;
trackPackageRemoved(removed);
maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);

Expand Down
18 changes: 2 additions & 16 deletions src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ struct TxMempoolInfo
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

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.
Expand Down Expand Up @@ -436,20 +435,7 @@ class CTxMemPool

using Options = kernel::MemPoolOptions;

const int64_t m_max_size_bytes;
const std::chrono::seconds m_expiry;
const CFeeRate m_incremental_relay_feerate;
const CFeeRate m_min_relay_feerate;
const CFeeRate m_dust_relay_feerate;
const bool m_permit_bare_multisig;
const std::optional<unsigned> m_max_datacarrier_bytes;
const bool m_require_standard;
const bool m_full_rbf;
const bool m_persist_v1_dat;

const Limits m_limits;

ValidationSignals* const m_signals;
const Options m_opts;

/** Create a new CTxMemPool.
* Sanity checks will be off by default for performance, because otherwise
Expand Down Expand Up @@ -625,7 +611,7 @@ class CTxMemPool
* would otherwise be half of this, it is set to 0 instead.
*/
CFeeRate GetMinFee() const {
return GetMinFee(m_max_size_bytes);
return GetMinFee(m_opts.max_size_bytes);
}

/** Remove transactions from the mempool until its dynamic size is <= sizelimit.
Expand Down

0 comments on commit f5fc319

Please sign in to comment.