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

feat: added a cosmos-to-cosmos relayer module with basic tests #170

Merged
merged 30 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9e54b8a
feat: added boilerplate for tx builder
srdtrk Dec 6, 2024
ea835a0
deps: added ibc-proto-eureka and removed reqwest
srdtrk Dec 6, 2024
a6080ae
imp: added helper rpc methods
srdtrk Dec 6, 2024
f52d725
imp: save progress
srdtrk Dec 6, 2024
f4a2011
imp: save progress
srdtrk Dec 7, 2024
1dbbc7f
merge: branch 'main' into serdar/153-cosmos-to-cosmos
srdtrk Dec 7, 2024
6f94380
imp: save progress
srdtrk Dec 7, 2024
23a84c8
merge: branch 'main' into serdar/153-cosmos-to-cosmos
srdtrk Dec 7, 2024
897df2b
imp: constructed timeout messages
srdtrk Dec 9, 2024
2e8ba3b
imp: added _recv_msgs
srdtrk Dec 9, 2024
50fb453
imp: all msgs added
srdtrk Dec 10, 2024
b1dcc89
imp: constructed update msg
srdtrk Dec 10, 2024
fd7ebeb
feat: added the basics of the module
srdtrk Dec 10, 2024
ad12011
feat: added constructor for server
srdtrk Dec 10, 2024
8258122
feat: implemented 'RelayerService'
srdtrk Dec 10, 2024
77862df
feat: implemented ModuleServer
srdtrk Dec 10, 2024
c4dba9f
feat: added relayer module
srdtrk Dec 11, 2024
0e7ad7b
merge: branch 'main' into serdar/153-cosmos-to-cosmos
srdtrk Dec 11, 2024
288f010
e2e: rename chainA to EthChain
srdtrk Dec 12, 2024
46b1f56
e2e: allow multiple chains
srdtrk Dec 12, 2024
30e827d
merge: branch 'main' into serdar/153-cosmos-to-cosmos
srdtrk Dec 13, 2024
f13395e
e2e: added eth testnet none
srdtrk Dec 13, 2024
5d97c7d
e2e: refactor
srdtrk Dec 13, 2024
0c58fae
imp: added chain info test
srdtrk Dec 13, 2024
b267c93
ci: added test
srdtrk Dec 13, 2024
0a22897
feat: test passing
srdtrk Dec 13, 2024
542f77e
e2e: refactor
srdtrk Dec 13, 2024
fb23893
imp: refactored the justfile
srdtrk Dec 13, 2024
667393d
imp: updated cosmos event key
srdtrk Dec 13, 2024
519a72c
imp: review items
srdtrk Dec 13, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jobs:
- TestWithRelayerTestSuite/TestTimeoutPacketFromEth_Plonk
- TestWithRelayerTestSuite/Test_10_TimeoutPacketFromEth_Groth16
- TestWithRelayerTestSuite/Test_5_TimeoutPacketFromEth_Plonk
- TestWithCosmosRelayerTestSuite/TestRelayerInfo
- TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16
- TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk
- TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16
Expand Down
11 changes: 5 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ tokio = { version = "1.0", default-features = false }
axum = { version = "0.7", default-features = false }
tonic = { version = "0.12", default-features = false }
tonic-build = { version = "0.12", default-features = false }
reqwest = { version = "0.12", default-features = false }

