Skip to main content

Relayer Guide

The following information is based off of this guide created by Clemens from CryptoCrew.

Minimum Requirements

  • 8-core (4 physical core), x86_64 architecture processor
  • 32 GB RAM (or equivalent swap file set up)
  • 1TB+ nVME drives

If running many nodes on a single VM, ensure your open files limit is increased

Prerequisites

Before beginning, ensure you have an osmosis node running in the background of the same machine you intend to relay on. Follow this guide or use the Osmosis installer to set up an Osmosis node if you have not already.

In this guide, we will be relaying between Osmosis (channel-0) and Cosmos Hub (channel-141). When setting up your Cosmos and Osmosis full nodes, be sure to offset the ports being used in both the app.toml and config.toml files of the respective chains (I will show how to do this below).

In this example, I will be using the default ports for Osmosis and will manually change the ports of the Cosmos node.

Osmosis Daemon Settings

Here I will leave grpc server on port 9090 in the app.toml directory:

nano $HOME/.osmosisd/config/app.toml
[grpc]

# Enable defines if the gRPC server should be enabled.
enable = true

# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9090"

Here I will leave the pprof_laddr set to port 6060, rpc laddr to port 26657, and p2p laddr to 26656 in the config.toml directory:

nano $HOME/.osmosisd/config/config.toml
# pprof listen address (https://golang.org/pkg/net/http/pprof)
pprof_laddr = "localhost:6060"
[rpc]

# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://127.0.0.1:26657"
[p2p]

# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26656"

Cosmos Hub Daemon Settings

Here I will set grpc server to port 9092 in the app.toml directory:

nano $HOME/.gaiad/config/app.toml
[grpc]

# Enable defines if the gRPC server should be enabled.
enable = true

# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9092"

Here I will set the pprof_laddr to port 6062, rpc laddr to port 26757, and p2p laddr to 26756 in the config.toml directory:

nano $HOME/.gaiad/config/config.toml
# pprof listen address (https://golang.org/pkg/net/http/pprof)
pprof_laddr = "localhost:6062"
[rpc]

# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://127.0.0.1:26757"
[p2p]

# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26756"

Install Rust Dependencies

Install the following rust dependencies:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
sudo apt-get install pkg-config libssl-dev
sudo apt install librust-openssl-dev build-essential git

Build & setup Hermes

Make the directory where you'll place the binary, clone the hermes source repository and build it using the latest release.

mkdir -p $HOME/hermes
git clone https://github.com/informalsystems/ibc-rs.git hermes
cd hermes
git checkout v0.12.0
cargo install ibc-relayer-cli --bin hermes --locked

Make hermes config & keys directory, copy config-template to config directory:

mkdir -p $HOME/.hermes
mkdir -p $HOME/.hermes/keys
cp config.toml $HOME/.hermes

Check hermes version & config dir setup

hermes version
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
hermes 0.12.0

Edit hermes config (use ports according to the port configuration we set above, add only chains you want to relay)

nano $HOME/.hermes/config.toml

In this example, we will set channel-141 on the cosmoshub-4 chain settings and channel-0 on the osmosis-1 chain settings:

[[chains]]
id = 'cosmoshub-4'
rpc_addr = 'http://127.0.0.1:26757'
grpc_addr = 'http://127.0.0.1:9092'
websocket_addr = 'ws://127.0.0.1:26757/websocket'
rpc_timeout = '10s'
account_prefix = 'cosmos'
key_name = 'cosmos'
address_type = { derivation = 'cosmos' }
store_prefix = 'ibc'
default_gas = 2000000
max_gas = 10000000
gas_price = { price = 0.005, denom = 'uatom' }
gas_adjustment = 0.1
max_msg_num = 25
max_tx_size = 180000
clock_drift = '10s'
max_block_time = '10s'
trusting_period = '14days'
memo_prefix = ''
trust_threshold = { numerator = '1', denominator = '3' }
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-141'], # osmosis-1
]

[[chains]]
id = 'osmosis-1'
rpc_addr = 'http://127.0.0.1:26657'
grpc_addr = 'http://127.0.0.1:9090'
websocket_addr = 'ws://127.0.0.1:26657/websocket'
rpc_timeout = '10s'
account_prefix = 'osmo'
key_name = 'osmosis'
address_type = { derivation = 'cosmos' }
store_prefix = 'ibc'
default_gas = 5000000
max_gas = 15000000
gas_price = { price = 0.0026, denom = 'uosmo' }
gas_adjustment = 0.1
max_msg_num = 20
max_tx_size = 209715
clock_drift = '20s'
max_block_time = '10s'
trusting_period = '10days'
memo_prefix = 'Relayed by Czar'
trust_threshold = { numerator = '1', denominator = '3' }
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-0'], # cosmoshub-4
]

Add your relayer wallet to Hermes' keyring (located in $HOME/.hermes/keys)

Best practice is to use the same mnemonic over all networks. Do not use your relaying-addresses for anything else because it will lead to account sequence errors.

hermes keys restore cosmoshub-4 -m "24-word mnemonic seed"
hermes keys restore osmosis-1 -m "24-word mnemonic seed"

Ensure this wallet has funds in both OSMO and ATOM in order to pay the fees required to relay.

Final Checks

You can validate your hermes configuration file:

hermes config validate
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
Success: "validation passed successfully"

Perform health check to see if all connected nodes are up and synced:

hermes health-check
INFO ThreadId(01) using default configuration from '/home/relay/.hermes/config.toml'
INFO ThreadId(01) telemetry service running, exposing metrics at http://0.0.0.0:3001/metrics
INFO ThreadId(01) starting REST API server listening at http://127.0.0.1:3000
INFO ThreadId(01) [cosmoshub-4] chain is healthy
INFO ThreadId(01) [osmosis-1] chain is healthy

When your nodes are fully synced you can start the hermes daemon:

hermes start

Watch hermes' output for successfully relayed packets or any errors. It will try & clear any unreceived packets after startup has completed.

Helpful Commands

Query Hermes for unreceived packets & acknowledgements (check if channels are "clear")

hermes query packet unreceived-packets cosmoshub-4 transfer channel-141
hermes query packet unreceived-acks cosmoshub-4 transfer channel-141
hermes query packet unreceived-packets osmosis-1 transfer channel-0
hermes query packet unreceived-acks osmosis-1 transfer channel-0

Query Hermes for packet commitments:

hermes query packet commitmentss cosmoshub-4 transfer channel-141
hermes query packet commitments osmosis-1 transfer channel-0

Clear channel (only works on hermes v0.12.0 and higher)

hermes clear packets cosmoshub-4 transfer channel-141
hermes clear packets osmosis-1 transfer channel-0

Clear unreceived packets manually. Experimental: you'll need to stop your hermes daemon for it not to get confused with account sequences.

hermes tx raw packet-recv osmosis-1 cosmoshub-4 transfer channel-141
hermes tx raw packet-ack osmosis-1 cosmoshub-4 transfer channel-141
hermes tx raw packet-recv cosmoshub-4 osmosis-1 transfer channel-0
hermes tx raw packet-ack cosmoshub-4 osmosis-1 transfer channel-0