docs(sofi): the recovery object closes the last slot, and a market b becomes constructible - #780
Merged
Merged
Conversation
…becomes constructible 2c-A froze the settlement bundle and stopped one field short on purpose: MarketTerms field 6 recovery_material is mandatory and its nested class was 2c-B's. Because it is mandatory there was no encodable market MarketTerms, therefore no encodable market SettlementBundle, therefore no conformant market b. This closes it. Substrate 0x0031 DsmSuccessorEvidence, seven fields: the six inputs the relationship chain tip commits, plus sigma_dsm. Its address is computed over canonical CCB bytes rather than prost, which is the point - the shipping object violated 2.10 twice, addressing itself over protobuf and using prost determinism as its canonical form. c_dsm_plus is NOT a field. It is doubly derivable - the chain tip recomputes it from the six inputs, and it equals trader_successor - so carrying it would state one fact three times, and the existing verifier already recomputes rather than trusting the carried value. Two foreign byte grammars are frozen as GRAMMARS, not as a function name: CloseAuthorizationPreimageV1 (discriminator 28, ten fields) and DlvSettleOperationPreimageV1 (discriminator 26, nineteen fields), each with exact widths, little-endian lengths, and length-prefixed 32-byte values - the opposite of CCB's big-endian digest32, stated so nobody conflates them. The shipping Operation::to_bytes is the current implementation of these grammars and is evidence of them, never the authority; a refactor that changes these bytes changes the protocol. Validity is ordered. The encoding-level conjunct on operation_bytes runs BEFORE the chain-tip equalities, because without it a producer who computed trader_successor over arbitrary bytes satisfies the equality trivially. And the set of cross-object comparisons 2c-B performs is exhaustive by construction - two equalities plus the syntax checks - so everything further is ValidDlvSuccessor and belongs to 2c-C. Encoding closure is not production enablement, and the amendment says so in its own voice. Four DlvSettle fields are caller-supplied and never checked: sigma is hard-coded zeros, settler_public_key is never compared with the key that actually signed. The chain-tip conjunct pins them so reconstruction is exact; nothing establishes they are meaningful. Also corrects a boundary three documents overstated. The owner-close shape was described as fully constructible under 2c-A alone; it is encodable given already-prepared close_authorization bytes, and the grammar for producing fresh ones is frozen here. Propagated to the registry sections 4, 5.19 and 7 and to two places in 2c-A. Size, measured from the frozen tables rather than estimated: the recovery object is 150,447 bytes for a pinned fixture, because a market bundle carries THREE SPHINCS+ signatures where an owner close carries one. That is 28.7% of the 512 KiB authenticated ingress cap - a 3.5x margin against the close's 10.4x - and it EXCEEDS the 128 KiB b0x envelope, which turns "settlement bundles do not traverse b0x" from a convenience into a load-bearing constraint.
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.
What this closes
2c-A froze the settlement bundle and stopped one field short on purpose.
MarketTerms(0x0033)field 6
recovery_materialis mandatory and its nested class was 2c-B's, so there was noencodable market
MarketTerms, therefore no encodable marketSettlementBundle, therefore noconformant market
b. Registry §6 named it as the single remaining encoding blocker.This closes it. A conformant market
bis now constructible.0x0031 DsmSuccessorEvidence— substrate, seven fieldsThe six inputs the relationship chain tip commits, plus
sigma_dsm. Its address is computed overcanonical CCB bytes, which is the whole point: the shipping object violated §2.10 twice —
addressing itself over prost bytes, and using prost determinism as its canonical form.
c_dsm_plusis not a field. It is doubly derivable — the chain tip recomputes it from the sixinputs, and it equals
trader_successor— so carrying it would state one fact three times, andthe existing verifier already recomputes rather than trusting the carried value.
Two foreign grammars, frozen as grammars
CloseAuthorizationPreimageV1(discriminator 28, ten fields) andDlvSettleOperationPreimageV1(discriminator 26, nineteen fields), each enumerated with exact widths. Both use little-endian
lengths and length-prefix their 32-byte values — the opposite of CCB's big-endian
digest32,stated explicitly so an implementation cannot conflate them.
That distinction is deliberate: it stops a future Rust refactor from silently changing a protocol
signing preimage. Freezing a CCB close preimage instead would have invalidated every existing close
signature.
Validity is ordered, and the comparison set is exhaustive
The encoding-level conjunct on
operation_bytesruns before the chain-tip equalities, becausewithout it a producer who computed
trader_successorover arbitrary bytes satisfies the equalitytrivially. And 2c-B performs exactly two cross-object comparisons plus the syntax checks —
exhaustive by construction, so everything further is
ValidDlvSuccessorand belongs to 2c-C.Encoding closure is not production enablement
Stated in the amendment's own voice. Four
DlvSettlefields are caller-supplied and never checked:sigmais hard-coded zeros, andsettler_public_keyis never compared with the key that actuallysigned. The chain-tip conjunct pins them so reconstruction is exact; nothing establishes they
are meaningful. Production acceptance stays gated on 2c-C.
A boundary three documents overstated
The owner-close shape was described as "fully constructible today" under 2c-A alone. It is
encodable given already-prepared
close_authorizationbytes — and the grammar for producing afresh one is frozen here. Corrected in registry §4, §5.19 and §7, and in two places in 2c-A.
Size — measured, not estimated
Encoding the objects from the frozen tables, with a pinned fixture:
A market bundle carries three signatures where an owner close carries one. Two consequences:
the market margin is about a third of the close's, and a market bundle does not fit the
b0xenvelope at all — which turns "settlement bundles never traverse
b0x" from a convenience into aload-bearing constraint. Same shape as the incident behind this repo's prior 413.
Verification
Namespace re-audited before writing (code tops out at
0x0030;0x0031/0x0032in no Rustconstant or proto). §2.8 audit: seven new field numbers, no reuse, no new burn — first ship at
schema 1. Both grammars encoded from the amendment's tables alone, with the close preimage's
arithmetic closing independently at 150 bytes and the cleared signature rendering as
00 00 00 00.Def 6.26 re-read at its line range. Self-contradiction sweep clean. §4 counts re-derived and sum to
22 live.
Owed at implementation, and stated rather than implied: byte-equality of both grammars against
a running
Operation::to_bytes, and the hostile malformed-operation_bytescase, both need a testbinary this docs-only change cannot add. The first commit implementing
0x0031must assert them —and if they differ, the amendment is wrong, not the code.
Documentation only.