aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kernel/mempool_entry.h30
-rw-r--r--src/txmempool.cpp4
-rw-r--r--src/validationinterface.cpp11
-rw-r--r--src/validationinterface.h17
4 files changed, 59 insertions, 3 deletions
diff --git a/src/kernel/mempool_entry.h b/src/kernel/mempool_entry.h
index 7c905ca4f4..ce32fe20dc 100644
--- a/src/kernel/mempool_entry.h
+++ b/src/kernel/mempool_entry.h
@@ -178,4 +178,34 @@ public:
using CTxMemPoolEntryRef = CTxMemPoolEntry::CTxMemPoolEntryRef;
+struct TransactionInfo {
+ const CTransactionRef m_tx;
+ /* The fee the transaction paid */
+ const CAmount m_fee;
+ /**
+ * The virtual transaction size.
+ *
+ * This is a policy field which considers the sigop cost of the
+ * transaction as well as its weight, and reinterprets it as bytes.
+ *
+ * It is the primary metric by which the mining algorithm selects
+ * transactions.
+ */
+ const int64_t m_virtual_transaction_size;
+ /* The block height the transaction entered the mempool */
+ const unsigned int txHeight;
+
+ TransactionInfo(const CTransactionRef& tx, const CAmount& fee, const int64_t vsize, const unsigned int height)
+ : m_tx{tx},
+ m_fee{fee},
+ m_virtual_transaction_size{vsize},
+ txHeight{height} {}
+};
+
+struct RemovedMempoolTransactionInfo {
+ TransactionInfo info;
+ explicit RemovedMempoolTransactionInfo(const CTxMemPoolEntry& entry)
+ : info{entry.GetSharedTx(), entry.GetFee(), entry.GetTxSize(), entry.GetHeight()} {}
+};
+
#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 7fd9c1cc25..f75dd7efea 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -654,17 +654,21 @@ void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigne
}
// Before the txs in the new block have been removed from the mempool, update policy estimates
if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);}
+ std::vector<RemovedMempoolTransactionInfo> txs_removed_for_block;
+ txs_removed_for_block.reserve(vtx.size());
for (const auto& tx : vtx)
{
txiter it = mapTx.find(tx->GetHash());
if (it != mapTx.end()) {
setEntries stage;
stage.insert(it);
+ txs_removed_for_block.emplace_back(*it);
RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
}
removeConflicts(*tx);
ClearPrioritisation(tx->GetHash());
}
+ GetMainSignals().MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight);
lastRollingFeeUpdate = GetTime();
blockSinceLastRollingFeeBump = true;
}
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index 9241395ad5..893ef69582 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -9,6 +9,7 @@
#include <chain.h>
#include <consensus/validation.h>
#include <kernel/chain.h>
+#include <kernel/mempool_entry.h>
#include <logging.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
@@ -233,6 +234,16 @@ void CMainSignals::BlockConnected(ChainstateRole role, const std::shared_ptr<con
pindex->nHeight);
}
+void CMainSignals::MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight)
+{
+ auto event = [txs_removed_for_block, nBlockHeight, this] {
+ m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.MempoolTransactionsRemovedForBlock(txs_removed_for_block, nBlockHeight); });
+ };
+ ENQUEUE_AND_LOG_EVENT(event, "%s: block height=%s txs removed=%s", __func__,
+ nBlockHeight,
+ txs_removed_for_block.size());
+}
+
void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
{
auto event = [pblock, pindex, this] {
diff --git a/src/validationinterface.h b/src/validationinterface.h
index eb15aa4d5f..ea49a45aa8 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -21,6 +21,7 @@ struct CBlockLocator;
class CValidationInterface;
class CScheduler;
enum class MemPoolRemovalReason;
+struct RemovedMempoolTransactionInfo;
/** Register subscriber */
void RegisterValidationInterface(CValidationInterface* callbacks);
@@ -60,10 +61,10 @@ void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
/**
- * Implement this to subscribe to events generated in validation
+ * Implement this to subscribe to events generated in validation and mempool
*
* Each CValidationInterface() subscriber will receive event callbacks
- * in the order in which the events were generated by validation.
+ * in the order in which the events were generated by validation and mempool.
* Furthermore, each ValidationInterface() subscriber may assume that
* callbacks effectively run in a single thread with single-threaded
* memory consistency. That is, for a given ValidationInterface()
@@ -113,7 +114,7 @@ protected:
* This does not fire for transactions that are removed from the mempool
* because they have been included in a block. Any client that is interested
* in transactions removed from the mempool for inclusion in a block can learn
- * about those transactions from the BlockConnected notification.
+ * about those transactions from the MempoolTransactionsRemovedForBlock notification.
*
* Transactions that are removed from the mempool because they conflict
* with a transaction in the new block will have
@@ -131,6 +132,14 @@ protected:
* Called on a background thread.
*/
virtual void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}
+ /*
+ * Notifies listeners of transactions removed from the mempool as
+ * as a result of new block being connected.
+ * MempoolTransactionsRemovedForBlock will be fired before BlockConnected.
+ *
+ * Called on a background thread.
+ */
+ virtual void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int nBlockHeight) {}
/**
* Notifies listeners of a block being connected.
* Provides a vector of transactions evicted from the mempool as a result.
@@ -140,6 +149,7 @@ protected:
virtual void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
/**
* Notifies listeners of a block being disconnected
+ * Provides the block that was connected.
*
* Called on a background thread. Only called for the active chainstate, since
* background chainstates should never disconnect blocks.
@@ -202,6 +212,7 @@ public:
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
void TransactionAddedToMempool(const CTransactionRef&, uint64_t mempool_sequence);
void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
+ void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>&, unsigned int nBlockHeight);
void BlockConnected(ChainstateRole, const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
void ChainStateFlushed(ChainstateRole, const CBlockLocator &);