sync

package
v0.0.0-...-011bec4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2024 License: MIT, MIT Imports: 10 Imported by: 0

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:

  1. l2block.number == l2block.l2parent.block.number + 1
  2. l2block.l1Origin.number >= l2block.l2parent.l1Origin.number
  3. l2block.l1Origin is in the canonical chain on L1
  4. 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

View Source
const (
	CLSyncString string = "consensus-layer"
	ELSyncString string = "execution-layer"
)
View Source
const MaxReorgSeqWindows = 5

Variables

View Source
var Modes = []Mode{CLSync, ELSync}
View Source
var ReorgFinalizedErr = errors.New("cannot reorg finalized block")
View Source
var TooDeepReorgErr = errors.New("reorg is too deep")
View Source
var WrongChainErr = errors.New("wrong chain")

Functions

This section is empty.

Types

type Config

type Config struct {
	// SyncMode is defined above.
	SyncMode Mode `json:"syncmode"`
	// 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 --syncmode=execution-layer on op-node and --syncmode=snap on op-geth
	// Warning: This will be removed when we implement proper checkpoints.
	// Note: We probably need to detect the condition that snap sync has not complete when we do a restart prior to running sync-start if we are doing
	// snap sync with a genesis finalization data.
	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.

type L1Chain

type L1Chain interface {
	L1BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L1BlockRef, error)
	L1BlockRefByNumber(ctx context.Context, number uint64) (eth.L1BlockRef, error)
	L1BlockRefByHash(ctx context.Context, hash common.Hash) (eth.L1BlockRef, error)
}

type L2Chain

type L2Chain interface {
	L2BlockRefByHash(ctx context.Context, l2Hash common.Hash) (eth.L2BlockRef, error)
	L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error)
}

type Mode

type Mode int
const (
	CLSync Mode = iota
	ELSync
)

There are two kinds of sync mode that the op-node does:

  1. In consensus-layer (CL) sync, the op-node fully drives the execution client and imports unsafe blocks & fetches unsafe blocks that it has missed.
  2. In execution-layer (EL) sync, the op-node tells the execution client to sync towards the tip of the chain. It will consolidate the chain as usual. This allows execution clients to snap sync if they are capable of it.

func StringToMode

func StringToMode(s string) (Mode, error)

func (*Mode) Clone

func (m *Mode) Clone() any

func (*Mode) Set

func (m *Mode) Set(value string) error

func (Mode) String

func (m Mode) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL