Skip to content

[FEATURE] Rename the BlockFinality config fields so that different semantics get different names #1848

Description

@arnaubennassar

Feature Request

Is your feature request related to a problem? Please describe

Almost every component exposes a config field called BlockFinality (or a close variant), all typed aggkittypes.BlockNumberFinality, all documented with the same enum list — but they mean at least three different things:

Field What it actually controls
L1Multidownloader.BlockFinality Reorg-safety boundary: below it the multidownloader stops re-verifying headers and marks blocks final; above it is the "unsafe zone" that is re-checked every step. Shared by every syncer registered on it.
ReorgDetector.FinalizedBlock Same role as above for the legacy sync path.
L1InfoTreeSync.BlockFinality, BridgeSync.BlockFinality, L2GERSync.BlockFinality, ClaimSync.BlockFinality, BridgeServiceFinder.BlockFinality, BridgeTracker.L1BlockFinality / L2BlockFinality Sync target (SyncerConfig.ToBlock): how far the syncer wants blocks downloaded and processed. Does not affect reorg checking.
AggSender.BlockFinalityForL1InfoTree, AggSender.Validator.BlockFinalityForL1InfoTree Read-side selection: which L1 info tree root aggsender picks to prove against (must be acceptable to agglayer-node). Does not affect what is synced.

Because they share a name, operators (and code) reasonably assume they are the same thing and should be set to the same value. They are not, and setting them equal is actively harmful: lowering L1Multidownloader.BlockFinality to match a relaxed syncer target disables reorg detection above that tag for every syncer, while raising a syncer target to match the multidownloader's boundary just makes ingestion slower for no safety gain. The intended configuration is asymmetric (conservative reorg boundary, relaxed sync targets, conservative proof-root selection), and the naming hides that.

The confusion has also leaked into code: L1InfoTreeSync.Finality() returns the multidownloader's boundary in one mode and the syncer's target in the other (#1846), and aggsender's startup guard compares its own field against whichever one it gets.

Describe the solution you'd like

Give each semantic its own name and keep the shared type. Suggestion (names are a starting point):

  • Reorg-safety boundary → ReorgSafeBlock (or FinalityBoundary) on L1Multidownloader and ReorgDetector. Doc: "blocks at or below this tag are trusted not to reorg; blocks above it are re-verified".
  • Sync target → SyncUpToBlock (or TargetBlock) on all syncers. Doc: "the syncer downloads and processes blocks up to this tag; it does not affect reorg detection".
  • Read-side selection → keep the …For<Data> shape, e.g. AggSender.L1InfoTreeRootFinality. Doc: "the L1 info tree root selected for proofs is the latest one at or below this tag".

Additionally:

  • Keep the old mapstructure keys accepted for one release with a deprecation warning, then remove.
  • Update config/default.go comments so each default explains which semantic it is.
  • Make L1InfoTreeSync.Finality() (and any equivalent getters) unambiguous about which one they return, or split them (SyncTarget() vs ReorgSafeBlock()).

Describe alternatives you've considered

  • Documentation only (a table like the one above in docs/): helps, but the field name is what people see in the TOML and in error messages, and the same word keeps inviting "bind them together" proposals.
  • Binding the fields to a single value: rejected — it removes the safety margin the multidownloader's unsafe-zone machinery exists to provide.

Additional context

Related bugs that stem from the same conflation: #1846, #1847, #1706.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions