Validator
This page explains how to configure a ChainNode or ChainNodeSet to run a validator. Cosmopilot provides multiple options to suit different use cases.
The options below (existing key, create-validator, genesis init) apply to a single validator configured under .spec.validator. A ChainNodeSet can also run multiple validators by declaring validator groups under .spec.nodes[] — see Multiple Validators.
Existing Consensus Key
Storing mnemonics and private keys in Kubernetes secrets may not be secure and is recommended only for testnets. For production networks, consider using TmKMS for enhanced security.
If a consensus key is already defined in the genesis file as a validator, you can configure the node as follows:
- Create a Kubernetes secret containing the private key:
$ kubectl create secret generic my-validator-key --from-file=my-validator-key.json
Make sure the secret is created in the same namespace as your ChainNode or ChainNodeSet.
- Specify the secret name in
.spec.validator.privateKeySecret.
Example configuration:
validator:
privateKeySecret: my-validator-key
Manual Create-Validator
For nodes that are not validators by default, you can:
- Configure
.spec.validator.info.monikerwith the validator's moniker. - Manually submit a
create-validatortransaction to the blockchain to make the node a validator.
Example configuration:
validator:
info:
moniker: my-validator
Automated Create-Validator
Cosmopilot can also submit a create-validator transaction for you. For that you need to:
- Either create a Kubernetes secret containing the mnemonic of an account that has funds (the secret name must follow the pattern
<chainnode-name>-account), or wait forCosmopilotto create an account and you can send funds to it later. - Configure
.spec.validator.infoand.spec.validator.createValidator.
Example configuration:
validator:
info:
moniker: my-validator
website: https://validator.example.com
details: "A reliable validator"
identity: "ABCD1234"
createValidator:
stakeAmount: "1000000unibi"
commissionRate: "0.1"
commissionMaxRate: "0.2"
commissionMaxChangeRate: "0.01"
gasPrices: "0.025unibi"
minSelfDelegation: "1"
Multiple Validators
The .spec.validator field configures a single validator. To run several validators in one ChainNodeSet, declare validator groups under .spec.nodes[]: a group is a validator group when it has a validator block, and instances controls how many validators it runs. Each instance gets its own consensus key and operator account, created automatically by Cosmopilot (<nodeset>-<group>-<index>-priv-key and <nodeset>-<group>-<index>-account).
There are two ways to add validators, depending on whether you are bootstrapping a new network or joining an existing one.
Genesis validators
Use a group with validator.init to bake multiple validators into a brand-new genesis. Instance 0 generates the genesis and the rest are added to it as full validators:
nodes:
- name: validators
instances: 3
validator:
accountPrefix: nibi
valPrefix: nibivaloper
init:
chainID: my-testnet-1
assets: ["100000000unibi"]
stakeAmount: "1000000unibi"
See Initializing a New Network → Multiple Genesis Validators and the Nibiru Testnet Multi Validator example.
instances, not several groupsOn a chain you are initializing yourself, every validator Cosmopilot runs lives in one group. Only one
validator may carry validator.init, and a validator group without init requires an external
.spec.genesis — so the intuitive "one group initializes the genesis, other validator groups join
it" layout is rejected by both rules at once. Scale the single init group with instances instead.
Genesis validators that Cosmopilot does not run — keys provisioned elsewhere, or ones needing their
own stake, assets or moniker — go in that group's validator.init.genesisValidators list.
Separate validator groups are for chains whose genesis already exists — there each group either
carries a consensus key the genesis already lists (Existing Consensus Key)
or joins with createValidator (below).
Validators on a running chain
Use a group with validator.createValidator (together with an external .spec.genesis) to add validators to a chain that is already running. Each instance submits its own create-validator transaction once it is synced:
genesis:
url: https://example.com/my-network-genesis.json
chainID: my-network-1
nodes:
- name: validators
instances: 2
validator:
accountPrefix: nibi
valPrefix: nibivaloper
createValidator:
stakeAmount: "1000000unibi"
gasPrices: "0.025unibi"
# accountMnemonicSecret: my-funded-account # optional; otherwise an account is generated per instance and must be funded
Things to know
- Per-instance keys are mandatory. A multi-instance validator group cannot set a shared
privateKeySecret,tmKMS, or account secret — that would make every instance sign with the same key (double-signing). Single-instance validator groups may use them, just like.spec.validator. validatoris a reserved group name (it backs the legacy.spec.validator). Use any other name for your groups.- Genesis (
init) validator groups are immutable after the genesis is created — you cannot add, remove, scale, or change their keys. Use acreateValidatorgroup to grow a running validator set. - A
cosmosignercollapses the group to one validator. A signer holds a single consensus identity, so a group it targets is ONE validator whose instances are redundant signing endpoints —instances: 3means three validators without a signer and one with it. Cosmopilot warns at admission when a genesis-initializing group is affected, since the resulting genesis validator set cannot be changed afterwards. See High-availability validators. - Backward compatible. The singleton
.spec.validatorcontinues to work unchanged and is equivalent to a one-instance validator group that keeps the legacy ChainNode name<nodeset>-validator.
Where to put each setting
A validator group's pods are built from its validator block, so most pod-shaping settings move under nodes[].validator.*. Setting them at group level is a no-op — Cosmopilot reports it as an admission warning (visible in kubectl apply output, and logged when webhooks are disabled), but the value is never applied.
| Setting | Validator group | Regular group |
|---|---|---|
config, persistence, resources, nodeSelector, affinity, stateSyncRestore, stateSyncResources, vpa, pdb, overrideVersion | nodes[].validator.* | nodes[].* |
instances, peers, expose, individualIngresses, individualGatewayRoutes, snapshotNodeIndex, cosmosigner | nodes[].* | nodes[].* |
ignoreGroupOnDisruptionChecks | no effect — validator pods coordinate disruptions chain-wide | nodes[].* |
inheritValidatorGasPrice | no effect — a validator group is the gas-price source | nodes[].* |
Initializing a New Network
Please refer to Initializing a New Network page for information about setting up new networks.