Task
Bring crates/dig-wallet onto the current chia-query line. It declares chia-query = "0.21.0" (crates/dig-wallet/Cargo.toml:133); current published is 0.24.0 — three minors, on the live wallet path.
Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3194
This is not a version-number change. Two of the three minors alter what a caller SEES without altering a signature, so a caret bump that compiles is not evidence the semantics still hold.
SEQUENCING — this does not pin 0.24.0
0.24.0 carries a HIGH defect: DIG-Network/chia-query#59 — the light-client drive loop can wedge on a superseded session, freezing the coin-state cache with no rearm signal, so a consumer cannot distinguish "nothing happened" from "wedged on a dead session".
dig-wallet is exactly the consumer that defect hurts: a silently frozen coin-state cache is a wallet that stops seeing money arrive. The analysis and the code work proceed now; the exact pin is taken as the last step, after #59 lands and publishes.
Context — the surface this crate actually calls
Measured on origin/main (c0e3597), not assumed:
| call site |
method |
delta that touches it |
sage/fallback.rs:397 |
get_coin_records_by_puzzle_hashes |
0.22.0 set agreement |
sage/fallback.rs:407 |
get_coin_records_by_hints |
0.22.0 set agreement |
sage/fallback.rs:517 |
get_coin_records_by_parent_ids |
0.22.0 set agreement |
sage/chain.rs:692, sage/spend.rs:366 |
push_tx |
0.24.0 refusal routing |
sage/spend.rs:440 |
wait_for_confirmation |
unchanged |
sage/fallback.rs:571 |
get_coin_spend_opt |
unchanged |
sage/chain.rs:556, fallback.rs:375 |
peak_height_opt |
unchanged |
sage/sources.rs, chain.rs:427 |
ChiaQueryProvider |
0.23.0 lineage walk |
Those three get_coin_records_by_* calls are the wallet's coin-discovery path — how it finds the user's money — and they are where the 0.22.0 change is felt. Signatures are unchanged (Result<Vec<CoinRecord>, _>), so the compiler says nothing; the behaviour behind them is now set-agreement with a fail-closed Err(SourcesDisagree) where the old code returned whichever source answered first.
The deltas, per version
- 0.21.0 → 0.22.0 —
Vec-returning router methods became fail-closed wrappers over _graded twins returning CorroboratedSet<T> with as_of_height. New SetAnswer<T> has no absence arm: an empty set is a value, disagreement is Err(SourcesDisagree), an uncorroborated set that coinset cannot second is Err(UncorroboratedPresence).
- 0.22.0 → 0.23.0 — the rival singleton lineage walk was deleted.
ChiaQueryProvider::resolve_singleton_lineage delegates whole to dig_chainsource_interface::resolve_singleton_lineage_via_walk, which reads coin_record as well as coin_spend and fails closed where the old copy returned an unconfirmed derived successor as the authenticated live tip.
- 0.23.0 → 0.24.0 — unscoped
FrameFanout::subscribe(capacity) removed; new mempool_refusal module; new SessionEndReason::OversizedFrame; push_tx retries one other peer on a view-dependent refusal and never consults coinset about a refusal.
Two things specific to this crate
1. mempool_refusal — adopt by re-export, delete the local copy. BUNDLE_INTRINSIC_REFUSALS (crates/dig-wallet/src/sage/chain.rs:241, 11 names) was moved byte-identical into chia_query::mempool_refusal so there would be one copy. Two copies of this list is a rival implementation of a money decision. Already tracked as #556, which this closes.
Also correct the is_definitive_rejection doc (crates/dig-wallet/src/sage/rpc.rs:2326-2335), which describes routing push_tx no longer performs.
TxStatus gets NO new field — dig-wallet builds it as a struct literal at chain.rs:876. Verified against 0.24.0: still no new field.
2. The subscribe removal is a no-op here. Measured: dig-node contains zero references to FrameFanout, FrameSubscription or subscribe_frames; its subscribe_store/unsubscribe_store are dig-node's own store subscriptions and unrelated. run_update_loop (sync.rs:1274) is a future adopter, not a current caller. Recorded so the next reader does not re-derive it.
The invariant most at risk
sage/corroborated_source.rs:312-317 documents a deliberate distinction between "the peers did not agree, or too few spoke" (→ Err) and "this source exposes no peak" (→ Ok(None)). That is NC-12 plurality, and a set-agreement adoption is exactly where it gets flattened by accident. Collapsing concurrently-queried peers to a single voice is a regression that looks like a clean refactor.
The adoption must preserve it and say how it was verified, with a test that fails without the adoption.
Constraints
- NC-12 — every dialled peer untrusted; content accepted because it verifies, never because a peer asserted it.
- §908 — the node signs nothing on the user's behalf; the user's spend key never enters it.
chia-* moves as a set or not at all. Do not bump the chia family to 0.48: chia-wallet-sdk 0.36.0 is latest and anchors it at ^0.36.1. Verified: chia-query 0.24.0 declares the same 0.36 line as 0.21.0, so this adoption moves no chia crate.
- §2.4b — bring this crate's
dig-*/chia-* deps to latest in the same PR.
- MSI caps on dig-node's version: MAJOR <= 255, MINOR <= 255, PATCH <= 65535.
Closable
Done when crates/dig-wallet/Cargo.toml declares the current non-#59 chia-query line, Cargo.lock resolves it once, the local BUNDLE_INTRINSIC_REFUSALS is gone in favour of the re-export, the is_definitive_rejection doc matches the shipped routing, the plurality distinction is shown preserved by a test, and cargo test --workspace --all-targets --all-features --locked is green.
Task
Bring
crates/dig-walletonto the currentchia-queryline. It declareschia-query = "0.21.0"(crates/dig-wallet/Cargo.toml:133); current published is 0.24.0 — three minors, on the live wallet path.Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3194
This is not a version-number change. Two of the three minors alter what a caller SEES without altering a signature, so a caret bump that compiles is not evidence the semantics still hold.
SEQUENCING — this does not pin 0.24.0
0.24.0 carries a HIGH defect: DIG-Network/chia-query#59 — the light-client drive loop can wedge on a superseded session, freezing the coin-state cache with no rearm signal, so a consumer cannot distinguish "nothing happened" from "wedged on a dead session".
dig-wallet is exactly the consumer that defect hurts: a silently frozen coin-state cache is a wallet that stops seeing money arrive. The analysis and the code work proceed now; the exact pin is taken as the last step, after #59 lands and publishes.
Context — the surface this crate actually calls
Measured on
origin/main(c0e3597), not assumed:sage/fallback.rs:397get_coin_records_by_puzzle_hashessage/fallback.rs:407get_coin_records_by_hintssage/fallback.rs:517get_coin_records_by_parent_idssage/chain.rs:692,sage/spend.rs:366push_txsage/spend.rs:440wait_for_confirmationsage/fallback.rs:571get_coin_spend_optsage/chain.rs:556,fallback.rs:375peak_height_optsage/sources.rs,chain.rs:427ChiaQueryProviderThose three
get_coin_records_by_*calls are the wallet's coin-discovery path — how it finds the user's money — and they are where the 0.22.0 change is felt. Signatures are unchanged (Result<Vec<CoinRecord>, _>), so the compiler says nothing; the behaviour behind them is now set-agreement with a fail-closedErr(SourcesDisagree)where the old code returned whichever source answered first.The deltas, per version
Vec-returning router methods became fail-closed wrappers over_gradedtwins returningCorroboratedSet<T>withas_of_height. NewSetAnswer<T>has no absence arm: an empty set is a value, disagreement isErr(SourcesDisagree), an uncorroborated set that coinset cannot second isErr(UncorroboratedPresence).ChiaQueryProvider::resolve_singleton_lineagedelegates whole todig_chainsource_interface::resolve_singleton_lineage_via_walk, which readscoin_recordas well ascoin_spendand fails closed where the old copy returned an unconfirmed derived successor as the authenticated live tip.FrameFanout::subscribe(capacity)removed; newmempool_refusalmodule; newSessionEndReason::OversizedFrame;push_txretries one other peer on a view-dependent refusal and never consults coinset about a refusal.Two things specific to this crate
1.
mempool_refusal— adopt by re-export, delete the local copy.BUNDLE_INTRINSIC_REFUSALS(crates/dig-wallet/src/sage/chain.rs:241, 11 names) was moved byte-identical intochia_query::mempool_refusalso there would be one copy. Two copies of this list is a rival implementation of a money decision. Already tracked as #556, which this closes.Also correct the
is_definitive_rejectiondoc (crates/dig-wallet/src/sage/rpc.rs:2326-2335), which describes routingpush_txno longer performs.TxStatusgets NO new field — dig-wallet builds it as a struct literal atchain.rs:876. Verified against 0.24.0: still no new field.2. The
subscriberemoval is a no-op here. Measured: dig-node contains zero references toFrameFanout,FrameSubscriptionorsubscribe_frames; itssubscribe_store/unsubscribe_storeare dig-node's own store subscriptions and unrelated.run_update_loop(sync.rs:1274) is a future adopter, not a current caller. Recorded so the next reader does not re-derive it.The invariant most at risk
sage/corroborated_source.rs:312-317documents a deliberate distinction between "the peers did not agree, or too few spoke" (→Err) and "this source exposes no peak" (→Ok(None)). That is NC-12 plurality, and a set-agreement adoption is exactly where it gets flattened by accident. Collapsing concurrently-queried peers to a single voice is a regression that looks like a clean refactor.The adoption must preserve it and say how it was verified, with a test that fails without the adoption.
Constraints
chia-*moves as a set or not at all. Do not bump the chia family to 0.48:chia-wallet-sdk 0.36.0is latest and anchors it at^0.36.1. Verified: chia-query 0.24.0 declares the same0.36line as 0.21.0, so this adoption moves no chia crate.dig-*/chia-*deps to latest in the same PR.Closable
Done when
crates/dig-wallet/Cargo.tomldeclares the current non-#59chia-queryline,Cargo.lockresolves it once, the localBUNDLE_INTRINSIC_REFUSALSis gone in favour of the re-export, theis_definitive_rejectiondoc matches the shipped routing, the plurality distinction is shown preserved by a test, andcargo test --workspace --all-targets --all-features --lockedis green.