Documentation ¶
Overview ¶
Package sync is responsible for reconciling L1 and L2.
The Ethereum chain is a DAG of blocks with the root block being the genesis block. At any given time, the head (or tip) of the chain can change if an offshoot/branch of the chain has a higher total difficulty. This is known as a re-organization of the canonical chain. Each block points to a parent block and the node is responsible for deciding which block is the head and thus the mapping from block number to canonical block.
The Optimism (L2) chain has similar properties, but also retains references to the Ethereum (L1) chain. Each L2 block retains a reference to an L1 block (its "L1 origin", i.e. L1 block associated with the epoch that the L2 block belongs to) and to its parent L2 block. The L2 chain node must satisfy the following validity rules:
- l2block.number == l2block.l2parent.block.number + 1
- l2block.l1Origin.number >= l2block.l2parent.l1Origin.number
- l2block.l1Origin is in the canonical chain on L1
- l1_rollup_genesis is an ancestor of l2block.l1Origin
During normal operation, both the L1 and L2 canonical chains can change, due to a re-organisation or due to an extension (new L1 or L2 block).
In particular, in the case of L1 extension, the L2 unsafe head will generally remain the same, but in the case of an L1 re-org, we need to search for the new safe and unsafe L2 block.
Index ¶
Constants ¶
const MaxReorgSeqWindows = 5
Variables ¶
var ReorgFinalizedErr = errors.New("cannot reorg finalized block")
var TooDeepReorgErr = errors.New("reorg is too deep")
var WrongChainErr = errors.New("wrong chain")
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { // EngineSync is true when the EngineQueue can trigger execution engine P2P sync. EngineSync bool `json:"engine_sync"` // SkipSyncStartCheck skip the sanity check of consistency of L1 origins of the unsafe L2 blocks when determining the sync-starting point. This defers the L1-origin verification, and is recommended to use in when utilizing l2.engine-sync SkipSyncStartCheck bool `json:"skip_sync_start_check"` }
type FindHeadsResult ¶
type FindHeadsResult struct { Unsafe eth.L2BlockRef Safe eth.L2BlockRef Finalized eth.L2BlockRef }
func FindL2Heads ¶
func FindL2Heads(ctx context.Context, cfg *rollup.Config, l1 L1Chain, l2 L2Chain, lgr log.Logger, syncCfg *Config) (result *FindHeadsResult, err error)
FindL2Heads walks back from `start` (the previous unsafe L2 block) and finds the finalized, unsafe and safe L2 blocks.
- The *unsafe L2 block*: This is the highest L2 block whose L1 origin is a *plausible* extension of the canonical L1 chain (as known to the op-node).
- The *safe L2 block*: This is the highest L2 block whose epoch's sequencing window is complete within the canonical L1 chain (as known to the op-node).
- The *finalized L2 block*: This is the L2 block which is known to be fully derived from finalized L1 block data.
Plausible: meaning that the blockhash of the L2 block's L1 origin (as reported in the L1 Attributes deposit within the L2 block) is not canonical at another height in the L1 chain, and the same holds for all its ancestors.