Skip to content

feat(economic): 3.5b PR2 — peer-lineage validation: balance-free chain tip v2, replayable evidence, the iterative foreign walker - #736

Merged
cryptskii merged 1 commit into
mainfrom
feat/peer-lineage-validation
Aug 27, 2026
Merged

feat(economic): 3.5b PR2 — peer-lineage validation: balance-free chain tip v2, replayable evidence, the iterative foreign walker#736
cryptskii merged 1 commit into
mainfrom
feat/peer-lineage-validation

Conversation

@cryptskii

Copy link
Copy Markdown
Collaborator

3.5b PR 2 of 4, per the owner-approved plan, its four review rounds, and the PR2-specific fifth-round amendments (balance-map burn; iterative walks).

What a foreign verifier can now do

Walk and validate a peer's entire economic lineage from public material alone — register winners, content-addressed evidence, and P0–P6 — running the SAME advance_validated conjuncts any device runs, with every fact recomputed and nothing taken from the claimant.

The prerequisite: the balance map is burned out of the chain tip

The old relationship chain-tip preimage folded the device's whole balance_witness into every tip — a second authenticated balance representation beside R_econ (the dual-authority coupling the economic root exists to remove), and an exposure of the balance portfolio to any counterparty. Now: DSM/relationship-chain-tip/v2 commits succession facts only; the relationship use of DSM/state-hash is burned (State::compute_hash keeps it — one domain, one meaning); balance_witness is removed from the type, archive codec (v3), recovery wire, and proto (field reserved); one canonical preimage helper serves compute_chain_tip and the evidence verifier. The burn control test: identical succession facts derive identical tips across differing balance states.

Three evidence formats (strict codecs, core verifiers, seedless verification)

  • AuthorityEvidenceV1 — portable P0–P6 (AnchorPresentationV3 minus the vault anchor). OwnerAuthorityAtPosition now surfaces the recomputed network_id (P0 read it and dropped it; the recomputed value was unreachable everywhere), and resolve_for_trader gets its first production caller.
  • DsmSuccessorEvidenceV1 + sigma_dsm = Sign_AK(H(G ‖ DevID ‖ C_dsm+ ‖ op_digest)) — the signature that did not exist: nothing anywhere signed C_dsm+ (chain-state sig fields are dead in production, the faucet self-loop signed nothing, the substrate address held bare operation bytes). "This identity accepted this successor carrying this operation" is now checkable, not asserted.
  • PeerTransferAcceptanceEvidenceV1 + EkCertStepV1 — the recipient-produced sig_b IS the acceptance (A-side material alone is a proposal). EK certificate ancestry follows the signer through content-addressed steps, so role reversal and BLE cert-head advances chain correctly; nothing silently assumes A→A/B→B.

The walker and the exact peer-debit predicate

Iterative position loop; explicit in_progress cycle set; step budget + cross-identity depth cap where exhaustion is Incomplete, never Invalid; memoized conclusions. ProvenanceResolver now returns Result<_, PeerLineageFailure{Incomplete|Invalid|Quarantined}> — an outage and a forgery are different events and Option erased that. The ValidatedPeerDebit arm enforces the full frozen semantics: the peer's verified operation must be an online Transfer addressed to the consuming DevID, the named mutation must be THE debit that operation performed, and the acceptance bundle must verify with both EK chains rooted at the P0–P6-proven AKs and its receipt bound to the exact debit successor.

SDK

