Running Agents Guide
Overview
Nomad agent processes observe and index on-chain events, interacting with multiple blockchains in order to facilitate cross-chain messaging.
See the Off-Chain Agents section for details on each agent role.
Home/Replica Model
Nomad channels are dual-simplex. This simply means they are composite bi-directional communication channels between two given blockchains. Each composite channel is composed of a single data channel flowing in one direction paired with a corresponding data channel flowing in the opposite direction. These data channels flow outward from the Home contract on each blockchain.
Agents are architected in a Home-centric model, meaning that by default agents must be configured with secrets like signing keys and RPC endpoints for each blockchain that the configured Home has a Replica on.
This means if you want to facilitate bi-directional communication between two or more networks (or Watch both directions of a channel), you must run one agent instance per Home.
If that didn't make much sense, go read Cross-Chain Messaging and come back.
Configuring an Agent
Agents are simple Rust binaries that are easily run inside Docker Containers. Agents read runtime configuration from a mix of JSON config files and environment variables.
Configuration is loaded in the following order:
Built-In Configuration
Configuration File
Environment Variables
Nomad Configuration Repository
Nomad publishes JSON configurations for each of the three public environments we operate, they can be found in the Nomad Configuration Repository on Github. These configs provide public network info such as contract addresses and chain finality settings which the agents consume.
By default, agents get compiled with the JSON environment configuration that was available at compile-time, however this config can be optionally overridden at runtime via the CONFIG_PATH
environment variable.
Environment Variables
The agent has specific required environment variables, but additionally supports specific additional configuration overrides. The key fields one must specify are detailed below.
Note:DEFAULT
_ values are only used if a network-specific override is not provided.
Run Environment
RUN_ENV
: Used to switch between built-in environmentsdevelopment
,staging
, orproduction
Agent Home
AGENT_HOME_NAME
: A network name which the agent will treat as Home, see built-in configs for details
Agent Replicas
Specify networks:
AGENT_REPLICA_0_NAME
,AGENT_REPLICA_1_NAME
,AGENT_REPLICA_2_NAME
, etc...What replica(s) the agent will run against
Default to all connected networks:
AGENT_REPLICAS_ALL
Expects all connected replicas if
true
Expects specified networks if
false
or not set
RPC Info
Network-specific:
{network}_RPCSTYLE
: What RPC stylenetwork
is; "ethereum" for all EVM chains{network}_CONNECTION_URL
: RPC endpoint url
Default:
DEFAULT_RPCSTYLE
: Default rpc style for any network not explicitly configured
Transaction Submission Info
Network-specific:
Transaction Submission Type:
{network}_SUBMITTER_TYPE
local
for local signing/submittinggelato
if you are integrated with Gelato Relay
Local Submission:
Transaction signer key:
Hex key:
{network}_TXSIGNER_KEY
Raw 0x-prefixed hex key
AWS Key:
{network}_TXSIGNER_ID
AWS key id
Gelato Submission (ignore if you do not plan on using Gelato Relay):
Sponsor signer:
Hex key:
{network}_GELATO_SPONSOR_KEY
Raw 0x-prefixed hex key
AWS Key:
{network}_GELATO_SPONSOR_ID
AWS key id
Fee token
{network}_GELATO_SPONSOR_FEETOKEN
0x-prefixed token contract address
Default:
Default for any network not explicitly configured
Same as network-specific (above) but replacing specific
{network}
withDEFAULT
Example:
DEFAULT_SUBMITTER_TYPE=local
DEFAULT_TXSIGNER_ID=some_aws_id
All networks use
local
transaction submission with the default txsigner key
Attestation Signer (optional)
Required only for updater and watcher
Hex key:
ATTESTATION_SIGNER_KEY
Raw 0x-prefixed hex key
AWS Key:
ATTESTATION_SIGNER_ID
AWS key id
Agent Configuration Overrides (optional)
Agents also have configuration settings that can be optionally overridden by environment variables. If present, these variables will override values given by configuration files.
All Agents
Agent interval:
{agent}_INTERVAL
The frequency at which an agent runs its loop in milliseconds
Kathy
Chat config:
Recipient:
KATHY_CHAT_RECIPIENT
0x-prefixed recipient address
Message:
KATHY_CHAT_MESSAGE
A message string
Message list:
KATHY_CHAT_MESSAGES
A quoted, comma separated list of message strings
Random messages:
KATHY_CHAT_RANDOM
An integer value for the number of random messages to send
Processor
Allowed senders:
PROCESSOR_ALLOWED
A comma separated list of 0x-prefixed sender addresses
Denied senders:
PROCESSOR_DENIED
A comma separated list of 0x-prefixed sender addresses
Subsidized remotes:
PROCESSOR_SUBSIDIZED_REMOTES
A comma separated list of network names
S3 Bucket:
AWS Bucket:
PROCESSOR_S3_BUCKET
AWS bucket id
AWS Region:
PROCESSOR_S3_REGION
AWS region id
For an example of agent configuration overrides, please see our example overrides env file.
Running Agent
AWS Keys: Note that the AWS key_id
field can be a key id, key name, alias name, or alias ARN, as documented in the Rusoto KMS docs. For more information on configuring AWS credentials, please refer to the Rusoto AWS credentials usage documentation.
For more info on our different run environments and key configuration/provisioning, please refer to our agents operations page.
You can see an example .env file below:
If you would like to configure an agent to run against all connected networks (against all replicas the home is connected to), see this example. For more examples of .env files, see our test fixtures folder.
Once you have populated a .env file, running an agent is as simple as running the following command:
env $(cat .env | xargs) cargo run --bin <AGENT>
This will build the codebase and run the specified <AGENT>
binary (updater, relayer, processor, or watcher) using the provided environment variables.
Agents Release Process
Our release process follows a monthly cadence. We follow Semantic Versioning, where breaking changes constitute changes that break agent configuration compatibility.
We manage releases through GitHub. You can find new per-agent releases here.
Production Builds
When making changes to the Rust codebase, it is important to ensure the Docker build used in production environments still works. You can check this automatically in CI as it is built on every PR (see docker workflow here), however you can check it much faster usually by attempting to build it locally.
You can build the docker image by running the following script in the rust
directory:
./build.sh latest
If that goes smoothly, you can rest assured it will most likely also work in CI.
Last updated