Files
zeekayandHanzo Dev 34e3edcba3 staker: derive a validator set from the mnemonic
Hanzo mainnet lost five validator identities this week. Not the keys alone — the
genesis still named the NodeIDs, and there was no seed behind them, so the names
were unrunnable and the set had to be rebuilt around whatever keys happened to
still exist. Staking identities were minted with crypto/rand, one invocation per
validator, and kept only as files; when the files went, the identity went.

Derived from the mnemonic instead, a set is a function of the seed and the
network. HKDF over the BIP-39 seed, domain-separated by network and by role, so
one seed's Hanzo validators are disjoint from its Zoo validators and a TLS
identity can never also be a BLS one. Nothing shares material with the account
path that funds the genesis alloc.

WHICH NAME SURVIVES A SEED, AND WHICH DOES NOT. A post-quantum profile derives
the NodeID from the ML-DSA public key, and FIPS 204 keygen consumes a fixed
seed, so that name is a function of the mnemonic. A classical profile derives it
from the TLS CERTIFICATE, and that is not reproducible: Go signs ECDSA with a
hedged nonce and randutil.MaybeReadByte consumes entropy only some of the time,
deliberately, so the same key and template give a different certificate and a
different NodeID on every run. Measured, and pinned by a test that fails if a
future Go makes it stable.

So the mnemonic is a complete backup of a validator set on the PQ path and only
of its keys on the classical one. That is an argument for the PQ profile, and it
is stated here rather than discovered again the next time a cluster is lost.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 14:09:48 -07:00
..