Live Validator Admission for DAG Testnets
This guide covers the new shared-testnet flow for DAG consensus:
- RP1 runs the core validator set with
rp1d testnet start - the command emits a
bootstrap.jsonmanifest for external joiners - partners use
rp1d testnet jointo initialize an observer node and optionally broadcast validator admission transactions - the validator-admission module evaluates candidates at epoch boundaries using staking weight plus QUIC reachability evidence
What changed
The DAG path now supports:
- observer nodes that are not part of the active validator set
- a bootstrap manifest with genesis, public RPC/REST URLs, and public core consensus addresses
- partner join initialization from a bootstrap file or URL
- automatic
create-validatorplusregister-consensus-endpointsubmission whentestnet joinis run with--from - QUIC-based reachability probing in validator-admission vote extensions
- epoch-based validator set updates without restarting the chain
Default validator-admission parameters:
epoch_length = 100candidate_maturity = 1full epochreachability_threshold = >2/3max_active_validators = 32offline_eject_after = 2bad epochs
Core set startup
Use rp1d testnet start for the RP1-operated core set. For a public shared testnet, always publish externally reachable client URLs and one consensus address per core validator.
Example:
rp1d testnet start \
--v 4 \
--output-dir ./.testnets/shared \
--rpc.address tcp://0.0.0.0:26657 \
--api.address tcp://0.0.0.0:1317 \
--bootstrap.rpc-url https://testnet.rpc.rp.one \
--bootstrap.rest-url https://testnet.rest.rp.one \
--bootstrap.core-consensus-addr core-1.testnet.rp.one:26656 \
--bootstrap.core-consensus-addr core-2.testnet.rp.one:26656 \
--bootstrap.core-consensus-addr core-3.testnet.rp.one:26656 \
--bootstrap.core-consensus-addr core-4.testnet.rp.one:26656
Notes:
--bootstrap.core-consensus-addrmust be provided once per validator, in validator index order.- if the bootstrap URL flags are omitted,
bootstrap.jsonfalls back to the local listeners normalized for local use, for examplehttp://127.0.0.1:26657. - the command prints the location of the generated
bootstrap.json. Publish that file at a stable URL for partners, for examplehttps://testnet.rp.one/bootstrap.json.
The generated manifest contains:
chain_id- the exact
genesis.json rpc_urlrest_urlcore_validators[]withmoniker,validator_id, andconsensus_addr
Partner join flow
Partners need:
- a funded operator key in the local keyring
- a public QUIC address that other validators can dial
- access to the shared bootstrap manifest
Create the operator key:
rp1d keys add partner-validator --home ~/.rp1-testnet-partner --keyring-backend test
Fund the resulting account with enough urp1 to cover self-delegation and fees.
Initialize the node and broadcast the admission transactions:
rp1d testnet join \
--home ~/.rp1-testnet-partner \
--bootstrap-url https://testnet.rp.one/bootstrap.json \
--consensus.listen-addr 0.0.0.0:26656 \
--consensus.advertise-addr partner-1.example.com:26656 \
--from partner-validator \
--keyring-backend test \
--moniker partner-1 \
--self-delegation 100urp1
What testnet join does:
- writes the shared
genesis.json - configures the node as an observer in
config/app.toml - populates
consensus.peersfrom the core validator list - creates
config/priv_validator_key.jsonif it does not exist - when
--fromis set, broadcasts:MsgCreateValidatorMsgRegisterConsensusEndpoint
When --from is omitted, the command only initializes the home directory. That is useful when an operator wants to inspect the generated config first or broadcast transactions separately.
After initialization, start the node:
rp1d start --home ~/.rp1-testnet-partner
Node address rules
Use these address types consistently:
rpc_urlandrest_urlare for wallets, explorers, faucets, and CLI transaction submissionconsensus_addris for validator-to-validator QUIC traffic--consensus.advertise-addrmust be the public address visible to the rest of the validator set
Important:
- do not publish
0.0.0.0in a shared bootstrap manifest - if a partner is behind NAT, they must publish the forwarded public host and port, not the internal listener
- one public client RPC endpoint is enough for users, but validator admission still needs one public consensus endpoint per core validator
Admission lifecycle
The permissionless path is:
- the partner starts as an observer and syncs from the core set
- the partner submits
create-validatorplusregister-consensus-endpoint - active validators probe the candidate's QUIC endpoint during the epoch
- vote extensions aggregate reachability evidence
- at the next epoch boundary, the app computes the next active set
- consensus hot-reloads the validator set and peer map
With default params, a candidate must remain reachable for one full epoch before activation.
Operational caveats
testnet joindoes not create or fund the operator account for you- the join transaction submission path uses the manifest
rpc_urlunless--nodeis provided explicitly - the self-delegation default is
100urp1; override it with--self-delegationif your network uses a different threshold - the bootstrap manifest publisher is an operational concern outside this repo; the CLI generates and consumes the manifest but does not host it
Troubleshooting
Join initialized the node but did not submit transactions
You likely omitted --from. Re-run testnet join with:
--from <key-name> --keyring-backend <backend>
Join transaction submission fails immediately
Check:
- the operator key exists in the local keyring
- the operator account is funded
- the manifest
rpc_urlis reachable, or override it with--node
Candidate never becomes active
Check:
- the validator was created successfully on-chain
- the consensus endpoint was registered successfully
--consensus.advertise-addrpoints to a public reachable QUIC endpoint- the node stayed reachable for the full admission epoch
Core validators are not usable from outside the cluster
Regenerate the core manifest with explicit published addresses:
--bootstrap.rpc-url https://testnet.rpc.rp.one
--bootstrap.rest-url https://testnet.rest.rp.one
--bootstrap.core-consensus-addr core-N.testnet.rp.one:26656