You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
dash: versioned payload types that add versions without breaking earlier encodings #1146
Payloads whose layout depends on their version (CbTx v4, ProUpServTx/ProUpRegTx v3, ProRegTx v3, ...) model the version-dependent parts as Option fields gated by if version >= N. Every new version forces hand-written consensus, bincode and serde impls to avoid breaking the formats of earlier versions (see #1137, #1138), and nothing ties a field to the versions it belongs to.
Design a versioned type system that makes adding a version simple and safe:
Each version's layout is a type (e.g. enum variants per version), and the version picks the variant automatically when (de)serializing.
Adding a version means adding a variant, without touching or re-encoding earlier ones.
Consensus, bincode and serde stay backward compatible by construction, not by hand-written impls.
Protocol version (the payload's version): its consensus encoding is defined by Core and never changes.
Storage format version (our serde/bincode encoding): ours, so it can evolve.
With a format marker in the persisted data (e.g. Stored::{V0(OldShape), V1(NewShape)} with From conversions and #[serde(from, into)]), a type can read any older format into the current type and always write the latest one, migrating lazily instead of freezing the old shape forever.
The marker is required: some format changes can't be told apart by reading (e.g. the PlatformNodeId byte order). Data persisted without one would be read as format 0. Older binaries won't read newer formats.
Activity
ZocoLini commentedon Oct 8, 2026
Keep two versions apart in the design:
version): its consensus encoding is defined by Core and never changes.With a format marker in the persisted data (e.g.
Stored::{V0(OldShape), V1(NewShape)}withFromconversions and#[serde(from, into)]), a type can read any older format into the current type and always write the latest one, migrating lazily instead of freezing the old shape forever.The marker is required: some format changes can't be told apart by reading (e.g. the
PlatformNodeIdbyte order). Data persisted without one would be read as format 0. Older binaries won't read newer formats.