Task
A mirror coin advertises where its store can be fetched from. dig_mirror_coin::create refuses
an advertisement with no URL — "a mirror must advertise at least one URL" — and a mirror coin is
the only thing that makes a held (store, root) discoverable. This node has no configured public
name, so NodeMirrorEffects::create refuses by name ahead of any chain read and
server::spawn_mirror_passes passes an empty URL set.
With dig-node#421 landed, this is the last thing between a funded operator wallet and a bond
actually being created.
Why it is not a one-liner
The URL is not a display string; it is published on chain in the coin's memos and is what a peer
uses to fetch. So the question is a real one and belongs to whoever answers it:
- What does this node advertise? Its
dig.local name is useless to a stranger. rpc.dig.net is
a shared gateway, not this node. A public DNS name or reachable address is operator knowledge, and
config::is_self_upstream already documents that the node cannot decide it by resolver alone.
- Configured, or derived? An operator-set value is honest and needs a config surface. A derived
one risks advertising an address nobody outside can reach — which stakes real $DIG on a claim the
node cannot keep, and §25 penalises exactly that.
- More than one?
MirrorAdvertisement.urls is a Vec, and IPv6-first (CLAUDE.md §5.2) suggests
more than one entry is the normal case rather than the exception.
- Changing it later. A mirror coin's URLs are fixed at create. Moving a node means reclaiming and
re-creating, which costs a round trip and a fee — worth knowing before the shape is locked.
Scope
A node that CAN advertise does; one that cannot says so and does not create. The refusal that exists
today is the correct default and must survive: publishing an unreachable URL is worse than not
publishing, because it locks collateral against a claim that will be penalised.
Context
crates/dig-node-service/src/mirror/lifecycle.rs — NodeMirrorEffects::create, the named refusal.
crates/dig-node-service/src/server.rs — spawn_mirror_passes, where the empty Vec is passed
with the reason stated inline.
crates/dig-node-service/src/config.rs — is_self_upstream, on why a public name is not derivable.
SPEC.md §25.
Also still open on the same path (not this ticket): spawn_mirror_passes passes
broadcaster: None, and DIG_WALLET_ENABLE_LIVE_BROADCAST must be on for a signer to exist.
Parent
#412 ·
#377 ·
epic https://github.com/DIG-Network/dig_ecosystem/issues/3166
Sibling
#421 — the operator-scoped selector, which this
unblocks the other half of.
Task
A mirror coin advertises where its store can be fetched from.
dig_mirror_coin::createrefusesan advertisement with no URL — "a mirror must advertise at least one URL" — and a mirror coin is
the only thing that makes a held
(store, root)discoverable. This node has no configured publicname, so
NodeMirrorEffects::createrefuses by name ahead of any chain read andserver::spawn_mirror_passespasses an empty URL set.With dig-node#421 landed, this is the last thing between a funded operator wallet and a bond
actually being created.
Why it is not a one-liner
The URL is not a display string; it is published on chain in the coin's memos and is what a peer
uses to fetch. So the question is a real one and belongs to whoever answers it:
dig.localname is useless to a stranger.rpc.dig.netisa shared gateway, not this node. A public DNS name or reachable address is operator knowledge, and
config::is_self_upstreamalready documents that the node cannot decide it by resolver alone.one risks advertising an address nobody outside can reach — which stakes real $DIG on a claim the
node cannot keep, and §25 penalises exactly that.
MirrorAdvertisement.urlsis aVec, and IPv6-first (CLAUDE.md §5.2) suggestsmore than one entry is the normal case rather than the exception.
re-creating, which costs a round trip and a fee — worth knowing before the shape is locked.
Scope
A node that CAN advertise does; one that cannot says so and does not create. The refusal that exists
today is the correct default and must survive: publishing an unreachable URL is worse than not
publishing, because it locks collateral against a claim that will be penalised.
Context
crates/dig-node-service/src/mirror/lifecycle.rs—NodeMirrorEffects::create, the named refusal.crates/dig-node-service/src/server.rs—spawn_mirror_passes, where the emptyVecis passedwith the reason stated inline.
crates/dig-node-service/src/config.rs—is_self_upstream, on why a public name is not derivable.SPEC.md§25.Also still open on the same path (not this ticket):
spawn_mirror_passespassesbroadcaster: None, andDIG_WALLET_ENABLE_LIVE_BROADCASTmust be on for a signer to exist.Parent
#412 ·
#377 ·
epic https://github.com/DIG-Network/dig_ecosystem/issues/3166
Sibling
#421 — the operator-scoped selector, which this
unblocks the other half of.