Skip to content

A transient degraded source seals a permanently uncorrectable low collateral requirement — fix before #377 #405

Description

@MichaelTaylor3d

Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3173
Found by: the PR #401 security gate
Sequencing: this MUST be resolved before #377 lands.

The defect

A transient degraded chain read can write a permanently uncorrectable low collateral
requirement.

Three properties compose into it, each individually reasonable:

  1. The census bypasses NC-12 corroboration that exists in the same struct. ChainTransport prefers
    peer_reads — agreement across concurrently-queried peers — for the wallet's own reads
    (chain.rs:343-352). The census instead goes through ChiaQueryProvider, whose
    peak_height/coin reads resolve coinset-first (coinset_fallback_enabled: true by default,
    sources.rs:116-118), degrading to an unagreed peer-tracked value when coinset is unreachable.
  2. put is immutable and never lets a later record supersede a Censused one. That is deliberate
    and correct against a peer — it is what stops a lying peer overwriting a node's own census.
  3. catch_up never re-censuses an epoch it has already recorded. Also deliberate: it is what makes
    the walk idempotent and cheap.

Together: a source that is briefly wrong writes a record that is wrong forever, and the two
mechanisms that would normally repair it are the same two mechanisms protecting it from a peer.

Why it is not gating PR #401, and why it becomes serious the moment #377 lands

Today every record is (stores: 0, owners: 0, locked: 0) and that is the correct answer — nothing
has ever minted a mirror coin in production, because the creation path is
#377, still an open draft PR. A degraded read that
produces zero today produces the same number a healthy read produces.

#377 is exactly what makes it exploitable. Once real mirror coins exist, a degraded read produces a
count lower than the truth, the requirement is derived from that count, and the record is sealed. That
is the down direction — the direction the user named explicitly as the threat this model must resist,
and the direction in which a wrong answer under-collateralises the network rather than over-charging it.

An attacker does not need to sustain the degradation. One badly-timed window per epoch is enough, and
epochs are seven days apart.

What a fix has to preserve

Any remedy must keep the two properties it is threading between:

Three shapes worth considering, none decided:

  1. Route the census through the same NC-12 corroboration the wallet uses, so a degraded source cannot
    produce a confident low count in the first place. Most direct; the cost is that census reads become
    as expensive as wallet reads.
  2. Record the read's provenance in the record and permit a self-supersession when a later census
    ran against a strictly better-corroborated source. Preserves peer immutability, since only this node's
    own census may supersede — but "strictly better" needs a total order that does not currently exist.
  3. Refuse to record at all when the source is degraded, leaving the epoch unknown. Fails closed and
    matches this family's established preference for an honest unknown over a confident figure — but an
    epoch left unrecorded interacts with the walk's no-gaps property and with retention.

Acceptance

A census run against a degraded or single-source chain view cannot seal a requirement that a healthy
run would have computed differently — either because it does not record, or because it can later be
superseded by this node's own better-corroborated census. Peer records still cannot supersede a
Censused record, and the walk stays idempotent.

Verify by probe, not by reading: the PR #401 gate demonstrated that a census result can be moved by
controlling the source, which is the same lever this defect uses. A test that degrades the source mid-walk
and asserts the outcome is the direct proof.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:businessa person can DO something new, or money moves, or a shipped surface stops lying to themmvpgates the releasable MVP

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions