interop

package
v1.18.0 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnknownChain is returned when an executing message references
	// a chain that is not registered with the interop activity.
	ErrUnknownChain = errors.New("unknown chain")

	// ErrTimestampViolation is returned when an executing message references
	// an initiating message with a timestamp > the executing message's timestamp.
	ErrTimestampViolation = errors.New("initiating message timestamp must not be greater than executing message timestamp")

	// ErrMessageExpired is returned when an executing message references
	// an initiating message that has expired (older than the message expiry window).
	ErrMessageExpired = errors.New("initiating message has expired")
)
View Source
var (
	// ErrPreviousTimestampNotSealed is returned when a logsDB write path needs a
	// previous timestamp that has not been sealed yet.
	ErrPreviousTimestampNotSealed = errors.New("previous timestamp not sealed in logsDB")

	// ErrParentHashMismatch is returned when the block's parent hash does not match
	// the hash of the last sealed block in the logsDB.
	ErrParentHashMismatch = errors.New("block parent hash does not match logsDB")

	// ErrStaleLogsDB is returned when the logsDB has data for a different block
	// at the same height (e.g., after a chain reorg). The caller should repair
	// the logsDB by trimming to the verified frontier and retrying.
	ErrStaleLogsDB = errors.New("logsDB has stale block data from a reorg")
)
View Source
var (
	ErrNotFound         = errors.New("timestamp not found")
	ErrNonSequential    = errors.New("timestamps must be committed sequentially with no gaps")
	ErrAlreadyCommitted = errors.New("timestamp already committed")
)
View Source
var ErrCycle = errors.New("cycle detected in same-timestamp messages")

ErrCycle is returned when a cycle is detected in same-timestamp messages.

View Source
var InteropActivationTimestampFlag = &cli.Uint64Flag{
	Name:    "interop.activation-timestamp",
	Usage:   "Override the interop activation timestamp derived from rollup configs",
	EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "INTEROP_ACTIVATION_TIMESTAMP"),
	Value:   0,
}

InteropActivationTimestampFlag is the CLI flag for the interop activation timestamp.

View Source
var InteropLogBackfillDepthFlag = &cli.DurationFlag{
	Name:    "interop.log-backfill-depth",
	Usage:   "Duration to pre-ingest logs behind the tip before interop validation (e.g. 168h). Never loads logs before interop.activation-timestamp. Requires interop.activation-timestamp.",
	EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "INTEROP_LOG_BACKFILL_DEPTH"),
	Value:   0,
}

InteropLogBackfillDepthFlag extends initiating-message log ingestion backward from the L2 tip by this duration (clamped to activation). Validation still starts only beyond the local safe head.

Functions

This section is empty.

Types

type Decision

type Decision int

Decision represents the outcome of the pure decision function.

const (
	DecisionWait Decision = iota
	DecisionAdvance
	DecisionInvalidate
	DecisionRewind
)

func (Decision) MarshalJSON

func (d Decision) MarshalJSON() ([]byte, error)

func (Decision) String

func (d Decision) String() string

Decision is serialized as a self-describing string in the WAL so that the on-disk format survives enum re-ordering or the insertion of new variants.

func (*Decision) UnmarshalJSON

func (d *Decision) UnmarshalJSON(data []byte) error

type Interop

type Interop struct {
	// contains filtered or unexported fields
}

Interop is a VerificationActivity that can also run background work as a RunnableActivity.

func New

func New(
	log log.Logger,
	activationTimestamp uint64,
	messageExpiryWindow uint64,
	chains map[eth.ChainID]cc.InteropChain,
	dataDir string,
	l1Source l1ByNumberSource,
	logBackfillDepth time.Duration,
	metrics *resources.SupernodeMetrics,
) *Interop

New constructs a new Interop activity.

func (*Interop) ActivationTimestamp

func (i *Interop) ActivationTimestamp() uint64

ActivationTimestamp returns the immutable protocol-defined interop activation timestamp. This is the value that fronts protocol-facing RPC responses and never advances at runtime.

