Skip to content

Commit a62f5ee

Browse files
committed
Merge bitcoin/bitcoin#27675: p2p: Drop m_recently_announced_invs bloom filter
fb02ba3 mempool_entry: improve struct packing (Anthony Towns) 1a11806 net_processing: Clean up INVENTORY_BROADCAST_MAX constants (Anthony Towns) 6fa4993 test: Check tx from disconnected block is immediately requestable (glozow) e4ffabb net_processing: don't add txids to m_tx_inventory_known_filter (Anthony Towns) 6ec1809 net_processing: drop m_recently_announced_invs bloom filter (Anthony Towns) a70beaf validation: when adding txs due to a block reorg, allow immediate relay (Anthony Towns) 1e9684f mempool_entry: add mempool entry sequence number (Anthony Towns) Pull request description: This PR replaces the `m_recently_announced_invs` bloom filter with a simple sequence number tracking the mempool state when we last considered sending an INV message to a node. This saves 33kB per peer (or more if we raise the rate at which we relay transactions over the network, in which case we would need to increase the size of the bloom filter proportionally). The philosophy here (compare with #18861 and #19109) is that we consider the rate limiting on INV messages to only be about saving bandwidth and not protecting privacy, and therefore after you receive an INV message, it's immediately fair game to request any transaction that was in the mempool at the time the INV message was sent. We likewise consider the BIP 133 feefilter and BIP 37 bloom filters to be bandwidth optimisations here, and treat transactions as requestable if they would have been announced without those filters. Given that philosophy, tracking the timestamp of the last INV message and comparing that against the mempool entry time allows removal of each of `m_recently_announced_invs`, `m_last_mempool_req` and `UNCONDITIONAL_RELAY_DELAY` and associated logic. ACKs for top commit: naumenkogs: ACK fb02ba3 amitiuttarwar: review ACK fb02ba3 glozow: reACK fb02ba3 Tree-SHA512: cbba5ee04c86df26b6057f3654c00a2b45ec94d354f4f157a769cecdaa0b509edaac02b3128afba39b023e82473fc5e28c915a787f84457ffe66638c6ac9c2d4
2 parents 60d3e4b + fb02ba3 commit a62f5ee

15 files changed

+151
-91
lines changed

src/bench/mempool_eviction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& po
1313
{
1414
int64_t nTime = 0;
1515
unsigned int nHeight = 1;
16+
uint64_t sequence = 0;
1617
bool spendsCoinbase = false;
1718
unsigned int sigOpCost = 4;
1819
LockPoints lp;
1920
pool.addUnchecked(CTxMemPoolEntry(
20-
tx, nFee, nTime, nHeight,
21+
tx, nFee, nTime, nHeight, sequence,
2122
spendsCoinbase, sigOpCost, lp));
2223
}
2324

src/bench/mempool_stress.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_R
1616
{
1717
int64_t nTime = 0;
1818
unsigned int nHeight = 1;
19+
uint64_t sequence = 0;
1920
bool spendsCoinbase = false;
2021
unsigned int sigOpCost = 4;
2122
LockPoints lp;
22-
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, spendsCoinbase, sigOpCost, lp));
23+
pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, sequence, spendsCoinbase, sigOpCost, lp));
2324
}
2425