tracing = { version = "0.1", default-features = false }
tracing-subscriber = { version = "0.3", default-features = false }
Expand Down
12 changes: 8 additions & 4 deletions e2e/interchaintestv8/chainconfig/chain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ import (

var DefaultChainSpecs = []*interchaintest.ChainSpec{
// -- IBC-Go --
{
IbcGoChainSpec("ibc-go-simd-1", "simd-1"),
}

func IbcGoChainSpec(name, chainId string) *interchaintest.ChainSpec {
return &interchaintest.ChainSpec{
ChainConfig: ibc.ChainConfig{
Type: "cosmos",
Name: "ibc-go-simd",
ChainID: "simd-1",
Name: name,
ChainID: chainId,
Images: []ibc.DockerImage{
{
Repository: "ghcr.io/cosmos/ibc-go-wasm-simd", // FOR LOCAL IMAGE USE: Docker Image Name
Expand All @@ -29,5 +33,5 @@ var DefaultChainSpecs = []*interchaintest.ChainSpec{
TrustingPeriod: "508h",
NoHostMount: false,
},
},
}
}
118 changes: 118 additions & 0 deletions e2e/interchaintestv8/cosmos_relayer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package main

import (
"context"
"os"
"testing"

"github.com/stretchr/testify/suite"

"github.com/strangelove-ventures/interchaintest/v8/chain/cosmos"
"github.com/strangelove-ventures/interchaintest/v8/ibc"

"github.com/srdtrk/solidity-ibc-eureka/e2e/v8/chainconfig"
"github.com/srdtrk/solidity-ibc-eureka/e2e/v8/e2esuite"
"github.com/srdtrk/solidity-ibc-eureka/e2e/v8/relayer"
"github.com/srdtrk/solidity-ibc-eureka/e2e/v8/testvalues"
relayertypes "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/relayer"
)

// CosmosRelayerTestSuite is a struct that holds the test suite for two Cosmos chains.
type CosmosRelayerTestSuite struct {
e2esuite.TestSuite

SimdA *cosmos.CosmosChain
SimdB *cosmos.CosmosChain

SimdASubmitter ibc.Wallet
SimdBSubmitter ibc.Wallet

AtoBRelayerClient relayertypes.RelayerServiceClient
BtoARelayerClient relayertypes.RelayerServiceClient
}

// TestWithIbcEurekaTestSuite is the boilerplate code that allows the test suite to be run
func TestWithCosmosRelayerTestSuite(t *testing.T) {
suite.Run(t, new(CosmosRelayerTestSuite))
}

// SetupSuite calls the underlying IbcEurekaTestSuite's SetupSuite method
// and deploys the IbcEureka contract
func (s *CosmosRelayerTestSuite) SetupSuite(ctx context.Context) {
chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, chainconfig.IbcGoChainSpec("ibc-go-simd-2", "simd-2"))

os.Setenv(testvalues.EnvKeyEthTestnetType, testvalues.EthTestnetTypeNone)

s.TestSuite.SetupSuite(ctx)

s.SimdA, s.SimdB = s.CosmosChains[0], s.CosmosChains[1]
s.SimdASubmitter = s.CreateAndFundCosmosUser(ctx, s.SimdA)
s.SimdBSubmitter = s.CreateAndFundCosmosUser(ctx, s.SimdB)

var relayerProcess *os.Process
var configInfo relayer.CosmosToCosmosConfigInfo
s.Require().True(s.Run("Start Relayer", func() {
err := os.Chdir("../..")
s.Require().NoError(err)

configInfo = relayer.CosmosToCosmosConfigInfo{
ChainATmRPC: s.SimdA.GetHostRPCAddress(),
ChainBTmRPC: s.SimdB.GetHostRPCAddress(),
ChainAUser: s.SimdASubmitter.FormattedAddress(),
ChainBUser: s.SimdBSubmitter.FormattedAddress(),
}

err = configInfo.GenerateCosmosToCosmosConfigFile(testvalues.RelayerConfigFilePath)
s.Require().NoError(err)

relayerProcess, err = relayer.StartRelayer(testvalues.RelayerConfigFilePath)
s.Require().NoError(err)

s.T().Cleanup(func() {
os.Remove(testvalues.RelayerConfigFilePath)
})
}))

s.T().Cleanup(func() {
if relayerProcess != nil {
_ = relayerProcess.Kill()
srdtrk marked this conversation as resolved.
Show resolved Hide resolved
}
})

s.Require().True(s.Run("Create Relayer Client", func() {
var err error
s.AtoBRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainAToChainBGRPCAddress())
s.Require().NoError(err)

s.BtoARelayerClient, err = relayer.GetGRPCClient(configInfo.ChainBToChainAGRPCAddress())
s.Require().NoError(err)
}))
}

// TestRelayer is a test that runs the relayer
func (s *CosmosRelayerTestSuite) TestRelayerInfo() {
ctx := context.Background()
s.SetupSuite(ctx)

s.Run("Chain A to B Relayer Info", func() {
info, err := s.AtoBRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{})
s.Require().NoError(err)
s.Require().NotNil(info)

s.T().Logf("Relayer Info: %+v", info)

s.Require().Equal(s.SimdA.Config().ChainID, info.SourceChain.ChainId)
s.Require().Equal(s.SimdB.Config().ChainID, info.TargetChain.ChainId)
})

s.Run("Chain B to A Relayer Info", func() {
info, err := s.BtoARelayerClient.Info(context.Background(), &relayertypes.InfoRequest{})
s.Require().NoError(err)
s.Require().NotNil(info)

s.T().Logf("Relayer Info: %+v", info)

s.Require().Equal(s.SimdB.Config().ChainID, info.SourceChain.ChainId)
s.Require().Equal(s.SimdA.Config().ChainID, info.TargetChain.ChainId)
})
}
6 changes: 3 additions & 3 deletions e2e/interchaintestv8/e2esuite/light_clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri
return
}