LiveRegisterResolver implements the walk over quorum register reads + re-hash-verified immutable fetches; peer_economic_lineage cache (schema 9 → 10; the verifier's own conclusions, never authority — an Invalid from a cached start discards the rows and re-walks); storage split (economic_faucet.rs is ticket-only; neutral accessors moved to economic_lineage.rs). Minimal faucet migration per the owner's correction: authority_position is now t0.digest() — it was a device-tree ROOT where P3 matches a transition DIGEST, so every walk over old manifests failed Incomplete even with perfect evidence — plus real AuthorityEvidenceV1 and signed DsmSuccessorEvidenceV1 at the manifest addresses; resume replays the frozen forms and re-signs nothing.

Latent defect found and fixed

The new e2e exposed that Operation::FaucetClaim shipped in B1 with to_bytes (tag 31) and no from_bytes arm — green across two merged boards because nothing ever decoded the bytes until foreign replay did. Fixed; captured as a refinement candidate (every new wire variant owes its inverse in the same PR).

Tests and mutation controls

economic_peer_evidence.rs (8): sigma_dsm round-trip + tamper refusals; the full acceptance bundle with real keys and per-binding refusals (wrong party, wrong transfer, wrong bilateral step, tampered sig_b); one-step EK ancestry + unhashed-substitution refusal; the peer-debit refusal clauses (Burn-cannot-fund, third-party transfer, not-the-operation's-debit, Incomplete vs Invalid taxonomy, addr-equality). SDK: a_faucet_lineage_is_walkable_by_a_foreign_verifier — live claim, then a from-zero foreign walk agreeing byte-for-byte with the local admission. Two compiling mutation controls run red and restored: Burn-admitted-as-funding, bilateral-step binding self-compares.

Boards (pinned 1.98.0, exact final tree)

cargo test --locked --workspace --exclude dsm_storage_node -- --nocapture --test-threads=1
  70 suites, 3853 passed / 0 failed  (dsm lib 1664/0, dsm_sdk lib 1776/0, 7 ignored)
cargo test --locked -p dsm_storage_node --no-default-features --features local-dev,strict
  270 passed / 0 failed
make lint                             exit 0
bash ci/production_safety_checks.sh   exit 0

Next: PR 3 — generalized admission producer + sender Transfer/Burn/CreateToken wiring (register-at-send, wire locator fields, full faucet seam migration).

…replayable evidence, the iterative foreign walker

3.5b PR2 of 4. A foreign verifier can now walk and validate a peer's entire
economic lineage from public material alone — registers, content-addressed
evidence, and P0-P6 — with the SAME advance_validated any device runs.

THE PREREQUISITE — the balance map is burned out of the relationship chain
tip. The old preimage folded the device's whole balance_witness into every
tip: a second authenticated balance representation beside R_econ (the exact
dual-authority coupling the economic root removes) that also exposed the
balance portfolio to any counterparty. New domain
DSM/relationship-chain-tip/v2 commits succession facts ONLY; the
relationship use of DSM/state-hash is burned (State::compute_hash keeps it —
one domain, one meaning); balance_witness is REMOVED from the type, the
archive codec (v3), the recovery wire and the proto (field reserved); ONE
canonical preimage helper serves compute_chain_tip and the evidence
verifier. R_econ is the sole authenticated online balance representation.

New evidence formats (strict codecs, core verifiers, all seedless):
- AuthorityEvidenceV1: portable P0-P6 (AnchorPresentationV3 minus the vault
  anchor). OwnerAuthorityAtPosition now SURFACES the recomputed network_id —
  P0 read it and dropped it; nothing in the tree ever reached the recomputed
  value. resolve_for_trader gets its first production caller.
- DsmSuccessorEvidenceV1 + sigma_dsm = Sign_AK(H(G ‖ DevID ‖ C_dsm+ ‖
  op_digest)): the signature that did not exist — nothing signed C_dsm+
  anywhere (the chain-state sig fields are dead, the faucet self-loop signed
  nothing, and the substrate address held bare operation bytes).
- PeerTransferAcceptanceEvidenceV1 + EkCertStepV1: the recipient-produced
  sig_b IS the acceptance (A-side material alone is a proposal); EK
  certificate ancestry follows the SIGNER through content-addressed steps —
  role reversal and BLE advances chain correctly, nothing assumes A→A/B→B.

The walker (dsm/src/economic/peer_lineage.rs): iterative position loop,
explicit in_progress cycle set, step budget + cross-identity depth cap
(exhaustion is Incomplete, NEVER Invalid), memoized conclusions. Per step it
recomputes everything: register winner self-verifies, manifest by content
address, P0-P6 recovers AK + committed network (resolve_for_trader enforces
the expected network and the canonical set), the claim key must BE the
proven AK, sigma_dsm must verify under it — then advance_validated.

The exact ValidatedPeerDebit predicate: the peer's VERIFIED operation must
be an online Transfer addressed to the consuming DevID whose named mutation
is THE debit that operation performed, and the acceptance bundle must
verify with both EK chains rooted at the P0-P6-proven AKs and its receipt
bound to the exact debit successor. ProvenanceResolver returns
Result<_, PeerLineageFailure{Incomplete|Invalid|Quarantined}> — an outage
and a forgery are different events, and Option erased that.

SDK: LiveRegisterResolver implements the walker over quorum reads +
re-hash-verified immutable fetches; peer_economic_lineage cache (schema
v10; the verifier's OWN conclusions, never authority — Invalid from a
cached start discards and re-walks); storage split (economic_faucet.rs is
ticket-only, neutral accessors in economic_lineage.rs). Minimal faucet
migration per the owner's correction: authority_position is now t0.digest()
(it was a device-tree ROOT where P3 matches a transition DIGEST — every
walk on old manifests failed Incomplete), real AuthorityEvidenceV1 and
signed DsmSuccessorEvidenceV1 at the manifest addrs, resume replays the
frozen forms.

Latent B1 defect found by the new e2e and fixed: Operation::FaucetClaim had
to_bytes (tag 31) and NO from_bytes arm — green across two merged boards
because nothing ever decoded it until foreign replay did.

Tests: economic_peer_evidence.rs (8 — sigma_dsm round-trip + tampers, full
acceptance bundle with real keys + per-binding refusals, one-step EK
ancestry + unhashed-substitution refusal, the peer-debit refusal clauses
incl. Burn-cannot-fund and Incomplete-vs-Invalid taxonomy);
a_faucet_lineage_is_walkable_by_a_foreign_verifier (SDK e2e: live claim →
foreign walk → byte-identical agreement with the local admission); the
chain-tip burn control (identical succession facts ⇒ identical tips across
differing balance states). Two mutation controls red-under-compiling-mutant
and restored: Burn-admitted-as-funding, bilateral-step-binding.

Boards (pinned 1.98.0, exact final tree): workspace 70 suites 3853/0
(dsm lib 1664/0, dsm_sdk lib 1776/0), dsm_storage_node 270/0, make lint
exit 0, production_safety_checks.sh exit 0.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant