Skip to content

Commit bfcd401

Browse files
committed
CValidationInterface, mempool: add new callback to CValidationInterface
This commit adds a new callback `MempoolTransactionsRemovedForBlock` which notify its listeners of the transactions that are removed from the mempool because a new block is connected, along with the block height the transactions were removed. The transactions are in `RemovedMempoolTransactionInfo` format. `CTransactionRef`, base fee, virtual size, and height which the transaction was added to the mempool are all members of the struct called `RemovedMempoolTransactionInfo`. A struct `NewMempoolTransactionInfo`, which has fields similar to `RemovedMempoolTransactionInfo`, will be added in a later commit, create a struct `TransactionInfo` with all similar fields. They can both have a member with type `TransactionInfo`.
1 parent 0889e07 commit bfcd401

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

src/kernel/mempool_entry.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,34 @@ class CTxMemPoolEntry
178178

179179
using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
180180

181+
struct TransactionInfo {
182+
const CTransactionRef m_tx;
183+
/* The fee the transaction paid */
184+
const CAmount m_fee;
185+
/**
186+
* The virtual transaction size.
187+
*
188+
* This is a policy field which considers the sigop cost of the
189+
* transaction as well as its weight, and reinterprets it as bytes.
190+
*
191+
* It is the primary metric by which the mining algorithm selects
192+
* transactions.
193+
*/
194+
const int64_t m_virtual_transaction_size;
195+
/* The block height the transaction entered the mempool */
196+
const unsigned int txHeight;
197+
198+
TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
199+
: m_tx{tx},
200+
m_fee{fee},
201+
m_virtual_transaction_size{vsize},
202+
txHeight{height} {}
203+
};
204+
205+
struct RemovedMempoolTransactionInfo {
206+
TransactionInfo info;
207+
explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
208+
: info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
209+
};
210+
181211
#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H

src/txmempool.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,17 +654,21 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
654654
}
655655
// Before the txs in the new block have been removed from the mempool, update policy estimates
656656
if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);}
657+
std::vector<RemovedMempoolTransactionInfo> txs_removed_for_block;
658+
txs_removed_for_block.reserve(vtx.size());
657659
for (const auto& tx : vtx)
658660
{
659661
txiter it = mapTx.find(tx->GetHash());
660662
if (it != mapTx.end()) {
661663
setEntries stage;
662664
stage.insert(it);
665+
txs_removed_for_block.emplace_back(*it);
663666
RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
664667
}
665668
removeConflicts(*tx);
666669
ClearPrioritisation(tx->GetHash());
667670
}
671+
GetMainSignals().MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight);
668672
lastRollingFeeUpdate = GetTime();
669673
blockSinceLastRollingFeeBump = true;
670674
}

src/validationinterface.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <chain.h>
1010
#include <consensus/validation.h>
1111
#include <kernel/chain.h>
12+
#include <kernel/mempool_entry.h>
1213
#include <logging.h>
1314
#include <primitives/block.h>
1415
#include <primitives/transaction.h>
@@ -233,6 +234,16 @@ void CMainSignals::BlockConnected(ChainstateRole role, const std::shared_ptr<con
233234
pindex->nHeight);
234235
}
235236

237+
void CMainSignals::MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight)
238+
{
239+
auto event = [txs_removed_for_block, nBlockHeight, this] {
240+
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight); });
241+
};
242+
ENQUEUE_AND_LOG_EVENT(event, "%s: block height=%s txs removed=%s", __func__,
243+
nBlockHeight,
244+
txs_removed_for_block.size());
245+
}
246+
236247
void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
237248
{
238249
auto event = [pblock, pindex, this] {

src/validationinterface.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct CBlockLocator;
2121
class CValidationInterface;
2222
class CScheduler;
2323
enum class MemPoolRemovalReason;
24+
struct RemovedMempoolTransactionInfo;
2425

2526
/** Register subscriber */
2627
void RegisterValidationInterface(CValidationInterface* callbacks);
@@ -60,10 +61,10 @@ void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
6061
void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
6162

6263
/**
63-
* Implement this to subscribe to events generated in validation
64+
* Implement this to subscribe to events generated in validation and mempool
6465
*
6566
* Each CValidationInterface() subscriber will receive event callbacks
66-
* in the order in which the events were generated by validation.
67+
* in the order in which the events were generated by validation and mempool.
6768
* Furthermore, each ValidationInterface() subscriber may assume that
6869
* callbacks effectively run in a single thread with single-threaded
6970
* memory consistency. That is, for a given ValidationInterface()
@@ -113,7 +114,7 @@ class CValidationInterface {
113114
* This does not fire for transactions that are removed from the mempool
114115
* because they have been included in a block. Any client that is interested
115116
* in transactions removed from the mempool for inclusion in a block can learn
116-
* about those transactions from the BlockConnected notification.
117+
* about those transactions from the MempoolTransactionsRemovedForBlock notification.
117118
*
118119
* Transactions that are removed from the mempool because they conflict
119120
* with a transaction in the new block will have
@@ -131,6 +132,14 @@ class CValidationInterface {
131132
* Called on a background thread.
132133
*/
133134
virtual void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}
135+
/*
136+
* Notifies listeners of transactions removed from the mempool as
137+
* as a result of new block being connected.
138+
* MempoolTransactionsRemovedForBlock will be fired before BlockConnected.
139+
*
140+
* Called on a background thread.
141+
*/
142+
virtual void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight) {}
134143
/**
135144
* Notifies listeners of a block being connected.
136145
* Provides a vector of transactions evicted from the mempool as a result.
@@ -140,6 +149,7 @@ class CValidationInterface {
140149
virtual void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
141150
/**
142151
* Notifies listeners of a block being disconnected
152+
* Provides the block that was connected.
143153
*
144154
* Called on a background thread. Only called for the active chainstate, since
145155
* background chainstates should never disconnect blocks.
@@ -202,6 +212,7 @@ class CMainSignals {
202212
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
203213
void TransactionAddedToMempool(const CTransactionRef&, uint64_t mempool_sequence);
204214
void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
215+
void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>&, unsigned int nBlockHeight);
205216
void BlockConnected(ChainstateRole, const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
206217
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
207218
void ChainStateFlushed(ChainstateRole, const CBlockLocator &);

0 commit comments

Comments
 (0)