eth, simd := s.ChainA, s.ChainB
eth, simd := s.EthChain, s.CosmosChains[0]

// Wait until we have a block number greater than the minimum update to
var updateTo int64
Expand Down Expand Up @@ -222,7 +222,7 @@ func (s *TestSuite) UpdateEthClient(ctx context.Context, ibcContractAddress stri
}

func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser ibc.Wallet, ibcContractAddress string, rustFixtureGenerator *types.RustFixtureGenerator) {
eth, simd := s.ChainA, s.ChainB
eth, simd := s.EthChain, s.CosmosChains[0]

file, err := os.Open("e2e/interchaintestv8/wasm/ethereum_light_client_minimal.wasm.gz")
s.Require().NoError(err)
Expand Down Expand Up @@ -329,7 +329,7 @@ func (s *TestSuite) createUnionLightClient(ctx context.Context, simdRelayerUser
}

func (s *TestSuite) createDummyLightClient(ctx context.Context, simdRelayerUser ibc.Wallet) {
eth, simd := s.ChainA, s.ChainB
eth, simd := s.EthChain, s.CosmosChains[0]

file, err := os.Open("e2e/interchaintestv8/wasm/wasm_dummy_light_client.wasm.gz")
s.Require().NoError(err)
Expand Down
43 changes: 26 additions & 17 deletions e2e/interchaintestv8/e2esuite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ const anvilFaucetPrivateKey = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5ef
type TestSuite struct {
suite.Suite

ChainA ethereum.Ethereum
EthChain ethereum.Ethereum
ethTestnetType string
ChainB *cosmos.CosmosChain
UserB ibc.Wallet
CosmosChains []*cosmos.CosmosChain
CosmosUsers []ibc.Wallet
dockerClient *dockerclient.Client
network string
logger *zap.Logger
ExecRep *testreporter.RelayerExecReporter

EthereumLightClientID string
TendermintLightClientID string
Expand All @@ -59,7 +58,7 @@ func (s *TestSuite) SetupSuite(ctx context.Context) {
case testvalues.EthTestnetTypePoS:
kurtosisChain, err := chainconfig.SpinUpKurtosisPoS(ctx) // TODO: Run this in a goroutine and wait for it to be ready
s.Require().NoError(err)
s.ChainA, err = ethereum.NewEthereum(ctx, kurtosisChain.RPC, &kurtosisChain.BeaconApiClient, kurtosisChain.Faucet)
s.EthChain, err = ethereum.NewEthereum(ctx, kurtosisChain.RPC, &kurtosisChain.BeaconApiClient, kurtosisChain.Faucet)
s.Require().NoError(err)
s.T().Cleanup(func() {
ctx := context.Background()
Expand All @@ -68,6 +67,8 @@ func (s *TestSuite) SetupSuite(ctx context.Context) {
}
kurtosisChain.Destroy(ctx)
})
case testvalues.EthTestnetTypeNone:
// Do nothing
default:
s.T().Fatalf("Unknown Ethereum testnet type: %s", s.ethTestnetType)
}
Expand All @@ -80,40 +81,48 @@ func (s *TestSuite) SetupSuite(ctx context.Context) {
chains, err := cf.Chains(s.T().Name())
s.Require().NoError(err)

s.ChainB = chains[0].(*cosmos.CosmosChain)

ic := interchaintest.NewInterchain()
for _, chain := range chains {
ic = ic.AddChain(chain)
}

s.ExecRep = testreporter.NewNopReporter().RelayerExecReporter(s.T())
execRep := testreporter.NewNopReporter().RelayerExecReporter(s.T())

// TODO: Run this in a goroutine and wait for it to be ready
s.Require().NoError(ic.Build(ctx, s.ExecRep, interchaintest.InterchainBuildOptions{
s.Require().NoError(ic.Build(ctx, execRep, interchaintest.InterchainBuildOptions{
TestName: s.T().Name(),
Client: s.dockerClient,
NetworkID: s.network,
SkipPathCreation: true,
}))

// map all query request types to their gRPC method paths for cosmos chains
s.Require().NoError(populateQueryReqToPath(ctx, s.ChainB))

if s.ethTestnetType == testvalues.EthTestnetTypePoW {
anvil := chains[1].(*icethereum.EthereumChain)
anvil := chains[len(chains)-1].(*icethereum.EthereumChain)
faucet, err := crypto.ToECDSA(ethcommon.FromHex(anvilFaucetPrivateKey))
s.Require().NoError(err)

s.ChainA, err = ethereum.NewEthereum(ctx, anvil.GetHostRPCAddress(), nil, faucet)
s.EthChain, err = ethereum.NewEthereum(ctx, anvil.GetHostRPCAddress(), nil, faucet)
s.Require().NoError(err)

// Remove the Ethereum chain from the cosmos chains
chains = chains[:len(chains)-1]
}

for _, chain := range chains {
cosmosChain := chain.(*cosmos.CosmosChain)
s.CosmosChains = append(s.CosmosChains, cosmosChain)
}

// map all query request types to their gRPC method paths for cosmos chains
s.Require().NoError(populateQueryReqToPath(ctx, s.CosmosChains[0]))

// Fund user accounts
cosmosUserFunds := sdkmath.NewInt(testvalues.InitialBalance)
cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, s.ChainB)
s.UserB = cosmosUsers[0]
cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, chains...)
s.CosmosUsers = cosmosUsers

s.proposalIDs = make(map[string]uint64)
s.proposalIDs[s.ChainB.Config().ChainID] = 1
for _, chain := range s.CosmosChains {
s.proposalIDs[chain.Config().ChainID] = 1
}
}
34 changes: 4 additions & 30 deletions e2e/interchaintestv8/e2esuite/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ import (
ethereumligthclient "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/ethereumlightclient"
)

// FundAddressChainB sends funds to the given address on Chain B.
// The amount sent is 1,000,000,000 of the chain's denom.
func (s *TestSuite) FundAddressChainB(ctx context.Context, address string) {
s.fundAddress(ctx, s.ChainB, s.UserB.KeyName(), address)
}

// BroadcastMessages broadcasts the provided messages to the given chain and signs them on behalf of the provided user.
// Once the broadcast response is returned, we wait for two blocks to be created on chain.
func (s *TestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, msgs ...sdk.Msg) (*sdk.TxResponse, error) {
Expand Down Expand Up @@ -96,32 +90,12 @@ func (s *TestSuite) BroadcastMessages(ctx context.Context, chain *cosmos.CosmosC
return &resp, nil
}

// fundAddress sends funds to the given address on the given chain
func (s *TestSuite) fundAddress(ctx context.Context, chain *cosmos.CosmosChain, keyName, address string) {
err := chain.SendFunds(ctx, keyName, ibc.WalletAmount{
Address: address,
Denom: chain.Config().Denom,
Amount: sdkmath.NewInt(1_000_000_000),
})
s.Require().NoError(err)

// wait for 2 blocks for the funds to be received
err = testutil.WaitForBlocks(ctx, 2, chain)
s.Require().NoError(err)
}

// GetRelayerUsers returns two ibc.Wallet instances which can be used for the relayer users
// on the two chains.
func (s *TestSuite) GetRelayerUsers(ctx context.Context) (*ecdsa.PrivateKey, ibc.Wallet) {
eth, simd := s.ChainA, s.ChainB

ethKey, err := eth.CreateAndFundUser()
s.Require().NoError(err)

// CreateAndFundCosmosUser returns a new cosmos user with the given initial balance and funds it with the native chain denom.
func (s *TestSuite) CreateAndFundCosmosUser(ctx context.Context, chain *cosmos.CosmosChain) ibc.Wallet {
cosmosUserFunds := sdkmath.NewInt(testvalues.InitialBalance)
cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, simd)
cosmosUsers := interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), cosmosUserFunds, chain)

return ethKey, cosmosUsers[0]
return cosmosUsers[0]
}

// GetEvmEvent parses the logs in the given receipt and returns the first event that can be parsed
Expand Down
Loading
Loading