Craig's Blog

Blockchain Finality and Mempools

The primary purpose of this document is informative. The end goal is to technically explain what finality is with a focus on how that is used from a customer perspective. To achieve that goal, we will start with understanding the life cycle of a transaction on a blockchain. This document will focus on bitcoin and ethereum, as they are both offerings in CQ, and the vast majority of popular blockchains are derived from these two chains.

What is the definition of finality? an action or event that ends something irreversibly [Oxford dictionary definition]. That is interesting, because this except from the ethereum foundation is more philosophical.

First of all, a very important philosophical point to make is that there is no system in the world that offers truly 100% settlement finality in the literal sense of the term. If share ownership is recorded on a paper registry, then it is always possible for the registry to burn down, or for a hooligan to run into the registry, draw a “c” in front of every “1” to make it look like a “9”, and run out. Even without any malicious attackers, it is also possible that one day everyone who knows the registry’s location will be struck by lightning and die simultaneously. Centralized computerized registries have the same problems, and arguably an attack is even easier to pull off, at least if the security of the central bank of Bangladesh is any indication.

So, finality is tricky. Lets start with a transaction lifecycle, from creation through the mempool and to finalization. Each step will showcase what the customer is looking for and examples of things that happen. After the lifecycle, we will come back to finality. Note - I am intentionally excluding MEV/Miner specific transactions except where required. If desired, I can do a separate writeup on MEV. I strongly recommend you read the entire document from start to finish; however, if you would like you can jump straight to finality or the so what.

Transaction Lifecycle

Step 0: Transaction creation - Alice has a public/private key-pair. For the purpose of simplicity, she creates a transaction. Then she uses her private key to sign the transaction, which attests that Alice does in fact want to make the transaction. Alice now needs to submit this to a node, and this is where things start to differ. The transaction creation and signing can be done online or offline, and does not need to interact with a blockchain node. This step is referred to as a “raw” transaction.

Step 1: Transaction enters Mempool - Alice submits the transaction to a blockchain node. There are a couple of different ways to do this. Maybe Alice is running her own node. Maybe Alice’s friend Bob is running a node. Or, maybe she uses (or pays) for an online relay. At this point, the transaction is only present on a single node, the node that Alice is directly interacting with. The probability that this specific node will add Alice’s transaction to a block in a timespan Alice is comfortable with is infinitesimally small (or zero on non-mining nodes), so this transaction will be shared with others to increase its probability of being included in a block.

Step 2: Transaction is broadcasted to the Mempool - The full node that Alice submitted the transaction to will use a special gossip channel to relay or broadcast the transaction to other nodes. There are largely two configurations used here, private mempools and public mempools. In a public mempool, the transaction is broadcast to every node connected, which in turn broadcasts to every node its connected to, and this process continues until every node in the network knows about this transaction. A private mempool is similar, except instead of broadcasting to every node, the transaction is only broadcasted to nodes in the private mempool. In simpler terms, the transaction never leaves the set of allow-listed nodes.

One common issue with mempools is DOS (denial of service) attacks. Techniques to handle DOS attacks vary per each chain, but they are largely similar. Transactions are constantly entering and exiting the mempool with some of them being mined (included in a block), some of them being replaced, and some of them just being dropped. Most people check a mempool explorer to make sure their transaction is broadcasted correctly, at this step the transaction is referred to as a “pending” transaction. Below are a few techniques mempools use to handle pending transactions and their customer impacts.

  1. Fixed mempool size. On the blockchain node, you can configure a field to dedicate a specific configuration or an amount of memory to use on pending transactions. Mempool.space has a great diagram which shows which transactions are getting “purged” from standard bitcoin clients. Different clients and blockchains have different options here, some allocate a fixed size (100MB), whereas some define a fixed floor (10 sat/vB), while others specify the number of transactions (1000 txs). All achieve the same outcome, limiting the size of the mempool on a given node. Most people, including myself, configure their personal nodes to always keep their transactions in the mempool and rebroadcast as necessary.
    1. For example, if Alice submits a standard bitcoin transaction and the purge depth is 5 sat/vB, but Alice’s transaction was 4 sat/vB, then Alices transaction will get dropped from the mempool. If it is dropped or not included on a node, then that node will also not broadcast it to other nodes. If Alice’s transaction is dropped, she will need to rebroadcast the transaction at a later time. This is EXTREMELY COMMON on bitcoin, where a user will submit with an expected gas price and it will enter some mempools, but the gas price will increase sharply (due to small block sizes) quickly purging items from mempools.
    2. For example, the bitcoin purge depth is 5 sat/vB, but Alice does not want to pay the high gas price and knows the rate is normally cheaper overnight. She submits 2 sat/vB to her personal node. The node does not broadcast this transaction as it is not a viable transaction for other nodes. After some time has passed and the purge depth drops, Alice’s personal node automatically forwards to other nodes. Alice will not see her transaction on a mempool explorer until it is broadcasted.
  2. Single write transaction per address. Each address (Alice) is only permitted to have a single write in progress at a time. There are some nuances and ways to get around this, but generally speaking each address can only have a single write at a time. The mempool will either reject the incoming transaction, or will eject the older transaction. Due to distributed nature of mempools, it is difficult to know which scenario will be applied, so some nodes like bitcoin nodes automatically reject these transactions. Bitcoin has RBF (replace-by-fee), which is a special transaction to increase the fees of a transaction so the transaction does not get purged and has a higher chance of being included. Bitcoin also has CPFP (Child-pays-for-parent) where a child transaction pays an increased fee for the parent transaction so that both get included in the same block. Ethereum uses nonces such that only a single transaction with a single nonce can be executed.
    1. For example, Alice sends a bitcoin transaction with 4 sat/vB, but later decides it is not enough. She tries to send another transaction with 5 sat/vB, but this is rejected by her wallet/node.
    2. For example, Alice sends a bitcoin transaction with 4 sat/vB, but later decides it is not enough. Shes uses RBF to inform the mempool she is increasing the fee to 5 sat/vB, the mempool replaces the older 4 sat/vB transaction.
    3. For example, Alice sends an ethereum transaction with a nonce of 1. Before it is included in a block, she sends another transaction with a nonce of 1 with a higher fee. The mempool replaces the older transaction with the newer transaction.