func (*Interop) BackfillAttempts

func (i *Interop) BackfillAttempts() int32

BackfillAttempts returns the number of times runLogBackfill has been invoked since the most recent Start. Integration tests use it to confirm the retry loop has engaged.

func (*Interop) BackfillCompleted

func (i *Interop) BackfillCompleted() bool

BackfillCompleted reports whether the log backfill phase has finished (either ran and returned nil, or was skipped because logBackfillDepth was 0). Integration tests use it to gate assertions on downstream state until backfill is done.

func (*Interop) BackfillEndTimestamp

func (i *Interop) BackfillEndTimestamp() uint64

BackfillEndTimestamp returns the inclusive last timestamp whose logs were sealed by runLogBackfill, or 0 if backfill has not run. The main loop starts verification at BackfillEndTimestamp()+1 (or ActivationTimestamp() when backfill was skipped).

func (*Interop) CurrentL1

func (i *Interop) CurrentL1() eth.BlockID

CurrentL1 returns the L1 block which has been fully considered for interop, whether or not it advanced the verified timestamp.

func (*Interop) FirstSealedBlock

func (i *Interop) FirstSealedBlock(chainID eth.ChainID) (suptypes.BlockSeal, error)

FirstSealedBlock returns the earliest block sealed in the logs DB for the given chain, along with its timestamp. Returns an error if the chain is unknown or the logs DB is empty.

func (*Interop) FirstVerifiableTimestamp

func (i *Interop) FirstVerifiableTimestamp() uint64

FirstVerifiableTimestamp returns the timestamp at which the main loop begins verification. It is intended for tests after startup has completed.

func (*Interop) IsActiveAt

func (i *Interop) IsActiveAt(ts uint64) bool

IsActiveAt reports whether the interop verifier is responsible for verifying L2 content at the given timestamp. Returns false for timestamps strictly before the configured activation timestamp.

func (*Interop) LatestSealedBlock

func (i *Interop) LatestSealedBlock(chainID eth.ChainID) (suptypes.BlockSeal, bool, error)

LatestSealedBlock returns the most recent block sealed in the logs DB for the given chain along with its timestamp. Returns an error if the chain is unknown and (zero, false) if the DB is empty.

func (*Interop) LatestVerifiedL2Block

func (i *Interop) LatestVerifiedL2Block(chainID eth.ChainID) (eth.BlockID, uint64)

LatestVerifiedL2Block returns the latest L2 block which has been verified, along with the timestamp at which it was verified.

func (*Interop) Name

func (i *Interop) Name() string

func (*Interop) PauseAt

func (i *Interop) PauseAt(ts uint64)

PauseAt sets a timestamp at which the interop activity should pause. When progressInterop encounters this timestamp or any later timestamp, it returns early without processing. Uses >= check so that if the activity is already beyond the pause point, it will still stop. Pass 0 to clear the pause (equivalent to calling Resume).

func (*Interop) Reset

func (i *Interop) Reset(chainID eth.ChainID, timestamp uint64, invalidatedBlock eth.BlockRef)

Reset is intentionally a no-op for interop. Interop-owned invalidation and rewind handling is driven synchronously through PendingTransition application, so callback-driven resets are not part of the correctness path anymore.

func (*Interop) Resume

func (i *Interop) Resume()

Resume clears any pause timestamp, allowing normal processing to continue.

func (*Interop) Start

func (i *Interop) Start(ctx context.Context) error

Start begins the Interop activity background loop and blocks until ctx is canceled.

func (*Interop) Stop

func (i *Interop) Stop(ctx context.Context) error

Stop stops the Interop activity.

func (*Interop) VerifiedAtTimestamp

func (i *Interop) VerifiedAtTimestamp(ts uint64) (bool, error)

VerifiedAtTimestamp returns whether the data is verified at the given timestamp. Timestamps before the first verifiable timestamp are already covered by pre-activation consensus or by the safe-head startup handoff.

