Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions node/derivation/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ type Metrics struct {
// LocalVerifyTriggered increments once per batch processed under
// VerifyModeLocal -- presence/absence on dashboards confirms the local
// verifier is running. Failure tracking is intentionally not split into
// separate counters; failures surface as Error logs and propagate as
// ErrBatchVerifyDivergence to BatchStatus=stateException.
// separate counters; failures surface as Error logs only --
// BatchStatus=stateException is set from verifyBatchRoots, not from
// this path.
LocalVerifyTriggered metrics.Counter

// Tag management metrics. SafeL2BlockNumber / FinalizedL2BlockNumber are
Expand Down
9 changes: 5 additions & 4 deletions node/derivation/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import (
// a true "verifier reached a verdict of inconsistent" — i.e. the local
// chain disagrees with what L1 committed. Currently produced by:
// - verifyBatchRoots, when local stateRoot or withdrawalRoot ≠ L1 calldata
// - verify_local's rebuildBlob, for kinds versioned_hash_mismatch and
// blob_count_mismatch
// - verify_local's rebuildBlob, for kind blob_count_mismatch
//
// Call sites in derivation.go gate `metrics.SetBatchStatus(stateException)`
// on errors.Is(err, ErrBatchVerifyDivergence). Transient or runtime errors
// Only the verifyBatchRoots call site in derivation.go gates
// `metrics.SetBatchStatus(stateException)` on errors.Is(err,
// ErrBatchVerifyDivergence); the rebuildBlob failure path logs and retries
// without inspecting the sentinel. Transient or runtime errors
// (RPC down, tx parsing failure, encoding bug, ...) intentionally do NOT
// wrap this sentinel: they reflect "verifier could not run", not "verifier
// determined divergence", and must not light up the divergence alert.
Expand Down
15 changes: 6 additions & 9 deletions node/derivation/verify_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,17 @@ func (d *Derivation) fetchBatchInfoOutline(ctx context.Context, txHash common.Ha
//
// Failure paths intentionally inline metric inc + structured log + error
// construction at each kind site rather than route through a shared
// helper. One error-wrapping invariant the call site (derivation.go)
// relies on:
// helper. On error wrapping:
//
// - kind=versioned_hash_mismatch and kind=blob_count_mismatch wrap
// ErrBatchVerifyDivergence so the call site flips BatchStatus to
// stateException ONLY on a real "verifier reached unequal verdict";
// transient / runtime errors must NOT light up the divergence alert.
// versioned_hash_mismatch will additionally be the self-heal trigger
// once the EL change lands (see file-level comment).
// - kind=blob_count_mismatch wraps ErrBatchVerifyDivergence, but this
// function's call site in derivation.go only logs and retries -- it
// does not read the sentinel. BatchStatus=stateException is set only
// on verifyBatchRoots failures (state / withdrawal root vs L1).
//
// All other kinds are plain errors. When you add a new kind, decide
// deliberately whether it represents "verifier could not run" (no
// sentinel) vs "verifier produced a divergence verdict" (wrap
// ErrBatchVerifyDivergence) and update the SentinelContract test.
// ErrBatchVerifyDivergence).
func (d *Derivation) rebuildBlob(ctx context.Context, batchInfo *BatchInfo) ([]common.Hash, error) {
d.metrics.IncLocalVerifyTriggered()

Expand Down
Loading