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 txins 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 wtxids is then updated. As vTxHashes stores the wtxids 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. |