Node Migration (Promoting a Full Node to Validator)
Backup Recommendation: We highly recommend backing up all validator configuration files and keys. This ensures you can recover quickly in the event of a node crash or unexpected failure.
There are several ways to achieve high availability for your validator node. This document specifically provides instructions for running a full node and promoting it to a validator using the proper configuration files and keys.
In situations of planned or unplanned maintenance, validators can migrate their node keys with minimal downtime by running a full node. This node can be seamlessly converted into a validator, allowing for continuous participation in consensus.
At the moment downtime results in the loss of rewards for validators and their delegators. However there is no slashing live on the chain as of now.
Follow these steps to safely migrate your validator role, minimize downtime, and maintain network health.
Prerequisites
- Monad version >=
0.12.x. id-secpandid-blskeys of the validator.node.tomlconfiguration file of the validator.KEYSTORE_PASSWORDvalue from the.envfile.
Instructions
-
Follow the full node instructions to sync a full node to the tip of the network.
-
Backup existing configuration files on the full node from
/home/monad/monad-bft/configand move them to/opt/monad/backup./home/monad/monad-bft/config/node.toml/home/monad/monad-bft/config/id-secp/home/monad/monad-bft/config/id-bls
-
Copy
id-secp,id-blsandnode.tomlfrom the validator to the full node. -
From the full node, run the
monad-sign-name-recordutility to generate a name-record signature for the new IP address.
# Source the .env file to load the keystore password env variablesource /home/monad/.env# Generate a name record and signaturemonad-sign-name-record --address $(curl -s4 ifconfig.me):8000 \--node-config /home/monad/monad-bft/config/node.toml \--authenticated-udp-port 8001 \--self-record-seq-num 1 \--keystore-path /home/monad/monad-bft/config/id-secp \--password "$KEYSTORE_PASSWORD"Example Output:
self_address = "<IP>:8000"self_record_seq_num = 1 # Incremented by 1 from the previous valueself_name_record_sig = "<HEX SIG>"- From the full node, replace the
[peer_discovery]block innode.tomlwith the output of the above command (3 lines).
- The
self_record_seq_numis incremented each time the node undergoes a migration process. - This value is crucial as it is directly linked to the
self_name_record_sig, ensuring consistency and integrity of the node's identity during transitions.
-
If the original validator had (other) custom configuration related to dedicated full nodes, e.g.
[[fullnode_dedicated.identities]], those will need to be added to the full node'snode.toml. To maintain connectivity with downstream nodes all downstream peers must update the name record for the validator in theirnode.tomlconfiguration. -
Ensure
enable_publisher = true,enable_client = trueandexpand_to_group = true. Inexpand_to_group = truemode, full nodes support relies on secondary raptorcast peers specified in the full node'snode.toml -
Double-check and ensure if the
beneficiary =values are copied from the validator'snode.tomlto full node'snode.toml. -
From the validator node, run
systemctlcommands to stop the services.
systemctl stop monad-bft monad-rpc monad-execution- Verify the validator services are stopped.
systemctl status monad-bft monad-rpc monad-execution- Stop the full node services and restart the services as a validator.
systemctl stop monad-bft monad-rpc monad-executionsleep 1systemctl start monad-bft monad-rpc monad-execution- Verify the systemd services are running:
systemctl status monad-bft monad-execution monad-rpc
# Check logs for each servicejournalctl -fu monad-bftjournalctl -fu monad-executionjournalctl -fu monad-rpcRestoring the original validator
If you would like to restore the original validator (A) to its original role, you will need to perform one of two procedures:
- Re-sync A - this will result in some downtime based on the time to statesync / blocksync
- Copy the
node.tomlfrom node B to node A - From A, run
monad-sign-name-recordusing node B'snode.tomlwith incrementedself_record_seq_num - Update the corresponding two fields in
node.toml - From the temporary validator (B), stop the services.
- Soft or hard reset (A)
- Copy the
- Run A as a full node, then perform steps above
- For A, generate new keys
- Sign a new name record (see instructions above) and setup as a dedicated node to a validator, e.g. your temporary validator (B)
- Perform the steps above with roles reversed.
Always ensure that each node maintains distinct node_name values in their respective node.toml files.
- If node B was originally a full node with
node_name = "node_B", it should retain this name when returning to full node operation - Node B should only temporarily use node A's
node_nameduring the migration procedure - After restoration, each node must return to its original
node_nameto avoid conflicts