Explainer: More Protection for Stacks Users With ‘Transaction Replay’
Hey Stackers, in this post, we’re diving into the details of the Transaction Replay feature – an effort led by Hank, a long-time Stacks developer at Trust Machines and key ecosystem contributor. This new feature is now in its final implementation stages.

For more information on underway milestones for Stacks, check out the latest community-driven roadmap.

What is Transaction Replay?

In short, transaction replay offers protection in the event that Bitcoin forks, smartly preserving transactions at the Stacks layer should Bitcoin fork away the block the Stacks block was connected to.

Some background: All Stacks blocks are anchored to a particular Bitcoin block. When Bitcoin forks, the Stacks blocks associated with the old fork, and therefore the transactions in that Stacks block, would be ‘lost’ if there were no logic to handle this situation. This is an important problem because not handling this scenario can result in a sub-par experience for users. For example, miners have the ability to extract MEV by ordering these transactions in a certain way (ie, sandwiching) that can harm users and general confusion about seeing a transaction go through and it ‘disappearing’.

In sum, "Transaction replay" refers to the set of solutions to ensure these transactions, instead of being lost, are ‘replayed’ on the now canonical fork of Bitcoin in a new Stacks block. Typically, Bitcoin does not fork very deeply, and these smaller forks are already handled well by the current system, but these additional transaction replay features offer important additional robustness as the network looks to scale Bitcoin DeFi and other use cases.

An example

To provide an example, imagine we have Bitcoin block A at height 100, and it has two Stacks blocks in it. The first Stacks block has transactions t1 and t2, and the second Stacks block has t3.
Then, Bitcoin forks, and there is a new block (B) for height 100. Today, the Stacks miner can make whatever block they want. For example, maybe they make a block with a new transaction t4, and then they re-order t2 and t3:
With transaction replay, Stacks signers will enforce that this can’t happen. Instead, they’ll validate that blocks produced after a fork will always replay the transactions that were forked, in the original order that they appeared. So with transaction replay enforcement, the Stacks block would be:

Unmineable transactions

For the most part, transactions that are replayed after forks will end up with the same exact result as they did before the fork. However, there are certain types of transactions that depend on Bitcoin state, and a Bitcoin fork can result in that transaction having a different result. Because of this, some transactions can become unminable after a Bitcoin fork.

For example, imagine a contract call where Alice transfers STX to Bob only if a certain Bitcoin transaction was mined. The code might look something like this:
Imagine that, in this scenario, the contract call was successful (because the BTC transaction was mined), resulting in Bob having a STX balance. Then, Bob follows up with his own transaction, where he uses the newly received STX to pay for the transaction fee.
If Bitcoin forks, these two transactions will get replayed. This time, the first contract call doesn’t transfer STX to Bob, and so Bob doesn’t have STX to cover his transaction fees. Thus, his transaction is unmineable, meaning the transaction cannot even be included on the Stacks chain.

When signers validate blocks after a fork, they include special logic to allow these unmineable transactions to get dropped.

To visualize this, tx1 is the contract call where Alice transfers STX to Bob only if a BTC transaction was mined, and tx2 is the transaction where Bob uses those fees to pay STX. The original scenario would look like this:
After the fork, tx2 is dropped, so the result after transaction replay would be:

Current status of Transaction Replay

A majority of the work has been completed for the implementation of transaction replay. You can follow progress via this Github issue.

As of the time of writing, the two remaining code implementations are:
  • Handling “double forks” - AKA what happens if Bitcoin forks block A to block B, but then soon after forks to block C while transaction replay is in-progress.
  • Handling large replays, where the transactions being replayed can’t fit into one block (due to cost limits). In this scenario, miners will issue a Tenure Extend transaction in the middle of transaction replay, which will allow the remaining transactions to be included.
Once implementation is complete, we’ll extensively test transaction replay functionality, both on Testnet and on controlled networks where we can simulate various scenarios of Bitcoin forking.