Running a validator node
Kroma is the first universal Optimistic rollup to achieve Stage 2 by implementing a permissionless, decentralized validator system. Participating in Kroma's validator network not only promotes the network's decentralization but also earns rewards for the submission of checkpoint outputs upon their finalization. You'll need to bond $ETH to submit an output. Both the validator reward and the bond amount are subject to governance decisions.
A validator node on Kroma should perform the following tasks:
- Synchronize the blocks and transactions with the Mainnet and run a local node.
- Submit checkpoint outputs to Layer 1(Ethereum).
- Initiate a challenge if an invalid checkpoint output is identified.
When a validator detects that a submitted L2 output root contains an invalid state transition, it can start a dispute challenge process by triggering the Colosseum contract. We refer to a validator who submits a dispute challenge as a "challenger" and a validator who initially submitted an L2 output as an "asserter." A dispute challenge entails a confrontational interaction between an asserter and a challenger, which persists until one of them emerges victorious. Detection, Bisection, and Proof Submission completes a cycle of a challenge.
A challenge starts with a validator detecting an invalid checkpoint output that is submitted by another validator. The validator who detects a difference between its local output and the submitted output initiates a dispute challenge process by calling createChallenge function in Colosseum.sol.
After a challenge is successfully created, the asserter(the validator who submitted a potentially invalid checkpoint output) and the challenger(the validator who started the challenge) will take turns to bisect until the challenger finds a single block to prove fault.
Once the challenger finds a single step of a block to prove fault, the challenger generates a ZK fault proof on the specific block and submit the proof to Verifier.sol. To generate a ZK fault proof, the challenger must run a kroma-prover client.