Step 3: Transaction is mined - Different blockchains have different mechanisms for mining, but they all fundamentally produce blocks which contain a set of ordered transactions. One lucky node will produce a block containing transactions. For the purposes of this discussion, Alice’s transaction is included in the block, and so has been updated to a confirmed transaction. Bitcoin uses Nakamoto consensus, also known as proof of work, where there is an agreement on which hash constitutes a valid block. Ethereum uses a type of proof of stake, where a set of nodes (validators) are randomly elected to produce blocks.

There is an interesting nuance with ethereum transaction status. A successful transaction is a transaction which has the intended side effects (Alice successfully transfers tokens). A failed transaction is a transaction which does not have intended consequences. One of the most common examples of a failed transaction is a DeFi swap where slippage is not met, normally due to a MEV bot. Alice wants to convert ETH to USDC at 1K USDC per ETH, and is willing to take a 10% slippage (900 USDC per ETH), but a bot lowers to 800 USDC per ETH. Rather than take a loss, the transaction reverts. A very common point of confusion is that these failed transactions are sometimes referred to as reverted, but that is not the terminology we will be using. It is named as such because in the programming language (solidity) there is a revert keyword to mark a transaction as failed if the revert is executed, as it reverts the contract execution.

Similar to mempools, blocks have dos protections built in. The primary protection on both ethereum and bitcoin is fees and maximum size. If you want to submit a transaction, you must pay $$. Ethereum has a gas limit, and charges gas for everything the transaction does, such as storing data or computation. Bitcoin has a data limit, so blocks must be smaller than a certain size to be included. Both networks have fee mechanisms for users to “tip” miners, this is commonly leveraged for a mechanism called MEV. Miners are incentivized to only add transactions to the blockchain if they get paid for their effort. Although MEV is out of scope of the document, it is important to distinguish that most ethereum blocks are not produced by the miner elected. Instead, the miner places the block up for bid, and other people pay for the opportunity to produce the block. The miner then takes that produced block and uses it during their lucky opportunity, collecting the rewards that go with it. This separation (Proposer-builder-separation PBS) is important to monitor if it becomes an aspect of the protocol of supported networks, as it will have impacts on both the ability to revert transactions (instant guarantees) and finality (decrease or instant finality). This is also imporatant, because different validators have different configurations, meaning they include, exclude, or disable/revert certain transactions. There are different configurations (regulated, ethical, max profit, etc…) which during a re-org cause different types of reverts to happen.

