Skip to main content

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.json manifest for external joiners
  • partners use rp1d testnet join to 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-validator plus register-consensus-endpoint submission when testnet join is 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 = 100
  • candidate_maturity = 1 full epoch
  • reachability_threshold = >2/3
  • max_active_validators = 32
  • offline_eject_after = 2 bad 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-addr must be provided once per validator, in validator index order.
  • if the bootstrap URL flags are omitted, bootstrap.json falls back to the local listeners normalized for local use, for example http://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 example https://testnet.rp.one/bootstrap.json.

The generated manifest contains:

  • chain_id
  • the exact genesis.json
  • rpc_url
  • rest_url
  • core_validators[] with moniker, validator_id, and consensus_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.peers from the core validator list
  • creates config/priv_validator_key.json if it does not exist
  • when --from is set, broadcasts:
    • MsgCreateValidator
    • MsgRegisterConsensusEndpoint

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_url and rest_url are for wallets, explorers, faucets, and CLI transaction submission
  • consensus_addr is for validator-to-validator QUIC traffic
  • --consensus.advertise-addr must be the public address visible to the rest of the validator set

Important:

  • do not publish 0.0.0.0 in 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:

  1. the partner starts as an observer and syncs from the core set
  2. the partner submits create-validator plus register-consensus-endpoint
  3. active validators probe the candidate's QUIC endpoint during the epoch
  4. vote extensions aggregate reachability evidence
  5. at the next epoch boundary, the app computes the next active set
  6. 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 join does not create or fund the operator account for you
  • the join transaction submission path uses the manifest rpc_url unless --node is provided explicitly
  • the self-delegation default is 100urp1; override it with --self-delegation if 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_url is 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-addr points 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