2526
struct Available {

src/bench/rpc_mempool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
1717
{
1818
LockPoints lp;
19-
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
19+
pool.addUnchecked(CTxMemPoolEntry(tx, fee, /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0, /*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
2020
}
2121

2222
static void RpcMempool(benchmark::Bench& bench)

src/kernel/mempool_entry.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class CTxMemPoolEntry
7878
const int32_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize())
7979
const size_t nUsageSize; //!< ... and total memory usage
8080
const int64_t nTime; //!< Local time when entering the mempool
81+
const uint64_t entry_sequence; //!< Sequence number used to determine whether this transaction is too recent for relay
8182
const unsigned int entryHeight; //!< Chain height when entering the mempool
8283
const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase
8384
const int64_t sigOpCost; //!< Total sigop cost
@@ -101,14 +102,15 @@ class CTxMemPoolEntry
101102

102103
public:
103104
CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
104-
int64_t time, unsigned int entry_height,
105+
int64_t time, unsigned int entry_height, uint64_t entry_sequence,
105106
bool spends_coinbase,
106107
int64_t sigops_cost, LockPoints lp)
107108
: tx{tx},
108109
nFee{fee},
109110
nTxWeight{GetTransactionWeight(*tx)},
110111
nUsageSize{RecursiveDynamicUsage(tx)},
111112
nTime{time},
113+
entry_sequence{entry_sequence},
112114
entryHeight{entry_height},
113115
spendsCoinbase{spends_coinbase},
114116
sigOpCost{sigops_cost},
@@ -130,6 +132,7 @@ class CTxMemPoolEntry
130132
int32_t GetTxWeight() const { return nTxWeight; }
131133
std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; }
132134
unsigned int GetHeight() const { return entryHeight; }
135+
uint64_t GetSequence() const { return entry_sequence; }
133136
int64_t GetSigOpCost() const { return sigOpCost; }
134137
CAmount GetModifiedFee() const { return m_modified_fee; }
135138
size_t DynamicMemoryUsage() const { return nUsageSize; }

src/net_processing.cpp

Lines changed: 23 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@
5151
#include <optional>
5252
#include <typeinfo>
5353

54-
/** How long a transaction has to be in the mempool before it can unconditionally be relayed. */
55-
static constexpr auto UNCONDITIONAL_RELAY_DELAY = 2min;
5654
/** Headers download timeout.
5755
* Timeout = base + per_header * (expected number of headers) */
5856
static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_BASE = 15min;
@@ -149,15 +147,12 @@ static constexpr auto OUTBOUND_INVENTORY_BROADCAST_INTERVAL{2s};
149147
/** Maximum rate of inventory items to send per second.
150148
* Limits the impact of low-fee transaction floods. */
151149
static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND = 7;
150+
/** Target number of tx inventory items to send per transmission. */
151+
static constexpr unsigned int INVENTORY_BROADCAST_TARGET = INVENTORY_BROADCAST_PER_SECOND * count_seconds(INBOUND_INVENTORY_BROADCAST_INTERVAL);
152152
/** Maximum number of inventory items to send per transmission. */
153-
static constexpr unsigned int INVENTORY_BROADCAST_MAX = INVENTORY_BROADCAST_PER_SECOND * count_seconds(INBOUND_INVENTORY_BROADCAST_INTERVAL);
154-
/** The number of most recently announced transactions a peer can request. */
155-
static constexpr unsigned int INVENTORY_MAX_RECENT_RELAY = 3500;
156-
/** Verify that INVENTORY_MAX_RECENT_RELAY is enough to cache everything typically
157-
* relayed before unconditional relay from the mempool kicks in. This is only a
158-
* lower bound, and it should be larger to account for higher inv rate to outbound
159-
* peers, and random variations in the broadcast mechanism. */
160-
static_assert(INVENTORY_MAX_RECENT_RELAY >= INVENTORY_BROADCAST_PER_SECOND * UNCONDITIONAL_RELAY_DELAY / std::chrono::seconds{1}, "INVENTORY_RELAY_MAX too low");
153+
static constexpr unsigned int INVENTORY_BROADCAST_MAX = 1000;
154+
static_assert(INVENTORY_BROADCAST_MAX >= INVENTORY_BROADCAST_TARGET, "INVENTORY_BROADCAST_MAX too low");
155+
static_assert(INVENTORY_BROADCAST_MAX <= MAX_PEER_TX_ANNOUNCEMENTS, "INVENTORY_BROADCAST_MAX too high");
161156
/** Average delay between feefilter broadcasts in seconds. */
162157
static constexpr auto AVG_FEEFILTER_BROADCAST_INTERVAL{10min};
163158
/** Maximum feefilter broadcast delay after significant change. */
@@ -273,13 +268,10 @@ struct Peer {
273268
/** A bloom filter for which transactions to announce to the peer. See BIP37. */
274269
std::unique_ptr<CBloomFilter> m_bloom_filter PT_GUARDED_BY(m_bloom_filter_mutex) GUARDED_BY(m_bloom_filter_mutex){nullptr};
275270

276-
/** A rolling bloom filter of all announced tx CInvs to this peer */
277-
CRollingBloomFilter m_recently_announced_invs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){INVENTORY_MAX_RECENT_RELAY, 0.000001};
278-
279271
mutable RecursiveMutex m_tx_inventory_mutex;
280-
/** A filter of all the txids and wtxids that the peer has announced to
272+
/** A filter of all the (w)txids that the peer has announced to
281273
* us or we have announced to the peer. We use this to avoid announcing
282-
* the same txid/wtxid to a peer that already has the transaction. */
274+
* the same (w)txid to a peer that already has the transaction. */
283275
CRollingBloomFilter m_tx_inventory_known_filter GUARDED_BY(m_tx_inventory_mutex){50000, 0.000001};
284276
/** Set of transaction ids we still have to announce (txid for
285277
* non-wtxid-relay peers, wtxid for wtxid-relay peers). We use the
@@ -290,11 +282,12 @@ struct Peer {
290282
* permitted if the peer has NetPermissionFlags::Mempool or we advertise
291283
* NODE_BLOOM. See BIP35. */
292284
bool m_send_mempool GUARDED_BY(m_tx_inventory_mutex){false};
293-
/** The last time a BIP35 `mempool` request was serviced. */
294-
std::atomic<std::chrono::seconds> m_last_mempool_req{0s};
295285
/** The next time after which we will send an `inv` message containing
296286
* transaction announcements to this peer. */
297287
std::chrono::microseconds m_next_inv_send_time GUARDED_BY(m_tx_inventory_mutex){0};
288+
/** The mempool sequence num at which we sent the last `inv` message to this peer.
289+
* Can relay txs with lower sequence numbers than this (see CTxMempool::info_for_relay). */
290+
uint64_t m_last_inv_sequence GUARDED_BY(NetEventsInterface::g_msgproc_mutex){1};
298291

299292
/** Minimum fee rate with which to filter transaction announcements to this node. See BIP133. */
300293
std::atomic<CAmount> m_fee_filter_received{0};
@@ -907,7 +900,7 @@ class PeerManagerImpl final : public PeerManager
907900
std::atomic<std::chrono::seconds> m_last_tip_update{0s};
908901

909902
/** Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */
910-
CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
903+
CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid)
911904
EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, NetEventsInterface::g_msgproc_mutex);
912905

913906
void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc)
@@ -2288,22 +2281,14 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
22882281
}
22892282
}
22902283

