Skip to content

Commit

Permalink
Fixes and wires up CreateClient (#965)
Browse files Browse the repository at this point in the history
* createClient WIP

* use chain id instead of chain name

* imp hermes
  • Loading branch information
boojamya committed Feb 5, 2024
1 parent 1ac6f84 commit 23a8755
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 4 deletions.
143 changes: 143 additions & 0 deletions examples/ibc/client_creation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package ibc_test

import (
"context"
"testing"

"github.com/strangelove-ventures/interchaintest/v8"
"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"
"github.com/strangelove-ventures/interchaintest/v8/testreporter"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
)

var (
numVals = 1
numFullNodes = 0
)

type relayerImp struct {
name string
relayerImp ibc.RelayerImplementation
}

func TestCreatClient(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}

t.Parallel()

var tests = []relayerImp{
{
name: "Cosmos Relayer",
relayerImp: ibc.CosmosRly,
},
{
name: "Hermes",
relayerImp: ibc.Hermes,
},
}

for _, tt := range tests {
tt := tt
testname := tt.name
t.Run(testname, func(t *testing.T) {
t.Parallel()

ctx := context.Background()

chainSpec := []*interchaintest.ChainSpec{
{
Name: "ibc-go-simd",
ChainName: "chain1",
Version: "v8.0.0",

NumValidators: &numVals,
NumFullNodes: &numFullNodes,
},
{
Name: "ibc-go-simd",
ChainName: "chain2",
Version: "v8.0.0",

NumValidators: &numVals,
NumFullNodes: &numFullNodes,
},
}

chains := interchaintest.CreateChainsWithChainSpecs(t, chainSpec)

client, network := interchaintest.DockerSetup(t)

chain, counterpartyChain := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain)

rf := interchaintest.NewBuiltinRelayerFactory(
tt.relayerImp,
zaptest.NewLogger(t),
)

r := rf.Build(t, client, network)

pathName := "ibc-path"

ic := interchaintest.NewInterchain().
AddChain(chain).
AddChain(counterpartyChain).
AddRelayer(r, "relayer").
AddLink(interchaintest.InterchainLink{
Chain1: chain,
Chain2: counterpartyChain,
Relayer: r,
Path: pathName,
})

rep := testreporter.NewNopReporter()

require.NoError(t, ic.Build(ctx, rep.RelayerExecReporter(t), interchaintest.InterchainBuildOptions{
TestName: t.Name(),
Client: client,
NetworkID: network,
SkipPathCreation: true,
}))
t.Cleanup(func() {
_ = ic.Close()
})

eRep := rep.RelayerExecReporter(t)

// Get clients for each chain
srcClientInfoBefore, err := r.GetClients(ctx, eRep, chain.Config().ChainID)
require.NoError(t, err)
destClientInfoBefore, err := r.GetClients(ctx, eRep, counterpartyChain.Config().ChainID)
require.NoError(t, err)

require.NoError(t,
r.GeneratePath(ctx, eRep, chain.Config().ChainID, counterpartyChain.Config().ChainID, pathName))

// create single client
require.NoError(t,
r.CreateClient(ctx, eRep,
chain.Config().ChainID,
counterpartyChain.Config().ChainID,
pathName, ibc.CreateClientOptions{},
),
)

srcClientInfoAfter, err := r.GetClients(ctx, eRep, chain.Config().ChainID)
require.NoError(t, err)
destClientInfoAfter, err := r.GetClients(ctx, eRep, counterpartyChain.Config().ChainID)
require.NoError(t, err)

// After creating the single client on the source chain, there should be one more client than before
require.Equal(t, len(srcClientInfoBefore), (len(srcClientInfoAfter) - 1), "there is not exactly 1 more client on the source chain after running createClient")

// createClients should only create a client on source, NOT destination chain
require.Equal(t, len(destClientInfoBefore), len(destClientInfoAfter), "a client was created on the destination chain")

})

}

}
5 changes: 5 additions & 0 deletions ibc/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ type Relayer interface {
// on src that tracks the state of dst, and a light client on dst that tracks the state of src.
CreateClients(ctx context.Context, rep RelayerExecReporter, pathName string, opts CreateClientOptions) error

// CreateClient performs the client handshake steps necessary for creating a light client
// on src that tracks the state of dst.
// Unlike CreateClients, this only creates the client on the destination chain
CreateClient(ctx context.Context, rep RelayerExecReporter, srcChainID, dstChainID, pathName string, opts CreateClientOptions) error

// CreateConnections performs the connection handshake steps necessary for creating a connection
// between the src and dst chains.
CreateConnections(ctx context.Context, rep RelayerExecReporter, pathName string) error
Expand Down
7 changes: 7 additions & 0 deletions relayer/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ func (r *DockerRelayer) CreateClients(ctx context.Context, rep ibc.RelayerExecRe
return res.Err
}

func (r *DockerRelayer) CreateClient(ctx context.Context, rep ibc.RelayerExecReporter, srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions) error {
cmd := r.c.CreateClient(srcChainID, dstChainID, pathName, opts, r.HomeDir())
res := r.Exec(ctx, rep, cmd, nil)
return res.Err
}

func (r *DockerRelayer) CreateConnections(ctx context.Context, rep ibc.RelayerExecReporter, pathName string) error {
cmd := r.c.CreateConnections(pathName, r.HomeDir())
res := r.Exec(ctx, rep, cmd, nil)
Expand Down Expand Up @@ -554,6 +560,7 @@ type RelayerCommander interface {
AddKey(chainID, keyName, coinType, signingAlgorithm, homeDir string) []string
CreateChannel(pathName string, opts ibc.CreateChannelOptions, homeDir string) []string
CreateClients(pathName string, opts ibc.CreateClientOptions, homeDir string) []string
CreateClient(srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions, homeDir string) []string
CreateConnections(pathName, homeDir string) []string
Flush(pathName, channelID, homeDir string) []string
GeneratePath(srcChainID, dstChainID, pathName, homeDir string) []string
Expand Down
4 changes: 4 additions & 0 deletions relayer/hermes/hermes_commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ func (c commander) CreateClients(pathName string, opts ibc.CreateClientOptions,
panic("create clients implemented in hermes relayer not the commander")
}

func (c commander) CreateClient(srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions, homeDir string) []string {
panic("create client implemented in hermes relayer not the commander")
}

func (c commander) CreateConnections(pathName string, homeDir string) []string {
panic("create connections implemented in hermes relayer not the commander")
}
Expand Down
31 changes: 31 additions & 0 deletions relayer/hermes/hermes_relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,37 @@ func (r *Relayer) CreateClients(ctx context.Context, rep ibc.RelayerExecReporter
return res.Err
}

func (r *Relayer) CreateClient(ctx context.Context, rep ibc.RelayerExecReporter, srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions) error {
pathConfig := r.paths[pathName]

createClientCmd := []string{hermes, "--json", "create", "client", "--host-chain", srcChainID, "--reference-chain", dstChainID}
if opts.TrustingPeriod != "" {
createClientCmd = append(createClientCmd, "--trusting-period", opts.TrustingPeriod)
}
if opts.MaxClockDrift != "" {
createClientCmd = append(createClientCmd, "--clock-drift", opts.MaxClockDrift)
}
res := r.Exec(ctx, rep, createClientCmd, nil)
if res.Err != nil {
return res.Err
}

clientId, err := GetClientIdFromStdout(res.Stdout)
if err != nil {
return err
}

if pathConfig.chainA.chainID == srcChainID {
pathConfig.chainA.chainID = clientId
} else if pathConfig.chainB.chainID == srcChainID {
pathConfig.chainB.chainID = clientId
} else {
return fmt.Errorf("%s not found in path config", srcChainID)
}

return res.Err
}

// RestoreKey restores a key from a mnemonic. In hermes, you must provide a file containing the mnemonic. We need
// to copy the contents of the mnemonic into a file on disk and then reference the newly created file.
func (r *Relayer) RestoreKey(ctx context.Context, rep ibc.RelayerExecReporter, cfg ibc.ChainConfig, keyName, mnemonic string) error {
Expand Down
5 changes: 5 additions & 0 deletions relayer/hyperspace/hyperspace_commander.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ func (c *hyperspaceCommander) CreateClients(pathName string, opts ibc.CreateClie
}
}

// TODO: Implement if available in hyperspace relayer
func (hyperspaceCommander) CreateClient(srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions, homeDir string) []string {
panic("[CreateClient] Not Implemented")
}

func (c *hyperspaceCommander) CreateConnections(pathName, homeDir string) []string {
fmt.Println("[hyperspace] CreateConnections", pathName, homeDir)
_, ok := c.paths[pathName]
Expand Down
7 changes: 3 additions & 4 deletions relayer/rly/cosmos_relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type CosmosRelayerChainConfig struct {

const (
DefaultContainerImage = "ghcr.io/cosmos/relayer"
DefaultContainerVersion = "v2.4.1"
DefaultContainerVersion = "v2.5.0"
)

// Capabilities returns the set of capabilities of the Cosmos relayer.
Expand Down Expand Up @@ -165,9 +165,8 @@ func (commander) CreateClients(pathName string, opts ibc.CreateClientOptions, ho
return cmd
}

// passing a value of 0 for customeClientTrustingPeriod will use default
func (commander) CreateClient(pathName, homeDir string, opts ibc.CreateClientOptions) []string {
cmd := []string{"rly", "tx", "client", pathName, "--home", homeDir}
func (commander) CreateClient(srcChainID, dstChainID, pathName string, opts ibc.CreateClientOptions, homeDir string) []string {
cmd := []string{"rly", "tx", "client", srcChainID, dstChainID, pathName, "--home", homeDir}

clientOptions := createClientOptsHelper(opts)
cmd = append(cmd, clientOptions...)
Expand Down

0 comments on commit 23a8755

Please sign in to comment.