Addition to the mempool
Transactions are added to the mempool via addUnchecked()
as part of the AcceptToMemoryPool()
flow. See Transaction validation for more information on how this flow is entered.
The function name addUnchecked specifically refers to the fact that no checks are being performed, so this must not be called until policy checks have passed. |
This function is called from within validation.cpp (MemPoolAccept::Finalize()
) where the appropriate consensus and policy checks have already been performed on the transaction. The transaction is added to the primary index mapTx
before any fee prioritisation ("delta") is applied to it.
Next any links to parent transactions are generated by looping through the inputs and mapping the COutPoint
of the input to this transaction CTransaction
in the mapNextTx
map. Additionally the tx input is added to a set which is used to update parent transactions if they are still in the mempool.
After all inputs have been considered, UpdateAncestorsOf()
is called which will add this transaction as a descendant to any ancestors in the mempool. This is followed by UpdateEntryForAncestors()
which will re-calculate and apply descendant count
, size
, fee
and sigOpCost
of the ancestors with the new descendant being accounted for.
Finally update totalTxSize
and totalFee
(both sum totals of the mempool) to account for this new transaction.
Removal from the mempool
Transactions are removed from the mempool for a number of reasons:
-
A new block has been connected
removeForBlock()
-
A re-org is taking place
removeForReorg()
-
The transaction has expired
Expire()
-
The transaction is being replaced by a higher-fee version
MemPoolAccept::Finalize()
-
The mempool must be trimmed back down below its maximum size
TrimToSize()
RemoveStaged()
takes a set of transactions referenced by their txid along with their removal reason, and removes them sequentially. It does this by first updating the ancestors of the transaction, followed by the descendants. After calculating and updating related transaction information it calls removeUnchecked()
which actions the removal from the mempool.
removeUnchecked()
starts by notifying the validation interface that a transaction has been removed from the mempool for all reasons other than a new block arriving, as there is a different BlockConnected
signal which can be used for that.
Next it loops over the txin
s of the transaction, and removes each prevout
of each txin
from the mapNextTx
map.
You can see the map being created as new transactions are learned about in |
If the node has upgraded to SegWit the vTxHashes
vector, which stores wtxid
s is then updated. As vTxHashes
stores the wtxid
s in random order, first we move the transaction’s entry to the back, and then pop it off, resizing the vector if needed.
Finally, as with addUnchecked()
we update the mempool sum totals for txSize
and fee
and erase the transaction from the primary mempool index mapTx
.
Both adding and removing transactions increment the mempool_seqence counter. This is used by the getrawmempool RPC (via MempoolToJSON ) in tracking the number of mempool database transaction operations. |