Step 3.5: Transaction is reverted - This step is optional and does not always happen. On some blockchains this cannot happen, on others such as ethereum it is rare (<1% of blocks), and on others such as bitcoin it is fairly common (>1%). One important aspect to note is that as the hashing power required to mine bitcoin blocks increases, the probability of a collision/reorg decreases. Blockchains are distributed ledgers which makes consistency guarantees difficult. While the miner produced a valid block which included Alice’s transaction, a different miner could have produced a different block which may or may not have included Alice’s transaction. Which step we jump to next depends on what happened.

  1. The new block did not include Alice’s transaction. If Alice’s transaction is above the mempool cutoff, then the transaction remains as a pending transaction in step 2. From Alice’s perspective, her transaction went from confirmed to pending.
  2. The new block did not include Alice’s transaction. If Alice’s transaction is below the mempool cutoff, then the transaction is rejected from mempools and goes back to step 2. From Alice’s perspective, her transaction went from confirmed to missing (not present on mempool explorers). On bitcoin, I would hypothesize (difficult to collect data) this the most common outcome, especially since Ordinals launched.
  3. The new block included Alice’s transaction. Alice’s transaction was included in both blocks! No matter which block “wins”, Alice’s transaction is included. From Alice’s perspective, her transaction is still confirmed and she may not even notice the reorg. On ethereum, I would hypothesize (difficult to collect data) this the most common outcome assuming Alice is not a censored address.
  4. This is a rare permutation of #3. Lets say that Alice was trying to convert ETH to USDC, and her transaction was successfully converting ETH to USDC. However, the other miner was malicious and caused Alice’s transaction to fail perhaps through a MEV exploit. In this case, from Alice’s perspective, her transaction went from successfully converting ETH to USDC to failed and not converting ETH to USDC. This is rare, but does happen on censored addresses (collect example?).

Step 4: Transaction is unable to be reverted - This step takes some time after step 3 to complete. However, once this step is reached, step 3.5 can no longer happen. Alice is able to transfer funds, and more importantly, be able to remove them from major banking institutions. From Alice’s perspective, her transaction is finalized.

What is finality?

As we have established, there are some loose guidelines on what finality means. So, by definition this section is opinionated (Craig’s opinion).

Finality is social consensus that something will not be undone, enforced through economic measures [Craig’s definition]

There are two really good examples of social consensus, one on bitcoin and one on ethereum. In both examples, irregardless of time and duration, the community decides what is correct.

In 2010 an attacker gave themselves 186 billion BTC by exploiting a vulnerability. Well, bitcoin only has 21 million BTC, so something is clearly wrong. An update to the software was made and it rejected that block, effectively cancelling all transactions that happened on that day. The community quickly got together, determined it was unacceptable, and reverted that transaction regardless of the duration that it took. However, in doing so, many other transactions got reverted.

In July of 2016 an attacker exploited a vulnerability in “The DAO” which manages the Ethereum Foundations treasury. However, the community got together and determined this was unacceptable. They made an irregular state change (hard-coded behavior) to erase the theft from the blockchain. This was not a revert in the traditional sense, but it did mutate the state of the blockchain in a new manner, effectively undoing a previous transaction. This incident is the famous ETH/ETC split.

How does finality work on ethereum? There is a definition on ethereum - If a pair of checkpoints attracts votes representing at least two-thirds of the total staked ETH, the checkpoints are upgraded. The more recent of the two (target) becomes “justified”. Whenever 2/3rds of the total staked ETH would be slashed (1/3rd burned) to modify state, then something is final. Due to how checkpoints are selected and upgraded, this is difficult to calculate; however, the nodes provide a nice API which determines whether a block is final or not. In sunny day scenarios, this is 2 epochs long, which is ~64 slots, which is 12.8 minutes. Earlier in 2023, there were multiple scenarios of ethereum failing to finalize for longer durations.

How does finality work on bitcoin? There is no definition. Most banks use 6 blocks, although some are dropping to 5. Why? Because the amount of hashing power (to mine blocks) to re-mine a chain longer then 6 blocks is both computationally and economically infeasible. It would cost billions of dollars (not including opportunity cost) to pull off an attack of this magnitude. As the hashing power to mine new blocks continues to increase, so too does that cost. Mining a block is probabilistic, so there is no defined duration. Some blocks are mined instantly and some take over an hour; however, there is a target set at an average of 10 minutes per block. Meaning on average, finality is roughly one hour.

So What?

Customers want to see data at every step along the way. However, services need to be careful to not lose trust. If that service is held to a very high bar, and a customer reads data, they expect that data to be correct. And, customers may misinterpret data, so using industry terms and industry conventions is important.

We can break a transaction into its separate states. Created - A transaction has been created. Pending - The transaction is in the mempool. This is difficult because mempools are distributed and have different configurations, meaning every mempool is a little different. Confirmed - The transaction is present in at least one block. This block and the corresponding transactions may be orphaned and not included in the chain, but the transaction is present in at least one block. Justified - The transaction (ethereum only) is present in a block, that is present in a single epoch, that has attracted votes from a majority of validators. PreFinality - (Fake term) - Representing some state between Confirmed and Finalized, where the probability of being reverted is sufficiently (needs defined) low. One and two block re-orgs are common (daily to weekly) on both ethereum and bitcoin. However, a three block re-org is rare (~yearly) on bitcoin. Finalized - The transaction cannot be undone. The nuances discussed in the finality section.

Conclusion

Hopefully this document was informative. It contains the minimum number of opinions required to explain the lifecycle of a transaction and what finality means. It defines some terms as well as real life examples of blockchain behaviors which will help clarify new requirements.

** This document has been slightly modified for public consumption

← Back to all posts