Skip to main content

Validators

Everything you need to start running a validator.

Hyperlane validators are not networked with other validators and do not regularly submit transactions. Hyperlane validators are run on a per-origin-chain basis, and these instructions are written for a single chain.

Running a validator simply requires the following:

  • An RPC node
    • Validators make simple view calls to read merkle roots from the Mailbox contract on the chain they are validating for.
caution

Operating a validator for Polygon mainnet requires access to an archive node. This is because validators should only sign roots once they've been finalized, and Polygon requires 256 block confirmations to achieve finality.

  • A secure signing key

    • Validators use this key to sign the Mailbox's latest merkle root. Securing this key is important. If it is compromised, attackers can attempt to falsify messages, causing the validator to be slashed.
    • The Hyperlane validator agent currently supports signing with AWS KMS keys that are accessed via API keys/secrets as well as hexadecimal plaintext keys for testing. See more under agent keys.
  • Publicly readable storage

    • Validators write their signatures off-chain to publicly accessible, highly available, storage, so that they can be aggregated by the relayer.
    • The Hyperlane validator agent currently supports storing signatures on AWS S3 using the same AWS API key above, as well as storing signatures in the local filesystem for testing.
  • A machine to run on

    • Validators can compile the Rust binary themselves or run a Docker image provided by Abacus Works. The binary can be run using your favorite cloud service. You can even run multiple instances of them in different regions for high availability, as Hyperlane has no notion of "double signing".

Guide

info

The local setup is only intended for testing or development purposes.

This is intended to show how you can run a validator on your local machine, which is only for testing and development purposes. This also means that signatures from local validators are only able to be accessed by a locally ran relayer.

For running a validator in a production environment, see the AWS setup guide.

Create a hexadecimal key for your validator to sign with

See the agent key guide.

Create a local directory for your validator's signatures

When running a validator locally, your validator will write its signatures to a local directory. This directory can be named whatever you like, just remember to use this directory when setting your configuration.

# Pick an informative name specific to the chain you're validating
MY_VALIDATOR_SIGNATURES_DIRECTORY=/tmp/hyperlane-validator-signatures-ethereum

# Create the directory
mkdir -p $MY_VALIDATOR_SIGNATURES_DIRECTORY

Configuration

info

Take a look at the agent configuration page and the configuration reference for a full list of configuration possibilities. The list below is not complete, however it should be enough to get started.

Your validator takes arguments and environment variables as configuration. See below for both the general configurations and those that are specific to the setup instructions you followed.

ArgumentDescription
--reorgPeriodThe number of block confirmations a validator should wait before signing the Mailbox merkle root. Note that signing a root that is later invalidated (i.e. due to a re-org) is considered fraudulent behavior and will eventually be slashable.
--originChainNameThe name of the chain being validated (e.g. ethereum)
--chains.[origin chain name].customrpcurlsThe RPC URLs of the node for the chain you are validating. Note Polygon mainnet requires an RPC URL of an archive node. (e.g. --chains.ethereum.customrpcurls or --chains.polygon.customrpcurls)
--dbThe path to where the validator should write persistent data to disk. Ensure this path to be persistent when using cloud setups. When using Docker, make sure to mount the persistent path/volume into the container.
Environment variableDescription
CONFIG_FILESIf you want to add additional configuration files you can add additional paths here as a comma separated list. These files must be accessible within the filesystem your agent has access to. If you're running in Docker, see the docker section of agent configuration for tips on mounting your config files into your Docker container.

Setup-specific configuration

These required environment variables differ based on which of the environments you set up.

These are required for the local setup.

ArgumentDescription
--validator.keyYour validator's private key, which is used to sign merkle roots.
--chains.${localchainname}.signer.keyYour validator's private key, which will be used to submit a transaction on chain that publicly announce your validator's checkpoint syncer.
--checkpointSyncer.typeSet to localStorage.
--checkpointSyncer.pathThe path to your local directory where validator signatures will be written. This should be the value of $MY_VALIDATOR_SIGNATURES_DIRECTORY from the local setup.Example: --checkpointSyncer.path='/tmp/hyperlane-validator-signatures-ethereum'
warning

Note that the relayer must be configured with --allowLocalCheckpointSyncers to be able to read signatures from this validator.

Installation

The recommended installation method for a production environment is using a Docker image.

To download the docker image, run:

docker pull gcr.io/abacus-labs-dev/hyperlane-agent:f44589e-20231130-114734

Start Validating

Running the binary

Find the latest docker image and set it to the environment variable $DOCKER_IMAGE.

docker run \
-it \
--mount type=bind,source="$(pwd)"/hyperlane_db,target=/hyperlane_db \
$DOCKER_IMAGE \
./validator --db /hyperlane_db --originChainName ethereum --reorgPeriod 20 --checkpointSyncer.type localStorage --checkpointSyncer.path /tmp/hyperlane-validator-signatures-ethereum
info

If you have followed the instructions to deploy hyperlane and are specifying a path to your own config file in the CONFIG_FILES environment variable, check out the config files with docker section of agent configuration.

tip

If you're running validators with a local setup on the same machine and want the relayer to access these validator signatures, be sure to mount your local validator's signature directory into your relayer at the same path that you used when announcing your validator

For example, if your local validator is writing signatures to /tmp/hyperlane-validator-signatures-ethereum, you should mount a directory for the Docker container:

docker run \
-it \
-e CONFIG_FILES=/path/to/file/inside/container \
--mount type=bind,source="$(pwd)"/hyperlane-validator-signatures-ethereum,target=/tmp/hyperlane-validator-signatures-ethereum,readonly \
--mount type=bind,source="$(pwd)"/hyperlane_db,target=/hyperlane_db \
$DOCKER_IMAGE \
./validator --db /hyperlane_db --originChainName ethereum --reorgPeriod 20 --checkpointSyncer.type localStorage --checkpointSyncer.path /tmp/hyperlane-validator-signatures-ethereum

Announcing your validator

The relayer needs to know where to find your validator's signatures. Your validator will automatically attempt to announce itself by writing to the ValidatorAnnounce contract on the chain that you're validating.

To do this, your validator must have a small amount of tokens to pay for the gas for this transaction.

If your validator has not yet announced itself, and does not have enough tokens to pay for gas, it will log a message specifying how many tokens are needed.

Success!

The validator will index the origin Mailbox contract for messages. If a message has been sent, you should see log messages that the validator has signed them. If everything is configured correctly, you should see json files being written to your S3 bucket (if you followed the AWS setup) or to your local signatures directory if you followed the local setup. New json files get written every time a new outbound message is inserted into the mailbox.

Running multiple validators

We encourage folks to validate on as many chains as they are interested in supporting. We recommend that resources are not shared between validator instances.