-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
1,365 additions
and
608 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# CODEOWNERS: https://help.github.com/articles/about-codeowners/ | ||
|
||
* @colin-axner @fedekunze @AdityaSripal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//') | ||
COMMIT := $(shell git log -1 --format='%H') | ||
SDKCOMMIT := $(shell go list -m -u -f '{{.Version}}' github.com/cosmos/cosmos-sdk) | ||
GAIA_VERSION := main | ||
GAIA_VERSION := v4.0.0 | ||
AKASH_VERSION := jack/update-sdk | ||
WASMD_VERSION := v0.14.1 | ||
|
||
GOPATH := $(shell go env GOPATH) | ||
GOBIN := $(GOPATH)/bin | ||
|
||
all: ci-lint install | ||
|
||
############################################################################### | ||
|
@@ -38,7 +43,7 @@ compile-clib: | |
|
||
install: go.sum | ||
@echo "installing rly binary..." | ||
@go build -mod=readonly $(BUILD_FLAGS) -o $${GOBIN-$${GOPATH-$$HOME/go}/bin}/rly main.go | ||
@go build -mod=readonly $(BUILD_FLAGS) -o $(GOBIN)/rly main.go | ||
|
||
############################################################################### | ||
# Tests / CI | ||
|
@@ -81,7 +86,14 @@ get-akash: | |
@mkdir -p ./chain-code/ | ||
@git clone --branch $(AKASH_VERSION) [email protected]:ovrclk/akash.git ./chain-code/akash | ||
|
||
get-chains: get-gaia get-akash | ||
get-chains: get-gaia get-akash get-wasmd | ||
|
||
get-wasmd: | ||
@mkdir -p ./chain-code/ | ||
@git clone --branch $(WASMD_VERSION) [email protected]:CosmWasm/wasmd.git ./chain-code/wasmd | ||
|
||
build-wasmd: | ||
@./scripts/build-wasmd | ||
|
||
delete-chains: | ||
@echo "Removing the ./chain-code/ directory..." | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,29 @@ | ||
# Relayer | ||
|
||
![GOZ](./docs/images/github-repo-banner.png) | ||
![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 well documented and intended as an example where anyone who is | ||
interested in building their own relayer can come for complete, working, examples. | ||
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 | ||
|
||
If you would like to report a security critical bug related to the relayer repo, please send an email to [`[email protected]`](mailto:[email protected]) | ||
|
||
## Code of Conduct | ||
|
||
The iqlusion team 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 | ||
|
||
|
@@ -29,6 +37,38 @@ If you would like to join a relayer testnet, please [check out the instructions] | |
|-------|--------|----------------| | ||
| [`gaia`](https://github.com/cosmos/gaia) | ![gaia](https://github.com/cosmos/relayer/workflows/TESTING%20-%20gaia%20to%20gaia%20integration/badge.svg) | `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 | ||
- sending an UpgradePlan proposal for an IBC breaking upgrade | ||
- upgrading clients after a counterparty 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 | ||
- 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. | ||
|
||
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). | ||
|
||
## Demoing the Relayer | ||
|
||
![Demo](./docs/images/demo.gif) | ||
|
@@ -75,7 +115,7 @@ $ rly q bal ibc-0 | |
$ rly q bal ibc-1 | ||
|
||
# Send the tokens back to the account on ibc-0 | ||
$ rly tx xfer ibc-1 ibc-0 1000000transfer/ibczeroxfer/samoleans $(rly ch addr ibc-0) | ||
$ rly tx xfer ibc-1 ibc-0 1000000ibc/27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C $(rly ch addr ibc-0) | ||
$ rly tx rly demo -d | ||
|
||
# See that the return trip has completed | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/* | ||
Package cmd includes relayer commands | ||
Copyright © 2020 Jack Zampolin [email protected] | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
|
@@ -32,7 +33,9 @@ import ( | |
) | ||
|
||
const ( | ||
ORDERED = "ORDERED" | ||
// ORDERED is exported channel type constant | ||
ORDERED = "ORDERED" | ||
// UNORDERED is exported channel type constant | ||
UNORDERED = "UNORDERED" | ||
defaultOrder = ORDERED | ||
defaultVersion = "ics20-1" | ||
|
@@ -77,17 +80,36 @@ $ %s cfg list`, appName, defaultHome, appName)), | |
return fmt.Errorf("config does not exist: %s", cfgPath) | ||
} | ||
|
||
out, err := yaml.Marshal(config) | ||
jsn, err := cmd.Flags().GetBool(flagJSON) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(string(out)) | ||
return nil | ||
yml, err := cmd.Flags().GetBool(flagYAML) | ||
if err != nil { | ||
return err | ||
} | ||
switch { | ||
case yml && jsn: | ||
return fmt.Errorf("can't pass both --json and --yaml, must pick one") | ||
case jsn: | ||
out, err := json.Marshal(config) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(out)) | ||
return nil | ||
default: | ||
out, err := yaml.Marshal(config) | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(out)) | ||
return nil | ||
} | ||
}, | ||
} | ||
|
||
return cmd | ||
return yamlFlag(jsonFlag(cmd)) | ||
} | ||
|
||
// Command for inititalizing an empty config at the --home location | ||
|
@@ -218,15 +240,17 @@ func cfgFilesAdd(dir string) (cfg *Config, err error) { | |
} | ||
|
||
pthName := strings.Split(f.Name(), ".")[0] | ||
if err = config.ValidatePath(p); err != nil { | ||
fmt.Printf("%s: %s\n", pth, err.Error()) | ||
continue | ||
} | ||
if err = cfg.AddPath(pthName, p); err != nil { | ||
fmt.Printf("%s: %s\n", pth, err.Error()) | ||
continue | ||
} | ||
|
||
// TODO: Do bottom up validation | ||
// For now, we assume that all chain files must have same filename as chain-id | ||
// this is to ensure non-chain files (global config) does not get parsed into chain struct. | ||
// Future work should implement bottom-up validation. | ||
if c.ChainID != pthName { | ||
fmt.Printf("Skipping non chain file: %s\n", f.Name()) | ||
continue | ||
|
@@ -414,3 +438,121 @@ func overWriteConfig(cfg *Config) (err error) { | |
} | ||
return err | ||
} | ||
|
||
// ValidatePath checks that a path is valid | ||
func (c *Config) ValidatePath(p *relayer.Path) (err error) { | ||
if p.Src.Version == "" { | ||
return fmt.Errorf("source must specify a version") | ||
} | ||
if err = c.ValidatePathEnd(p.Src); err != nil { | ||
return err | ||
} | ||
if err = c.ValidatePathEnd(p.Dst); err != nil { | ||
return err | ||
} | ||
if _, err = p.GetStrategy(); err != nil { | ||
return err | ||
} | ||
if p.Src.Order != p.Dst.Order { | ||
return fmt.Errorf("both sides must have same order ('ORDERED' or 'UNORDERED'), got src(%s) and dst(%s)", | ||
p.Src.Order, p.Dst.Order) | ||
} | ||
return nil | ||
} | ||
|
||
// ValidatePathEnd validates provided pathend and returns error for invalid identifiers | ||
func (c *Config) ValidatePathEnd(pe *relayer.PathEnd) error { | ||
if err := pe.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
chain, err := c.Chains.Get(pe.ChainID) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
height, err := chain.QueryLatestHeight() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if pe.ClientID != "" { | ||
if err := c.ValidateClient(chain, height, pe); err != nil { | ||
return err | ||
} | ||
|
||
if pe.ConnectionID != "" { | ||
if err := c.ValidateConnection(chain, height, pe); err != nil { | ||
return err | ||
} | ||
|
||
if pe.ChannelID != "" { | ||
if err := c.ValidateChannel(chain, height, pe); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
if pe.ConnectionID == "" && pe.ChannelID != "" { | ||
return fmt.Errorf("connectionID is not configured for the channel: %s", pe.ChannelID) | ||
} | ||
} | ||
|
||
if pe.ClientID == "" && pe.ConnectionID != "" { | ||
return fmt.Errorf("clientID is not configured for the connection: %s", pe.ConnectionID) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ValidateClient validates client id in provided pathend | ||
func (c *Config) ValidateClient(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error { | ||
if err := pe.Vclient(); err != nil { | ||
return err | ||
} | ||
|
||
_, err := chain.QueryClientState(height) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ValidateConnection validates connection id in provided pathend | ||
func (c *Config) ValidateConnection(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error { | ||
if err := pe.Vconn(); err != nil { | ||
return err | ||
} | ||
|
||
connection, err := chain.QueryConnection(height) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if connection.Connection.ClientId != pe.ClientID { | ||
return fmt.Errorf("clientID of connection: %s didn't match with provided ClientID", pe.ConnectionID) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ValidateChannel validates channel id in provided pathend | ||
func (c *Config) ValidateChannel(chain *relayer.Chain, height int64, pe *relayer.PathEnd) error { | ||
if err := pe.Vchan(); err != nil { | ||
return err | ||
} | ||
|
||
channel, err := chain.QueryChannel(height) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, connection := range channel.Channel.ConnectionHops { | ||
if connection == pe.ConnectionID { | ||
return nil | ||
} | ||
} | ||
|
||
return fmt.Errorf("connectionID of channel: %s didn't match with provided ConnectionID", pe.ChannelID) | ||
} |
Oops, something went wrong.