Documentation
¶
Index ¶
- Constants
- Variables
- type Decision
- type Interop
- func (i *Interop) ActivationTimestamp() uint64
- func (i *Interop) BackfillAttempts() int32
- func (i *Interop) BackfillCompleted() bool
- func (i *Interop) CurrentL1() eth.BlockID
- func (i *Interop) FirstSealedBlock(chainID eth.ChainID) (messages.BlockSeal, error)
- func (i *Interop) FirstVerifiableTimestamp() uint64
- func (i *Interop) IsActiveAt(ts uint64) bool
- func (i *Interop) LatestSealedBlock(chainID eth.ChainID) (messages.BlockSeal, bool, error)
- func (i *Interop) LatestVerifiedL2Block(chainID eth.ChainID) (eth.BlockID, uint64, error)
- func (i *Interop) Name() string
- func (i *Interop) PauseAt(ts uint64)
- func (i *Interop) Reset(chainID eth.ChainID, timestamp uint64, invalidatedBlock eth.BlockRef)
- func (i *Interop) Resume()
- func (i *Interop) Start(ctx context.Context) error
- func (i *Interop) Stop(ctx context.Context) error
- func (i *Interop) VerificationStartTimestamp() uint64
- func (i *Interop) VerifiedAtTimestamp(ts uint64) (bool, error)
- func (i *Interop) VerifiedBlockAtL1(chainID eth.ChainID, l1Block eth.L1BlockRef) (eth.BlockID, uint64, error)
- func (i *Interop) VerifiedResultAtTimestamp(ts uint64) (VerifiedResult, eth.BlockID, error)
- type InvalidHead
- type LogsDB
- type NoopVerifiedResultReader
- type PendingInvalidation
- type PendingTransition
- type Result
- type RewindPlan
- type RoundObservation
- type StepOutput
- type VerifiedDB
- func (v *VerifiedDB) ClearPendingTransition() error
- func (v *VerifiedDB) Close() error
- func (v *VerifiedDB) Commit(result VerifiedResult) error
- func (v *VerifiedDB) FirstTimestamp() (uint64, bool)
- func (v *VerifiedDB) Get(ts uint64) (VerifiedResult, error)
- func (v *VerifiedDB) GetPendingTransition() (*PendingTransition, error)
- func (v *VerifiedDB) Has(ts uint64) (bool, error)
- func (v *VerifiedDB) LastTimestamp() (uint64, bool)
- func (v *VerifiedDB) Rewind(timestamp uint64) (bool, error)
- func (v *VerifiedDB) SetPendingTransition(pending PendingTransition) error
- type VerifiedResult
- type VerifiedResultReader
Constants ¶
const ( InteropStateNotStarted = 0 InteropStateColdStartWaiting = 1 InteropStateRunning = 2 InteropStateHalted = 3 )
Interop activity state values exposed via supernode_interop_activity_state gauge.
const DefaultLogBackfillDepth = time.Duration(depset.MessageExpiryTimeSecondsInterop) * time.Second
DefaultLogBackfillDepth matches the interop message expiry window so backfill covers every initiating message that could still be referenced by an executing message.
Variables ¶
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") // ErrExecutedTooEarly is returned when an executing message is in the executing chain's // pre-activation or activation block. ErrExecutedTooEarly = errors.New("interop is not active for at least one block on the executing chain") // ErrInitiatedTooEarly is returned when an executing message references an initiating // message in the initiating chain's pre-activation or activation block. ErrInitiatedTooEarly = errors.New("interop is not active for at least one block on the initiating chain") )
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") )
var ( ErrNotFound = errors.New("timestamp not found") ErrNonSequential = errors.New("timestamps must be committed sequentially with no gaps") ErrAlreadyCommitted = errors.New("timestamp already committed") )
var ErrBeforeVerifiedDB = errors.New("timestamp below verified-db start")
ErrBeforeVerifiedDB signals that ts is post-activation but below the verifier's first verifiable timestamp on this node. The timestamp is already covered by the startup handoff: no VerifiedResult will be produced here, but callers can treat optimistic outputs as canonical.
var ErrCycle = errors.New("cycle detected in same-timestamp messages")
ErrCycle is returned when a cycle is detected in same-timestamp messages.
var ErrNotActive = errors.New("interop not active for timestamp")
ErrNotActive signals that ts is before interop activation. Callers compose the super root from per-chain optimistic outputs.
var ErrNotStarted = errors.New("interop activity not started")
ErrNotStarted signals that Start has not yet populated i.ctx. Callers should retry after startup completes.
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.
var InteropLogBackfillDepthFlag = &cli.DurationFlag{ Name: "interop.log-backfill-depth", Usage: "Duration to pre-ingest logs behind the tip before interop validation. Never loads logs before interop.activation-timestamp. Set to 0 to disable.", EnvVars: opservice.PrefixEnvVar(flags.EnvVarPrefix, "INTEROP_LOG_BACKFILL_DEPTH"), Value: DefaultLogBackfillDepth, }
InteropLogBackfillDepthFlag extends initiating-message log ingestion backward from the startup boundary by this duration (clamped to activation).
Functions ¶
This section is empty.
Types ¶
type Decision ¶
type Decision int
Decision represents the outcome of the pure decision function.
func (Decision) MarshalJSON ¶
func (Decision) 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 ¶
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 ¶
ActivationTimestamp returns the immutable protocol-defined interop activation timestamp for this verifier. Used by the SuperAuthority to compute the per-(chain, verifier) activation-anchor block and by RPC surfaces that expose the configured activation point.
func (*Interop) BackfillAttempts ¶
BackfillAttempts returns the number of times advanceColdStartInit has been invoked since the most recent Start. Integration tests use it to confirm the cold-start retry loop has engaged.
func (*Interop) BackfillCompleted ¶
BackfillCompleted reports whether cold-start init has finished (backfill ran, or resume skipped it). Integration tests gate downstream assertions on this.
func (*Interop) CurrentL1 ¶
CurrentL1 returns the L1 block currently being processed by the interop verifier. Every L1 block strictly below CurrentL1.Number has been fully considered for interop (i.e. used to verify every L2 timestamp whose source is at or below it); data at CurrentL1 itself may still be unverified, since L1Inclusion is monotonic in L2 timestamp and the next unverified timestamp can share the same L1 source. Consumers must require CurrentL1.Number > X to treat L1[≤X] as fully verified.
func (*Interop) FirstSealedBlock ¶
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 ¶
FirstVerifiableTimestamp returns the lowest timestamp the verifier covers (verifiedDB.FirstTimestamp when commits exist, else VerificationStartTimestamp). Returns 0 before initialization completes.
func (*Interop) IsActiveAt ¶
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 ¶
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 ¶
LatestVerifiedL2Block returns the latest verified L2 block for chainID. (empty, capTimestamp, nil) means nothing verified — capTimestamp is the pre-activation anchor (`activationTimestamp - 1`) for the caller to resolve. A non-nil error means verifiedDB could not be read.
func (*Interop) PauseAt ¶
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 ¶
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 ¶
Start begins the Interop activity background loop and blocks until ctx is canceled.
func (*Interop) VerificationStartTimestamp ¶ added in v1.19.0
VerificationStartTimestamp returns the L2 timestamp at which the main loop begins verification on the most recent Start. Returns 0 before initialization completes.
func (*Interop) VerifiedAtTimestamp ¶
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 startup handoff.
func (*Interop) VerifiedBlockAtL1 ¶
func (i *Interop) VerifiedBlockAtL1(chainID eth.ChainID, l1Block eth.L1BlockRef) (eth.BlockID, uint64, error)
VerifiedBlockAtL1 returns the latest verified L2 block for chainID whose L1 inclusion is at or below l1Block. (empty, capTimestamp, nil) means no match — capTimestamp is the pre-activation anchor for the caller to resolve. A non-nil error means verifiedDB could not be read.
func (*Interop) VerifiedResultAtTimestamp ¶ added in v1.18.1
VerifiedResultAtTimestamp returns the committed VerifiedResult for ts plus the verifier's CurrentL1 captured atomically with the verifiedDB read.
- ts < activationTimestamp → ErrNotActive
- ts < firstVerifiableTimestamp → ErrBeforeVerifiedDB
- verifiedDB.Get returns ErrNotFound → ethereum.NotFound
- else → the stored VerifiedResult
The local ErrNotFound is translated to the standard ethereum.NotFound at the public boundary so consumers can errors.Is against the standard sentinel without taking a dependency on this package's private error.
The atomic (verifiedDB, currentL1) snapshot lets callers report a CurrentL1 that cannot overstate verifier progress relative to the verifiedDB observation. The verifier holds i.mu when mutating currentL1 (commit advances currentL1 after writing the entry; rewind zeros currentL1 before deleting entries), so a snapshot taken under RLock is consistent with one side or the other of those transitions.
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() (messages.BlockSeal, error)
// FindSealedBlock returns the block seal for the given block number.
FindSealedBlock(number uint64) (messages.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]*messages.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 messages.ContainsQuery) (messages.BlockSeal, error)
// AddLog adds a log entry to the database.
AddLog(logHash common.Hash, parentBlock eth.BlockID, logIdx uint32, execMsg *messages.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(newHead eth.BlockID) error
// Clear removes all data from the database.
Clear() 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 NoopVerifiedResultReader ¶ added in v1.18.1
type NoopVerifiedResultReader struct{}
NoopVerifiedResultReader is used when interop is not configured: every call returns ErrNotActive.
func (NoopVerifiedResultReader) VerifiedResultAtTimestamp ¶ added in v1.18.1
func (NoopVerifiedResultReader) VerifiedResultAtTimestamp(uint64) (VerifiedResult, eth.BlockID, error)
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"`
InvalidationParentPayloads map[eth.ChainID]*eth.ExecutionPayloadEnvelope `json:"invalidationParentPayloads,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.
InvalidationParentPayloads is populated only for DecisionInvalidate transitions. It carries the canonical parent payload (height-1) for each invalidated chain, captured at build time and used at apply time to drive the rewind. Storing the full payload means a crash mid-rewind can be recovered without consulting the live EL — the canonical block may already have been pruned by the EL once it left the canonical chain.
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) 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"`
TargetPayloads map[eth.ChainID]*eth.ExecutionPayloadEnvelope `json:"targetPayloads,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.
TargetPayloads carries the canonical payload at each chain's rewind target, captured at build time. The apply path uses it to drive the engine rewind without consulting the live EL — see the InvalidationParentPayloads comment on PendingTransition for the rationale.
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
L1NeedsRewind 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 ¶
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) 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.
type VerifiedResultReader ¶ added in v1.18.1
type VerifiedResultReader interface {
VerifiedResultAtTimestamp(ts uint64) (result VerifiedResult, currentL1 eth.BlockID, err error)
}
VerifiedResultReader exposes committed VerifiedResults to non-interop activities. Errors discriminate the regime:
- nil: verified entry returned
- ErrNotActive: pre-activation; compose from optimistic outputs
- ErrBeforeVerifiedDB: post-activation but below firstVerifiable; the handoff covers ts, so compose from optimistic outputs
- ethereum.NotFound: verifier may eventually produce a result but has not yet — return Data = nil and let CurrentL1 communicate progress
currentL1 is the verifier's CurrentL1 observed atomically with the verifiedDB read. Callers must combine it with their own CurrentL1 view (via min) so the response cannot report a CurrentL1 that is inconsistent with the verifiedDB observation.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package raftwallogdb implements LogsDB on top of hashicorp/raft-wal.
|
Package raftwallogdb implements LogsDB on top of hashicorp/raft-wal. |