Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 33 additions & 19 deletions registry/chains/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,39 @@ recorded nowhere.

## Which chains belong here

Split by how long the chain lives, not by convenience.

**Commit here: pacific-1 and atlantic-2.** They are never re-genesised, so a
recorded address stays true. Committing puts the address in a reviewed pull
request and in a signed image, next to the bindings that encode against it.

**Supply by `--chain-file` instead: arctic-1, and every devnet.** arctic-1 is
re-genesised on a devnet cadence, and each re-genesis changes its genesis hash
and invalidates a committed entry. Recovering from that here means a sei-load
pull request, a CI build, and a hand-edited image pin in each cell — where the
three canary cells are pinned independently on purpose. A file the deployment
supplies recovers with one reconcile.

The cost of supplying it is real and worth stating: anyone who can edit that
source can point a run at a contract of their choosing, and the code-hash check
cannot catch it — the check proves the address holds the code the *file*
recorded, not that the code is ours. The canary mounts a funded key, so the loss
is bounded by that key's balance. That bound is the reason this is acceptable for
arctic-1 and not for pacific-1.
Split by whether a recorded address stays true, not by what we call the chain.

**Commit here: pacific-1, atlantic-2 and arctic-1.** A recorded address stays
true for as long as the chain does. Committing puts it in a reviewed pull request
and in a signed image, beside the bindings that encode against it.

arctic-1 differs from the other two in one way. It is ours, so we can
re-genesise it. Committing it anyway is a decision rather than an oversight. We
control that re-genesis and intend not to do it, and the alternative costs more
than the risk.

That alternative is supplying the file from a deployment. Anyone who can edit
that source then points a run at a contract of their choosing. The code-hash
check cannot catch it: the check proves the address holds the code the *file*
recorded, not that the code is ours. Committing removes that exposure. It also

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] "Committing removes that exposure" overstates what committing achieves. --chain-file is still accepted (main.go:71, config.ChainFiles), and Registry.add replaces an entry under the same chainID+genesisHash key, so a supplied file still wins over the compiled-in one (registry/registry.go:132-144; main.go:71 documents "a later file wins"). Anyone who can edit the deployment source can therefore still redirect an arctic-1 run to a contract of their choosing, and the code-hash check still cannot catch it. Committing removes the need to supply a file and gives a reviewed default, but the override path remains — worth stating as the residual trust boundary rather than claiming the exposure is gone.

puts every address change through review.

A re-genesis changes the chain's genesis hash, and the committed entries stop
matching. A run then deploys its own contracts, which is what every run did
before this directory held a file. Recovery is therefore a pull request here, at
whatever pace suits, rather than an outage.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[suggestion] The graceful-degradation claim holds only when the profile's genesisHash is updated at the same time as the re-genesis. genesisHash comes from the profile config (config/config.go:25, read at generator/prepare.go:233), not from the chain. If a profile still names the pre-re-genesis hash, Resolve matches the stale committed entry, Verify reads no code at the recorded address, and the run fails at startup with MismatchError — whose own message names re-genesis as "the usual cause" (registry/resolve.go:42-48). That is the outage this paragraph says will not happen; "a run then deploys its own contracts" is only reached once the profile carries the new hash. Since the profiles live outside this repo, recovery is still a coordinated profile change, which weakens the trade-off argument as written.


One case does not degrade quietly. A recorded address whose code has changed
fails Verify, and the run stops at startup rather than binding something else.

A profile that reads a committed entry has to name the chain's `genesisHash`. The
registry keys on it, so a profile that omits it matches nothing. A run that omits
it, on a chain the registry describes, fails at startup and says why. It does not
redeploy on every restart in silence.

**Supply by `--chain-file` instead: a chain that outlives a run but not a
release.** The flag stays for that case, and for bootstrapping a chain before
anyone commits its file here.

**Never commit an ephemeral chain's file.** It disappears after the run, so the
entry could never verify again.
Expand Down
Loading