Run a Validator Node

Create a validator from running node


Ensure that you have a full node setup and synced.

To check on the status of syncing:

selfchaind status

This will give output like this:

 "latest_block_hash": "920E4D32F02CFF8064D26DD7D34C65DC623F4026C65C192BBCD7DBF19AFB5630",
 "latest_app_hash": "442E7E55982109D9F73467EA0E374312B402AE620DEC81CB3441E949ED0D0A29",
 "latest_block_height": "2437",
 "latest_block_time": "2022-05-25T23:07:36.752766828Z",
 "earliest_block_hash": "9D2AF876309BB9174604004A813DCFEE94F4947B08C5BB4C1A042F318488851E",
 "earliest_app_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
 "earliest_block_height": "1",
 "earliest_block_time": "2022-05-25T17:00:00Z",
 "catching_up": true

The main thing to watch is that the block height is increasing. Once you are caught up with the chain, catching_up will become false. At that point, you can start using your node to create a validator.

Create a Validator

At this point, we’ve managed to deploy and start the node. Once the node is fully synced, we can use the CLI tool to turn our Node into a Validator Node.

The Validators set is defined in the staking module. It is first formed using the initial validators from the genesis file. However, this is a dynamic set meaning that new validators can decide to join the set by staking an amount and existing ones can decide to leave.

Joining Validator Set

A validator is created using the [MsgCreateValidator](<>) message. The validator must be created with an initial delegation from the operator.

As you can see here the message includes amongst others the commission validator will be charging delegators. Let’s describe the commission rate fields:

  1. rate: the commission rate charged to delegators, as a fraction. For example, if the validator charges 10% then this value would be 0.1

  2. max_rate: defines the maximum commission rate that which validator can ever charge, as a fraction. Each validator can send MsgEditValidator to update the commission rate (at most once within 24 hours). The max_rate will make sure that the new rate does not exceed this value.

  3. max_change_rate: max_change_rate defines the maximum daily increase of the validator commission, as a fraction. For example, we can say that when a validator updates the rate then the new rate cannot be, let’s say 20% higher than the previous rate.

At this point, it’s worth mentioning that rewards and commissions are not automatically distributed. Validators and delegators should use the delegation module.

Check the logs of your node and make sure that it is synced with the latest block. Avoid sending the create-validator transaction if the node is not fully synced. In any other case, you risk your validator getting jailed and part of the staked amount being slashed.

To join the validator set we simply send a transaction to the blockchain using the operation key we created above. Note that the operator account (i.e --from) must have sufficient uslf balance to cover the staked amount, as well as, the gas cost.

selfchaind tx staking create-validator \
    --amount=1000000000uslf \
    --node \
    --pubkey=$(selfchaind tendermint show-validator --home $SELF_CHAIN_HOME) \
    --moniker="moniker" \
    --website="" \
    --details="This is a validator that was added post genesis" \
    --chain-id="self-dev-1" \
    --commission-rate="0.10" \
    --commission-max-rate="0.15" \
    --commission-max-change-rate="0.05" \
    --min-self-delegation="1000000000" \
    --broadcast-mode block \
    --gas="auto" \
    --gas-adjustment="1.2" \
    --gas-prices="0.5uself" \
    --keyring-backend file \
    --keyring-dir $SELF_CHAIN_HOME/keys \

Let’s describe the most important parameters:

  • --amount: This is the total amount we’re willing to stake. In reality, what we do is we use the operator key to delegate to our validator. Here we staked 1000000000uslf which is 1000slf.

  • --node: This is the RPC URL of a full node. We can use the address of our node, as well.

  • --moniker: The same moniker we used when we initialized the chain. This is the name of the validator that will be shown on the explorer.

  • --min-self-delegation: The minimum amount of SLFs the validator candidate need to have bonded at all time. Check the section below for details

  • --from: The public key or a key name that we used when we created the operation key.

It's recommended to create a validator with a small amount of SLF token first, then verify things. Then you can delegate more tokens later. This will prevent unexpected issues leading to losing tokens.

You might be wondering what is the min-self-delegation. It is basically, the minimum amount of SLFs the validator candidate need to have bonded at all time. If the validator's self-bonded stake falls below this limit, their entire staking pool (i.e. all its delegators) will unbond. This parameter exists as a safeguard for delegators. Indeed, when a validator misbehaves, part of their total stake gets slashed. This included the validator's self-delegated stake as well as their delegators' stake. Thus, a validator with a high amount of self-delegated Atoms has more skin in the game than a validator with a low amount. The minimum self-bond amount parameter guarantees to delegators that a validator will never fall below a certain amount of self-bonded stake, thereby ensuring a minimum level of skin in the game. This parameter can only be increased by the validator operator. More on this here

Delegate tokens to a validator

selfchaind tx staking delegate validator_operation_address 888999820718uself\
    --node \
    --chain-id="self-dev-1" \
    --broadcast-mode block \
    --gas="auto" \
    --gas-adjustment="1.2" \
    --gas-prices="0.5uslf" \
    --keyring-backend file \
    --keyring-dir $SELF_CHAIN_HOME/keys \

To find validator_operation_address, visit the validator page on Self Chain Explorer.

Delegation can be done with our staking application.


Check the slashing params by running:

selfchaind  query slashing params --node
downtime_jail_duration: 600s
min_signed_per_window: "0.500000000000000000"
signed_blocks_window: "100"
slash_fraction_double_sign: "0.050000000000000000"
slash_fraction_downtime: "0.010000000000000000"

This says if you miss 95% (1-min_signed_per_window) of any 100-block window (signed_blocks_window), you will be slashed 0.01% (slash_fraction_downtime).

Basically, if you’ll be offline for 95 blocks then you will be slashed.


If your validator has been jailed for any reason e.g. liveness checks failed, min self-delegation violated, etc. You can use the slashing module to unjail.

selfchaind tx slashing unjail \
  --node \
  --gas="auto" \
  --chain-id="self-1" \
  --gas-adjustment="1.2" \
  --gas-prices="0.5uslf" \
  --broadcast-mode block \
  --keyring-backend file \
  --keyring-dir $SELF_CHAIN_HOME/keys \

Last updated