Skip to content

Mirror-coin lifecycle: the pass runner, the state surface, the DHT pointer, and the real-machine proof #412

Description

@MichaelTaylor3d

Task

Land the impure half of dig-node#377 step 4 — the pass RUNNER — plus steps 6–8, which the parent PR names as children rather than deferrals.

The parent (#377, PR #379) landed everything that can be decided without I/O: the planner, the presence debounce, the spend builders, the scoped signer + OperatorWallet, the §25.7 switch, and mirror::pass::decide — a pure function over PassInputs. What is left is the part that touches a chain, a wallet, a clock and a socket.

Context

  • crates/dig-node-service/src/mirror/pass.rsdecide(&PassInputs) -> PassDecision is the whole decision. The runner's job is to GATHER PassInputs and EXECUTE PassDecision, not to re-decide anything.
  • crates/dig-node-service/src/mirror/signer.rsMirrorSigner::sign(&MirrorSpends, &RecordedSpend). Do not relax that signature. A RecordedSpend is obtainable only from SpendJournal::begin, which is what makes "every unattended spend is recorded" structural rather than conventional. If the journal is awkward to construct at bring-up, make construction work.
  • SPEC.md §25.4 (pass order, reclaims first, fee = 0 fallback, in-flight suppression), §25.6 (DHT pointer + epoch rollover), §25.8 (the per-(store, root) state surface, still marked PENDING).
  • crates/dig-node-service/src/mirror/pass.rs's BondState doc records a vocabulary divergence step 6 must reconcile: §25.8 gives withheld a NARROWER meaning (Relayed provenance) and names a reclaiming state the enum has no variant for. Reconcile at the interface; do not quietly rename the enum to match.

Scope — four pieces, in this order

  1. The runner. Start-up reconcile + round tick (dig_constants::MIRROR_ROUND_LENGTH_MS) + debounced presence deltas. Observe the Held set and dig_mirror_coin::list; call decide; execute reclaims first, then creates; audit begin → sign → broadcast → confirm; a process end with no outcome resolves to unresolved.
  2. Step 6, release-first: declare the §25.8 state method in dig-node-control-interface and publish 0.25.0 before the node adopts it, then serve it and add the dign verb (the §8.6 CLI-parity drift test will demand it). Unblocks Drive the out-of-funds OS notification: the decision is built and tested but has no caller dig-app#300 and Activity tab auditing all automated spends, plus an hourly OS notification when out of DIG/XCH dig-app#289.
  3. Step 7: dig-dht 0.12.1 → 0.15, attach unverified_mirror_coin_id at crates/dig-node-core/src/seams/dig_peer/dht.rs:423, re-announce on epoch rollover. §2.4b binds and the cascade is measured from the lock, never from the caret — dig-dht 0.13.0 took dig-nat 0.21 as a breaking bump, so check the dig-peer / dig-download / dig-peer-selector lines before assuming this is one line.
  4. Step 8 — the §2.6 acceptance, which is what closes the parent. A person on a real machine: fund the wallet with $DIG, serve a .dig, watch the coin appear (dign spends, coin id resolvable on chain at the epoch's required amount — the schedule starts at 1.000 DIG per (store, root)), delete the .dig, watch the collateral return. Not a green suite.

Evidence

Simulator (chia-sdk-test) e2e for piece 1: a bond created for a Held capsule, the capsule removed, the coin reclaimed, the full amount back, and the audit ledger showing the whole lifecycle. Then the real-machine run for piece 4.

Parent

#377 · epic https://github.com/DIG-Network/dig_ecosystem/issues/3166

Metadata

Metadata

Assignees

No one assigned

    Labels

    mvpgates the releasable MVP

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions