High-level
An ORU block goes through an interactive verification game (“IVG”). This game eventually outputs true or false, after a time period. Contingent blocks add a second validity condition to a Rollup block: the validity of 1 or more other blocks from other rollups. This allows immediate reads of the remote rollup’s state, regardless of whether that rollup’s waiting period has elapsed, because if the state being read reverts, the state reading it must ALSO revert.
Structure
When sequencing, the sequencer chooses a parent to build upon, and applies state transitions to create a new root. Each child is naturally predicated on the parent. If the parent reverts, the child will too. We generalize this concept to allow the sequencer to also include “parent” roots from other rollups, so long as the validity of that rollup can be verified on the L1. The sequencer chooses undisputed, but pending, roots from other running rollups, and commits them. We call these "predicate roots” because the validity of the new commitment is predicated upon them. We say that a block is “contingent” on its predicate roots. At any time, anyone may notify the Rollup contract that a predicate root does not exist, or has reverted, and cause any contingent root to be invalidated.
The relationship between contingent and predicate is generalizable. We can say “predicate rollup” which contains the “predicate root” committing the “predicate state”. Then there is a “contingent rollup” which contains the “contingent root” committing to the “contingent state”. Rollups may contain many predicate relationships between each other in their histories. Predicate relationships between roots and states form a DAG, where the nodes are roots/states and the edges are predicate commitments.
The sequencer is responsible for knowing whether a block is “safe” to predicate upon. Anyone may check that a block is safe by running the predicate rollup. When a block is contingent on another, it may access any state in that other block. This is safe, as if the predicate state reverts, the contingent state will also revert. This means that the state of the remote rollup is readable without waiting for its interactive verification game to complete. Which is to say, rollups can communicate with each other faster than they can communicate with the L1.
To achieve communication the contingent state may access any data committed to by the predicate root. It does this by processing a proof of the state under the predicate commitment. The state proof may be provided by the sequencer. As a bonus, the state proof may be elided. Because the state of the predicate rollup is generally assumed to be available, there can be a concurrent IVG for the predicate state proofs. Which is to say the sequencer doesn’t need to provide the state proof under a predicate commitment, it can merely make the statement that such a proof exists, and allow anyone to challenge the assertion via an IVG.
Downside of Contingency: Security inheritance
The contingent rollup inherits the risk of the IVG of the predicate rollup for the duration of the predicate’s IVG. This means a security reliance on the predicate rollup’s 1-of-N assumption, as well as a security assumption wrt the availability of the predicate rollup’s state. Because the predicate root may itself be contingent on some other predicate root, this security inheritance is transitive. An uncaught fault (via buggy IVG or 1-of-N assumption violation or unavailable state) can affect any transitive contingent rollup. This property couples rollup safety assumptions more tightly to each other.
A full node of the contingent rollup therefore cannot be sure of the state of a contingent block without some information about the predicate rollup. It must decide whether it optimistically accepts the predicate commitment, waits to accept it (potentially the full IVG duration), or consults a trusted 3rd party.
Extension to Shared Sequencer
If the two rollups happen to share a sequencer, that sequencer could produce several commitments on each rollup in a single logical “synchronous block”. Each meta-commitment contains several iterative rollup root commitments on each rollup. In this case, the contingency relationship provides an internal ordering for commitments that are committed to the host chain at the same time. The sequencer does this by alternating blocks from each rollup, and adding alternating contingency relationships. Producing synchronous blocks allows for 2-way communication between the rollups within a single logical host chain block.
By convention, we recommend that the iterative commitments beyond the first ONLY handle cross-chain messages, and ONLY in the order they were dispatched, without handling any other user transactions. This prevents sequencer discretion from affecting the execution outcome.
Summary
Contingency relationships allow data sharing between ORUs. They do this safely (all reverted writes result in reverted reads), and quickly (reads can be made when a block is ordered, long before the IVG resolves).
Future work:
Generalize to include predication on any data available via L1 staticcall
Describe node behavior when in a contingent state more fully
Discuss