func (*Interop) VerifiedBlockAtL1

func (i *Interop) VerifiedBlockAtL1(chainID eth.ChainID, l1Block eth.L1BlockRef) (eth.BlockID, uint64)

VerifiedBlockAtL1 returns the verified L2 block and timestamp which guarantees that the verified data at that timestamp originates from or before the supplied L1 block.

type InvalidHead

type InvalidHead struct {
	eth.BlockID
	StateRoot                eth.Bytes32 `json:"stateRoot"`
	MessagePasserStorageRoot eth.Bytes32 `json:"messagePasserStorageRoot"`
}

InvalidHead pairs a block identifier with the output preimage fields needed for optimistic root computation in the superroot API. The full OutputV0 can be reconstructed on demand via OutputV0() since BlockHash is already in BlockID.

type LogsDB

type LogsDB interface {
	// LatestSealedBlock returns the latest sealed block ID, or false if no blocks are sealed.
	LatestSealedBlock() (eth.BlockID, bool)
	// FirstSealedBlock returns the first block seal in the DB.
	FirstSealedBlock() (types.BlockSeal, error)
	// FindSealedBlock returns the block seal for the given block number.
	FindSealedBlock(number uint64) (types.BlockSeal, error)
	// OpenBlock returns the block reference, log count, and executing messages for a block.
	OpenBlock(blockNum uint64) (ref eth.BlockRef, logCount uint32, execMsgs map[uint32]*types.ExecutingMessage, err error)
	// Contains checks if an initiating message exists in the database.
	// Returns the block seal if found, or an error (ErrConflict if not found, ErrFuture if not yet indexed).
	Contains(query types.ContainsQuery) (types.BlockSeal, error)
	// AddLog adds a log entry to the database.
	AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *types.ExecutingMessage) error
	// SealBlock seals a block in the database.
	SealBlock(parentHash common.Hash, block eth.BlockID, timestamp uint64) error
	// Rewind removes all blocks after newHead from the database.
	Rewind(inv reads.Invalidator, newHead eth.BlockID) error
	// Clear removes all data from the database.
	Clear(inv reads.Invalidator) error
	// Close closes the database.
	Close() error
}

LogsDB is the interface for interacting with a chain's logs database. *logs.DB implements this interface.

type PendingInvalidation

type PendingInvalidation struct {
	ChainID                  eth.ChainID `json:"chainID"`
	BlockID                  eth.BlockID `json:"blockID"`
	Timestamp                uint64      `json:"timestamp"` // the interop decision timestamp
	StateRoot                eth.Bytes32 `json:"stateRoot"`
	MessagePasserStorageRoot eth.Bytes32 `json:"messagePasserStorageRoot"`
}

PendingInvalidation records a chain invalidation that needs to be executed.

type PendingTransition

type PendingTransition struct {
	Decision Decision    `json:"decision"`
	Result   *Result     `json:"result,omitempty"`
	Rewind   *RewindPlan `json:"rewind,omitempty"`
}

PendingTransition is the generic write-ahead-log entry for an effectful interop decision. Recovery and steady-state both use the same apply path.

Phase 2 keeps this intentionally small: - advance/invalidate carry their Result directly - rewind carries the accepted frontier to rewind from Later phases can expand this into a richer explicit transition plan.

type Result

type Result struct {
	Timestamp    uint64                      `json:"timestamp"`
	L1Inclusion  eth.BlockID                 `json:"l1Inclusion"`
	L2Heads      map[eth.ChainID]eth.BlockID `json:"l2Heads"`
	InvalidHeads map[eth.ChainID]InvalidHead `json:"invalidHeads"`
}

Result represents the result of interop validation at a specific timestamp given current data. it contains all the same information as VerifiedResult, but also contains a list of invalid heads.

func (*Result) IsEmpty

func (r *Result) IsEmpty() bool

func (*Result) IsValid

func (r *Result) IsValid() bool

func (*Result) ToVerifiedResult