When running a validator node, an initial bond of 0.2 ETH is required. This bond acts as a security deposit and is necessary to participate in the network. Upon the finalization of your output, you will be rewarded, aiming at a 10% APR when $ETH is used.
To ensure the network's integrity, it is necessary for one of the validators to submit a checkpoint output every 1800 blocks, which is equivalent to approximately 1 hour. The selection of the validator with the assertion priority is chosen at random for each submission.
Please note that some parameters are set differently on Ethereum Sepolia testnet compared to Ethereum mainnet to provide a faster test environment. Refer to the following table for the differences:
Parameter | Ethereum Sepolia | Ethereum Mainnet |
l2OutputOracleSubmissionInterval | 60 blocks | 1800 blocks |
validatorPoolNonPenaltyPeriod | 20 seconds | 600 seconds |
validatorPoolPenaltyPeriod | 40 seconds | 1200 seconds |
finalizationPeriodSeconds | 600 seconds | 604800 seconds (7 days) |
colosseumBisectionTimeout | 120 seconds | 120 seconds |
colosseumProvingTimeout | 480 seconds | 7200 seconds |
colosseumSegmentsLengths | “4,3,6,3” | “9,6,10,6” |
validatorPoolMinBondAmount | 0.1 ETH | 0.2 ETH |
The process of running a validator node entails several steps, including hardware setup, software installation, and node configuration. These steps also encompass the process of depositing into the ValidatorPool and managing your deposit.
The following are the minimum and recommended hardware requirements to run a validator on Kroma:
Minimum | Recommended | |
kroma-geth |
|
|
kroma-node |
|
|
kroma-validator |
|
|
kroma-prover |
|
|
Note: kroma-prover is expensive and only needed when a challenge occurs. It is recommended to turn it on and off as needed to generate a ZK fault proof. Therefore, we provide an additional Docker image for a lightweight proxy server that turns the prover client on only when a ZK fault proof for a block needs to be generated and turns it off afterward. Step-by-step guide on how to set up a kroma-prover client and a kroma-prover-proxy client is provided below.
Clone the kroma-up Git repository and navigate to the cloned directory:
> git clone https://github.com/kroma-network/kroma-up.git
> cd kroma-up
Note: Please ensure you are cloning to the latest version of the repository.
Run the following command to generate keys and environment variables required to run a node:
> ./startup.sh mainnet
Step 3 will generate a .env file with default values. Configure the .env file according to your requirements. Here are the environment variables in the .env file:
[Environment variables in .env file]
Name | Description |
NETWORK_NAME | The name of the network to run on. The values available are mainnet or sepolia. |
IMAGE_TAG__KROMA_GETH | The docker image tag of kroma-geth. Default value is provided while generating the .env file. |
IMAGE_TAG__KROMA_NODE | The docker image tag of kroma-node. Default value is provided while generating the .env file. |
IMAGE_TAG__KROMA_VALIDATOR | The docker image tag of kroma-validator. Default value is provided while generating the .env file. |
KROMA_NODE__L1_RPC_ENDPOINT | The HTTP RPC endpoint of Layer 1 |
KROMA_VALIDATOR__L1_RPC_ENDPOINT | The websocket RPC endpoint of Layer 1 |
KROMA_GETH__BOOT_NODES | The address of a bootnode for kroma-geth client. Default value is provided while generating the .env file. |
KROMA_NODE__BOOT_NODES | The address of a bootnode for kroma-node client. Default value is provided while generating the .env file. |
KROMA_VALIDATOR__MNEMONIC | The mnemonic phrase of the Ethereum account connected to the validator client. This should be provided along with the HD path value. When this value is provided, the private key value should be empty. |
KROMA_VALIDATOR__HD_PATH | The HD path of the Ethereum account connected to the validator client. This should be provided along with the mNemonic value. When this value is provided, the private key value should be empty. |
KROMA_VALIDATOR__PRIVATE_KEY | The private key of the Ethereum account connected to the validator client. When this value is provided, the mnemonic and HD path values should be empty. |
KROMA_VALIDATOR__OUTPUT_SUBMITTER_ENABLED | A flag to determine if the validator node is going to submit checkpoint outputs. Default value is true. |
KROMA_VALIDATOR__ALLOW_PUBLIC_ROUND | A flag to determine if the validator node is going to submit an output in public round. Default value is false. |
KROMA_VALIDATOR__CHALLENGER_ENABLED | A flag to determine if the validator node is going to validate unfinalized checkpoint outputs and initiate a challenge if an invalid checkpoint output is detected. Default value is false. |
KROMA_VALIDATOR__GUARDIAN_ENABLED | A flag for the Security Council member. Members of the Security Council are whitelisted and only those can operate as a Guardian. Default value is false. |
KROMA_VALIDATOR__PROVER_RPC | The RPC address of the kroma-prover client. If KROMA_VALIDATOR__CHALLENGER_ENABLED is true, this value must be provided. |
KROMA_PROVER_PROXY__PROVER_BASE_DIR | The base directory of proofs of prover. We recommend using the values provided by default. |
KROMA_PROVER_PROXY__PROVER_URL_SCHEMA | The prover url schema of prover. We recommend using the values provided by default. |
KROMA_PROVER_PROXY__PROVER_RPC_PORT | The RPC port of prover. We recommend using the values provided by default. |
KROMA_PROVER_PROXY__AWS_REGION | If you are using AWS Access Key, the information must be provided. |
KROMA_PROVER_PROXY__AWS_ACCESS_KEY_ID | If you are using AWS Access Key, the information must be provided. |
KROMA_PROVER_PROXY__AWS_SECRET_ACCESS_KEY | If you are using AWS Access Key, the information must be provided. |
KROMA_PROVER_PROXY__PROVER_INSTANCE_ID | Currently, Kroma-prover-proxy only supports AWS, so you'll need to enter the AWS EC2 instance ID where the Kroma-prover is running. |
KROMA_PROVER_PROXY__PROVER_ADDRESS_TYPE | You need to specify in which network environment the kroma-prover-proxy will call kroma-prover. If kroma-prover-proxy and kroma-prover are on the same network, set it to private so that the communication is internalHowever, if they are on different networks, set it to public so that kroma-prover can utilize the public IP of the instance it is running on. |
Now, open the .env file:
> vim .env
Set the values for your Ethereum account to connect the validator client with your account. You can choose either the private key or the mnemonic and HD path values.
[Example for Using Private Key]
#.env (it was created in "STEP 3: Start up the environment")
...
VALIDATOR_PRIVATE_KEY=${YOUR_ETH_PRIVATE_KEY}
# It should be kept as an empty value.
VALIDATOR_MNEMONIC=
VALIDATOR_HD_PATH=
[Example for Using Mnemonic and HD Path]
#.env (it was created in "STEP 3: Start up the environment")
...
VALIDATOR_MNEMONIC=${YOUR_ETH_MNEMONIC}
VALIDATOR_HD_PATH=${YOUR_ETH_HD_PATH}
# It should be kept as an empty value.
VALIDATOR_PRIVATE_KEY=
[Example for Validator as an OutputSubmitter]
#.env (it was created in "STEP 3: Start up the environment")
...
KROMA_VALIDATOR__OUTPUT_SUBMITTER_ENABLED=true
KROMA_VALIDATOR__CHALLENGER_ENABLED=false
# It should be kept as an empty value.
KROMA_VALIDATOR__PROVER_RPC=
[Example for Validator as a Challenger (w/ Prover RPC setting)]
#.env (it was created in "STEP 3: Start up the environment")
...
KROMA_VALIDATOR__OUTPUT_SUBMITTER_ENABLED=false
KROMA_VALIDATOR__CHALLENGER_ENABLED=true
KROMA_VALIDATOR__PROVER_RPC=${YOUR_KROMA_PROVER_CLIENT_RPC_ADDRESS}
[Example for Validator as Both an Output Submitter and a Challenger (w/ Prover RPC setting)]
#.env (it was created in "STEP 3: Start up the environment")
...
KROMA_VALIDATOR__OUTPUT_SUBMITTER_ENABLED=true
KROMA_VALIDATOR__CHALLENGER_ENABLED=true
KROMA_VALIDATOR__PROVER_RPC=${YOUR_KROMA_PROVER_CLIENT_RPC_ADDRESS}
Please note that either
KROMA_VALIDATOR__OUTPUT_SUBMITTER_ENABLED
or KROMA_VALIDATOR__CHALLENGER_ENABLED
must be set to true to operate as a validator node.Please note that the kroma-prover instance should be running on AWS Cloud, as currently the kroma-prover-proxy only supports AWS.
The kroma-prover client must be up and running before starting the kroma-validator because the kroma-validator requires the RPC endpoint of the kroma-prover client.
> docker compose --profile prover up -d
> docker compose logs kroma-prover
If you see the log saying
[KROMA] Prover server starting on 0.0.0.0:3030
, this means that your kroma-prover client has successfully started.You can run the kroma-prover-proxy on other cloud services, but the kroma-prover must be run on AWS.
The kroma-prover-proxy client should have the authorities to start and stop the kroma-prover EC2 instance.
The AWS roles that are required to be set are:
REGION
: The region of the kroma-prover EC2ACCOUNT_ID
: The AWS account id of the kroma-prover EC2INSTANCE_ID
: The instance ID of the kroma-prover EC2
An example of the IAM role setting is provided below:
# kroma-prover-proxy-role.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:StopInstances",
"ec2:StartInstances"
],
"Resource": "arn:aws:ec2:${REGION}:${ACCOUNT_ID}:instance/${INSTANCE_ID}"
},
{
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeTags"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
To learn more about how to create and manage AWS IAM roles, please refer to the official AWS guides below:
Please refer to the official AWS guide on how to grant the role to a EC2 instance:
To control an AWS instance from outside, you need to have an access key for the IAM user. Please refer to the links below to generate the access key:
> vim .env
# .env
...
KROMA_VALIDATOR__CHALLENGER_ENABLED=true
KROMA_VALIDATOR__PROVER_RPC=http://kroma-prover-proxy:6000
KROMA_PROVER_PROXY__AWS_REGION=${YOUR_KROMA_PROVER_EC2_REGION}
KROMA_PROVER_PROXY__AWS_ACCESS_KEY_ID=${YOUR_KROMA_PROVER_EC2_ACCESS_KEY_ID}
KROMA_PROVER_PROXY__AWS_SECRET_ACCESS_KEY=${YOUR_KROMA_PROVER_EC2_SECRET_ACCESS_KEY}
KROMA_PROVER_PROXY__PROVER_INSTANCE_ID=${YOUR_KROMA_PROVER_INSTANCE_ID}
KROMA_PROVER_PROXY__PROVER_ADDRESS_TYPE=private # if you're not running the kroma-prover-proxy on AWS, the value should be 'public'
If you have followed the previous steps, you can now start your validator node. Ensure that Docker is running, and execute the following command:
> docker compose --profile validator+proxy up -d
Please make sure you stop the kroma-prover instance started on STEP 5 because your kroma-prover-proxy client will turn it on and off automatically when needed.
To enable your validator node to submit checkpoint outputs or challenges, you need to deposit a certain amount of Ethereum into the ValidatorPool to be used as a bond for each output submission. The bonding amount for each output submission is 0.2 ETH.
You can deposit your ETH into the ValidatorPool contract either via the running kroma-validator container or via CLI. Note that to run commands via CLI, you should clone the kroma git repository and run the commands in the directory you cloned the repo.
> docker exec kroma-validator kroma-validator deposit --amount 1000000000000000000 #(unit:wei)
> cd components/validator
> go run ./cmd/main.go \
--valpool-address <validator-pool-address> \ # must be set
--l1-eth-rpc <l1-eth-rpc> \
--mnemonic <mnemonic> \
--hd-path <hd-path> \
--rollup-rpc "" \ # empty required flags
--l2oo-address "" \
--colosseum-address "" \
--challenger.poll-interval 0s \
deposit \
--amount <amount-wei> # must be set
valpool-address
means ValidatorPool proxy address on Ethereum Sepolia, which can be found here. For more details, please refer to the Github documentation.If you want to withdraw some or all of your deposited amount in ValidatorPool, you can withdraw via the running kroma-validator container or via CLI. Keep in mind that if the deposited amount is lower than the minimum bonding amount, your validator node will not be eligible for output submission.
> docker exec kroma-validator kroma-validator withdraw --amount 1000000000000000000 #(unit:wei)
> cd components/validator
> go run ./cmd/main.go \
--valpool-address <validator-pool-address> \ # must be set
--l1-eth-rpc <l1-eth-rpc> \
--mnemonic <mnemonic> \
--hd-path <hd-path> \
--rollup-rpc "" \ # empty required flags
--l2oo-address "" \
--colosseum-address "" \
--challenger.poll-interval 0s \
withdraw \
--amount <amount-wei> # must be set
The bonded ETH of a checkpoint output is automatically unbonded after the finalization time. As the finalization of the output is checked when new outputs are submitted, sometimes you may need to wait an additional hour after the finalization time if a new output is not submitted yet to check your output’s finalization. In such cases, you can directly try to unbond in ValidatorPool via the running kroma-validator container or via CLI commands.
> docker exec kroma-validator kroma-validator unbond
> cd components/validator
> go run ./cmd/main.go \
--valpool-address <validator-pool-address> \ # must be set
--l1-eth-rpc <l1-eth-rpc> \
--mnemonic <mnemonic> \
--hd-path <hd-path> \
--rollup-rpc "" \ # empty required flags
--l2oo-address "" \
--colosseum-address "" \
--challenger.poll-interval 0s \
unbond
To remove a running validator node, you can use the following command:
> docker compose --profile validator down -v
Please note that removing a running node does not automatically withdraw the Ethereum deposited by the validator node. Even if you forget to withdraw your deposit before removing the node, you can always access your assets by re-running the validator node with the same Ethereum account environment variable settings. This ensures that your deposited funds are not lost and can be easily recovered when running the validator node again.
We are working on providing the Grafana system for the validator client, which includes Geth metrics and Node metrics. This will help you better manage and track the performance of your node.
Last modified 17d ago