2291-
CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid, const std::chrono::seconds mempool_req, const std::chrono::seconds now)
2284+
CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid)
22922285
{
2293-
auto txinfo = m_mempool.info(gtxid);
2286+
// If a tx was in the mempool prior to the last INV for this peer, permit the request.
2287+
auto txinfo = m_mempool.info_for_relay(gtxid, tx_relay.m_last_inv_sequence);
22942288
if (txinfo.tx) {
2295-
// If a TX could have been INVed in reply to a MEMPOOL request,
2296-
// or is older than UNCONDITIONAL_RELAY_DELAY, permit the request
2297-
// unconditionally.
2298-
if ((mempool_req.count() && txinfo.m_time <= mempool_req) || txinfo.m_time <= now - UNCONDITIONAL_RELAY_DELAY) {
2299-
return std::move(txinfo.tx);
2300-
}
2289+
return std::move(txinfo.tx);
23012290
}
23022291

2303-
// Otherwise, the transaction might have been announced recently.
2304-
bool recent = tx_relay.m_recently_announced_invs.contains(gtxid.GetHash());
2305-
if (recent && txinfo.tx) return std::move(txinfo.tx);
2306-
23072292
// Or it might be from the most recent block
23082293
{
23092294
LOCK(m_most_recent_block_mutex);
@@ -2326,10 +2311,6 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
23262311
std::vector<CInv> vNotFound;
23272312
const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
23282313

2329-
const auto now{GetTime<std::chrono::seconds>()};
2330-
// Get last mempool request time
2331-
const auto mempool_req = tx_relay != nullptr ? tx_relay->m_last_mempool_req.load() : std::chrono::seconds::min();
2332-
23332314
// Process as many TX items from the front of the getdata queue as
23342315
// possible, since they're common and it's efficient to batch process
23352316
// them.
@@ -2347,33 +2328,12 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic
23472328
continue;
23482329
}
23492330

2350-
CTransactionRef tx = FindTxForGetData(*tx_relay, ToGenTxid(inv), mempool_req, now);
2331+
CTransactionRef tx = FindTxForGetData(*tx_relay, ToGenTxid(inv));
23512332
if (tx) {
23522333
// WTX and WITNESS_TX imply we serialize with witness
23532334
int nSendFlags = (inv.IsMsgTx() ? SERIALIZE_TRANSACTION_NO_WITNESS : 0);
23542335
m_connman.PushMessage(&pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *tx));
23552336
m_mempool.RemoveUnbroadcastTx(tx->GetHash());
2356-
// As we're going to send tx, make sure its unconfirmed parents are made requestable.
2357-
std::vector<uint256> parent_ids_to_add;
2358-
{
2359-
LOCK(m_mempool.cs);
2360-
auto tx_iter = m_mempool.GetIter(tx->GetHash());
2361-
if (tx_iter) {
2362-
const CTxMemPoolEntry::Parents& parents = (*tx_iter)->GetMemPoolParentsConst();
2363-
parent_ids_to_add.reserve(parents.size());
2364-
for (const CTxMemPoolEntry& parent : parents) {
2365-
if (parent.GetTime() > now - UNCONDITIONAL_RELAY_DELAY) {
2366-
parent_ids_to_add.push_back(parent.GetTx().GetHash());
2367-
}
2368-
}
2369-
}
2370-
}
2371-
for (const uint256& parent_txid : parent_ids_to_add) {
2372-
// Relaying a transaction with a recent but unconfirmed parent.
2373-
if (WITH_LOCK(tx_relay->m_tx_inventory_mutex, return !tx_relay->m_tx_inventory_known_filter.contains(parent_txid))) {
2374-
tx_relay->m_recently_announced_invs.insert(parent_txid);
2375-
}
2376-
}
23772337
} else {
23782338
vNotFound.push_back(inv);
23792339
}
@@ -4131,14 +4091,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
41314091

41324092
const uint256& hash = peer->m_wtxid_relay ? wtxid : txid;
41334093
AddKnownTx(*peer, hash);
4134-
if (peer->m_wtxid_relay && txid != wtxid) {
4135-
// Insert txid into m_tx_inventory_known_filter, even for
4136-
// wtxidrelay peers. This prevents re-adding of
4137-
// unconfirmed parents to the recently_announced
4138-
// filter, when a child tx is requested. See
4139-
// ProcessGetData().
4140-
AddKnownTx(*peer, txid);
4141-
}
41424094

41434095
LOCK(cs_main);
41444096

@@ -5684,7 +5636,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
56845636
std::vector<CInv> vInv;
56855637
{
56865638
LOCK(peer->m_block_inv_mutex);
5687-
vInv.reserve(std::max<size_t>(peer->m_blocks_for_inv_relay.size(), INVENTORY_BROADCAST_MAX));
5639+
vInv.reserve(std::max<size_t>(peer->m_blocks_for_inv_relay.size(), INVENTORY_BROADCAST_TARGET));
56885640

56895641
// Add blocks
56905642
for (const uint256& hash : peer->m_blocks_for_inv_relay) {
@@ -5736,14 +5688,12 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57365688
if (!tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue;
57375689
}
57385690
tx_relay->m_tx_inventory_known_filter.insert(hash);
5739-
// Responses to MEMPOOL requests bypass the m_recently_announced_invs filter.
57405691
vInv.push_back(inv);
57415692
if (vInv.size() == MAX_INV_SZ) {
57425693
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
57435694
vInv.clear();
57445695
}
57455696
}
5746-
tx_relay->m_last_mempool_req = std::chrono::duration_cast<std::chrono::seconds>(current_time);
57475697
}
57485698

