Skip to main content

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

  1. Monad version >= 0.12.x.
  2. id-secp and id-bls keys of the validator.
  3. node.toml configuration file of the validator.
  4. KEYSTORE_PASSWORD value from the .env file.

Instructions

  1. Follow the full node instructions to sync a full node to the tip of the network.

  2. Backup existing configuration files on the full node from /home/monad/monad-bft/config and 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
  3. Copy id-secp,id-bls and node.toml from the validator to the full node.

  4. From the full node, run the monad-sign-name-record utility to generate a name-record signature for the new IP address.

# Source the .env file to load the keystore password env variable
source /home/monad/.env
# Generate a name record and signature
monad-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 value
self_name_record_sig = "<HEX SIG>"
  1. From the full node, replace the [peer_discovery] block in node.toml with the output of the above command (3 lines).
info
  • The self_record_seq_num is 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.
  1. 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's node.toml. To maintain connectivity with downstream nodes all downstream peers must update the name record for the validator in their node.toml configuration.

  2. Ensure enable_publisher = true, enable_client = true and expand_to_group = true. In expand_to_group = true mode, full nodes support relies on secondary raptorcast peers specified in the full node's node.toml

  3. Double-check and ensure if the beneficiary = values are copied from the validator's node.toml to full node's node.toml.

  4. From the validator node, run systemctl commands to stop the services.

systemctl stop monad-bft monad-rpc monad-execution
  1. Verify the validator services are stopped.
systemctl status monad-bft monad-rpc monad-execution
  1. Stop the full node services and restart the services as a validator.
systemctl stop monad-bft monad-rpc monad-execution
sleep 1
systemctl start monad-bft monad-rpc monad-execution
  1. Verify the systemd services are running:
systemctl status monad-bft monad-execution monad-rpc
# Check logs for each service
journalctl -fu monad-bft
journalctl -fu monad-execution
journalctl -fu monad-rpc

Restoring 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:

  1. Re-sync A - this will result in some downtime based on the time to statesync / blocksync
    1. Copy the node.toml from node B to node A
    2. From A, run monad-sign-name-record using node B's node.toml with incremented self_record_seq_num
    3. Update the corresponding two fields in node.toml
    4. From the temporary validator (B), stop the services.
    5. Soft or hard reset (A)
  2. Run A as a full node, then perform steps above
    1. For A, generate new keys
    2. Sign a new name record (see instructions above) and setup as a dedicated node to a validator, e.g. your temporary validator (B)
    3. Perform the steps above with roles reversed.
Node Name Management

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_name during the migration procedure
  • After restoration, each node must return to its original node_name to avoid conflicts