Run a Gravity Mainnet Validator (Invite Only)
Run an invite-only Gravity Mainnet (L1) validator. Validator onboarding is currently invite-only. Covers validator node deployment, StakePool creation, governance whitelisting, validator join, status
This guide walks approved operators through adding a validator to Gravity Mainnet (L1, Chain ID 127001). A validator participates in AptosBFT consensus and must be backed by a StakePool that has been approved through governance.
Validator onboarding is currently invite-only. If you only need a node for reads, writes, or indexing, run a Public Full Node instead.
Placeholders. Commands below use
<YOUR_...>placeholders. Replace each value before running. Never paste private keys into shared shells or commit generated node identities.
Network Role
Validators connect to each other on the validator network and optionally expose VFN-network endpoints for VFNs:
validator set --validator net--> consensus
validator --VFN net--> VFN --public net--> PFN / RPCThe onboarding flow is:
Prepare validator config and identity.
Deploy the node package.
Fund the validator account.
Create a StakePool.
Add the StakePool to the validator whitelist through governance.
Join the validator set with the node's public identity.
Start the node and verify status.
Prerequisites
Approval from current governance / operators. The StakePool must be whitelisted before it can join the validator set.
A Linux x86-64 host, preferably Ubuntu 24.04 LTS.
gravity_nodeandgravity_cli.Mainnet
genesis.jsonandwaypoint.txt. Use the canonical mainnet artifacts fromgravity-sdk/genesis/mainnet; do not regenerate genesis locally.A fresh validator EVM account. This account owns and operates the StakePool. Do not reuse public test keys for a long-running validator.
System contract addresses for staking, validator management, and governance. See the mainnet contract reference for current addresses.
1. Write cluster-validator.toml
Download the canonical mainnet artifacts where the config below expects them:
Create a config such as:
If identity is stored in a secret manager, pin a fixed version rather than latest:
2. Generate Identity and Deploy
Expected layout:
The public identity used during validator join is written to:
3. Optional: Warm Start the Databases
To reduce cold-sync time, copy only chain databases from an existing RPC/PFN you control:
Do not copy another node's secure_storage.json. It contains safety-rules owner and consensus-key state. Reusing it can produce errors such as:
4. Fund the Validator Account
Set common variables:
Fund the validator account with enough balance for stake and gas:
The validator account must sign StakePool and validator lifecycle operations. Use your normal secure signing workflow. If gravity_cli prompts for a key on stdin, ensure the signer is the StakePool operator.
5. Create a StakePool
Use the validator account to create a StakePool:
Record the created pool:
Verify:
If the chain enforces a minimum lockup duration, do not set the lockup exactly at the minimum. Add a buffer so timestamp drift does not trigger LockupDurationTooShort.
6. Whitelist the StakePool
The whitelist target is the StakePool address, not the validator EOA:
This call must go through governance. Direct calls from an EOA are expected to revert.
Create calldata:
Create, vote, resolve, and execute the proposal according to the current governance process:
Confirm the pool is allowed:
7. Join the Validator Set
Read the node's public identity:
Join:
The signer must be the StakePool operator.
8. Start and Verify
Check validator set and epoch status:
Status values:
0
INACTIVE
1
PENDING_ACTIVE
2
ACTIVE
3
PENDING_INACTIVE
After joining, a validator usually enters PENDING_ACTIVE and becomes ACTIVE after an epoch transition.
You can also check node health:
Leave the Validator Set
To leave:
If the validator is ACTIVE, it becomes PENDING_INACTIVE and exits after the next epoch transition. If it is still PENDING_ACTIVE, it can become INACTIVE immediately.
Verify:
Troubleshooting
isValidatorPoolAllowed returns false
The governance whitelist proposal has not executed, or it targeted the wrong StakePool.
LockupDurationTooShort
Increase the lockup duration above the minimum with a buffer.
Validator remains PENDING_ACTIVE
Activation normally happens at the next epoch transition. Check gravity_cli epoch status.
Address not in set: <OLD_OWNER_ACCOUNT>
Another node's secure_storage.json was copied. Remove it and regenerate/redeploy with the correct identity.
Node paths do not point to <node>/data
data_dir should be the deploy directory, not the database directory.
See Also
Last updated
Was this helpful?

