Task
chain.rs:111 with_sources is dead code that constructs peer_reads: None — a ChainTransport
whose peak_height therefore takes the oracle-first router path instead of the peer round.
Either delete it, or make it take the peer reads, before anyone calls it.
Why this is worth a ticket rather than a comment
The NC-12 property being enforced elsewhere in this crate is that a chain fact is agreed across several
concurrently-queried, independently-held peer sessions — never determined by a single source.
service.rs:173 is the only production ChainTransport construction, and it attaches
with_peer_reads, so chain.rs:200 always short-circuits into the peer round; an empty draw returns
None rather than falling back to an oracle read. That is the property, and it holds today only
because the other constructor is unused.
with_sources is a loaded gun with the safety off. The first caller who reaches for it gets a
transport that silently answers peak_height from one endpoint, with nothing in its name or signature
saying so — and it will look like the obvious constructor to use.
This is the same shape as the defect the NC-12 work just fixed one layer up: two "independence groups"
that both resolved to api.coinset.org, so a 2-of-2 quorum was satisfiable by one endpoint with zero
peers. A guard is only as good as the paths that cannot route around it.
Context
Done condition
Either with_sources no longer exists, or it cannot produce a transport with peer_reads: None —
plus a test that fails if a future edit reintroduces a single-source peak_height path.
Prefer deletion. A constructor kept "in case someone needs it" is exactly how this returns.
Scope
Only this constructor. Do not widen into the rest of chain.rs.
Effort
Low — but the decision (delete vs. require peer reads) is worth a moment, because deleting is only
correct if genuinely nothing needs a source-only transport. Grep before deciding.
Task
chain.rs:111 with_sourcesis dead code that constructspeer_reads: None— aChainTransportwhose
peak_heighttherefore takes the oracle-first router path instead of the peer round.Either delete it, or make it take the peer reads, before anyone calls it.
Why this is worth a ticket rather than a comment
The NC-12 property being enforced elsewhere in this crate is that a chain fact is agreed across several
concurrently-queried, independently-held peer sessions — never determined by a single source.
service.rs:173is the only productionChainTransportconstruction, and it attacheswith_peer_reads, sochain.rs:200always short-circuits into the peer round; an empty draw returnsNonerather than falling back to an oracle read. That is the property, and it holds today onlybecause the other constructor is unused.
with_sourcesis a loaded gun with the safety off. The first caller who reaches for it gets atransport that silently answers
peak_heightfrom one endpoint, with nothing in its name or signaturesaying so — and it will look like the obvious constructor to use.
This is the same shape as the defect the NC-12 work just fixed one layer up: two "independence groups"
that both resolved to api.coinset.org, so a 2-of-2 quorum was satisfiable by one endpoint with zero
peers. A guard is only as good as the paths that cannot route around it.
Context
crates/dig-wallet/src/sage/chain.rs:111—with_sources, the dead constructorcrates/dig-wallet/src/sage/chain.rs:200— the peer-round short-circuit thatpeer_reads: Some(..)reachescrates/dig-node-service/src/service.rs:173— the only production construction, which does it correctlyrouter.rs:711-717—get_blockchain_state, whose first line is "Try coinset first for full state"Done condition
Either
with_sourcesno longer exists, or it cannot produce a transport withpeer_reads: None—plus a test that fails if a future edit reintroduces a single-source
peak_heightpath.Prefer deletion. A constructor kept "in case someone needs it" is exactly how this returns.
Scope
Only this constructor. Do not widen into the rest of
chain.rs.Effort
Low — but the decision (delete vs. require peer reads) is worth a moment, because deleting is only
correct if genuinely nothing needs a source-only transport. Grep before deciding.