This document is the canonical procedure for generating the keys that pin a
new quip-testnet bootnode operator into the genesis preset. Use it when
rotating an operator or onboarding additional slots beyond the initial three
shipped in v0.2.0.
Secret material never leaves the operator host. The mnemonic and the libp2p
nodekeyfile are the only secrets in the process. Only thepublic-bundle.txtblock is submitted back to the release coordinator.
-
Clone
quip-validatorat the release-candidate tag. -
Build the node binary:
cargo build --release -p quip-network-node
On macOS,
.cargo/config.tomlalready wires the rpath needed to resolvelibclang.dylib(required by the bindgen-drivenlibrocksdb-sysbuild script). No manualLIBCLANG_PATHexport is needed.
For each operator slot, run the helper script with the slot index (and optionally the bootnode hostname). The script wraps the full procedure:
scripts/derive-operator-keys.sh 1
scripts/derive-operator-keys.sh 2 bootnode-2.testnet.quip.network
scripts/derive-operator-keys.sh 3Each run produces, under quip-testnet-keys/operator-<N>/:
| File | Permissions | Purpose |
|---|---|---|
mnemonic |
0600 |
BIP39 master secret (back up, never share) |
nodekey |
0600 |
libp2p secret bytes; mount via --node-key-file on the bootnode host |
public-bundle.txt |
0644 |
Public peer-id, multiaddr, BABE/GRANDPA/TX public bytes |
The script auto-creates a .gitignore in quip-testnet-keys/ containing *
so secrets cannot accidentally be git add'd. The repo's .gitignore also
excludes the entire directory.
Send the contents of public-bundle.txt for each operator to the release
coordinator over a secure channel (signed message in the ops chat, encrypted
mail, etc.). The bundle is:
operator: <N>
hostname: <dns>
multiaddr: /dns4/<dns>/tcp/30333/p2p/<peer-id>
peer_id: 12D3KooW…
babe_pub: 0x… # 929 bytes hex (sr25519 + FN-DSA-512, H4)
grandpa_pub: 0x… # 929 bytes hex (ed25519 + FN-DSA-512, H2)
tx_account_ss58: 5…
tx_account_hex: 0x… # 32 bytes
The coordinator commits the public bytes into
runtime/src/genesis_quip_testnet/ (BABE/GRANDPA, one hex file per pubkey)
and into the inline tx_account_from_hex(...) calls in
the regenerated quip_testnet preset in
runtime/src/genesis_config_presets.rs.
Fresh quip-testnet genesis appoints the three existing operator transaction
accounts as Foundation members. The two-thirds threshold therefore requires
at least two operators. Validator stashes and consensus keys are unchanged.
The preset assigns operator 1 as sudo, faucet authority, and Ising spec builder:
no dedicated faucet public account or agreed sudo custody replacement is
committed yet. Changing those genesis defaults requires updated public role
assignments. After launch, Foundation can rotate the faucet authority on-chain
with faucetOps.set_authority, without editing genesis or committing new key
material. Editing a genesis preset does not migrate an existing chain or update
its Foundation membership.
For a fresh spec-119 testnet, complete this operational sequence:
- Before deploying the faucet service, pass a Foundation motion (two of
op1/op2/op3) for
faucetOps.set_authority(Some(<dedicated faucet account>))and fund that account. - Configure
QUIP_FAUCET_FAUCET_KEYwith the dedicated key only. Never put operator 1's key there or on the faucet host: it still controls sudo and a Foundation membership. The preset authority is a bootstrap assignment, not a faucet deployment credential. - Once custody signatories are agreed, use
sudo.set_key(<2-of-3 multisig>). Later, remove sudo withsudo.remove_keyonly after the governed runtime upgrade path has been proven.
Step 1 requires no committed key material and does not depend on changing the
preset's TODO(ops) assignments.
The --chain rehearsal preset uses four development validators (Alice, Bob,
Charlie, Dave) and keeps the minimum validator count at four. Foundation uses
Alice, Bob, and Charlie; Eve is the separate faucet authority. Sudo is the
2-of-3 Multisig::multi_account_id derived from the sorted H4 transaction
AccountIds of Alice, Bob, and Charlie. Eve and the multisig account are endowed
alongside the validators so they can exercise their roles immediately. Alice
remains the Ising spec builder. These public development seeds demonstrate
quorum control only; they are not independent production custody keys.
The small development/local presets retain Alice for their existing roles.
Runtime 117 launches from fresh genesis after wiping the previous chain state; it is not an in-place runtime upgrade. The three original operators retained their mnemonics for the relaunch, so no new mnemonic or libp2p node key is required. Before starting a validator against the new genesis, each operator must re-insert both consensus keys from the existing mnemonic into a fresh validator keystore:
./target/release/quip-network-node insert-hybrid-key \
--chain quip-testnet --base-path <validator-base-path> \
--scheme hybrid-babe-h444 --suri <mnemonic-file>
./target/release/quip-network-node insert-hybrid-key \
--chain quip-testnet --base-path <validator-base-path> \
--scheme hybrid-grandpa-h244 --suri <mnemonic-file>These commands derive the replacement H4 BABE and H2 GRANDPA keys from the same secret phrase. The bootnode peer ID and multiaddr remain unchanged because the libp2p node key is independent of the consensus-key rotation.
Should the helper script be unavailable, the equivalent commands are:
# 1. Mnemonic
./target/release/quip-network-node key generate
# → copy the "Secret phrase:" line
# 2. libp2p node-key file
./target/release/quip-network-node key generate-node-key --file ./nodekey
chmod 600 ./nodekey
./target/release/quip-network-node key inspect-node-key --file ./nodekey
# → prints the peer-id
# 3. Hybrid BABE/GRANDPA/TX public material
cd crates/transaction-crypto
cargo run --release --example derive_genesis_keys --features std -- "<mnemonic>"The example binary lives at
crates/transaction-crypto/examples/derive_genesis_keys.rs and produces the
same babe_pub / grandpa_pub / tx_account_* values regardless of whether
it is invoked directly or via the script.