Fresh Rust installation: For instructions on how to install Rust on your machine please follow the official Notes about Rust installation at https://www.rust-lang.org/tools/install
Setup full nodes & configure seeds, peers and endpoints
To successfully relay IBC packets you need to run private full nodes (custom pruning or archive node) on all networks you want to support. Since relaying-success highly depends on latency and disk-IO-rate it is currently recommended to service these full/archive nodes on the same machine as the relayer process.
Because the relaying process needs to be able to query the chain back in height for at least 2/3 of the unstaking period ("trusting period") it is recommended to use pruning settings that will keep the full chain-state for a longer period of time than the unstaking period:
edit app.toml - note: at an average block time of 6.5sec pruning-keep-recent=400000 will result in a retained chainstate of ~30d. This will suffice for most cosmos-sdk chains with an unstaking period < 30d
Beware that for security reasons this step should be done 'on some remote pc'
Make the directory where you'll place the source, clone the hermes source repository and build it using the latest release. Optional: copy binary to /usr/bin (or preferred directory for systemd execution)
Edit hermes config (use ports according to your port config, set filter=true to filter channels you don't relay) vim ~/.hermes/config.toml
# The global section has parameters that apply globally to the relayer operation.[global]# Specify the strategy to be used by the relayer. Default: 'packets'# Two options are currently supported:# - 'all': Relay packets and perform channel and connection handshakes.# - 'packets': Relay packets only.strategy ='packets'# Enable or disable the filtering mechanism. Default: 'false'# Valid options are 'true', 'false'.# Currently Hermes supports two filters:# 1. Packet filtering on a per-chain basis; see the chain-specific# filter specification below in [chains.packet_filter].# 2. Filter for all activities based on client state trust threshold; this filter# is parametrized with (numerator = 1, denominator = 3), so that clients with# thresholds different than this will be ignored.# If set to 'true', both of the above filters will be enabled.#filter = true # breaking in v0.11.0 where filter = true by default# Specify the verbosity for the relayer logging output. Default: 'info'# Valid options are 'error', 'warn', 'info', 'debug', 'trace'.log_level ='info'# Parametrize the periodic packet clearing feature.# Interval (in number of blocks) at which pending packets# should be eagerly cleared. A value of '0' will disable# periodic packet clearing. Default: 100clear_packets_interval =25# Toggle the transaction confirmation mechanism.# The tx confirmation mechanism periodically queries the `/tx_search` RPC# endpoint to check that previously-submitted transactions# (to any chain in this config file) have delivered successfully.# Experimental feature. Affects telemetry if set to false.# Default: true.tx_confirmation =true# The REST section defines parameters for Hermes' built-in RESTful API.# https://hermes.informal.systems/rest.html[rest]# Whether or not to enable the REST service. Default: falseenabled =true# Specify the IPv4/6 host over which the built-in HTTP server will serve the RESTful# API requests. Default: 127.0.0.1host ='127.0.0.1'# Specify the port over which the built-in HTTP server will serve the restful API# requests. Default: 3000port =3000# The telemetry section defines parameters for Hermes' built-in telemetry capabilities.# https://hermes.informal.systems/telemetry.html[telemetry]# Whether or not to enable the telemetry service. Default: falseenabled =true# Specify the IPv4/6 host over which the built-in HTTP server will serve the metrics# gathered by the telemetry service. Default: 127.0.0.1host ='127.0.0.1'# Specify the port over which the built-in HTTP server will serve the metrics gathered# by the telemetry service. Default: 3001port =3001[[chains]]id ='osmosis-1'rpc_addr ='http://localhost:7001'grpc_addr ='http://localhost:7002'websocket_addr ='ws://localhost:7001/websocket'rpc_timeout ='10s'account_prefix ='osmo'key_name ='osmosis'address_type = { derivation ='osmosis' }store_prefix ='ibc'default_gas =5000000max_gas =15000000gas_price = { price =0.000, denom ='uosmo' }gas_adjustment =0.1max_msg_num =20max_tx_size =2097152clock_drift ='20s'max_block_time ='10s'trusting_period ='10days'memo_prefix =''trust_threshold = { numerator ='1', denominator ='3' }[chains.packet_filter]policy ='allow'list = [ ['transfer','channel-73']][[chains]]id ='bitsong-2b'rpc_addr ='http://127.0.0.1:7011'grpc_addr ='http://127.0.0.1:7012'websocket_addr ='ws://127.0.0.1:7011/websocket'rpc_timeout ='10s'account_prefix ='bitsong'key_name ='bitsong'address_type = { derivation ='bitsong' }store_prefix ='ibc'default_gas =2000000max_gas =4000000gas_price = { price =0.026, denom ='ubtsg' }gas_adjustment =0.1max_msg_num =25max_tx_size =1800000clock_drift ='10s'max_block_time ='10s'trusting_period ='14d'memo_prefix =''trust_threshold = { numerator ='1', denominator ='3' }[chains.packet_filter]policy ='allow'list = [ ['transfer','channel-0'], ['transfer','channel-1'] ][[chains]]id ='cosmoshub-4'rpc_addr ='http://127.0.0.1:7021'grpc_addr ='http://127.0.0.1:7022'websocket_addr ='ws://127.0.0.1:7021/websocket'rpc_timeout ='10s'account_prefix ='cosmos'key_name ='cosmos'address_type = { derivation ='cosmos' }store_prefix ='ibc'default_gas =2000000max_gas =3000000gas_price = { price =0.001, denom ='uatom' }gas_adjustment =0.1max_msg_num =25max_tx_size =180000clock_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-229'] ]
Add your relaying-wallets 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 might lead to mismatched account sequence errors.
Hermes does a chain-health-check at startup. Watch the output to check if all connected nodes are up and synced
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) [osmosis-1] chain is healthy
INFO ThreadId(01) [cosmoshub-4] chain is healthy
INFO ThreadId(01) [bitsong-2b] chain is healthy
...
INFO ThreadId(01) Hermes has started
Hermes will try & clear any unreceived packets after startup has completed.
Snippets
Query Hermes for unreceived packets & acknowledgements (check if channels are "clear")
hermes query packet unreceived-packets bitsong-2b transfer channel-0
hermes query packet unreceived-acks bitsong-2b transfer channel-0
hermes query packet unreceived-packets osmosis-1 transfer channel-73
hermes query packet unreceived-acks bitsong-1 transfer channel-73
Query Hermes for packet commitments:
hermes query packet commitments osmosis-1 transfer channel-73
hermes query packet commitments bitsong-2b transfer channel-0
Clear channel (only works on hermes v0.12.0 and higher)
hermes clear packets omniflixhub-1 transfer channel-1
hermes clear packets osmosis-1 transfer channel-199
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 bitsong-2b transfer channel-0
hermes tx raw packet-recv bitsong-2b osmosis-1 transfer channel-73