Skip to content

Protocol upgrade invariant: canonical state must remain sufficient for future semantics #5445

Description

@tacticalnoot

While reviewing #5423, a more general upgrade invariant surfaced that seems worth making explicit Core-wide.

For valid histories H1, H2, if protocol version v maps them to the same canonical Core state:

C_v(H1) == C_v(H2)

then every later protocol rule must treat them identically unless an earlier upgrade canonically preserved the missing distinction.

Otherwise restart/catchup/replay cannot derive the new semantics from authoritative state alone.

Concrete #5423 example: AccountEntryExtensionV3.seqTime stores whole seconds. Origins 10.001s and 10.999s therefore collapse to the same persisted account state today, while a future millisecond minSeqAge could require opposite answers. A migration added later cannot reconstruct which origin happened.

Safe rollout shape:

current semantics -> preserve richer state with no behavior change -> later version may consume it

For already-coarse legacy state, either keep legacy interpretation or replace it through a new authoritative write that records the richer state.

This looks reusable beyond time: XDR refinements, protocol-version transitions, replay/catchup requirements, randomness locks, and any future feature that wants to add meaning to information older Core intentionally discarded.

Potential regression pattern: construct pairs of valid pre-upgrade histories that serialize to identical canonical state; any post-upgrade observable must remain identical unless the distinguishing information was canonically preserved before activation.

Would this be useful as a standard protocol-upgrade test/invariant?

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

    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