diff --git a/README.md b/README.md index 84f753167..c0bf9042c 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,127 @@ # Relayer -![Relayer](./docs/images/github-repo-banner.gif) - -![Relayer Build](https://github.com/cosmos/relayer/workflows/Build%20then%20run%20CI%20Chains/badge.svg) - -The Cosmos IBC `relayer` package contains a basic relayer implementation that is -meant for users wishing to relay packets/data between sets of IBC enabled chains. -In addition, it is intended as an example where anyone who is interested in building -their own relayer can come for complete, working, examples. - -**NOTE:** The relayer is in alpha and is not production ready. If it is used in production, -it should always be run in a secure environment and only with just enough funds to -relay transactions. Security critical operations **should** manually verify that the -client identifier used in the configuration file corresponds to the correct initial -consensus state of the counterparty chain. This can be done by querying the initial -consensus state and the header of the counterparty and verifying that the root and -hash of the next validator set match. This can be considered equivalent to checking -the sha hash of a download or a GPG signature. -### Security Notice +![Relayer](./docs/images/github-repo-banner.gif) -If you would like to report a security critical bug related to the relayer repo, please send an email to [`security@cosmosnetwork.dev`](mailto:security@cosmosnetwork.dev) +[![Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](https://img.shields.io/badge/repo%20status-WIP-yellow.svg?style=flat-square)](https://www.repostatus.org/#wip) +![GitHub Workflow Status](https://img.shields.io/github/workflow/status/cosmos/relayer/BUILD%20-%20build%20and%20binary%20upload?style=flat-square) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue?style=flat-square&logo=go)](https://godoc.org/github.com/cosmos/relayer) +[![Go Report Card](https://goreportcard.com/badge/github.com/cosmos/relayer?style=flat-square)](https://goreportcard.com/report/github.com/cosmos/relayer) +[![License: Apache-2.0](https://img.shields.io/github/license/cosmos/relayer.svg?style=flat-square)](https://github.com/cosmos/relayer/blob/master/LICENSE) +[![Lines Of Code](https://img.shields.io/tokei/lines/github/cosmos/relayer?style=flat-square)](https://github.com/cosmos/relayer) +[![Version](https://img.shields.io/github/tag/cosmos/relayer.svg?style=flat-square)](https://github.com/umee-network/cosmos/relayer/latest) + +This repository contains a Golang implementation of a Cosmos [IBC](https://ibcprotocol.org/) +relayer. The `relayer` package contains a basic relayer implementation that is +meant for users wanting to relay packets/data between sets of +[IBC](https://ibcprotocol.org/)-enabled chains. + +The relayer implementation also acts as a base reference implementation for those +wanting to build their [IBC](https://ibcprotocol.org/)-compliant relayer. + +> **NOTE:** The relayer is currently in alpha and is not production ready. If it +> is used in production, it should always be run in a secure environment and +> only with just enough funds to relay transactions. Security critical operations +> **should** manually verify that the client identifier used in the configuration +> file corresponds to the correct initial consensus state of the counter-party +> chain. This can be done by querying the initial consensus state and the header +> of the counter-party and verifying that the root and hash of the next validator +> set match. This can be considered equivalent to checking the sha hash of a +> download or a GPG signature. + +- [Relayer](#relayer) + - [Security Notice](#security-notice) + - [Code of Conduct](#code-of-conduct) + - [Testnet](#testnet) + - [Compatibility Table](#compatibility-table) + - [Features](#features) + - [Relayer Terminology](#relayer-terminology) + - [Recommended Pruning Settings](#recommended-pruning-settings) + - [Demoing the Relayer](#demoing-the-relayer) + - [Setting up Developer Environment](#setting-up-developer-environment) + +## Security Notice + +If you would like to report a security critical bug related to the relayer repo, +please send an email to [`security@cosmosnetwork.dev`](mailto:security@cosmosnetwork.dev) ## Code of Conduct -The Cosmos community is dedicated to providing an inclusive and harassment free experience for contributors. Please visit [Code of Conduct](CODE_OF_CONDUCT.md) for more information. +The Cosmos community is dedicated to providing an inclusive and harassment free +experience for contributors. Please visit [Code of Conduct](CODE_OF_CONDUCT.md) for more information. ## Testnet If you would like to join a relayer testnet, please [check out the instructions](./testnets/README.md). -### Compatibility Table: - -> NOTE: +## Compatibility Table -| chain | tests | supported ports | -|-------|--------|----------------| -| [`gaia`](https://github.com/cosmos/gaia) | ![gaia](https://github.com/cosmos/relayer/workflows/TESTING%20-%20gaia%20to%20gaia%20integration/badge.svg) | `transfer` | +| chain | build | supported ports | +|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| [gaia](https://github.com/cosmos/gaia) | ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/cosmos/relayer/TESTING%20-%20gaia%20to%20gaia%20integration?style=flat-square) | transfer | +| [akash](https://github.com/ovrclk/akash) | ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/cosmos/relayer/TESTING%20-%20akash%20to%20gaia%20integration?style=flat-square) | transfer | ## Features The relayer supports the following: + - creating/updating IBC Tendermint light clients - creating IBC connections - creating IBC transfer channels. - initiating a cross chain transfer - relaying a cross chain transfer transaction, its acknowledgement, and timeouts - relaying from state -- relaying from streaming events +- relaying from streaming events - sending an UpgradePlan proposal for an IBC breaking upgrade -- upgrading clients after a counterparty chain has performed an upgrade for IBC breaking changes +- upgrading clients after a counter-party chain has performed an upgrade for IBC breaking changes The relayer currently cannot: + - create clients with user chosen parameters (such as UpgradePath) -- submit IBC client unfreezing proposals -- monitor and submit misbehaviour for clients +- submit IBC client unfreezing proposals +- monitor and submit misbehavior for clients - use IBC light clients other than Tendermint such as Solo Machine - connect to chains which don't implement/enable IBC - connect to chains using a different IBC implementation (chains not using SDK's `x/ibc` module) ## Relayer Terminology -A Path in the relayer represents one very specific path followed to get from one chain to another. -Two chains may have many different paths between them. Any path with different clients, connections, -or channels are considered unqiuely different and non-fungible. +A `path` in the relayer represents one very specific path followed to get from +one chain to another. Two chains may have many different paths between them. Any +path with different clients, connections, or channels are considered uniquely +different and non-fungible. -When using with live networks, it is advised to pre-select your desired parameters for your client, -connection, and channel. The relayer will automatically reuse any existing clients that match your -configurations since clients, connections, and channels are public goods (no one has control over -them). +When using with live networks, it is advised to pre-select your desired parameters +for your clients, connections, and channels. The relayer will automatically +reuse any existing clients that match your configurations since clients, +connections, and channels are public goods (no one has control over them). ## Recommended Pruning Settings -The relayer relies on old headers and proofs constructed at past block heights to facilitate IBC. -For this reason, connected full nodes are recommended to prune old blocks once they have passed -the unbonding period of the chain. - -Here are the settings used to configure SDK based nodes: -``` ---pruning=custom --pruning-keep-recent=362880 --pruning-keep-every=0 --pruning-interval=100 -``` +The relayer relies on old headers and proofs constructed at past block heights +to facilitate correct[IBC](https://ibcprotocol.org/) behavior. For this reason, +connected full nodes may prune old blocks once they have passed the unbonding +period of the chain but not before. Not pruning at all is not necessary for a +fully functional relayer, however, pruning everything will lead to many issues! -`362880 (3*7*24*60*60 / 5 = 362880)` represents a 3 week unbonding period (assuming 5 seconds per block). +Here are the settings used to configure SDK-based full nodes (assuming 3 week unbonding period): -Note: -``` ---pruning-keep-every=0 --pruning-interval=100 +```shell +... --pruning=custom --pruning-keep-recent=362880 --pruning-keep-every=0 --pruning-interval=100 ``` -can be modified to your desired settings. +`362880 (3*7*24*60*60 / 5 = 362880)` represents a 3 week unbonding period (assuming 5 seconds per block). -Pruning nothing is not necessary for a fully functional relayer. Pruning everything will lead to many issues. +Note, operators can tweak `--pruning-keep-every` and `--pruning-interval` to their +liking. ## Demoing the Relayer ![Demo](./docs/images/demo.gif) -While the relayer is under active development, it is meant primarily as a learning tool to better understand the Inter-Blockchain Communication (IBC) protocol. In that vein, the following demo demonstrates the core functionality which will remain even after the changes: +While the relayer is under active development, it is meant primarily as a learning +tool to better understand the Inter-Blockchain Communication (IBC) protocol. In +that vein, the following demo demonstrates the core functionality which will +remain even after the changes: ```bash # ensure go and jq are installed @@ -150,9 +176,21 @@ $ rly q bal ibc-1 ## Setting up Developer Environment -Working with the relayer can frequently involve working with local development branches of `gaia`, `akash`, `cosmos-sdk` and the `relayer`. To setup your environment to point at the local versions of the code and reduce the amount of time in your read-eval-print loops try the following: - -1. Set `replace github.com/cosmos/cosmos-sdk => /path/to/local/github.com/comsos/cosmos-sdk` at the end of the `go.mod` files for the `relayer` and `gaia`. This will force building from the local version of the `cosmos-sdk` when running the `./dev-env` script. -2. After `./dev-env` has run, you can use `go run main.go` for any relayer commands you are working on. This allows you make changes and immediately test them as long as there are no server side changes. -3. If you make changes in `cosmos-sdk` that need to be reflected server-side, be sure to re-run `./two-chainz`. -4. If you need to work off of a `gaia` branch other than `master`, change the branch name at the top of the `./two-chainz` script. +Working with the relayer can frequently involve working with local development +branches of your desired applications/networks, e.g. `gaia`, `akash`, in addition +to `cosmos-sdk` and the `relayer`. + +To setup your environment to point at the local versions of the code and reduce +the amount of time in your read-eval-print loops try the following: + +1. Set `replace github.com/cosmos/cosmos-sdk => /path/to/local/github.com/comsos/cosmos-sdk` + at the end of the `go.mod` files for the `relayer` and your network/application, + e.g. `gaia`. This will force building from the local version of the `cosmos-sdk` + when running the `./dev-env` script. +2. After `./dev-env` has run, you can use `go run main.go` for any relayer + commands you are working on. This allows you make changes and immediately test + them as long as there are no server side changes. +3. If you make changes in `cosmos-sdk` that need to be reflected server-side, + be sure to re-run `./two-chainz`. +4. If you need to work off of a `gaia` branch other than `master`, change the + branch name at the top of the `./two-chainz` script. diff --git a/docs/testing.md b/docs/testing.md index 8732e13b2..55bde9dc9 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -1,27 +1,49 @@ # Testing -The relayer contains a testing framework designed to be used to test compatibility between different cosmos-sdk based chains for IBC relaying. This will be especially useful during the period where IBC is under active development as it will provide a central integration test to ensure that the many different implementations all work together. It will also be required if you are looking to participate with a custom zone in Game of Zones. +The relayer contains a testing framework designed to be used to test compatibility +between different cosmos-sdk based chains for IBC relaying. This will be especially +useful during the period where IBC is under active development as it will provide +a central integration test to ensure that the many different implementations all +work together. It will also be required if you are looking to participate with a +custom zone in Game of Zones. ## Using the test framework -Because of the nature of the relayer (i.e. it is meant to run against different chains), mocking out the interfaces for unit tests would be prohibitively expensive from a resources point of view. Because of this, I've decided to go with a full integration testing framework that tests the user-critical paths of the relayer code for each chain to ensure compatibility between the chains and a functional Game of Zones. To add your chain to the framework, follow the guide below: +Because of the nature of the relayer (i.e. it is meant to run against different chains), +mocking out the interfaces for unit tests would be prohibitively expensive from +a resources point of view. Because of this, we've decided to go with a full +integration testing framework that tests the user-critical paths of the relayer +code for each chain to ensure compatibility between the chains and a functional +Game of Zones. To add your chain to the framework, follow the guide below: -### Overview +## Overview -The test framework is built using `go test` and `docker`. What is happening for each test is that a number of independent chains of a specified type are spun up and the relayer runs a series of transactions and tests for the expected results. We are using the [`ory/dockertest`](https://github.com/ory/dockertest) to provide a nice interface for using docker programmatically w/in the tests. +The test framework is built using `go test` and `docker`. What is happening for +each test is that a number of independent chains of a specified type are spun up +and the relayer runs a series of transactions and tests for the expected results. +We are using the [`ory/dockertest`](https://github.com/ory/dockertest) to provide +a nice interface for using docker programmatically within the tests. ### Step 1: Write a Dockerfile and publish an image for your chain -The testing framework expects your chain to have a `Dockerfile` with an `ENTRYPOINT` script that accepts two arguments: `chain-id`, which should be unique to the individual test, and `relayer-address`, an address to include in the genesis file so that the testing relayer has access to funds. This is normally best accomplished with an `./entrypoint.sh` script that performs the necessary chain bootstrapping. The `cosmos/gaia` repositories provide an example of both: +The testing framework expects your chain to have a `Dockerfile` with an +`ENTRYPOINT` script that accepts two arguments: `chain-id`, which should be +unique to the individual test, and `relayer-address`, an address to include in +the genesis file so that the testing relayer has access to funds. This is normally +best accomplished with an `./entrypoint.sh` script that performs the necessary +chain bootstrapping. The `cosmos/gaia` repositories provide an example of both: - [`./entrypoint.sh`](https://github.com/cosmos/gaia/tree/master/contrib/single-node.sh) - [`Dockerfile.test`](https://github.com/cosmos/gaia/tree/master/contrib/Dockerfile.test) -Then you need to build and push your image to a public image repository. Having it tagged with the git sha and branch is best practice. See the build procedure for the gaia image: +Then you need to build and push your image to a public image repository. Having +it tagged with the git sha and branch is best practice. See the build procedure +for the gaia image: - [`Makefile`](https://github.com/cosmos/gaia/blob/master/Makefile#L164) -At the end, you should have an image you can run which starts up an instance of your chain: +At the end, you should have an image you can run which starts up an instance of +your chain: ```shell # add configuration for the yet-to-be-created chain to the relayer @@ -36,9 +58,12 @@ rly q bal mychainid ### Step 2: Add your chain configuration to the test harness -Next you will need to define a new instance of `testChainConfig` in the `test/test_chains.go` file. Follow the `gaiaTestConfig` example: +Next you will need to define a new instance of `testChainConfig` in the +`test/test_chains.go` file. Follow the `gaiaTestConfig` example: -> NOTE: I've increased the default block timeouts for gaia to the values noted below. This makes the tests faster. If you would like to do the same for your chain see the `sed` commands in the [entrypoint](https://github.com/cosmos/gaia/tree/master/contrib/single-node.sh). +> NOTE: We've increased the default block timeouts for gaia to the values noted +> below. This makes the tests faster. If you would like to do the same for your +> chain see the `sed` commands in the [entrypoint](https://github.com/cosmos/gaia/tree/master/contrib/single-node.sh). ```go // GAIA BLOCK TIMEOUTS on jackzampolin/gaiatest:jack_relayer-testing @@ -63,11 +88,19 @@ myChainTestConfig = testChainConfig { } ``` -> NOTE: If you do any custom encoding/decoding in your chain, you may want to import your codec and attach it here. To do this, `go get` the package your codec is in, include it in the `test/test_chains.go` `import` section and instantiate your codec. You may run into build errors due to incompatible Tendermint or SDK versions. Please bring your chain up the relayer version to continue with a custom codec. +> NOTE: If you do any custom encoding/decoding in your chain, you may want to +> import your codec and attach it here. To do this, `go get` the package your +> codec is in, include it in the `test/test_chains.go` `import` section and +> instantiate your codec. You may run into build errors due to incompatible +> Tendermint or SDK versions. Please bring your chain up the relayer version to +> continue with a custom codec. -### Step 3: Write your tests! +### Step 3: Write your tests -Now you can write tests! Create a new file named `test/relayer_{chain-type}_test.go` and write your tests! Emulate (or copy) the `gaia` examples to start. The framework is designed to be flexible enough to eventually allow testing of custom functionality. +Now you can write tests! Create a new file named `test/relayer_{chain-type}_test.go` +and write your tests! Emulate (or copy) the `gaia` examples to start. The +framework is designed to be flexible enough to eventually allow testing of +custom functionality. ```go var ( @@ -107,63 +140,67 @@ func TestGaiaToGaiaBasicTransfer(t *testing.T) { } ``` -### Step 4: Get your badge on the README! - -The [README](../README.md) contains a compatabilty matrix that is populated with status badges from Github Actions that shows the current status of different implementations. If you would like to add yours to this list (and if you have gotten this far, YOU SHOULD!!) do the following: - -1. Add a `Makefile` command that just calls your chain's tests. This is made easy by the `-tags` flag that reads parts of the filenames of go tests. See the `gaia` command for an example: - -```Makefile -test-gaia: - @go test -mod=readonly -v -coverprofile coverage.out ./test/... -tags gaia - -test-mychain: - @go test -mod=readonly -v -coverprofile coverage.out ./test/... -tags mychain -``` - -2. Add a `.github/{mychain}-tests.yml` file that is a copy of `.github/gaia-tests.yml` but modified for your chain. - -```yml -name: TESTING - gaia to mychain integration - -on: [push] - -jobs: - - build: - name: build - runs-on: ubuntu-latest - steps: - - # Install and setup go - - name: Set up Go 1.14 - uses: actions/setup-go@v1 - with: - go-version: 1.14 - id: go - - # setup docker - - name: Set up Docker 19.03 - uses: docker-practice/actions-setup-docker@0.0.1 - with: - docker-version: 19.03 - docker-channel: stable - - # checkout relayer - - name: checkout relayer - uses: actions/checkout@v2 - - # build cache - - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - # run tests - - name: run mychain tests - run: make test-mychain -``` - -3. Get the +### Step 4: Get your badge on the README + +The [README](../README.md) contains a compatabilty matrix that is populated with +status badges from Github Actions that shows the current status of different +implementations. If you would like to add yours to this list +(and if you have gotten this far, YOU SHOULD!!) do the following: + +1. Add a `Makefile` command that just calls your chain's tests. This is made + easy by the `-tags` flag that reads parts of the filenames of go tests. + See the `gaia` command for an example: + + ```Makefile + test-gaia: + @go test -mod=readonly -v -coverprofile coverage.out ./test/... -tags gaia + + test-mychain: + @go test -mod=readonly -v -coverprofile coverage.out ./test/... -tags mychain + ``` + +2. Add a `.github/{mychain}-tests.yml` file that is a copy of `.github/gaia-tests.yml` + but modified for your chain. + + ```yml + name: TESTING - gaia to mychain integration + + on: [push] + + jobs: + + build: + name: build + runs-on: ubuntu-latest + steps: + + # Install and setup go + - name: Set up Go 1.14 + uses: actions/setup-go@v1 + with: + go-version: 1.14 + id: go + + # setup docker + - name: Set up Docker 19.03 + uses: docker-practice/actions-setup-docker@0.0.1 + with: + docker-version: 19.03 + docker-channel: stable + + # checkout relayer + - name: checkout relayer + uses: actions/checkout@v2 + + # build cache + - uses: actions/cache@v1 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + # run tests + - name: run mychain tests + run: make test-mychain + ```