Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the Hermes relayer #396

Merged
merged 34 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0072f44
adding some scaffolding for hermes relayer
chatton Feb 2, 2023
fedafd6
chore: updating interface to accept create connection options type
chatton Feb 9, 2023
a35487e
chore: wip
chatton Feb 9, 2023
a18bf66
wip: adding path map to hermes relayer type
chatton Feb 10, 2023
19930b0
writing mnemonic file
chatton Feb 10, 2023
e78de86
correctly reading toml config
chatton Feb 13, 2023
3def8eb
ibc test passing with hermes relayer
chatton Feb 13, 2023
be8adbf
learn ibc test passing with hermes relayer
chatton Feb 14, 2023
7a5160e
adding parse client and connection output
chatton Feb 14, 2023
f7ca984
adding hermes test cases
chatton Feb 14, 2023
5bbefaa
remove unused types
chatton Feb 14, 2023
a1e091e
undid import change
chatton Feb 14, 2023
5ce3a8d
reverted import change
chatton Feb 14, 2023
5f573c9
reverted some unintentional changes
chatton Feb 14, 2023
5326b10
Merge branch 'main' into add-hermes-relayer-support
chatton Feb 14, 2023
48d8562
fix linting error
chatton Feb 14, 2023
791b8f0
Merge branch 'add-hermes-relayer-support' of https://github.com/chatt…
chatton Feb 14, 2023
47af05d
adding hermes to conformance matrix
chatton Feb 15, 2023
6783734
adding default value for matrix file for CI
chatton Feb 16, 2023
1976b22
pass absolute value for matrix file
chatton Feb 16, 2023
a40eff6
removed extra part of path
chatton Feb 16, 2023
8194b65
adding hermes to Labels function
chatton Feb 16, 2023
cde37cb
add capabilities for hermes
chatton Feb 16, 2023
4dfd2a1
temporarily strip down number of tests to verify hermes relayer
chatton Feb 16, 2023
9adbf3b
fixing conformance tests
chatton Feb 16, 2023
83b0c5a
fixing channel tests in TestRelayerSetup
chatton Feb 16, 2023
5ad0cec
revert to go rly to test
chatton Feb 16, 2023
b26c8c2
bump hermes version
chatton Feb 16, 2023
0c9e8f8
extract json response correctly
chatton Feb 16, 2023
385369d
extract json result from stdout
chatton Feb 16, 2023
136f35f
correct channel parsing json stdout
chatton Feb 16, 2023
5366e6f
set field ClearOnStart to true
chatton Feb 17, 2023
e066e90
switch back to go relayer as default
chatton Feb 17, 2023
b7797b1
add hermes to the default relayers list
chatton Feb 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Don't commit the interchaintest.test file,
# regardless of where it was built.
interchaintest.test

/bin
.idea
/bin
vendor
2 changes: 1 addition & 1 deletion cmd/interchaintest/example_matrix.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"Relayers": ["rly"],
"Relayers": ["rly", "hermes"],

