Repository navigation
feat(ccb): the VaultStateV2 encoder, checked by an implementation that shares no code - #690
Merged
cryptskii merged 1 commit intoAug 21, 2026
Conversation
…t shares no code
Implements docs/papers/ccb-object-registry.md for exactly the transitive
encoding closure of VaultStateV2 — 0x0001, 0x0002, 0x0004, 0x0005, 0x0007,
0x0009, 0x000A — and nothing else. The routing and settlement classes are
absent on purpose: they are still blocked in the registry, and a placeholder
encoder for a class whose field table does not exist would be the
encoder-defines-the-protocol failure the ordering exists to prevent. Encoding
only the closure also leaves 2b and 2c room to land without churning this code.
The registry is the authority and this module implements it, not the reverse.
c_n = H(DSM/vault-state || CCB(V_n)) and h_0 = H(DSM/vault-state-parent/
genesis/v2 || vault_id) get their domain tags; h_n = c_{n-1} follows.
There is deliberately no decoder here. CCB is not self-describing, so a decoder
written beside the encoder would share its assumptions and prove nothing.
tests/ccb_conformance.rs is the independent side. It is an integration test, so
the pub(crate) writers are unreachable by construction, and it rebuilds every
byte from the registry text using a different shape — explicit concatenation
rather than a shared push buffer — so a transcription slip cannot be common to
both. It also PARSES CCB(V_n) back into fifteen fields, which is the only thing
that demonstrates the bytes are uniquely readable.
That parser exists for one boundary in particular. Field 14 nests StorageSet in
its frozen envelope-less layout and field 15 is a bare u32. If a generic
"nested object gets an envelope" helper ever wrapped S, the bytes would remain
perfectly deterministic and stop being normative. The test asserts the reader
consumes exactly its input with nothing trailing, that q reads as 4, and that
splicing an envelope in front of S is detectable rather than silent.
Both guards are mutation-tested. Wrapping S in the generic envelope turns 4 of
7 red, including the boundary test written for it. Skipping the absent-optional
marker turns 3 of 7 red. Restored, all 7 green.
Validity conditions refuse rather than repair, per Req 3.2: an unordered or
equal token pair is rejected instead of swapped, a duplicate set element is
rejected instead of collapsed, and fee_bps at or above the denominator is
rejected. Silently repairing any of them would map two distinct logical inputs
onto one byte string.
Vectors cover genesis, a market successor and the terminal close, and a
populated encumbrance set — the last so the nested element encoding and its
ordering are exercised rather than left at an empty set, which is where a
second implementation is most likely to differ. Insertion order is proven not
to survive into the bytes.
The storage_set_id construction is checked to be unchanged by reaching it
through this module, since every deployed vault's anchor already commits one.
Local gate: fmt clean, clippy --all-targets -D warnings clean, cargo test -p dsm
--lib 1644 passed, conformance 7 passed.
cryptskii
merged commit Aug 21, 2026
0646830
into
docs/rev15-release-policy-and-vault-state
16 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 2+3+4 of the registry's ordering, in one PR because the encoder and its independent check are only meaningful together. Anchor V2 is the next PR, deliberately separate.
Scope: the closure, and nothing else
0x0001,0x0002,0x0004,0x0005,0x0007,0x0009,0x000A— exactly whatc_ndepends on.TradeIntent,ReferenceWindow,B_MandMare not encoded despite being specified, because they are not in the closure. The five blocked routing/settlement classes get no placeholder encoders at all — that would be the encoder-defines-the-protocol failure the ordering exists to prevent, and it keeps 2b/2c free of churn here.No decoder on the production side
CCB is not self-describing. A decoder written beside the encoder would share its assumptions and prove nothing, so parsing lives only in the independent implementation.
The independent check
tests/ccb_conformance.rsis an integration test, so thepub(crate)writers are unreachable by construction. It rebuilds every byte from the registry text in a different shape — explicit concatenation rather than a shared push buffer — so a transcription slip cannot be common to both.It also parses
CCB(V_n)back into fifteen fields, which is the only thing that demonstrates the bytes are uniquely readable.The boundary that matters
Field 14 nests
StorageSetin its frozen envelope-less layout; field 15 is a bareu32. If a generic "nested = envelope" helper ever wrappedS, the bytes would stay perfectly deterministic and stop being normative.The parser asserts it consumes exactly its input with nothing trailing, that
qreads as4, and that splicing an envelope in front ofSis detectable rather than silent.Mutation-tested
Sin the generic envelopeRefuse, don't repair
Per Req 3.2 — an unordered or equal token pair is rejected rather than swapped, a duplicate set element rejected rather than collapsed,
fee_bps ≥ 10_000rejected. Silently repairing any of them maps two distinct logical inputs onto one byte string.Vectors
Genesis, market successor, terminal close, plus a populated encumbrance set — the last so the nested element encoding and its §2.4 ordering are exercised rather than left at an empty set, which is where a second implementation is most likely to differ. Insertion order is proven not to survive into the bytes.
storage_set_idis checked unchanged when reached through this module, since every deployed vault's anchor already commits one.Local gate
cargo fmt --all -- --checkcleancargo clippy --all-targets -- -D warningscleancargo test -p dsm --lib— 1644 passed, 0 failedcargo test -p dsm --test ccb_conformance— 7 passed, 0 failed