func (r *Result) ToVerifiedResult() VerifiedResult

type RewindPlan

type RewindPlan struct {
	RewindAtOrAfter  uint64                      `json:"rewindAtOrAfter"`
	ResetAllChainsTo *uint64                     `json:"resetAllChainsTo,omitempty"`
	TargetHeads      map[eth.ChainID]eth.BlockID `json:"targetHeads,omitempty"`
}

RewindPlan is the explicit rewind transition persisted in the WAL. It captures the target verified frontier and engine reset decision so recovery can apply the same rewind path without recomputing it from live state.

type RoundObservation

type RoundObservation struct {
	LastVerifiedTS *uint64
	LastVerified   *VerifiedResult
	NextTimestamp  uint64
	ChainsReady    bool
	BlocksAtTS     map[eth.ChainID]eth.BlockID
	L1Heads        map[eth.ChainID]eth.BlockID
	L1Consistent   bool
	Paused         bool
}

RoundObservation is a consistent snapshot of the current round's state, captured upfront so the decision function operates on immutable data.

type StepOutput

type StepOutput struct {
	Decision Decision
	Result   Result
}

StepOutput combines a decision with the verification result (if any).

type VerifiedDB

type VerifiedDB struct {
	// contains filtered or unexported fields
}

VerifiedDB provides persistence for verified timestamps using bbolt.

func OpenVerifiedDB

func OpenVerifiedDB(dataDir string) (*VerifiedDB, error)

OpenVerifiedDB opens or creates a VerifiedDB at the given data directory.

func (*VerifiedDB) ClearPendingTransition

func (v *VerifiedDB) ClearPendingTransition() error

ClearPendingTransition removes the WAL entry after the transition is fully applied.

func (*VerifiedDB) Close

func (v *VerifiedDB) Close() error

Close closes the database.

func (*VerifiedDB) Commit

func (v *VerifiedDB) Commit(result VerifiedResult) error

Commit stores a verified result at the given timestamp. Timestamps must be committed sequentially with no gaps.

func (*VerifiedDB) FirstTimestamp added in v1.18.0

func (v *VerifiedDB) FirstTimestamp() (uint64, bool)

FirstTimestamp returns the first committed timestamp. Returns 0 and false if no timestamps have been committed.

func (*VerifiedDB) Get

func (v *VerifiedDB) Get(ts uint64) (VerifiedResult, error)

Get retrieves the verified result at the given timestamp.

func (*VerifiedDB) GetPendingTransition

func (v *VerifiedDB) GetPendingTransition() (*PendingTransition, error)

GetPendingTransition retrieves any pending transition from the WAL. Returns nil if no pending work exists.

func (*VerifiedDB) Has

func (v *VerifiedDB) Has(ts uint64) (bool, error)

Has returns whether a timestamp has been verified.

func (*VerifiedDB) LastTimestamp

func (v *VerifiedDB) LastTimestamp() (uint64, bool)

LastTimestamp returns the most recently committed timestamp. Returns 0 and false if no timestamps have been committed.

func (*VerifiedDB) Rewind

func (v *VerifiedDB) Rewind(timestamp uint64) (bool, error)

Rewind removes all verified results at or after the given timestamp. Returns true if any results were deleted, false otherwise.

func (*VerifiedDB) SetPendingTransition

func (v *VerifiedDB) SetPendingTransition(pending PendingTransition) error

SetPendingTransition persists a generic interop transition as a write-ahead log. Must be called BEFORE executing any durable side effects for crash safety.

type VerifiedResult

type VerifiedResult struct {
	Timestamp   uint64                      `json:"timestamp"`
	L1Inclusion eth.BlockID                 `json:"l1Inclusion"`
	L2Heads     map[eth.ChainID]eth.BlockID `json:"l2Heads"`
}

VerifiedResult represents the verified state at a specific timestamp. It contains the L1 inclusion block from which the L2 heads were included, and a map of each chain's L2 head at that timestamp.

Jump to

Keyboard shortcuts

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