"ChainSets": [
[
Expand Down
2 changes: 1 addition & 1 deletion cmd/interchaintest/interchaintest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func setUpTestMatrix() error {
if extraFlags.MatrixFile == "" {
fmt.Fprintln(os.Stderr, "No matrix file provided, falling back to rly with gaia and osmosis")

testMatrix.Relayers = []string{"rly"}
testMatrix.Relayers = []string{"rly", "hermes"}
testMatrix.ChainSets = [][]*interchaintest.ChainSpec{
{
{Name: "gaia", Version: "v7.0.1"},
Expand Down
8 changes: 7 additions & 1 deletion conformance/flush.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
interchaintest "github.com/strangelove-ventures/interchaintest/v6"
"github.com/strangelove-ventures/interchaintest/v6/ibc"
"github.com/strangelove-ventures/interchaintest/v6/relayer"
"github.com/strangelove-ventures/interchaintest/v6/relayer/hermes"
"github.com/strangelove-ventures/interchaintest/v6/testreporter"
"github.com/strangelove-ventures/interchaintest/v6/testutil"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -100,9 +101,14 @@ func TestRelayerFlushing(t *testing.T, ctx context.Context, cf interchaintest.Ch
afterFlushHeight, err := c0.Height(ctx)
req.NoError(err)

//flush packets and flush acks are the same command in hermes and are not separated as in the go relayer
// Ack shouldn't happen yet.
_, err = testutil.PollForAck(ctx, c0, beforeTransferHeight, afterFlushHeight+2, tx.Packet)
req.ErrorIs(err, testutil.ErrNotFound)
if _, isHermes := r.(*hermes.Relayer); isHermes {
req.NoError(err)
} else {
req.ErrorIs(err, testutil.ErrNotFound)
}
})

t.Run("flush acks", func(t *testing.T) {
Expand Down
15 changes: 8 additions & 7 deletions conformance/relayersetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
"fmt"
"testing"

conntypes "github.com/cosmos/ibc-go/v6/modules/core/03-connection/types"
interchaintest "github.com/strangelove-ventures/interchaintest/v6"
"github.com/strangelove-ventures/interchaintest/v6/ibc"
"github.com/strangelove-ventures/interchaintest/v6/testreporter"
"github.com/strangelove-ventures/interchaintest/v6/testutil"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"

conntypes "github.com/cosmos/ibc-go/v6/modules/core/03-connection/types"
)

// TestRelayerSetup contains a series of subtests that configure a relayer step-by-step.
Expand Down Expand Up @@ -102,7 +103,7 @@ func TestRelayerSetup(t *testing.T, ctx context.Context, cf interchaintest.Chain
conn0 := conns0[0]
req.NotEmpty(conn0.ID)
req.NotEmpty(conn0.ClientID)
req.Equal(conn0.State, conntypes.OPEN.String())
req.Subset([]string{conntypes.OPEN.String(), "Open"}, []string{conn0.State})

conns1, err := r.GetConnections(ctx, eRep, c1.Config().ChainID)
req.NoError(err)
Expand All @@ -111,7 +112,7 @@ func TestRelayerSetup(t *testing.T, ctx context.Context, cf interchaintest.Chain
conn1 := conns1[0]
req.NotEmpty(conn1.ID)
req.NotEmpty(conn1.ClientID)
req.Equal(conn1.State, conntypes.OPEN.String())
req.Subset([]string{conntypes.OPEN.String(), "Open"}, []string{conn1.State})

// Now validate counterparties.
req.Equal(conn0.Counterparty.ClientId, conn1.ClientID)
Expand Down Expand Up @@ -160,14 +161,14 @@ func TestRelayerSetup(t *testing.T, ctx context.Context, cf interchaintest.Chain

// Piecemeal assertions against each channel.
// Not asserting against ConnectionHops or ChannelID.
req.Equal(ch0.State, "STATE_OPEN")
req.Equal(ch0.Ordering, "ORDER_UNORDERED")
req.Subset([]string{"STATE_OPEN", "Open"}, []string{ch0.State})
req.Subset([]string{"ORDER_UNORDERED", "Unordered"}, []string{ch0.Ordering})
req.Equal(ch0.Counterparty, ibc.ChannelCounterparty{PortID: "transfer", ChannelID: ch1.ChannelID})
req.Equal(ch0.Version, "ics20-1")
req.Equal(ch0.PortID, "transfer")

req.Equal(ch1.State, "STATE_OPEN")
req.Equal(ch1.Ordering, "ORDER_UNORDERED")
req.Subset([]string{"STATE_OPEN", "Open"}, []string{ch1.State})
req.Subset([]string{"ORDER_UNORDERED", "Unordered"}, []string{ch1.Ordering})
req.Equal(ch1.Counterparty, ibc.ChannelCounterparty{PortID: "transfer", ChannelID: ch0.ChannelID})
req.Equal(ch1.Version, "ics20-1")
req.Equal(ch1.PortID, "transfer")
Expand Down
4 changes: 3 additions & 1 deletion conformance/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"testing"
"time"

transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
"github.com/docker/docker/client"
interchaintest "github.com/strangelove-ventures/interchaintest/v6"
"github.com/strangelove-ventures/interchaintest/v6/chain/cosmos"
Expand All @@ -47,6 +46,8 @@ import (
"github.com/strangelove-ventures/interchaintest/v6/testutil"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"

transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
)

const (
Expand Down Expand Up @@ -328,6 +329,7 @@ func TestChainPair(
}

if relayerImpl == nil {
t.Logf("creating relayer: %s", rf.Name())
// startup both chains.
// creates wallets in the relayer for src and dst chain.
// funds relayer src and dst wallets on respective chain in genesis.
Expand Down
8 changes: 4 additions & 4 deletions examples/ibc/interchain_accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,12 @@ func TestInterchainAccounts(t *testing.T) {
chain1Chans, err := r.GetChannels(ctx, eRep, chain1.Config().ChainID)
require.NoError(t, err)
require.Equal(t, 1, len(chain1Chans))
require.Equal(t, "STATE_CLOSED", chain1Chans[0].State)
require.Subset(t, []string{"STATE_CLOSED", "Closed"}, []string{chain1Chans[0].State})

chain2Chans, err := r.GetChannels(ctx, eRep, chain2.Config().ChainID)
require.NoError(t, err)
require.Equal(t, 1, len(chain2Chans))
require.Equal(t, "STATE_CLOSED", chain2Chans[0].State)
require.Subset(t, []string{"STATE_CLOSED", "Closed"}, []string{chain2Chans[0].State})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the go relayer and the hermes relayer return different states, this just accounts for either of them


// Attempt to open another channel for the same ICA
_, _, err = chain1.Exec(ctx, registerICA, nil)
Expand All @@ -294,12 +294,12 @@ func TestInterchainAccounts(t *testing.T) {
chain1Chans, err = r.GetChannels(ctx, eRep, chain1.Config().ChainID)
require.NoError(t, err)
require.Equal(t, 2, len(chain1Chans))
require.Equal(t, "STATE_OPEN", chain1Chans[1].State)
require.Subset(t, []string{"STATE_OPEN", "Open"}, []string{chain1Chans[1].State})

chain2Chans, err = r.GetChannels(ctx, eRep, chain2.Config().ChainID)
require.NoError(t, err)
require.Equal(t, 2, len(chain2Chans))
require.Equal(t, "STATE_OPEN", chain2Chans[1].State)
require.Subset(t, []string{"STATE_OPEN", "Open"}, []string{chain2Chans[1].State})
}

// parseInterchainAccountField takes a slice of bytes which should be returned when querying for an ICA via
Expand Down
36 changes: 30 additions & 6 deletions interchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ import (
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
)

func TestInterchain_DuplicateChain(t *testing.T) {
func TestInterchain_DuplicateChain_CosmosRly(t *testing.T) {
duplicateChainTest(t, ibc.CosmosRly)
}

func TestInterchain_DuplicateChain_HermesRelayer(t *testing.T) {
duplicateChainTest(t, ibc.Hermes)
}

func duplicateChainTest(t *testing.T, relayerImpl ibc.RelayerImplementation) {
if testing.Short() {
t.Skip("skipping in short mode")
}
Expand All @@ -46,7 +54,7 @@ func TestInterchain_DuplicateChain(t *testing.T) {

gaia0, gaia1 := chains[0], chains[1]

r := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, zaptest.NewLogger(t)).Build(
r := interchaintest.NewBuiltinRelayerFactory(relayerImpl, zaptest.NewLogger(t)).Build(
t, client, network,
)

Expand Down Expand Up @@ -74,7 +82,15 @@ func TestInterchain_DuplicateChain(t *testing.T) {
_ = ic.Close()
}

func TestInterchain_GetRelayerWallets(t *testing.T) {
func TestInterchain_GetRelayerWallets_CosmosRly(t *testing.T) {
getRelayerWalletsTest(t, ibc.CosmosRly)
}

func TestInterchain_GetRelayerWallets_HermesRelayer(t *testing.T) {
getRelayerWalletsTest(t, ibc.Hermes)
}

func getRelayerWalletsTest(t *testing.T, relayerImpl ibc.RelayerImplementation) {
if testing.Short() {
t.Skip("skipping in short mode")
}
Expand All @@ -94,7 +110,7 @@ func TestInterchain_GetRelayerWallets(t *testing.T) {

gaia0, gaia1 := chains[0], chains[1]

r := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, zaptest.NewLogger(t)).Build(
r := interchaintest.NewBuiltinRelayerFactory(relayerImpl, zaptest.NewLogger(t)).Build(
t, client, network,
)

Expand Down Expand Up @@ -230,7 +246,15 @@ func TestInterchain_CreateUser(t *testing.T) {
})
}

func TestCosmosChain_BroadcastTx(t *testing.T) {
func TestCosmosChain_BroadcastTx_CosmosRly(t *testing.T) {
broadcastTxCosmosChainTest(t, ibc.CosmosRly)
}

func TestCosmosChain_BroadcastTx_HermesRelayer(t *testing.T) {
broadcastTxCosmosChainTest(t, ibc.Hermes)
}

func broadcastTxCosmosChainTest(t *testing.T, relayerImpl ibc.RelayerImplementation) {
if testing.Short() {
t.Skip("skipping in short mode")
}
Expand All @@ -250,7 +274,7 @@ func TestCosmosChain_BroadcastTx(t *testing.T) {

gaia0, gaia1 := chains[0], chains[1]

r := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, zaptest.NewLogger(t)).Build(
r := interchaintest.NewBuiltinRelayerFactory(relayerImpl, zaptest.NewLogger(t)).Build(
t, client, network,
)

Expand Down
5 changes: 2 additions & 3 deletions internal/dockerutil/filewriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"bytes"
"context"
"fmt"
"path"
"time"

"github.com/docker/docker/api/types"
Expand Down Expand Up @@ -48,10 +47,10 @@ func (w *FileWriter) WriteFile(ctx context.Context, volumeName, relPath string,
Cmd: []string{
// Take the uid and gid of the mount path,
// and set that as the owner of the new relative path.
`chown "$(stat -c '%u:%g' "$1")" "$2"`,
`chown -R "$(stat -c '%u:%g' "$1")" "$2"`,
"_", // Meaningless arg0 for sh -c with positional args.
mountPath,
path.Join(mountPath, relPath),
mountPath,
Comment on lines +50 to +53
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this change as the hermes relayer ended up making several files in other places in the home directory and was running into permissions issues. I thought it might be fine if we just set the home directory to be owned by the relayer user. If this is a problem we can figure something else out!

},

// Use root user to avoid permission issues when reading files from the volume.
Expand Down
27 changes: 26 additions & 1 deletion relayer/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (
"go.uber.org/zap"
)

const (
defaultRlyHomeDirectory = "/home/relayer"
)

// DockerRelayer provides a common base for relayer implementations
// that run on Docker.
type DockerRelayer struct {
Expand All @@ -42,6 +46,8 @@ type DockerRelayer struct {

// wallets contains a mapping of chainID to relayer wallet
wallets map[string]ibc.Wallet

homeDir string
}

var _ ibc.Relayer = (*DockerRelayer)(nil)
Expand All @@ -64,12 +70,16 @@ func NewDockerRelayer(ctx context.Context, log *zap.Logger, testName string, cli
wallets: map[string]ibc.Wallet{},
}

r.homeDir = defaultRlyHomeDirectory

for _, opt := range options {
switch o := opt.(type) {
case RelayerOptionDockerImage:
r.customImage = &o.DockerImage
case RelayerOptionImagePull:
r.pullImage = o.Pull
case RelayerOptionHomeDir:
r.homeDir = o.HomeDir
}
}

Expand Down Expand Up @@ -122,6 +132,21 @@ func NewDockerRelayer(ctx context.Context, log *zap.Logger, testName string, cli
return &r, nil
}

// WriteFileToHomeDir writes the given contents to a file at the relative path specified. The file is relative
// to the home directory in the relayer container.
func (r *DockerRelayer) WriteFileToHomeDir(ctx context.Context, relativePath string, contents []byte) error {
fw := dockerutil.NewFileWriter(r.log, r.client, r.testName)
if err := fw.WriteFile(ctx, r.volumeName, relativePath, contents); err != nil {
return fmt.Errorf("failed to write file: %w", err)
}
return nil
}
Comment on lines +137 to +143
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this helper function as the hermes relayer required a few different files to be created.


// AddWallet adds a stores a wallet for the given chain ID.
func (r *DockerRelayer) AddWallet(chainID string, wallet ibc.Wallet) {
r.wallets[chainID] = wallet
}

func (r *DockerRelayer) AddChainConfiguration(ctx context.Context, rep ibc.RelayerExecReporter, chainConfig ibc.ChainConfig, keyName, rpcAddr, grpcAddr string) error {
// For rly this file is json, but the file extension should not matter.
// Using .config to avoid implying any particular format.
Expand Down Expand Up @@ -469,7 +494,7 @@ func (r *DockerRelayer) Bind() []string {

// HomeDir returns the home directory of the relayer on the underlying Docker container's filesystem.
func (r *DockerRelayer) HomeDir() string {
return "/home/relayer"
return r.homeDir
}

func (r *DockerRelayer) HostName(pathName string) string {
Expand Down
Loading