57495699
// Determine transactions to relay
@@ -5763,8 +5713,8 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57635713
// especially since we have many peers and some will draw much shorter delays.
57645714
unsigned int nRelayedTransactions = 0;
57655715
LOCK(tx_relay->m_bloom_filter_mutex);
5766-
size_t broadcast_max{INVENTORY_BROADCAST_MAX + (tx_relay->m_tx_inventory_to_send.size()/1000)*5};
5767-
broadcast_max = std::min<size_t>(1000, broadcast_max);
5716+
size_t broadcast_max{INVENTORY_BROADCAST_TARGET + (tx_relay->m_tx_inventory_to_send.size()/1000)*5};
5717+
broadcast_max = std::min<size_t>(INVENTORY_BROADCAST_MAX, broadcast_max);
57685718
while (!vInvTx.empty() && nRelayedTransactions < broadcast_max) {
57695719
// Fetch the top element from the heap
57705720
std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
@@ -5783,30 +5733,24 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
57835733
if (!txinfo.tx) {
57845734
continue;
57855735
}
5786-
auto txid = txinfo.tx->GetHash();
57875736
// Peer told you to not send transactions at that feerate? Don't bother sending it.
57885737
if (txinfo.fee < filterrate.GetFee(txinfo.vsize)) {
57895738
continue;
57905739
}
57915740
if (tx_relay->m_bloom_filter && !tx_relay->m_bloom_filter->IsRelevantAndUpdate(*txinfo.tx)) continue;
57925741
// Send
5793-
tx_relay->m_recently_announced_invs.insert(hash);
57945742
vInv.push_back(inv);
57955743
nRelayedTransactions++;
57965744
if (vInv.size() == MAX_INV_SZ) {
57975745
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
57985746
vInv.clear();
57995747
}
58005748
tx_relay->m_tx_inventory_known_filter.insert(hash);
5801-
if (hash != txid) {
5802-
// Insert txid into m_tx_inventory_known_filter, even for
5803-
// wtxidrelay peers. This prevents re-adding of
5804-
// unconfirmed parents to the recently_announced
5805-
// filter, when a child tx is requested. See
5806-
// ProcessGetData().
5807-
tx_relay->m_tx_inventory_known_filter.insert(txid);
5808-
}
58095749
}
5750+
5751+
// Ensure we'll respond to GETDATA requests for anything we've just announced
5752+
LOCK(m_mempool.cs);
5753+
tx_relay->m_last_inv_sequence = m_mempool.GetSequence();
58105754
}
58115755
}
58125756
if (!vInv.empty())

src/node/interfaces.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ class ChainImpl : public Chain
677677
{
678678
if (!m_node.mempool) return true;
679679
LockPoints lp;
680-
CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
680+
CTxMemPoolEntry entry(tx, 0, 0, 0, 0, false, 0, lp);
681681
const CTxMemPool::Limits& limits{m_node.mempool->m_limits};
682682
LOCK(m_node.mempool->cs);
683683
return m_node.mempool->CalculateMemPoolAncestors(entry, limits).has_value();

src/test/fuzz/util/mempool.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider,
2323
const CAmount fee{ConsumeMoney(fuzzed_data_provider, /*max=*/std::numeric_limits<CAmount>::max() / CAmount{100'000})};
2424
assert(MoneyRange(fee));
2525
const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
26+
const uint64_t entry_sequence{fuzzed_data_provider.ConsumeIntegral<uint64_t>()};
2627
const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
2728
const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
2829
const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
29-
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
30+
return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, entry_sequence, spends_coinbase, sig_op_cost, {}};
3031
}

src/test/util/setup_common.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContex
424424
LOCK2(cs_main, m_node.mempool->cs);
425425
LockPoints lp;
426426
m_node.mempool->addUnchecked(CTxMemPoolEntry(ptx, /*fee=*/(total_in - num_outputs * amount_per_output),
427-
/*time=*/0, /*entry_height=*/1,
427+
/*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
428428
/*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
429429
}
430430
--num_transactions;
@@ -454,7 +454,7 @@ void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
454454
const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
455455
m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
456456
m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee,
457-
/*time=*/0, /*entry_height=*/1,
457+
/*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
458458
/*spends_coinbase=*/true, /*sigops_cost=*/1, lp));
459459
m_node.mempool->TrimToSize(0);
460460
assert(m_node.mempool->GetMinFee() == target_feerate);

src/test/util/txmempool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx) co
3434

3535
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransactionRef& tx) const
3636
{
37-
return CTxMemPoolEntry{tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), nHeight, spendsCoinbase, sigOpCost, lp};
37+
return CTxMemPoolEntry{tx, nFee, TicksSinceEpoch<std::chrono::seconds>(time), nHeight, m_sequence, spendsCoinbase, sigOpCost, lp};
3838
}

0 commit comments

Comments
 (0)