# Go Relayer
Before you dive into Go relayers, make sure to:
- Install Go.
- Install Docker.
- Install Rust.
For all installations, please see the setup page.
Have you considered running a relayer?
In this section, you will learn:
- How to get started with the Go relayer.
- Basic Go relayer commands.
The Go relayer (opens new window) is a relayer implementation written in Golang. It can create clients, connections, and channels, as well as relay packets and update and upgrade clients.
The Go relayer aims to get your relayer up and running with minimal manual configuration and abstracts away a lot of the more complex Inter-Blockchain Communication Protocol (IBC) concepts. The objective is that users can spin up their own relayer and relay packets. To provide this functionality, it automates a lot of work to fetch configuration data from the chain registry (opens new window).
After the installation, you will get started with relaying on mainnet chains and do some local testing.
# Installation and getting started
The repository offers a script to start two chains, which you need to test the relayer.
The most up-to-date major version of the Go relayer is v2. This version delivered major updates and improvements, including the introduction of a provider interface to accommodate chains with different consensus types than CometBFT and event-based processing that results in performance improvements.
It is recommended to use this latest version, and the following commands assume you are using v2.
- First, create a folder for this section:
- Clone the Go relayer repository (opens new window):
- Now build the Go relayer:
Make sure that your $GOPATH
is set correctly and $GOPATH/bin
is included in your $PATH
.
To check the available commands, run the help command on the rly
binary.
Which returns:
Notice how the categories reflect the requirements you saw in the last section: to manage chain and path information, manage keys, query, and transact. The configuration data is added to the config file, stored at $HOME/.relayer/config/config.yaml
by default. If this is the first time you run the relayer, first initialize the config with the following command:
And check the config with:
By default, transactions will be relayed with a memo of rly(VERSION)
- for example, rly(v2.0.0)
.
To customize the memo for all relaying, use the --memo
flag when initializing the configuration.
Custom memos will have rly(VERSION)
appended. For example, a memo of My custom memo
running on relayer version v2.0.0
would result in a transaction memo of My custom memo | rly(v2.0.0)
.
The --memo
flag is also available for other rly
commands that involve sending transactions, such as rly tx link
and rly start
. It can be passed there to override the config.yaml
value if desired.
To omit the memo entirely, including the default value of rly(VERSION)
, use -
for the memo.
Now you are all set to add the chains and paths you want to relay on, add your keys and start relaying. You will investigate two different scenarios: setting up a relayer between two chains on the mainnet (this would enable you to start relaying in production), and setting up two local chains for testing purposes.
# Relaying in production
As stated earlier, the Go relayer strives to get your relayer up and running in a short amount of time. You will follow the tutorial from the Github repository (opens new window) to start relaying between the Cosmos Hub and Osmosis, one of the most popular paths.
- Configure the chains you want to relay between.
In this example, you will configure the relayer to operate on the canonical path between the Cosmos Hub and Osmosis.
The rly chains add
command fetches chain metadata from the chain registry (opens new window) and adds it to your config file:
Adding chains from the chain registry randomly selects a publicly available RPC address from the registry entry. If you are running your own node (which is recommended if you are running relaying services professionally), manually go into the config and adjust the rpc-addr
setting to the RPC endpoint you have exposed.
rly chains add
will check the liveliness of the available RPC endpoints for that chain in the chain registry. The command may fail if none of these RPC endpoints are available. In this case, you will want to manually add the chain config.
To add the chain config files manually, example config files have been included in the Cosmos relayer documentation (opens new window).
- Import OR create new keys for the relayer to use when signing and relaying transactions.
key-name
is an identifier of your choosing.
If you need to generate a new private key you can use the
add
subcommand:If you already have a private key and want to restore it from your mnemonic you can use the
restore
subcommand:
- Edit the relayer's
key
values in the config file to match thekey-name
s chosen above.
This step is necessary if you chose a key-name
other than "default".
Example:
- Ensure the keys associated with the configured chains are funded.
ATTENTION: Your configured addresses will need to contain some of the respective native tokens to pay relayer fees.
You can query the balance of each configured key by running:
- Configure path metadata in the config file.
You configured the chain metadata, now you need path metadata. This scenario assumes that there is already a canonical channel, so there is no need for light client creation, nor connection and channel handshakes to set these up.
There is one easy command to get this path information - initially from the interchain folder (opens new window) in the Go relayer repository, but this is being replaced by IBC data in the chain registry (opens new window).
Do not see the path metadata for paths you want to relay on? Please open a Push Request (PR) to add this metadata to the GitHub repository!
- Configure the channel filter.
By default, the relayer will relay packets over all channels on a given connection.
Each path has a src-channel-filter
, which you can utilize to specify which channels you would like to relay on.
The rule
can be one of three values:
allowlist
, which tells the relayer to relay on only the channels inchannel-list
.denylist
, which tells the relayer to relay on all channels except the channels inchannel-list
.- Empty value, which is the default setting and tells the relayer to relay on all channels.
Since you should only be worried about the canonical channel between the Cosmos Hub and Osmosis, our filter settings would look like the following:
Example:
Because two channels between chains are tightly coupled, there is no need to specify the dst channels.
- Do a status check.
Before starting to relay and after making some changes to the config, you can check the status of the chains and paths in the config:
Which returns this output when healthy:
Which returns this output when healthy:
In case one of the checks receives a ✘
instead of ✔
, you will need to check if you completed all the previous steps correctly.
- Finally, start the relayer on the desired path.
The relayer will periodically update the clients and listen for IBC messages to relay.
The relayer now has an event processor added to respond to emitted events signaling an IBC packet event. You can use it by adding an additional flag:
You will need to start a separate shell instance for each path you wish to relay over.
When running multiple instances of rly start
, you will need to use the --debug-addr
flag and provide an address:port
. You can also pass an empty string ''
to turn off this feature, or pass localhost:0
to randomly select a port.
# Testing locally
Besides running a relayer between mainnet chains, you can also run a relayer between public testnet chains, or run chains locally to do some testing of particular scenarios. Here you will use a docker-compose
network with two local checkers
chains and a relayer between them.
The example presented is based on the demo in the b9lab/cosmos-ibc-docker (opens new window) repository.
Start by cloning the repository:
Make sure that you have installed Docker Compose (opens new window) and Docker (opens new window) before continuing.
Then build the images for the checkers blockchain:
You can build the relayer image manually, or just start the network via docker-compose
and let it build the missing image for the ibc-go
relayer:
Observe the output of docker-compose
until the chains are ready - the chains will take some time.
When the chains are ready, start the relayer process. In a new terminal, jump into the relayer container:
The demo includes a script to start the relayer, but do the steps manually to practice a bit.
First, initialize the configuration:
You can find the configs
and paths
folders in the folder cosmos-ibc-docker/tokentransfer/relayer_go
. In the checkersa.json
and checkersb.json
, you can find the endpoints of the chains and a default key alias.
Populate the aliases:
The mnemonics are set in the checkers blockchains, take alice from checkersa
and bob from checkersb
.
Now check if the chains and path(s) are ready to relay over:
You can now connect the two chains with the link
command.
The relayer will check if any clients, connections, and channels are present for the given path. If not, the link
command will attempt to create the missing objects.
You can also check rly tx -h
to find the separate commands for these actions.
Next, check the token balances on both chains:
Finally, send some tokens between the chains:
The default key used for checkersa is alice.
$(rly chains address checkersb)
will give the address of bob.
You created the commitment proof on checkersa
to send the packet, but no relaying has taken place yet.
# Relay packets/acknowledgements
Running rly start demo
would essentially loop these two commands:
Check that the transfer was completed:
You can see that the tokens have a denom on the checkersb
chain because they are not native token
s of checkersb
. Send the tokens back to the account on checkersa
by replacing $denom
(this will be something like ibc/D11F61D9F5E49A31348A7CD2DECE888D4DFEE1DADA343F7D8D4502BFA9496936
):
Check that the return trip was completed:
You can see that the stake balances decreased on each chain because of the set fees in the configuration.
If you are finished with the tests, make sure to shut down your network with:
To summarize, this section has explored:
- The Go relayer, a relayer implementation written in Golang that can create clients, connections, and channels, as well as relay packets, and update and upgrade clients.
- How the Go relayer requires minimal manual configuration and abstracts away many more complex IBC concepts by automating a lot of work to fetch configuration data from the chain registry.
- How to install and configure the Go relayer, and how to run it between public testnet chains or locally run chains to conveniently test particular scenarios.