Skip to content

Read the federation one-shot from Config #12 - #61

Merged
rssh merged 1 commit into
mainfrom
feat/wi-090-config-federation-one-shot
Aug 14, 2026
Merged

rssh merged 1 commit into
mainfrom
feat/wi-090-config-federation-one-shot

Conversation

@rssh

@rssh rssh commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Depends on FluidTokens/ft-bifrost-bridge#45 and lantr-io/binocular#31.

Three [cardano] keys — registry_bootstrap, treasury_bootstrap, ban_bootstrap — were the same outpoint under three names on every bridge deploy-bridge stood up, since all the genesis mints share one. An operator typed one number three times, and the only thing three keys could add was a disagreement between them.

All three are refused at load now, each naming the field that replaced it. The value arrives from the authenticated Config datum instead, and it cannot come from a file at all: federation_one_shot is #[serde(skip)], filled only from a chain read, so there is no back door to the value every federation script hash derives from.

A failure mode removed rather than guarded. The ban list used to be refusable as half-configured — registry keys set, ban bootstrap not. That guard mattered: the eligible roster is the registry MINUS active bans, so a node that cannot read the list enumerates a different DKG participant set, with nothing wrong in either node's log. That state is now unrepresentable — one published one-shot parameterizes both, so a node that can derive the registry can always derive the ban list — and the guard is gone along with the divergence it caught.

BanListSource::from_blueprint also stops demanding a blueprint path, which WI-066 had already made an override.

Encoding, pinned both ways. Aiken's V3 OutputReference is Constr(0, [B(txid), I(idx)]) — the tx id as bare bytes, with no TxId wrapper constructor. There is a positive test for that shape and a negative one refusing the V2-style wrapped encoding, which would otherwise derive a registry policy id matching nothing on chain.

587 lib tests plus the integration suites pass; clippy clean.

Three `[cardano]` keys — registry_bootstrap, treasury_bootstrap and
ban_bootstrap — were the same outpoint under three names on every bridge
deploy-bridge stood up, since all the genesis mints share one. An operator typed
one number three times, and the only thing three keys could add was a
disagreement between them. All three are refused at load now, each naming the
field that replaced it, and the value arrives from the authenticated Config
datum instead. It cannot come from a file at all: `federation_one_shot` is
`#[serde(skip)]`, filled only from a chain read, so there is no back door to the
value every federation script hash derives from.

One consequence is worth naming because it removes a failure mode rather than
guarding it. The ban list used to be refusable as half-configured — registry
keys set, ban bootstrap not — which mattered because the eligible roster is the
registry minus active bans, so a node that cannot read the list enumerates a
different DKG participant set with nothing wrong in either log. That state is
now unrepresentable: one published one-shot parameterizes both, so a node that
can derive the registry can always derive the ban list, and the guard is gone
along with the divergence it caught. `BanListSource::from_blueprint` also stops
demanding a blueprint path, which WI-066 had already made an override.
@rssh
rssh merged commit d014738 into main Aug 14, 2026
3 checks passed
@rssh
rssh deleted the feat/wi-090-config-federation-one-shot branch August 14, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant