Page MenuHomePhabricator

D16019.id47299.diff
No OneTemporary

D16019.id47299.diff

diff --git a/src/net_processing.cpp b/src/net_processing.cpp
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1223,7 +1223,7 @@
// All of the following cache a recent block, and are protected by
// m_most_recent_block_mutex
- Mutex m_most_recent_block_mutex;
+ mutable Mutex m_most_recent_block_mutex;
std::shared_ptr<const CBlock>
m_most_recent_block GUARDED_BY(m_most_recent_block_mutex);
std::shared_ptr<const CBlockHeaderAndShortTxIDs>
@@ -6240,6 +6240,30 @@
LOCK(cs_main);
m_chainman.ActiveChainstate().UnparkBlock(pindex);
}
+
+ if (fPreConsensus) {
+ // First check if the block is cached before reading
+ // from disk.
+ auto pblock = WITH_LOCK(m_most_recent_block_mutex,
+ return m_most_recent_block);
+
+ if (!pblock ||
+ pblock->GetHash() != pindex->GetBlockHash()) {
+ std::shared_ptr<CBlock> pblockRead =
+ std::make_shared<CBlock>();
+ if (!ReadBlockFromDisk(
+ *pblockRead, pindex,
+ m_chainparams.GetConsensus())) {
+ assert(!"cannot load block from disk");
+ }
+ pblock = pblockRead;
+ }
+ assert(pblock);
+
+ LOCK(m_mempool.cs);
+ m_mempool.removeForFinalizedBlock(pblock->vtx);
+ }
+
m_chainman.ActiveChainstate().AvalancheFinalizeBlock(
pindex);
} break;
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -581,4 +581,57 @@
checkOrdering(entryB, entryA);
}
+BOOST_AUTO_TEST_CASE(remove_for_finalized_block) {
+ CTxMemPool &pool = *Assert(m_node.mempool);
+ TestMemPoolEntryHelper entry;
+
+ LOCK2(cs_main, pool.cs);
+
+ std::vector<CTransactionRef> txs;
+ txs.reserve(100);
+ for (size_t i = 0; i < 100; i++) {
+ CTransactionRef tx = make_tx({int64_t(i + 1) * COIN});
+ const TxId &txid = tx->GetId();
+ auto mempoolEntry = entry.FromTx(tx);
+
+ pool.addUnchecked(mempoolEntry);
+ BOOST_CHECK(pool.exists(txid));
+
+ BOOST_CHECK(pool.setAvalancheFinalized(mempoolEntry));
+ BOOST_CHECK(pool.isAvalancheFinalized(txid));
+
+ txs.push_back(std::move(tx));
+ }
+
+ std::vector<CTransactionRef> minedTxs(txs.begin(), txs.begin() + 50);
+ pool.removeForFinalizedBlock(minedTxs);
+
+ for (const auto &tx : minedTxs) {
+ // No longer in the radix tree
+ BOOST_CHECK(!pool.isAvalancheFinalized(tx->GetId()));
+ }
+ // Other txs are still there
+ for (size_t i = 50; i < 100; i++) {
+ BOOST_CHECK(pool.isAvalancheFinalized(txs[i]->GetId()));
+ }
+
+ // Repeat is no op
+ pool.removeForFinalizedBlock(minedTxs);
+ for (const auto &tx : minedTxs) {
+ // No longer in the radix tree
+ BOOST_CHECK(!pool.isAvalancheFinalized(tx->GetId()));
+ }
+ // Other txs are still there
+ for (size_t i = 50; i < 100; i++) {
+ BOOST_CHECK(pool.isAvalancheFinalized(txs[i]->GetId()));
+ }
+
+ // Remove them all
+ pool.removeForFinalizedBlock(txs);
+ for (const auto &tx : txs) {
+ // No longer in the radix tree
+ BOOST_CHECK(!pool.isAvalancheFinalized(tx->GetId()));
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/txmempool.h b/src/txmempool.h
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -365,6 +365,8 @@
EXCLUSIVE_LOCKS_REQUIRED(cs);
void removeConflicts(const CTransaction &tx) EXCLUSIVE_LOCKS_REQUIRED(cs);
void updateFeeForBlock() EXCLUSIVE_LOCKS_REQUIRED(cs);
+ void removeForFinalizedBlock(const std::vector<CTransactionRef> &vtx)
+ EXCLUSIVE_LOCKS_REQUIRED(cs);
void clear();
// lock free
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -192,6 +192,8 @@
// even if not directly reported below.
uint64_t mempool_sequence = GetAndIncrementSequence();
+ const TxId &txid = (*it)->GetTx().GetId();
+
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
@@ -199,6 +201,8 @@
// BlockConnected notification.
GetMainSignals().TransactionRemovedFromMempool(
(*it)->GetSharedTx(), reason, mempool_sequence);
+
+ finalizedTxs.remove(txid);
}
for (const CTxIn &txin : (*it)->GetTx().vin) {
@@ -206,11 +210,8 @@
}
/* add logging because unchecked */
- const TxId &txid = (*it)->GetTx().GetId();
RemoveUnbroadcastTx(txid, true);
- finalizedTxs.remove(txid);
-
totalTxSize -= (*it)->GetTxSize();
m_total_fee -= (*it)->GetFee();
cachedInnerUsage -= (*it)->DynamicMemoryUsage();
@@ -310,6 +311,19 @@
blockSinceLastRollingFeeBump = true;
}
+void CTxMemPool::removeForFinalizedBlock(
+ const std::vector<CTransactionRef> &vtx) {
+ AssertLockHeld(cs);
+
+ for (const auto &tx : vtx) {
+ // If the tx has a parent, it will be in the block as well or the block
+ // is invalid. If the tx has a child, it can remain in the tree for the
+ // next block. So we can simply remove the txs from the block with no
+ // further check.
+ finalizedTxs.remove(tx->GetId());
+ }
+}
+
void CTxMemPool::_clear() {
mapTx.clear();
mapNextTx.clear();
diff --git a/test/functional/abc_p2p_avalanche_transaction_voting.py b/test/functional/abc_p2p_avalanche_transaction_voting.py
--- a/test/functional/abc_p2p_avalanche_transaction_voting.py
+++ b/test/functional/abc_p2p_avalanche_transaction_voting.py
@@ -195,6 +195,26 @@
assert txid in node.getrawmempool()
tip = self.generate(node, 1)[0]
+
+ self.log.info("The transaction remains finalized after it's mined")
+
+ assert node.isfinaltransaction(txid, tip)
+ assert txid not in node.getrawmempool()
+
+ self.log.info("The transaction remains finalized even when reorg'ed")
+
+ node.parkblock(tip)
+ assert node.getbestblockhash() != tip
+ assert node.isfinaltransaction(txid)
+ assert txid in node.getrawmempool()
+
+ node.unparkblock(tip)
+ assert_equal(node.getbestblockhash(), tip)
+ assert node.isfinaltransaction(txid, tip)
+ assert txid not in node.getrawmempool()
+
+ self.log.info("The transaction remains finalized after the block is finalized")
+
self.wait_until(lambda: has_finalized_block(tip))
assert node.isfinaltransaction(txid, tip)
assert txid not in node.getrawmempool()

File Metadata

Mime Type
text/plain
Expires
Tue, May 20, 22:42 (4 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5866082
Default Alt Text
D16019.id47299.diff (7 KB)

Event Timeline