Skip to content

fix(mirror): mirror spends are signed under the DIG L2 genesis, so every mirror create and reclaim is rejected by Chia #447

Description

@MichaelTaylor3d

Task

crates/dig-node-service/src/mirror/lifecycle.rs:669 opens the operator wallet with
dig_constants::DIG_MAINNET.genesis_challenge() — the DIG L2 genesis
(0af981862a4df51f51ec59c312315d959931d917c375730b89b9e2b0854d1abf).

A mirror coin is a Chia L1 CAT. Its AGG_SIG_ME domain must be
ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb.

So every mirror create and reclaim is signed for the wrong chain. Chia's mempool returns
BAD_AGGREGATE_SIGNATURE -> TransactionAck.status = 3 -> ack: FAILED, deterministically,
from every peer. No mirror spend can land.

Evidence, measured on the live coin

Mirror coin 31e9077265a6254c32d3857a5cff3561c3b57d28e3bb7789b24173be6c89f14d
(1010 $DIG base units, block 9,224,641, unspent) — both variants of the same required signature:

required_signatures[chia-L1] key=a4ddda90... msg=0bafe268...||31e90772...||ccd5bb71...
required_signatures[dig-L2]  key=a4ddda90... msg=0bafe268...||31e90772...||0af98186...

AssertMyCoinId, AssertMyParentId, the CAT ring closing on itself, and CreateCoin of 1010
to the operator's own $DIG address all pass against chain. The signature is the ONLY unsatisfied
condition.

Regression window

Introduced by 5df3e34 (#419, merged 2026-08-30). v0.170.0 and v0.172.0 are clean;
v0.179.0 and v0.183.0 carry it.

Fix

Use MAINNET_CONSTANTS.genesis_challenge, matching every other chain-facing site in the tree
(dig-wallet/src/sage/service.rs:272, sage/peer_reads/dialed.rs:215). dig-constants is the
L2 chain's constants crate and has no business in an L1 CAT spend — that sentence goes in a
code comment so it is not re-introduced.

Acceptance

  1. A regression test that signs a real mirror reclaim and verifies the signature under the
    Chia L1 domain; it must fail today for the right reason.
  2. A class guard: the mirror agg_sig_data is not any dig_constants genesis.
  3. The live mirror coin above reclaimed on mainnet — spent = true on api.coinset.org,
    1010 base units back at the operator address.

Parent 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