Skip to content

ChainBlockMetadata has no borsh schema versioning #39

@hmoog

Description

@hmoog

Problem:

l1/types/src/chain_block_metadata.rs derives BorshSerialize/BorshDeserialize on ChainBlockMetadata with no version field. Borsh encodes structs positionally, so:

  • Adding a field silently breaks deserialization of any previously persisted bytes.
  • Reordering fields silently changes the wire format with no detection.

This matters because consumers persist these checkpoints across restarts (the bridge expects config.root / config.tip to be supplied as Checkpoint after a process restart, and the natural way to do that is to serialize with borsh). Once data is in the wild, schema evolution becomes a migration problem.

Options to consider:

  1. Prepend a version: u8 field and gate decoding on the supported set. Cheapest forward-compat option.
  2. Document the type as wire-stable append-only (// borsh order is wire-stable, append-only - never reorder, only append) and accept that schema changes require an explicit migration.
  3. Wrap in a versioned envelope (enum ChainBlockMetadataV { V1(...) }) to give explicit per-version codecs.

Decide before any consumer persists ChainBlockMetadata bytes - afterwards is a migration.

Related: review pass on l1/types/src/chain_block_metadata.rs noted that field order is currently interleaved (header-derived / parent-derived / lane-state). Reordering would aid readability but is wire-breaking; bundling a reorder with the versioning decision is natural.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions