diff --git a/pages/stack/interop/_meta.json b/pages/stack/interop/_meta.json index 87b15dc0d..cfeda8718 100644 --- a/pages/stack/interop/_meta.json +++ b/pages/stack/interop/_meta.json @@ -5,6 +5,7 @@ "op-supervisor": "OP Supervisor", "superchain-weth": "Interoperable ETH", "superchain-erc20": "SuperchainERC20", + "reorg": "Interop reorg awareness", "interop-security": "Safe interoperability", "tools": "Tools", "tutorials": "Tutorials" diff --git a/pages/stack/interop/reorg.mdx b/pages/stack/interop/reorg.mdx new file mode 100644 index 000000000..2472da76d --- /dev/null +++ b/pages/stack/interop/reorg.mdx @@ -0,0 +1,182 @@ +--- +title: Interop reorg awareness +lang: en-US +description: How Superchain interop enables low-latency interop and avoids the double-spend problem. +--- + +import { Callout } from 'nextra/components' +import Image from 'next/image' + +import { InteropCallout } from '@/components/WipCallout' + + + +# Interop reorg awareness + +[A chain reorganization, or “reorg”,](https://www.alchemy.com/overviews/what-is-a-reorg#what-happens-to-reorgs-after-the-merge) happens when validators disagree on the most accurate version of the blockchain. +If not handled correctly, reorgs in a cross-chain context could result in a [double-spend problem](https://en.wikipedia.org/wiki/Double-spending). +The most frequent solution to mitigate the double-spend problem is to wait for Ethereum finality; however, that solution results in high latency cross-chain communication and a poor user experience. + +
+ +What is double-spending? + +```mermaid + +flowchart LR + subgraph init ["Initiating transaction (source chain)"] + burn(tokens burned) + burn-->send(send) + end + subgraph exec ["Executing transaction (destination chain)"] + send==initiating message==>receive(receive) + receive-->mint(tokens minted) + end +``` + +In a normal asset transfer tokens are burned on the source chain first, then a message is sent to the destination chain. +When that message is received, the tokens are minted on the destination chain, where the user can now use those tokens. + +```mermaid + +flowchart LR + subgraph init ["Not really the source chain"] + err((error)) + end + subgraph exec ["Executing transaction (destination chain)"] + err==initiating message==>receive(receive) + receive-->mint(tokens minted) + end +``` + +A double-spend problem occurs when the destination chain receives a valid initiating message, but due to issues on the source chain, such as a reorg, that initiating transaction is no longer valid. +When that happens, the tokens are still on the source chain, but they are also on the destination chain. + +
+ +Most solutions to mitigate the double-spend problem rely on [L1 finality](https://ethereum.org/en/developers/docs/consensus-mechanisms/pos/#finality). However, that solution results in high latency and poor user experience. + +To mitigate the double-spend problem while delivering a low-latency cross-chain experience, Superchain interop uses [block safety levels](./explainer#block-safety-levels). +This means users can transfer assets across chains in the Superchain with 1-block latency, and should a reorg happen, either both the source and destination transactions would remain, or both of them would revert. +In every case, there is no window of opportunity to double spend. + +## Block safety levels + +```mermaid + +graph LR + classDef finalized fill:#CCC + classDef safe fill:#8F8 + classDef unsafe fill:#F89 + + subgraph A ["Chain A"] + A100["A100"]-->A101["A101"]-->A102["A102"]-->A103["A103"] + end + subgraph B ["Chain B"] + B300["B300"]-->B301["B301"]-->B302["B302"]-->B303["B303"] + end + A101-.->B302 + B300-.->A100 + class A100,B300,B301 safe + class A101,A102,A103,B302,B303 unsafe +``` + +In the diagram above, solid arrows are the derivation of a block from the previous block in the chain. +Dotted arrows go from the block with the initiating message (the source) to the block with the executing message (the destination). +Blocks can either be finalized (grey), cross-safe (green), or unsafe (red). +Blockchain A has only written block A100 to the blockchain. +As a result, block A101 is unsafe, and so are all the blocks that depend on it, directly (A102 and B302) or indirectly (A103 and B303). +Blocks B302 and B303 may be *local-safe* (if they are written to L1), but they cannot be *cross-safe* because they depend on a block that isn't. +If all goes well, eventually A101 will be written to L1, turn safe, and then the blocks that depend on it can become safe as well. + +The message between A101 and B302 can be an asset moving across the bridge. +In that case, the initiating message (A101) burns `n` tokens on the source chain (A), and the executing message (B302) mints `n` tokens on the destination chain (B). + +### L1 reorg + +In this case, an L1 block is replaced, and the new block either contains the same blob with chain data that was contained in the old block, or it doesn't. +If the new block contains the same blob, the change is meaningless from the L2 perspective. +If the new block does not contain the same blob, then the sequencer on the chain will know it is missing and reposts it. + +So L1 reorgs are basically invisible to L2. + +### Equivocation + +Sequencers inform the rest of the Superchain about a new block in two ways: + +- The gossip protocol, which is typically used as soon as the block is created. + The problem is that the gossip protocol does not create a commitment. +- Posting to L1, which typically happens a few minutes after the block is created. + The reason is cost, it is a lot cheaper if compression and L1 posting are done in large batches, rather than for each individual block. + + +Equivocation happens when a sequencer publishes a block using the gossip protocol that is different from the one that eventually gets written to L1. +In this case, the block that is written to L1 (let's call it A'101) is the valid one, and that causes every dependent block to be recalculated. + +```mermaid + +graph LR + classDef finalized fill:#CCC + classDef safe fill:#8F8 + classDef unsafe fill:#F89 + + subgraph A ["Chain A"] + A100["A100"]-->A101["A101"]-->A102["A102"]-->A103["A103"] + A100-->A101b["A'101"]-->A102b["A'102"]-->A103b["A'103"] + end + subgraph B ["Chain B"] + B300["B300"]-->B301["B301"]-->B302["B302"]-->B303["B303"] + B300-->B301b["B'301"]-->B302b["B'302"]-->B303b["B'303"] + end + subgraph C ["Chain C"] + C200["C200"]-->C201["C201"]-->C202["C202"]-->C203["C203"] + C202-->C203b["C'203"] + end + A101-.->B302 + A101-.->B301 + A101b-.->B302b + A101b-.->B301b + B300-.->A100 + B302-.->C203 + B302b-.->C203b + C200-.->B301 + class C200 finalized + class A100,B300,C201,C202 safe + class A101b,A102b,A103b,B301b,B302b,B303b,C203b safe + class A101,A102,A103,B301,B302,B303,C203 unsafe +``` + +Note that a block can only depend directly on a block in a separate chain if the block includes an executing message that uses an initiating message from that block. +So the change from A101 to A'101 cannot invalidate any existing safe blocks. + +### Invalid block + +If a block is invalid, even if it is posted on L1, the canonical chain replaces it with a block that only includes the deposit transactions, those transactions posted to L1. + +
+ +What makes a block invalid? + +There are several potential reasons: + +- The block posted to L1 includes incorrect information, for example because it relied on a node on a different blockchain for interop and that node reported incorrect information. +- The block was never posted. + After a timeout of twelve hours all the verifiers will assume that the block that should have been posted is a deposit-only block. + +
+ +This is functionally equivalent to equivocation, and dealt with the same way, so it can change unsafe blocks but only those blocks. + +{/* +### L2 reorg + +An L2 reorg could happen after the sequencer is decentralized. +In that case, there is a deterministic FCU (fork choice update), just as there is on L1. +At worst, some unsafe blocks need to be recalculated (if one fork is chosen over another). +*/} + +## Next steps + +- Build a [revolutionary app](/app-developers/get-started) that uses multiple blockchains within the Superchain. +- Deploy a [SuperchainERC20](./tutorials/deploy-superchain-erc20) to the Superchain. +- View more [interop tutorials](./tutorials). \ No newline at end of file