From 3c2262e4eab57060f52acb09a668c5563e822b93 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 14 Jan 2025 17:08:05 +0800 Subject: [PATCH 01/22] feat: added multichain config and improved utils --- .../e2esuite/light_clients.go | 22 +++--- e2e/interchaintestv8/ibc_eureka_test.go | 15 ++-- e2e/interchaintestv8/relayer/config.go | 5 +- .../relayer/multichain_config.go | 73 +++++++++++++++++++ .../relayer/multichain_config.tmpl | 52 +++++++++++++ 5 files changed, 146 insertions(+), 21 deletions(-) create mode 100644 e2e/interchaintestv8/relayer/multichain_config.go create mode 100644 e2e/interchaintestv8/relayer/multichain_config.tmpl diff --git a/e2e/interchaintestv8/e2esuite/light_clients.go b/e2e/interchaintestv8/e2esuite/light_clients.go index af56c63d..ffc23e5d 100644 --- a/e2e/interchaintestv8/e2esuite/light_clients.go +++ b/e2e/interchaintestv8/e2esuite/light_clients.go @@ -14,18 +14,19 @@ import ( clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" ibctesting "github.com/cosmos/ibc-go/v9/testing" + "github.com/strangelove-ventures/interchaintest/v9/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v9/ibc" "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/testvalues" ethereumtypes "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/ethereum" ) -func (s *TestSuite) CreateEthereumLightClient(ctx context.Context, simdRelayerUser ibc.Wallet, ibcContractAddress string) { +func (s *TestSuite) CreateEthereumLightClient(ctx context.Context, cosmosChain *cosmos.CosmosChain, simdRelayerUser ibc.Wallet, ibcContractAddress string) { switch s.ethTestnetType { case testvalues.EthTestnetTypePoW: - s.createDummyLightClient(ctx, simdRelayerUser) + s.createDummyLightClient(ctx, cosmosChain, simdRelayerUser) case testvalues.EthTestnetTypePoS: - s.createEthereumLightClient(ctx, simdRelayerUser, ibcContractAddress) + s.createEthereumLightClient(ctx, cosmosChain, simdRelayerUser, ibcContractAddress) default: panic(fmt.Sprintf("Unrecognized Ethereum testnet type: %v", s.ethTestnetType)) } @@ -33,15 +34,16 @@ func (s *TestSuite) CreateEthereumLightClient(ctx context.Context, simdRelayerUs func (s *TestSuite) createEthereumLightClient( ctx context.Context, + cosmosChain *cosmos.CosmosChain, simdRelayerUser ibc.Wallet, ibcContractAddress string, ) { - eth, simd := s.EthChain, s.CosmosChains[0] + eth := s.EthChain file, err := os.Open("e2e/interchaintestv8/wasm/cw_ics08_wasm_eth.wasm.gz") s.Require().NoError(err) - etheruemClientChecksum := s.PushNewWasmClientProposal(ctx, simd, simdRelayerUser, file) + etheruemClientChecksum := s.PushNewWasmClientProposal(ctx, cosmosChain, simdRelayerUser, file) s.Require().NotEmpty(etheruemClientChecksum, "checksum was empty but should not have been") genesis, err := eth.BeaconAPIClient.GetGenesis() @@ -121,7 +123,7 @@ func (s *TestSuite) createEthereumLightClient( consensusStateAny, err := clienttypes.PackConsensusState(&consensusState) s.Require().NoError(err) - res, err := s.BroadcastMessages(ctx, simd, simdRelayerUser, 200_000, &clienttypes.MsgCreateClient{ + res, err := s.BroadcastMessages(ctx, cosmosChain, simdRelayerUser, 200_000, &clienttypes.MsgCreateClient{ ClientState: clientStateAny, ConsensusState: consensusStateAny, Signer: simdRelayerUser.FormattedAddress(), @@ -133,13 +135,13 @@ func (s *TestSuite) createEthereumLightClient( s.Require().Equal("08-wasm-0", s.EthereumLightClientID) } -func (s *TestSuite) createDummyLightClient(ctx context.Context, simdRelayerUser ibc.Wallet) { - eth, simd := s.EthChain, s.CosmosChains[0] +func (s *TestSuite) createDummyLightClient(ctx context.Context, cosmosChain *cosmos.CosmosChain, simdRelayerUser ibc.Wallet) { + eth := s.EthChain file, err := os.Open("e2e/interchaintestv8/wasm/wasm_dummy_light_client.wasm.gz") s.Require().NoError(err) - dummyClientChecksum := s.PushNewWasmClientProposal(ctx, simd, simdRelayerUser, file) + dummyClientChecksum := s.PushNewWasmClientProposal(ctx, cosmosChain, simdRelayerUser, file) s.Require().NotEmpty(dummyClientChecksum, "checksum was empty but should not have been") _, ethHeight, err := eth.EthAPI.GetBlockNumber() @@ -166,7 +168,7 @@ func (s *TestSuite) createDummyLightClient(ctx context.Context, simdRelayerUser consensusStateAny, err := clienttypes.PackConsensusState(&consensusState) s.Require().NoError(err) - res, err := s.BroadcastMessages(ctx, simd, simdRelayerUser, 200_000, &clienttypes.MsgCreateClient{ + res, err := s.BroadcastMessages(ctx, cosmosChain, simdRelayerUser, 200_000, &clienttypes.MsgCreateClient{ ClientState: clientStateAny, ConsensusState: consensusStateAny, Signer: simdRelayerUser.FormattedAddress(), diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index 19ccaa72..642f767f 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -190,10 +190,8 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. s.Require().NoError(err) })) - simdUser := s.CreateAndFundCosmosUser(ctx, simd) - s.Require().True(s.Run("Add ethereum light client on Cosmos chain", func() { - s.CreateEthereumLightClient(ctx, simdUser, s.contractAddresses.IbcStore) + s.CreateEthereumLightClient(ctx, simd, s.SimdRelayerSubmitter, s.contractAddresses.IbcStore) })) s.Require().True(s.Run("Add client and counterparty on EVM", func() { @@ -218,17 +216,14 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. s.Require().True(s.Run("Create channel and register counterparty on Cosmos chain", func() { merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte("")) - _, err := s.BroadcastMessages(ctx, simd, simdUser, 200_000, &channeltypesv2.MsgCreateChannel{ + _, err := s.BroadcastMessages(ctx, simd, s.SimdRelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ ClientId: s.EthereumLightClientID, MerklePathPrefix: merklePathPrefix, - Signer: simdUser.FormattedAddress(), - }) - s.Require().NoError(err) - - _, err = s.BroadcastMessages(ctx, simd, simdUser, 200_000, &channeltypesv2.MsgRegisterCounterparty{ + Signer: s.SimdRelayerSubmitter.FormattedAddress(), + }, &channeltypesv2.MsgRegisterCounterparty{ ChannelId: ibctesting.FirstChannelID, CounterpartyChannelId: s.TendermintLightClientID, - Signer: simdUser.FormattedAddress(), + Signer: s.SimdRelayerSubmitter.FormattedAddress(), }) s.Require().NoError(err) })) diff --git a/e2e/interchaintestv8/relayer/config.go b/e2e/interchaintestv8/relayer/config.go index c42eaa9b..37ca40f4 100644 --- a/e2e/interchaintestv8/relayer/config.go +++ b/e2e/interchaintestv8/relayer/config.go @@ -6,6 +6,7 @@ import ( "text/template" ) +// EthCosmosConfigInfo is a struct that holds the configuration information for the Eth to Cosmos config template type EthCosmosConfigInfo struct { // gRPC port for the Eth to Cosmos relayer module EthToCosmosPort uint64 @@ -27,6 +28,7 @@ type EthCosmosConfigInfo struct { Mock bool } +// GenerateEthCosmosConfigFile generates an eth to cosmos config file from the template. func (c *EthCosmosConfigInfo) GenerateEthCosmosConfigFile(path string) error { tmpl, err := template.ParseFiles("e2e/interchaintestv8/relayer/config.tmpl") if err != nil { @@ -47,7 +49,7 @@ func (c *EthCosmosConfigInfo) EthToCosmosGRPCAddress() string { return fmt.Sprintf("127.0.0.1:%d", c.EthToCosmosPort) } -// CosmosToEthGRPCAddress returns the address for the eth to cosmos relayer gRPC server. +// CosmosToEthGRPCAddress returns the address for the cosmos to eth relayer gRPC server. func (c *EthCosmosConfigInfo) CosmosToEthGRPCAddress() string { return fmt.Sprintf("127.0.0.1:%d", c.CosmosToEthPort) } @@ -64,6 +66,7 @@ type CosmosToCosmosConfigInfo struct { ChainBUser string } +// GenerateCosmosToCosmosConfigFile generates a cosmos to cosmos config file from the template. func (c *CosmosToCosmosConfigInfo) GenerateCosmosToCosmosConfigFile(path string) error { tmpl, err := template.ParseFiles("e2e/interchaintestv8/relayer/cosmos_to_cosmos_config.tmpl") if err != nil { diff --git a/e2e/interchaintestv8/relayer/multichain_config.go b/e2e/interchaintestv8/relayer/multichain_config.go new file mode 100644 index 000000000..5bd7a518 --- /dev/null +++ b/e2e/interchaintestv8/relayer/multichain_config.go @@ -0,0 +1,73 @@ +package relayer + +import ( + "fmt" + "html/template" + "os" +) + +// MultichainConfigInfo is a struct that holds the configuration information for the multichain config template +type MultichainConfigInfo struct { + // gRPC port for the Eth to Chain A relayer module + EthToChainAPort uint64 + // gRPC port for the Chain A to Eth relayer module + ChainAToEthPort uint64 + // gRPC port for the Eth to Chain B relayer module + EthToChainBPort uint64 + // gRPC port for the Chain B to Eth relayer module + ChainBToEthPort uint64 + // Chain A tendermint RPC URL + ChainATmRPC string + // Chain B tendermint RPC URL + ChainBTmRPC string + // Chain A signer address + ChainASignerAddress string + // Chain B signer address + ChainBSignerAddress string + // ICS26 Router address + ICS26Address string + // Ethereum RPC URL + EthRPC string + // Ethereum Beacon API URL + BeaconAPI string + // SP1 private key + SP1PrivateKey string + // Whether we use the mock client in the cosmos chains + Mock bool +} + +// GenerateMultichainConfigFile generates a multichain config file from the template. +func (c *MultichainConfigInfo) GenerateMultichainConfigFile(path string) error { + tmpl, err := template.ParseFiles("e2e/interchaintestv8/relayer/multichain_config.tmpl") + if err != nil { + return err + } + + f, err := os.Create(path) + if err != nil { + return err + } + + defer f.Close() + return tmpl.Execute(f, c) +} + +// EthToChainAGRPCAddress returns the address for the eth to chain A relayer gRPC server. +func (c *MultichainConfigInfo) EthToChainAGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.EthToChainAPort) +} + +// ChainAToEthGRPCAddress returns the address for the chain A to eth relayer gRPC server. +func (c *MultichainConfigInfo) ChainAToEthGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.ChainAToEthPort) +} + +// EthToChainAGRPCAddress returns the address for the eth to chain A relayer gRPC server. +func (c *MultichainConfigInfo) EthToChainBGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.EthToChainBPort) +} + +// ChainAToEthGRPCAddress returns the address for the chain B to eth relayer gRPC server. +func (c *MultichainConfigInfo) ChainBToEthGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.ChainBToEthPort) +} diff --git a/e2e/interchaintestv8/relayer/multichain_config.tmpl b/e2e/interchaintestv8/relayer/multichain_config.tmpl new file mode 100644 index 000000000..e2495f1b --- /dev/null +++ b/e2e/interchaintestv8/relayer/multichain_config.tmpl @@ -0,0 +1,52 @@ +{ + "server": { + "log_level": "info", + "address": "127.0.0.1" + }, + "modules": [ + { + "name": "eth_to_cosmos", + "port": {{ .EthToChainAPort }}, + "config": { + "tm_rpc_url": "{{ .ChainATmRPC }}", + "ics26_address": "{{ .ICS26Address }}", + "eth_rpc_url": "{{ .EthRPC }}", + "eth_beacon_api_url": "{{ .BeaconAPI }}", + "signer_address": "{{ .ChainASignerAddress }}", + "mock": {{ .Mock }} + } + }, + { + "name": "cosmos_to_eth", + "port": {{ .ChainAToEthPort }}, + "config": { + "tm_rpc_url": "{{ .ChainATmRPC }}", + "ics26_address": "{{ .ICS26Address }}", + "eth_rpc_url": "{{ .EthRPC }}", + "sp1_private_key": "{{ .SP1PrivateKey }}" + } + }, + { + "name": "eth_to_cosmos", + "port": {{ .EthToChainBPort }}, + "config": { + "tm_rpc_url": "{{ .ChainBTmRPC }}", + "ics26_address": "{{ .ICS26Address }}", + "eth_rpc_url": "{{ .EthRPC }}", + "eth_beacon_api_url": "{{ .BeaconAPI }}", + "signer_address": "{{ .ChainBSignerAddress }}", + "mock": {{ .Mock }} + } + }, + { + "name": "cosmos_to_eth", + "port": {{ .ChainBToEthPort }}, + "config": { + "tm_rpc_url": "{{ .ChainBTmRPC }}", + "ics26_address": "{{ .ICS26Address }}", + "eth_rpc_url": "{{ .EthRPC }}", + "sp1_private_key": "{{ .SP1PrivateKey }}" + } + } + ] +} From 9f9e269463824a13342512c78ecd85eb9448e1ee Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 14 Jan 2025 17:59:50 +0800 Subject: [PATCH 02/22] feat: added new suite --- e2e/interchaintestv8/multi_chain_test.go | 345 +++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 e2e/interchaintestv8/multi_chain_test.go diff --git a/e2e/interchaintestv8/multi_chain_test.go b/e2e/interchaintestv8/multi_chain_test.go new file mode 100644 index 000000000..9c524d00 --- /dev/null +++ b/e2e/interchaintestv8/multi_chain_test.go @@ -0,0 +1,345 @@ +package main + +import ( + "context" + "crypto/ecdsa" + "encoding/hex" + "math/big" + "os" + "strconv" + "testing" + + "github.com/cosmos/solidity-ibc-eureka/abigen/ibcstore" + "github.com/cosmos/solidity-ibc-eureka/abigen/ics20transfer" + "github.com/cosmos/solidity-ibc-eureka/abigen/ics26router" + "github.com/cosmos/solidity-ibc-eureka/abigen/icscore" + "github.com/cosmos/solidity-ibc-eureka/abigen/sp1ics07tendermint" + "github.com/stretchr/testify/suite" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" + commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" + ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" + ibctesting "github.com/cosmos/ibc-go/v9/testing" + + "github.com/strangelove-ventures/interchaintest/v9/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/ethereum" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/operator" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/relayer" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/testvalues" + "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/erc20" + relayertypes "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/types/relayer" +) + +type MultichainTestSuite struct { + e2esuite.TestSuite + + // The private key of a test account + key *ecdsa.PrivateKey + // The private key of the faucet account of interchaintest + deployer *ecdsa.PrivateKey + + contractAddresses ethereum.DeployedContracts + + simdASP1Ics07Contract *sp1ics07tendermint.Contract + simdBSP1Ics07Contract *sp1ics07tendermint.Contract + icsCoreContract *icscore.Contract + ics26Contract *ics26router.Contract + ics20Contract *ics20transfer.Contract + erc20Contract *erc20.Contract + ibcStoreContract *ibcstore.Contract + escrowContractAddr ethcommon.Address + + EthToChainARelayerClient relayertypes.RelayerServiceClient + ChainAToEthRelayerClient relayertypes.RelayerServiceClient + EthToChainBRelayerClient relayertypes.RelayerServiceClient + ChainBToEthRelayerClient relayertypes.RelayerServiceClient + + SimdARelayerSubmitter ibc.Wallet + SimdBRelayerSubmitter ibc.Wallet + EthRelayerSubmitter *ecdsa.PrivateKey +} + +// TestWithMultichainTestSuite is the boilerplate code that allows the test suite to be run +func TestWithMultichainTestSuite(t *testing.T) { + suite.Run(t, new(MultichainTestSuite)) +} + +func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator.SupportedProofType) { + chainconfig.DefaultChainSpecs = append(chainconfig.DefaultChainSpecs, chainconfig.IbcGoChainSpec("ibc-go-simd-2", "simd-2")) + + s.TestSuite.SetupSuite(ctx) + + eth, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] + + var prover string + s.Require().True(s.Run("Set up environment", func() { + err := os.Chdir("../..") + s.Require().NoError(err) + + s.key, err = eth.CreateAndFundUser() + s.Require().NoError(err) + + s.EthRelayerSubmitter, err = eth.CreateAndFundUser() + s.Require().NoError(err) + + operatorKey, err := eth.CreateAndFundUser() + s.Require().NoError(err) + + s.deployer, err = eth.CreateAndFundUser() + s.Require().NoError(err) + + s.SimdARelayerSubmitter = s.CreateAndFundCosmosUser(ctx, simdA) + s.SimdBRelayerSubmitter = s.CreateAndFundCosmosUser(ctx, simdB) + + prover = os.Getenv(testvalues.EnvKeySp1Prover) + switch prover { + case "": + prover = testvalues.EnvValueSp1Prover_Network + case testvalues.EnvValueSp1Prover_Mock: + s.T().Logf("Using mock prover") + case testvalues.EnvValueSp1Prover_Network: + default: + s.Require().Fail("invalid prover type: %s", prover) + } + + os.Setenv(testvalues.EnvKeyRustLog, testvalues.EnvValueRustLog_Info) + os.Setenv(testvalues.EnvKeyEthRPC, eth.RPC) + os.Setenv(testvalues.EnvKeySp1Prover, prover) + os.Setenv(testvalues.EnvKeyOperatorPrivateKey, hex.EncodeToString(crypto.FromECDSA(operatorKey))) + })) + + s.Require().True(s.Run("Deploy ethereum contracts with SimdA client", func() { + os.Setenv(testvalues.EnvKeyTendermintRPC, simdA.GetHostRPCAddress()) + + args := append([]string{ + "--trust-level", testvalues.DefaultTrustLevel.String(), + "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod), + "-o", testvalues.Sp1GenesisFilePath, + }, proofType.ToOperatorArgs()...) + s.Require().NoError(operator.RunGenesis(args...)) + + var ( + stdout []byte + err error + ) + switch prover { + case testvalues.EnvValueSp1Prover_Mock: + s.FailNow("Mock prover not supported") + case testvalues.EnvValueSp1Prover_Network: + // make sure that the SP1_PRIVATE_KEY is set. + s.Require().NotEmpty(os.Getenv(testvalues.EnvKeySp1PrivateKey)) + + stdout, err = eth.ForgeScript(s.deployer, testvalues.E2EDeployScriptPath) + s.Require().NoError(err) + default: + s.Require().Fail("invalid prover type: %s", prover) + } + + s.contractAddresses, err = ethereum.GetEthContractsFromDeployOutput(string(stdout)) + s.Require().NoError(err) + s.simdASP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint), eth.RPCClient) + s.Require().NoError(err) + s.icsCoreContract, err = icscore.NewContract(ethcommon.HexToAddress(s.contractAddresses.IcsCore), eth.RPCClient) + s.Require().NoError(err) + s.ics26Contract, err = ics26router.NewContract(ethcommon.HexToAddress(s.contractAddresses.Ics26Router), eth.RPCClient) + s.Require().NoError(err) + s.ics20Contract, err = ics20transfer.NewContract(ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer), eth.RPCClient) + s.Require().NoError(err) + s.erc20Contract, err = erc20.NewContract(ethcommon.HexToAddress(s.contractAddresses.Erc20), eth.RPCClient) + s.Require().NoError(err) + s.escrowContractAddr = ethcommon.HexToAddress(s.contractAddresses.Escrow) + s.ibcStoreContract, err = ibcstore.NewContract(ethcommon.HexToAddress(s.contractAddresses.IbcStore), eth.RPCClient) + s.Require().NoError(err) + })) + + var simdBSp1Ics07ContractAddress string + s.Require().True(s.Run("Deploy SimdB light client on ethereum", func() { + os.Setenv(testvalues.EnvKeyTendermintRPC, simdB.GetHostRPCAddress()) + + args := append([]string{ + "--trust-level", testvalues.DefaultTrustLevel.String(), + "--trusting-period", strconv.Itoa(testvalues.DefaultTrustPeriod), + "-o", testvalues.Sp1GenesisFilePath, + }, proofType.ToOperatorArgs()...) + s.Require().NoError(operator.RunGenesis(args...)) + + var ( + stdout []byte + err error + ) + switch prover { + case testvalues.EnvValueSp1Prover_Mock: + s.FailNow("Mock prover not supported") + case testvalues.EnvValueSp1Prover_Network: + // make sure that the SP1_PRIVATE_KEY is set. + s.Require().NotEmpty(os.Getenv(testvalues.EnvKeySp1PrivateKey)) + + stdout, err = eth.ForgeScript(s.deployer, testvalues.SP1ICS07DeployScriptPath) + s.Require().NoError(err) + default: + s.Require().Fail("invalid prover type: %s", prover) + } + + simdBSp1Ics07ContractAddress, err = ethereum.GetOnlySp1Ics07AddressFromStdout(string(stdout)) + s.Require().NoError(err) + s.Require().NotEmpty(simdBSp1Ics07ContractAddress) + s.Require().True(ethcommon.IsHexAddress(simdBSp1Ics07ContractAddress)) + + s.simdBSP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(simdBSp1Ics07ContractAddress), eth.RPCClient) + s.Require().NoError(err) + })) + + s.T().Cleanup(func() { + _ = os.Remove(testvalues.Sp1GenesisFilePath) + }) + + s.Require().True(s.Run("Fund address with ERC20", func() { + tx, err := s.erc20Contract.Transfer(s.GetTransactOpts(eth.Faucet, eth), crypto.PubkeyToAddress(s.key.PublicKey), big.NewInt(testvalues.InitialBalance)) + s.Require().NoError(err) + + _, err = eth.GetTxReciept(ctx, tx.Hash()) // wait for the tx to be mined + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Add ethereum light client on SimdA", func() { + s.CreateEthereumLightClient(ctx, simdA, s.SimdARelayerSubmitter, s.contractAddresses.IbcStore) + })) + + s.Require().True(s.Run("Add simdA client and counterparty on EVM", func() { + channel := icscore.IICS04ChannelMsgsChannel{ + CounterpartyId: ibctesting.FirstChannelID, + MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, + } + lightClientAddress := ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint) + tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.key, eth), ibcexported.Tendermint, channel, lightClientAddress) + s.Require().NoError(err) + + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + + event, err := e2esuite.GetEvmEvent(receipt, s.icsCoreContract.ParseICS04ChannelAdded) + s.Require().NoError(err) + s.Require().Equal(ibctesting.FirstClientID, event.ChannelId) + s.Require().Equal(ibctesting.FirstChannelID, event.Channel.CounterpartyId) + s.TendermintLightClientID = event.ChannelId + })) + + s.Require().True(s.Run("Add ethereum light client on SimdB", func() { + s.CreateEthereumLightClient(ctx, simdB, s.SimdBRelayerSubmitter, s.contractAddresses.IbcStore) + })) + + s.Require().True(s.Run("Add simdB client and counterparty on EVM", func() { + channel := icscore.IICS04ChannelMsgsChannel{ + CounterpartyId: ibctesting.FirstChannelID, + MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, + } + lightClientAddress := ethcommon.HexToAddress(simdBSp1Ics07ContractAddress) + tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.key, eth), ibcexported.Tendermint, channel, lightClientAddress) + s.Require().NoError(err) + + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + + event, err := e2esuite.GetEvmEvent(receipt, s.icsCoreContract.ParseICS04ChannelAdded) + s.Require().NoError(err) + s.Require().Equal(ibctesting.SecondClientID, event.ChannelId) + s.Require().Equal(ibctesting.FirstChannelID, event.Channel.CounterpartyId) + s.TendermintLightClientID = event.ChannelId + })) + + s.Require().True(s.Run("Create channel and register counterparty on SimdA", func() { + merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte("")) + + _, err := s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ + ClientId: s.EthereumLightClientID, + MerklePathPrefix: merklePathPrefix, + Signer: s.SimdARelayerSubmitter.FormattedAddress(), + }, &channeltypesv2.MsgRegisterCounterparty{ + ChannelId: ibctesting.FirstChannelID, + CounterpartyChannelId: ibctesting.FirstClientID, + Signer: s.SimdARelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Create channel and register counterparty on SimdA", func() { + merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte("")) + + _, err := s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ + ClientId: s.EthereumLightClientID, + MerklePathPrefix: merklePathPrefix, + Signer: s.SimdBRelayerSubmitter.FormattedAddress(), + }, &channeltypesv2.MsgRegisterCounterparty{ + ChannelId: ibctesting.FirstChannelID, + CounterpartyChannelId: ibctesting.SecondClientID, + Signer: s.SimdBRelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + + var relayerProcess *os.Process + var configInfo relayer.MultichainConfigInfo + s.Require().True(s.Run("Start Relayer", func() { + beaconAPI := "" + // The BeaconAPIClient is nil when the testnet is `pow` + if eth.BeaconAPIClient != nil { + beaconAPI = eth.BeaconAPIClient.GetBeaconAPIURL() + } + + configInfo = relayer.MultichainConfigInfo{ + EthToChainAPort: 3000, + ChainAToEthPort: 3001, + ChainATmRPC: simdA.GetHostRPCAddress(), + ChainASignerAddress: s.SimdARelayerSubmitter.FormattedAddress(), + EthToChainBPort: 3002, + ChainBToEthPort: 3003, + ChainBTmRPC: simdB.GetHostRPCAddress(), + ChainBSignerAddress: s.SimdBRelayerSubmitter.FormattedAddress(), + ICS26Address: s.contractAddresses.Ics26Router, + EthRPC: eth.RPC, + BeaconAPI: beaconAPI, + SP1PrivateKey: os.Getenv(testvalues.EnvKeySp1PrivateKey), + Mock: os.Getenv(testvalues.EnvKeyEthTestnetType) == testvalues.EthTestnetTypePoW, + } + + err := configInfo.GenerateMultichainConfigFile(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 { + err := relayerProcess.Kill() + if err != nil { + s.T().Logf("Failed to kill the relayer process: %v", err) + } + } + }) + + s.Require().True(s.Run("Create Relayer Clients", func() { + var err error + s.EthToChainARelayerClient, err = relayer.GetGRPCClient(configInfo.EthToChainAGRPCAddress()) + s.Require().NoError(err) + + s.ChainAToEthRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainAToEthGRPCAddress()) + s.Require().NoError(err) + + s.EthToChainBRelayerClient, err = relayer.GetGRPCClient(configInfo.EthToChainBGRPCAddress()) + s.Require().NoError(err) + + s.ChainBToEthRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainBToEthGRPCAddress()) + s.Require().NoError(err) + })) +} From 739436a908c7298d85dd3bcc7dee84b9b61a14e0 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 12:01:09 +0800 Subject: [PATCH 03/22] feat: initial pass --- e2e/interchaintestv8/multi_chain_test.go | 47 +++++++++++++++++++++++- justfile | 6 +++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/e2e/interchaintestv8/multi_chain_test.go b/e2e/interchaintestv8/multi_chain_test.go index 9c524d00..26b78750 100644 --- a/e2e/interchaintestv8/multi_chain_test.go +++ b/e2e/interchaintestv8/multi_chain_test.go @@ -180,7 +180,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator // make sure that the SP1_PRIVATE_KEY is set. s.Require().NotEmpty(os.Getenv(testvalues.EnvKeySp1PrivateKey)) - stdout, err = eth.ForgeScript(s.deployer, testvalues.SP1ICS07DeployScriptPath) + stdout, err = eth.ForgeScript(s.deployer, testvalues.SP1ICS07DeployScriptPath, "--json") s.Require().NoError(err) default: s.Require().Fail("invalid prover type: %s", prover) @@ -268,7 +268,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) - s.Require().True(s.Run("Create channel and register counterparty on SimdA", func() { + s.Require().True(s.Run("Create channel and register counterparty on SimdB", func() { merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte("")) _, err := s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ @@ -343,3 +343,46 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) } + +func (s *MultichainTestSuite) TestDeploy_Groth16() { + ctx := context.Background() + proofType := operator.ProofTypeGroth16 + + s.SetupSuite(ctx, proofType) + + _, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] + + s.Require().True(s.Run("Verify SimdA SP1 Client", func() { + clientState, err := s.simdASP1Ics07Contract.GetClientState(nil) + s.Require().NoError(err) + + stakingParams, err := simdA.StakingQueryParams(ctx) + s.Require().NoError(err) + + s.Require().Equal(simdA.Config().ChainID, clientState.ChainId) + s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator) + s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator) + s.Require().Equal(uint32(testvalues.DefaultTrustPeriod), clientState.TrustingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.UnbondingPeriod) + s.Require().False(clientState.IsFrozen) + s.Require().Equal(uint32(1), clientState.LatestHeight.RevisionNumber) + s.Require().Greater(clientState.LatestHeight.RevisionHeight, uint32(0)) + })) + + s.Require().True(s.Run("Verify SimdB SP1 Client", func() { + clientState, err := s.simdBSP1Ics07Contract.GetClientState(nil) + s.Require().NoError(err) + + stakingParams, err := simdB.StakingQueryParams(ctx) + s.Require().NoError(err) + + s.Require().Equal(simdB.Config().ChainID, clientState.ChainId) + s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator) + s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator) + s.Require().Equal(uint32(testvalues.DefaultTrustPeriod), clientState.TrustingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.UnbondingPeriod) + s.Require().False(clientState.IsFrozen) + s.Require().Equal(uint32(2), clientState.LatestHeight.RevisionNumber) + s.Require().Greater(clientState.LatestHeight.RevisionHeight, uint32(0)) + })) +} diff --git a/justfile b/justfile index b484c8a2..7e96525c 100644 --- a/justfile +++ b/justfile @@ -123,6 +123,12 @@ test-e2e-sp1-ics07 testname: clean @echo "Running {{testname}} test..." just test-e2e TestWithSP1ICS07TendermintTestSuite/{{testname}} +# Run any e2e test in the MultichainTestSuite using the test's name +# For example, `just test-e2e-multichain TestDeploy_Groth16` +test-e2e-multichain testname: clean + @echo "Running {{testname}} test..." + just test-e2e TestWithMultichainTestSuite/{{testname}} + # Install the sp1-ics07-tendermint operator for use in the e2e tests install-operator: cargo install --bin operator --path programs/operator --locked From e581b1f314bddff3ae0d357a953b824eda80ce9d Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 12:20:24 +0800 Subject: [PATCH 04/22] ci: added new test --- .github/workflows/e2e.yml | 1 + e2e/interchaintestv8/ibc_eureka_test.go | 10 ++++----- e2e/interchaintestv8/multi_chain_test.go | 27 ++++++++++++++++++------ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index bef782d3..23d19220 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -80,6 +80,7 @@ jobs: - TestWithCosmosRelayerTestSuite/Test_10_ICS20RecvAndAckPacket - TestWithCosmosRelayerTestSuite/TestICS20TimeoutPacket - TestWithCosmosRelayerTestSuite/Test_10_ICS20TimeoutPacket + - TestWithMultichainTestSuite/TestDeploy_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16 diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index 642f767f..d2f1ebeb 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -144,6 +144,10 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. }, proofType.ToOperatorArgs()...) s.Require().NoError(operator.RunGenesis(args...)) + s.T().Cleanup(func() { + _ = os.Remove(testvalues.Sp1GenesisFilePath) + }) + var ( stdout []byte err error @@ -178,10 +182,6 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. s.Require().NoError(err) })) - s.T().Cleanup(func() { - _ = os.Remove(testvalues.Sp1GenesisFilePath) - }) - s.Require().True(s.Run("Fund address with ERC20", func() { tx, err := s.erc20Contract.Transfer(s.GetTransactOpts(eth.Faucet, eth), crypto.PubkeyToAddress(s.key.PublicKey), big.NewInt(testvalues.InitialBalance)) s.Require().NoError(err) @@ -200,7 +200,7 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, } lightClientAddress := ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint) - tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.key, eth), ibcexported.Tendermint, channel, lightClientAddress) + tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.deployer, eth), ibcexported.Tendermint, channel, lightClientAddress) s.Require().NoError(err) receipt, err := eth.GetTxReciept(ctx, tx.Hash()) diff --git a/e2e/interchaintestv8/multi_chain_test.go b/e2e/interchaintestv8/multi_chain_test.go index 26b78750..37b7a508 100644 --- a/e2e/interchaintestv8/multi_chain_test.go +++ b/e2e/interchaintestv8/multi_chain_test.go @@ -7,6 +7,7 @@ import ( "math/big" "os" "strconv" + "strings" "testing" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcstore" @@ -169,6 +170,10 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator }, proofType.ToOperatorArgs()...) s.Require().NoError(operator.RunGenesis(args...)) + s.T().Cleanup(func() { + _ = os.Remove(testvalues.Sp1GenesisFilePath) + }) + var ( stdout []byte err error @@ -195,10 +200,6 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) - s.T().Cleanup(func() { - _ = os.Remove(testvalues.Sp1GenesisFilePath) - }) - s.Require().True(s.Run("Fund address with ERC20", func() { tx, err := s.erc20Contract.Transfer(s.GetTransactOpts(eth.Faucet, eth), crypto.PubkeyToAddress(s.key.PublicKey), big.NewInt(testvalues.InitialBalance)) s.Require().NoError(err) @@ -217,7 +218,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, } lightClientAddress := ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint) - tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.key, eth), ibcexported.Tendermint, channel, lightClientAddress) + tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.deployer, eth), ibcexported.Tendermint, channel, lightClientAddress) s.Require().NoError(err) receipt, err := eth.GetTxReciept(ctx, tx.Hash()) @@ -240,7 +241,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, } lightClientAddress := ethcommon.HexToAddress(simdBSp1Ics07ContractAddress) - tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.key, eth), ibcexported.Tendermint, channel, lightClientAddress) + tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.deployer, eth), ibcexported.Tendermint, channel, lightClientAddress) s.Require().NoError(err) receipt, err := eth.GetTxReciept(ctx, tx.Hash()) @@ -385,4 +386,18 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { s.Require().Equal(uint32(2), clientState.LatestHeight.RevisionNumber) s.Require().Greater(clientState.LatestHeight.RevisionHeight, uint32(0)) })) + + s.Require().True(s.Run("Verify ICS02 Client", func() { + owner, err := s.icsCoreContract.Owner(nil) + s.Require().NoError(err) + s.Require().Equal(strings.ToLower(crypto.PubkeyToAddress(s.deployer.PublicKey).Hex()), strings.ToLower(owner.Hex())) + + clientAddress, err := s.icsCoreContract.GetClient(nil, ibctesting.FirstClientID) + s.Require().NoError(err) + s.Require().Equal(s.contractAddresses.Ics07Tendermint, strings.ToLower(clientAddress.Hex())) + + counterpartyInfo, err := s.icsCoreContract.GetChannel(nil, ibctesting.FirstClientID) + s.Require().NoError(err) + s.Require().Equal(ibctesting.FirstChannelID, counterpartyInfo.CounterpartyId) + })) } From 0dd3050d719f86cc4610a93851a9531dde439372 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 12:21:08 +0800 Subject: [PATCH 05/22] rename --- e2e/interchaintestv8/{multi_chain_test.go => multichain_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename e2e/interchaintestv8/{multi_chain_test.go => multichain_test.go} (100%) diff --git a/e2e/interchaintestv8/multi_chain_test.go b/e2e/interchaintestv8/multichain_test.go similarity index 100% rename from e2e/interchaintestv8/multi_chain_test.go rename to e2e/interchaintestv8/multichain_test.go From b1787dd8ad061748800fd7493ace47befa7ce836 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 12:26:58 +0800 Subject: [PATCH 06/22] imp: removed TendermintLightClientID and LastUpdate --- .../e2esuite/light_clients.go | 1 - e2e/interchaintestv8/e2esuite/suite.go | 4 +-- e2e/interchaintestv8/ibc_eureka_test.go | 31 +++++++++---------- e2e/interchaintestv8/multichain_test.go | 2 -- e2e/interchaintestv8/relayer_test.go | 16 +++++----- 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/e2e/interchaintestv8/e2esuite/light_clients.go b/e2e/interchaintestv8/e2esuite/light_clients.go index ffc23e5d..dc2d2f7f 100644 --- a/e2e/interchaintestv8/e2esuite/light_clients.go +++ b/e2e/interchaintestv8/e2esuite/light_clients.go @@ -105,7 +105,6 @@ func (s *TestSuite) createEthereumLightClient( s.Require().NoError(err) s.Require().NotEmpty(clientUpdates) - s.LastEtheruemLightClientUpdate = bootstrap.Data.Header.Beacon.Slot ethConsensusState := ethereumtypes.ConsensusState{ Slot: bootstrap.Data.Header.Beacon.Slot, StateRoot: bootstrap.Data.Header.Execution.StateRoot, diff --git a/e2e/interchaintestv8/e2esuite/suite.go b/e2e/interchaintestv8/e2esuite/suite.go index 375512fd..b1c7b23a 100644 --- a/e2e/interchaintestv8/e2esuite/suite.go +++ b/e2e/interchaintestv8/e2esuite/suite.go @@ -37,9 +37,7 @@ type TestSuite struct { network string logger *zap.Logger - EthereumLightClientID string - TendermintLightClientID string - LastEtheruemLightClientUpdate uint64 + EthereumLightClientID string // proposalIDs keeps track of the active proposal ID for cosmos chains proposalIDs map[string]uint64 diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index d2f1ebeb..3301cede 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -210,7 +210,6 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. s.Require().NoError(err) s.Require().Equal(ibctesting.FirstClientID, event.ChannelId) s.Require().Equal(ibctesting.FirstChannelID, event.Channel.CounterpartyId) - s.TendermintLightClientID = event.ChannelId })) s.Require().True(s.Run("Create channel and register counterparty on Cosmos chain", func() { @@ -222,7 +221,7 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context, proofType operator. Signer: s.SimdRelayerSubmitter.FormattedAddress(), }, &channeltypesv2.MsgRegisterCounterparty{ ChannelId: ibctesting.FirstChannelID, - CounterpartyChannelId: s.TendermintLightClientID, + CounterpartyChannelId: ibctesting.FirstClientID, Signer: s.SimdRelayerSubmitter.FormattedAddress(), }) s.Require().NoError(err) @@ -317,11 +316,11 @@ func (s *IbcEurekaTestSuite) DeployTest(ctx context.Context, proofType operator. s.Require().NoError(err) s.Require().Equal(strings.ToLower(crypto.PubkeyToAddress(s.deployer.PublicKey).Hex()), strings.ToLower(owner.Hex())) - clientAddress, err := s.icsCoreContract.GetClient(nil, s.TendermintLightClientID) + clientAddress, err := s.icsCoreContract.GetClient(nil, ibctesting.FirstClientID) s.Require().NoError(err) s.Require().Equal(s.contractAddresses.Ics07Tendermint, strings.ToLower(clientAddress.Hex())) - counterpartyInfo, err := s.icsCoreContract.GetChannel(nil, s.TendermintLightClientID) + counterpartyInfo, err := s.icsCoreContract.GetChannel(nil, ibctesting.FirstClientID) s.Require().NoError(err) s.Require().Equal(ibctesting.FirstChannelID, counterpartyInfo.CounterpartyId) })) @@ -452,7 +451,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT s.contractAddresses.Erc20, transferAmount, cosmosUserAddress, - s.TendermintLightClientID, + ibctesting.FirstClientID, timeout, "", ) @@ -478,7 +477,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT s.Require().Equal(timeout, sendPacket.TimeoutTimestamp) s.Require().Len(sendPacket.Payloads, 1) s.Require().Equal(transfertypes.PortID, sendPacket.Payloads[0].SourcePort) - s.Require().Equal(s.TendermintLightClientID, sendPacket.SourceChannel) + s.Require().Equal(ibctesting.FirstClientID, sendPacket.SourceChannel) s.Require().Equal(transfertypes.PortID, sendPacket.Payloads[0].DestPort) s.Require().Equal(ibctesting.FirstChannelID, sendPacket.DestChannel) s.Require().Equal(transfertypes.V1, sendPacket.Payloads[0].Version) @@ -543,7 +542,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{ackTxHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -643,7 +642,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{returnSendTxHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -816,7 +815,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{cosmosSendTxHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -942,7 +941,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest ibcERC20Address, transferAmount, cosmosUserAddress, - s.TendermintLightClientID, + ibctesting.FirstClientID, timeout, returnMemo, ) @@ -961,7 +960,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest s.Require().Equal(uint32(1), sendPacketEvent.Packet.Sequence) s.Require().Equal(timeout, sendPacketEvent.Packet.TimeoutTimestamp) s.Require().Equal(transfertypes.PortID, sendPacketEvent.Packet.Payloads[0].SourcePort) - s.Require().Equal(s.TendermintLightClientID, sendPacketEvent.Packet.SourceChannel) + s.Require().Equal(ibctesting.FirstClientID, sendPacketEvent.Packet.SourceChannel) s.Require().Equal(transfertypes.PortID, sendPacketEvent.Packet.Payloads[0].DestPort) s.Require().Equal(ibctesting.FirstChannelID, sendPacketEvent.Packet.DestChannel) s.Require().Equal(transfertypes.V1, sendPacketEvent.Packet.Payloads[0].Version) @@ -1017,7 +1016,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest s.Require().True(s.Run("Acknowledge packet on Ethereum", func() { s.Require().True(s.Run("Verify commitment exists", func() { - packetCommitmentPath := ibchostv2.PacketCommitmentKey(s.TendermintLightClientID, 1) + packetCommitmentPath := ibchostv2.PacketCommitmentKey(ibctesting.FirstClientID, 1) var ethPath [32]byte copy(ethPath[:], crypto.Keccak256(packetCommitmentPath)) @@ -1030,7 +1029,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{returnAckTxHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -1050,7 +1049,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest })) s.Require().True(s.Run("Verify commitment removed", func() { - packetCommitmentPath := ibchostv2.PacketCommitmentKey(s.TendermintLightClientID, 1) + packetCommitmentPath := ibchostv2.PacketCommitmentKey(ibctesting.FirstClientID, 1) var ethPath [32]byte copy(ethPath[:], crypto.Keccak256(packetCommitmentPath)) @@ -1122,7 +1121,7 @@ func (s *IbcEurekaTestSuite) ICS20TimeoutFromEthereumToTimeoutTest( s.contractAddresses.Erc20, transferAmount, cosmosUserAddress, - s.TendermintLightClientID, + ibctesting.FirstClientID, timeout, "testmemo", ) @@ -1158,7 +1157,7 @@ func (s *IbcEurekaTestSuite) ICS20TimeoutFromEthereumToTimeoutTest( s.Require().True(s.Run("Retrieve timeout tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ TimeoutTxIds: ethSendTxHashes, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 37b7a508..65b961d0 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -228,7 +228,6 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) s.Require().Equal(ibctesting.FirstClientID, event.ChannelId) s.Require().Equal(ibctesting.FirstChannelID, event.Channel.CounterpartyId) - s.TendermintLightClientID = event.ChannelId })) s.Require().True(s.Run("Add ethereum light client on SimdB", func() { @@ -251,7 +250,6 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) s.Require().Equal(ibctesting.SecondClientID, event.ChannelId) s.Require().Equal(ibctesting.FirstChannelID, event.Channel.CounterpartyId) - s.TendermintLightClientID = event.ChannelId })) s.Require().True(s.Run("Create channel and register counterparty on SimdA", func() { diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index 4231cc71..4b53b293 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -137,7 +137,7 @@ func (s *RelayerTestSuite) RecvPacketToEthTest( s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: sendTxHashes, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -153,7 +153,7 @@ func (s *RelayerTestSuite) RecvPacketToEthTest( })) s.Require().True(s.Run("Verify balances on Ethereum", func() { - denomOnEthereum := transfertypes.NewDenom(transferCoin.Denom, transfertypes.NewHop(transfertypes.PortID, s.TendermintLightClientID)) + denomOnEthereum := transfertypes.NewDenom(transferCoin.Denom, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstClientID)) ibcERC20Addr, err := s.ics20Contract.IbcERC20Contract(nil, denomOnEthereum.IBCDenom()) s.Require().NoError(err) @@ -257,7 +257,7 @@ func (s *RelayerTestSuite) ConcurrentRecvPacketToEthTest( resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: sendTxHashes, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -275,7 +275,7 @@ func (s *RelayerTestSuite) ConcurrentRecvPacketToEthTest( defer wg.Done() // decrement the counter when the request completes resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{txHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -347,7 +347,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToEthTest( s.contractAddresses.Erc20, transferAmount, cosmosUserAddress, - s.TendermintLightClientID, + ibctesting.FirstClientID, timeout, "", ) @@ -423,7 +423,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToEthTest( s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: [][]byte{ackTxHash}, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) @@ -498,7 +498,7 @@ func (s *RelayerTestSuite) RecvPacketToCosmosTest(ctx context.Context, numOfTran s.contractAddresses.Erc20, transferAmount, cosmosUserAddress, - s.TendermintLightClientID, + ibctesting.FirstClientID, timeout, "", ) @@ -655,7 +655,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToCosmosTest( s.Require().True(s.Run("Retrieve relay tx", func() { resp, err := s.CosmosToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ SourceTxIds: sendTxHashes, - TargetChannelId: s.TendermintLightClientID, + TargetChannelId: ibctesting.FirstClientID, }) s.Require().NoError(err) s.Require().NotEmpty(resp.Tx) From 75b142abe120724548a6227e055861c49fe10a83 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 12:50:52 +0800 Subject: [PATCH 07/22] imp: completed test deploy --- e2e/interchaintestv8/cosmos_relayer_test.go | 6 -- e2e/interchaintestv8/ibc_eureka_test.go | 9 +- e2e/interchaintestv8/multichain_test.go | 102 ++++++++++++++++++-- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index 65d63c8a..e0dcf10e 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -223,9 +223,6 @@ func (s *CosmosRelayerTestSuite) TestRelayerInfo() { 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) }) @@ -234,9 +231,6 @@ func (s *CosmosRelayerTestSuite) TestRelayerInfo() { 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) }) diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index 3301cede..1f12c4cf 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -341,7 +341,7 @@ func (s *IbcEurekaTestSuite) DeployTest(ctx context.Context, proofType operator. s.Require().Equal(testvalues.InitialBalance, userBalance.Int64()) })) - s.Require().True(s.Run("Verify etheruem light client", func() { + s.Require().True(s.Run("Verify ethereum light client", func() { _, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, simd, &clienttypes.QueryClientStateRequest{ ClientId: s.EthereumLightClientID, }) @@ -352,15 +352,13 @@ func (s *IbcEurekaTestSuite) DeployTest(ctx context.Context, proofType operator. }) s.Require().NoError(err) s.Require().Equal(s.EthereumLightClientID, channelResp.Channel.ClientId) + s.Require().Equal(ibctesting.FirstClientID, channelResp.Channel.CounterpartyChannelId) })) s.Require().True(s.Run("Verify Cosmos to Eth Relayer Info", func() { info, err := s.CosmosToEthRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) s.Require().NoError(err) s.Require().NotNil(info) - - s.T().Logf("Relayer Info: %+v", info) - s.Require().Equal(simd.Config().ChainID, info.SourceChain.ChainId) s.Require().Equal(eth.ChainID.String(), info.TargetChain.ChainId) })) @@ -369,9 +367,6 @@ func (s *IbcEurekaTestSuite) DeployTest(ctx context.Context, proofType operator. info, err := s.EthToCosmosRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) s.Require().NoError(err) s.Require().NotNil(info) - - s.T().Logf("Relayer Info: %+v", info) - s.Require().Equal(eth.ChainID.String(), info.SourceChain.ChainId) s.Require().Equal(simd.Config().ChainID, info.TargetChain.ChainId) })) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 65b961d0..d30c010b 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -20,6 +20,8 @@ import ( ethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" + clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" @@ -45,7 +47,8 @@ type MultichainTestSuite struct { // The private key of the faucet account of interchaintest deployer *ecdsa.PrivateKey - contractAddresses ethereum.DeployedContracts + contractAddresses ethereum.DeployedContracts + simdBSP1Ics07Address string simdASP1Ics07Contract *sp1ics07tendermint.Contract simdBSP1Ics07Contract *sp1ics07tendermint.Contract @@ -159,7 +162,6 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) - var simdBSp1Ics07ContractAddress string s.Require().True(s.Run("Deploy SimdB light client on ethereum", func() { os.Setenv(testvalues.EnvKeyTendermintRPC, simdB.GetHostRPCAddress()) @@ -191,12 +193,12 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().Fail("invalid prover type: %s", prover) } - simdBSp1Ics07ContractAddress, err = ethereum.GetOnlySp1Ics07AddressFromStdout(string(stdout)) + s.simdBSP1Ics07Address, err = ethereum.GetOnlySp1Ics07AddressFromStdout(string(stdout)) s.Require().NoError(err) - s.Require().NotEmpty(simdBSp1Ics07ContractAddress) - s.Require().True(ethcommon.IsHexAddress(simdBSp1Ics07ContractAddress)) + s.Require().NotEmpty(s.simdBSP1Ics07Address) + s.Require().True(ethcommon.IsHexAddress(s.simdBSP1Ics07Address)) - s.simdBSP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(simdBSp1Ics07ContractAddress), eth.RPCClient) + s.simdBSP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.simdBSP1Ics07Address), eth.RPCClient) s.Require().NoError(err) })) @@ -239,7 +241,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator CounterpartyId: ibctesting.FirstChannelID, MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, } - lightClientAddress := ethcommon.HexToAddress(simdBSp1Ics07ContractAddress) + lightClientAddress := ethcommon.HexToAddress(s.simdBSP1Ics07Address) tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.deployer, eth), ibcexported.Tendermint, channel, lightClientAddress) s.Require().NoError(err) @@ -349,7 +351,7 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { s.SetupSuite(ctx, proofType) - _, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] + eth, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] s.Require().True(s.Run("Verify SimdA SP1 Client", func() { clientState, err := s.simdASP1Ics07Contract.GetClientState(nil) @@ -397,5 +399,89 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { counterpartyInfo, err := s.icsCoreContract.GetChannel(nil, ibctesting.FirstClientID) s.Require().NoError(err) s.Require().Equal(ibctesting.FirstChannelID, counterpartyInfo.CounterpartyId) + + clientAddress, err = s.icsCoreContract.GetClient(nil, ibctesting.SecondClientID) + s.Require().NoError(err) + s.Require().Equal(s.simdBSP1Ics07Address, strings.ToLower(clientAddress.Hex())) + + counterpartyInfo, err = s.icsCoreContract.GetChannel(nil, ibctesting.SecondClientID) + s.Require().NoError(err) + s.Require().Equal(ibctesting.FirstChannelID, counterpartyInfo.CounterpartyId) + })) + + s.Require().True(s.Run("Verify ICS26 Router", func() { + owner, err := s.ics26Contract.Owner(nil) + s.Require().NoError(err) + s.Require().Equal(strings.ToLower(crypto.PubkeyToAddress(s.deployer.PublicKey).Hex()), strings.ToLower(owner.Hex())) + + transferAddress, err := s.ics26Contract.GetIBCApp(nil, transfertypes.PortID) + s.Require().NoError(err) + s.Require().Equal(s.contractAddresses.Ics20Transfer, strings.ToLower(transferAddress.Hex())) + })) + + s.Require().True(s.Run("Verify ERC20 Genesis", func() { + userBalance, err := s.erc20Contract.BalanceOf(nil, crypto.PubkeyToAddress(s.key.PublicKey)) + s.Require().NoError(err) + s.Require().Equal(testvalues.InitialBalance, userBalance.Int64()) + })) + + s.Require().True(s.Run("Verify ethereum light client for SimdA", func() { + _, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, simdA, &clienttypes.QueryClientStateRequest{ + ClientId: s.EthereumLightClientID, + }) + s.Require().NoError(err) + + channelResp, err := e2esuite.GRPCQuery[channeltypesv2.QueryChannelResponse](ctx, simdA, &channeltypesv2.QueryChannelRequest{ + ChannelId: ibctesting.FirstChannelID, + }) + s.Require().NoError(err) + s.Require().Equal(s.EthereumLightClientID, channelResp.Channel.ClientId) + s.Require().Equal(ibctesting.FirstClientID, channelResp.Channel.CounterpartyChannelId) + })) + + s.Require().True(s.Run("Verify ethereum light client for SimdB", func() { + _, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, simdB, &clienttypes.QueryClientStateRequest{ + ClientId: s.EthereumLightClientID, + }) + s.Require().NoError(err) + + channelResp, err := e2esuite.GRPCQuery[channeltypesv2.QueryChannelResponse](ctx, simdB, &channeltypesv2.QueryChannelRequest{ + ChannelId: ibctesting.FirstChannelID, + }) + s.Require().NoError(err) + s.Require().Equal(s.EthereumLightClientID, channelResp.Channel.ClientId) + s.Require().Equal(ibctesting.SecondChannelID, channelResp.Channel.CounterpartyChannelId) + })) + + s.Require().True(s.Run("Verify SimdA to Eth Relayer Info", func() { + info, err := s.ChainAToEthRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(simdA.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(eth.ChainID.String(), info.TargetChain.ChainId) + })) + + s.Require().True(s.Run("Verify Eth to SimdA Relayer Info", func() { + info, err := s.EthToChainARelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(eth.ChainID.String(), info.SourceChain.ChainId) + s.Require().Equal(simdA.Config().ChainID, info.TargetChain.ChainId) + })) + + s.Require().True(s.Run("Verify SimdB to Eth Relayer Info", func() { + info, err := s.ChainBToEthRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(simdB.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(eth.ChainID.String(), info.TargetChain.ChainId) + })) + + s.Require().True(s.Run("Verify Eth to SimdB Relayer Info", func() { + info, err := s.EthToChainBRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(eth.ChainID.String(), info.SourceChain.ChainId) + s.Require().Equal(simdB.Config().ChainID, info.TargetChain.ChainId) })) } From 49769d833fcc480001ccc771bf502ab9d2800906 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 13:02:03 +0800 Subject: [PATCH 08/22] fix: use lowercase address --- e2e/interchaintestv8/ethereum/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/interchaintestv8/ethereum/utils.go b/e2e/interchaintestv8/ethereum/utils.go index 19aa0c7a..8ffdc4a0 100644 --- a/e2e/interchaintestv8/ethereum/utils.go +++ b/e2e/interchaintestv8/ethereum/utils.go @@ -75,7 +75,7 @@ func GetOnlySp1Ics07AddressFromStdout(stdout string) (string, error) { return "", fmt.Errorf("no matches found in stdout") } // Extract the value - return matches[1], nil + return strings.ToLower(matches[1]), nil } // From https://medium.com/@zhuytt4/verify-the-owner-of-safe-wallet-with-eth-getproof-7edc450504ff From 0f03d3cb5ef69df747f944515f9438c1f1074cb0 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 14:23:04 +0800 Subject: [PATCH 09/22] fix: test deploy --- e2e/interchaintestv8/e2esuite/utils.go | 25 +++ e2e/interchaintestv8/ibc_eureka_test.go | 37 +--- e2e/interchaintestv8/multichain_test.go | 256 +++++++++++++++++++++++- e2e/interchaintestv8/relayer_test.go | 8 +- 4 files changed, 290 insertions(+), 36 deletions(-) diff --git a/e2e/interchaintestv8/e2esuite/utils.go b/e2e/interchaintestv8/e2esuite/utils.go index 4ee20d00..e55dd853 100644 --- a/e2e/interchaintestv8/e2esuite/utils.go +++ b/e2e/interchaintestv8/e2esuite/utils.go @@ -15,6 +15,8 @@ import ( "time" "unicode" + "github.com/cosmos/gogoproto/proto" + "github.com/ethereum/go-ethereum/accounts/abi/bind" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -27,6 +29,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cometbft/cometbft/crypto/ed25519" @@ -389,3 +392,25 @@ func (s *TestSuite) FetchCosmosHeader(ctx context.Context, chain *cosmos.CosmosC return &headerResp.SdkBlock.Header, nil } + +func (s *TestSuite) BroadcastSdkTxBody(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, txBodyBz []byte) *sdk.TxResponse { + var txBody txtypes.TxBody + err := proto.Unmarshal(txBodyBz, &txBody) + s.Require().NoError(err) + + var msgs []sdk.Msg + for _, msg := range txBody.Messages { + var sdkMsg sdk.Msg + err = chain.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) + s.Require().NoError(err) + + msgs = append(msgs, sdkMsg) + } + + s.Require().NotZero(len(msgs)) + + resp, err := s.BroadcastMessages(ctx, chain, user, gas, msgs...) + s.Require().NoError(err) + + return resp +} diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index 1f12c4cf..32a328df 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -12,7 +12,6 @@ import ( "testing" "time" - "github.com/cosmos/gogoproto/proto" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcerc20" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcstore" "github.com/cosmos/solidity-ibc-eureka/abigen/ics20lib" @@ -31,7 +30,6 @@ import ( banktypes "cosmossdk.io/x/bank/types" sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" @@ -41,7 +39,6 @@ import ( ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v9/testing" - "github.com/strangelove-ventures/interchaintest/v9/chain/cosmos" "github.com/strangelove-ventures/interchaintest/v9/ibc" "github.com/srdtrk/solidity-ibc-eureka/e2e/v8/e2esuite" @@ -510,7 +507,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT })) s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, relayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, relayTxBodyBz) ackTxHash, err = hex.DecodeString(resp.TxHash) s.Require().NoError(err) @@ -705,7 +702,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT })) s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, ackRelayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, ackRelayTxBodyBz) ackTxHash, err = hex.DecodeString(resp.TxHash) s.Require().NoError(err) @@ -845,7 +842,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest ibcERC20Address = ibcERC20Addr.Hex() s.Require().NotEmpty(ibcERC20Address) - ibcERC20, err = ibcerc20.NewContract(ethcommon.HexToAddress(ibcERC20Addr.Hex()), eth.RPCClient) + ibcERC20, err = ibcerc20.NewContract(ethcommon.HexToAddress(ibcERC20Address), eth.RPCClient) s.Require().NoError(err) actualDenom, err := ibcERC20.Name(nil) @@ -897,7 +894,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest })) s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, ackRelayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, ackRelayTxBodyBz) var err error ackTxHash, err = hex.DecodeString(resp.TxHash) @@ -989,12 +986,12 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest })) s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) var err error returnAckTxHash, err = hex.DecodeString(resp.TxHash) s.Require().NoError(err) - s.Require().NotEmpty(ackTxHash) + s.Require().NotEmpty(returnAckTxHash) })) s.Require().True(s.Run("Verify balances on Cosmos chain", func() { @@ -1218,25 +1215,3 @@ func (s *IbcEurekaTestSuite) createICS20MsgSendPacket( }, } } - -func (s *IbcEurekaTestSuite) BroadcastSdkTx(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, txBodyBz []byte) *sdk.TxResponse { - var txBody txtypes.TxBody - err := proto.Unmarshal(txBodyBz, &txBody) - s.Require().NoError(err) - - var msgs []sdk.Msg - for _, msg := range txBody.Messages { - var sdkMsg sdk.Msg - err = chain.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) - s.Require().NoError(err) - - msgs = append(msgs, sdkMsg) - } - - s.Require().NotZero(len(msgs)) - - resp, err := s.BroadcastMessages(ctx, chain, user, gas, msgs...) - s.Require().NoError(err) - - return resp -} diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index d30c010b..a30d7ba1 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -4,13 +4,17 @@ import ( "context" "crypto/ecdsa" "encoding/hex" + "fmt" "math/big" "os" "strconv" "strings" "testing" + "time" + "github.com/cosmos/solidity-ibc-eureka/abigen/ibcerc20" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcstore" + "github.com/cosmos/solidity-ibc-eureka/abigen/ics20lib" "github.com/cosmos/solidity-ibc-eureka/abigen/ics20transfer" "github.com/cosmos/solidity-ibc-eureka/abigen/ics26router" "github.com/cosmos/solidity-ibc-eureka/abigen/icscore" @@ -18,8 +22,14 @@ import ( "github.com/stretchr/testify/suite" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + sdkmath "cosmossdk.io/math" + banktypes "cosmossdk.io/x/bank/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" @@ -450,7 +460,7 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { }) s.Require().NoError(err) s.Require().Equal(s.EthereumLightClientID, channelResp.Channel.ClientId) - s.Require().Equal(ibctesting.SecondChannelID, channelResp.Channel.CounterpartyChannelId) + s.Require().Equal(ibctesting.SecondClientID, channelResp.Channel.CounterpartyChannelId) })) s.Require().True(s.Run("Verify SimdA to Eth Relayer Info", func() { @@ -485,3 +495,247 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { s.Require().Equal(simdB.Config().ChainID, info.TargetChain.ChainId) })) } + +func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { + ctx := context.Background() + proofType := operator.ProofTypeGroth16 + + s.SetupSuite(ctx, proofType) + + eth, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] + + ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router) + ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) + transferAmount := big.NewInt(testvalues.TransferAmount) + ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) + simdAUser, simdBUser := s.CosmosUsers[0], s.CosmosUsers[1] + + var simdASendTxHash []byte + s.Require().True(s.Run("Send transfer on SimdA chain", func() { + timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) + transferCoin := sdk.NewCoin(simdA.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) + + transferPayload := ics20lib.ICS20LibFungibleTokenPacketData{ + Denom: transferCoin.Denom, + Amount: transferCoin.Amount.BigInt(), + Sender: simdAUser.FormattedAddress(), + Receiver: strings.ToLower(ethereumUserAddress.Hex()), + Memo: "", + } + transferBz, err := ics20lib.EncodeFungibleTokenPacketData(transferPayload) + s.Require().NoError(err) + + payload := channeltypesv2.Payload{ + SourcePort: transfertypes.PortID, + DestinationPort: transfertypes.PortID, + Version: transfertypes.V1, + Encoding: transfertypes.EncodingABI, + Value: transferBz, + } + msgSendPacket := channeltypesv2.MsgSendPacket{ + SourceChannel: ibctesting.FirstChannelID, + TimeoutTimestamp: timeout, + Payloads: []channeltypesv2.Payload{ + payload, + }, + Signer: simdAUser.FormattedAddress(), + } + + resp, err := s.BroadcastMessages(ctx, simdA, simdAUser, 200_000, &msgSendPacket) + s.Require().NoError(err) + s.Require().NotEmpty(resp.TxHash) + + simdASendTxHash, err = hex.DecodeString(resp.TxHash) + s.Require().NoError(err) + + s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + // Check the balance of UserB + resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simdA, &banktypes.QueryBalanceRequest{ + Address: simdAUser.FormattedAddress(), + Denom: transferCoin.Denom, + }) + s.Require().NoError(err) + s.Require().NotNil(resp.Balance) + s.Require().Equal(testvalues.InitialBalance-testvalues.TransferAmount, resp.Balance.Amount.Int64()) + })) + })) + + var ( + ibcERC20 *ibcerc20.Contract + ibcERC20Address string + ) + s.Require().True(s.Run("Receive packet on Ethereum", func() { + var recvRelayTx []byte + s.Require().True(s.Run("Retrieve relay tx", func() { + resp, err := s.ChainAToEthRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: [][]byte{simdASendTxHash}, + TargetChannelId: ibctesting.FirstClientID, + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Equal(resp.Address, ics26Address.String()) + + recvRelayTx = resp.Tx + })) + + var packet ics26router.IICS26RouterMsgsPacket + s.Require().True(s.Run("Submit relay tx", func() { + receipt, err := eth.BroadcastTx(ctx, s.EthRelayerSubmitter, 5_000_000, ics26Address, recvRelayTx) + s.Require().NoError(err) + s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status, fmt.Sprintf("Tx failed: %+v", receipt)) + + ethReceiveAckEvent, err := e2esuite.GetEvmEvent(receipt, s.ics26Contract.ParseWriteAcknowledgement) + s.Require().NoError(err) + + packet = ethReceiveAckEvent.Packet + // ackTxHash = receipt.TxHash.Bytes() + // NOTE: ackTxHash is not used in the test since acking the packet is not necessary + })) + + // Recreate the full denom path + transferCoin := sdk.NewCoin(simdA.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) + denomOnEthereum := transfertypes.NewDenom(transferCoin.Denom, transfertypes.NewHop(packet.Payloads[0].DestPort, packet.DestChannel)) + + ibcERC20Addr, err := s.ics20Contract.IbcERC20Contract(nil, denomOnEthereum.IBCDenom()) + s.Require().NoError(err) + + ibcERC20Address = ibcERC20Addr.Hex() + s.Require().NotEmpty(ibcERC20Address) + + ibcERC20, err = ibcerc20.NewContract(ethcommon.HexToAddress(ibcERC20Address), eth.RPCClient) + s.Require().NoError(err) + + actualFullDenom, err := ibcERC20.FullDenomPath(nil) + s.Require().NoError(err) + s.Require().Equal(denomOnEthereum.Path(), actualFullDenom) + + s.True(s.Run("Verify balances on Ethereum", func() { + // User balance on Ethereum + userBalance, err := ibcERC20.BalanceOf(nil, ethereumUserAddress) + s.Require().NoError(err) + s.Require().Equal(transferAmount, userBalance) + + // ICS20 contract balance on Ethereum + ics20TransferBalance, err := ibcERC20.BalanceOf(nil, ics20Address) + s.Require().NoError(err) + s.Require().Equal(int64(0), ics20TransferBalance.Int64()) + })) + })) + + s.Require().True(s.Run("Approve the ICS20Transfer.sol contract to spend the erc20 tokens", func() { + tx, err := ibcERC20.Approve(s.GetTransactOpts(s.key, eth), ics20Address, transferAmount) + s.Require().NoError(err) + + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status) + + allowance, err := ibcERC20.Allowance(nil, ethereumUserAddress, ics20Address) + s.Require().NoError(err) + s.Require().Equal(transferAmount, allowance) + })) + + var ethSendTxHash []byte + s.Require().True(s.Run("Transfer tokens from Ethereum to SimdB", func() { + timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) + msgSendPacket := s.createICS20MsgSendPacket( + ethereumUserAddress, + ibcERC20Address, + transferAmount, + simdBUser.FormattedAddress(), + ibctesting.SecondClientID, + timeout, + "", + ) + + tx, err := s.ics26Contract.SendPacket(s.GetTransactOpts(s.key, eth), msgSendPacket) + s.Require().NoError(err) + + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status) + + ethSendTxHash = tx.Hash().Bytes() + + s.True(s.Run("Verify balances on Ethereum", func() { + userBalance, err := ibcERC20.BalanceOf(nil, ethereumUserAddress) + s.Require().NoError(err) + s.Require().Equal(int64(0), userBalance.Int64()) + + // the whole balance should have been burned + ics20TransferBalance, err := ibcERC20.BalanceOf(nil, ics20Address) + s.Require().NoError(err) + s.Require().Equal(int64(0), ics20TransferBalance.Int64()) + })) + })) + + s.Require().True(s.Run("Receive packet on SimdB", func() { + var relayTxBodyBz []byte + s.Require().True(s.Run("Retrieve relay tx", func() { + resp, err := s.EthToChainBRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: [][]byte{ethSendTxHash}, + TargetChannelId: ibctesting.FirstChannelID, + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) + + relayTxBodyBz = resp.Tx + })) + + s.Require().True(s.Run("Broadcast relay tx", func() { + _ = s.BroadcastSdkTxBody(ctx, simdB, s.SimdBRelayerSubmitter, 2_000_000, relayTxBodyBz) + })) + + s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + finalDenom := transfertypes.NewDenom(simdA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstClientID), transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)) + + // Check the balance of UserB + resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simdB, &banktypes.QueryBalanceRequest{ + Address: simdBUser.FormattedAddress(), + Denom: finalDenom.IBCDenom(), + }) + s.Require().NoError(err) + s.Require().NotNil(resp.Balance) + s.Require().Equal(testvalues.InitialBalance, resp.Balance.Amount.Int64()) + })) + })) +} + +func (s *MultichainTestSuite) createICS20MsgSendPacket( + sender ethcommon.Address, + denom string, + amount *big.Int, + receiver string, + sourceChannel string, + timeoutTimestamp uint64, + memo string, +) ics26router.IICS26RouterMsgsMsgSendPacket { + msgSendTransfer := ics20transfer.IICS20TransferMsgsSendTransferMsg{ + Denom: denom, + Amount: amount, + Receiver: receiver, + SourceChannel: sourceChannel, + DestPort: transfertypes.PortID, + TimeoutTimestamp: timeoutTimestamp, + Memo: memo, + } + msgSendPacket, err := s.ics20Contract.ContractCaller.NewMsgSendPacketV1(nil, sender, msgSendTransfer) + s.Require().NoError(err) + + // Because of the way abi generation work, the type returned by ics20 is ics20transfer.IICS26RouterMsgsMsgSendPacket + // So we just move the values over here: + return ics26router.IICS26RouterMsgsMsgSendPacket{ + SourceChannel: sourceChannel, + TimeoutTimestamp: timeoutTimestamp, + Payloads: []ics26router.IICS26RouterMsgsPayload{ + { + SourcePort: msgSendPacket.Payloads[0].SourcePort, + DestPort: msgSendPacket.Payloads[0].DestPort, + Version: msgSendPacket.Payloads[0].Version, + Encoding: msgSendPacket.Payloads[0].Encoding, + Value: msgSendPacket.Payloads[0].Value, + }, + }, + } +} diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index 4b53b293..049e17d0 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -396,7 +396,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToEthTest( })) s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) ackTxHash, err = hex.DecodeString(resp.TxHash) s.Require().NoError(err) @@ -543,7 +543,7 @@ func (s *RelayerTestSuite) RecvPacketToCosmosTest(ctx context.Context, numOfTran var ackTxHash []byte s.Require().True(s.Run("Broadcast relay tx", func() { - resp := s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) + resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) var err error ackTxHash, err = hex.DecodeString(resp.TxHash) @@ -699,7 +699,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToCosmosTest( })) s.Require().True(s.Run("Broadcast relay tx", func() { - _ = s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) + _ = s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) })) s.Require().True(s.Run("Verify commitments removed", func() { @@ -816,7 +816,7 @@ func (s *RelayerTestSuite) ICS20TimeoutFromCosmosTimeoutTest( })) s.Require().True(s.Run("Broadcast relay tx on Cosmos chain", func() { - _ = s.BroadcastSdkTx(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) + _ = s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, relayTxBodyBz) })) s.Require().True(s.Run("Verify balances on Cosmos chain", func() { From 4f4d360af49208c1be5fcf128fdb4f4bdb564208 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 16:05:21 +0800 Subject: [PATCH 10/22] feat: test passing now --- contracts/ICS20Transfer.sol | 10 +++++++--- e2e/interchaintestv8/multichain_test.go | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/contracts/ICS20Transfer.sol b/contracts/ICS20Transfer.sol index 83fbffb1..eaed74c3 100644 --- a/contracts/ICS20Transfer.sol +++ b/contracts/ICS20Transfer.sol @@ -233,14 +233,18 @@ contract ICS20Transfer is address erc20Address; if (originatorChainIsSource) { - // we are the source of this token, so the denom should be the contract address - erc20Address = ICS20Lib.mustHexStringToAddress(packetData.denom); + bool isERC20Address; + (erc20Address, isERC20Address) = ICS20Lib.hexStringToAddress(packetData.denom); + if (!isERC20Address) { + string memory ibcDenom = ICS20Lib.toIBCDenom(packetData.denom); + erc20Address = address(_getICS20TransferStorage().ibcDenomContracts[ibcDenom]); + } } else { // receiving chain is source of the token, so we've received and mapped this token before string memory ibcDenom = ICS20Lib.toIBCDenom(packetData.denom); erc20Address = address(_getICS20TransferStorage().ibcDenomContracts[ibcDenom]); - require(erc20Address != address(0), ICS20DenomNotFound(packetData.denom)); } + require(erc20Address != address(0), ICS20DenomNotFound(packetData.denom)); return (erc20Address, originatorChainIsSource); } diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index a30d7ba1..aacbc1a1 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -688,7 +688,11 @@ func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { })) s.Require().True(s.Run("Verify balances on Cosmos chain", func() { - finalDenom := transfertypes.NewDenom(simdA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstClientID), transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)) + finalDenom := transfertypes.NewDenom( + simdA.Config().Denom, + transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID), + transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstClientID), + ) // Check the balance of UserB resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simdB, &banktypes.QueryBalanceRequest{ @@ -697,7 +701,7 @@ func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { }) s.Require().NoError(err) s.Require().NotNil(resp.Balance) - s.Require().Equal(testvalues.InitialBalance, resp.Balance.Amount.Int64()) + s.Require().Equal(testvalues.TransferAmount, resp.Balance.Amount.Int64()) })) })) } From 620f42f7dea28ba589f57642e87cc2833af658e4 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 16:08:39 +0800 Subject: [PATCH 11/22] ci: added new test to ci --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 23d19220..bb9f17e9 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -81,6 +81,7 @@ jobs: - TestWithCosmosRelayerTestSuite/TestICS20TimeoutPacket - TestWithCosmosRelayerTestSuite/Test_10_ICS20TimeoutPacket - TestWithMultichainTestSuite/TestDeploy_Groth16 + - TestWithMultichainTestSuite/TestTransferCosmosToEthToCosmos_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16 From 9dbb1285e6cc1f12a41e5dab46da362f6437c914 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 16:44:07 +0800 Subject: [PATCH 12/22] feat: added cosmos <-> cosmos setup --- e2e/interchaintestv8/cosmos_relayer_test.go | 8 +- e2e/interchaintestv8/multichain_test.go | 140 +++++++++++++++++- .../relayer/multichain_config.go | 14 ++ .../relayer/multichain_config.tmpl | 18 +++ 4 files changed, 170 insertions(+), 10 deletions(-) diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index e0dcf10e..5aa251f2 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -219,21 +219,21 @@ func (s *CosmosRelayerTestSuite) TestRelayerInfo() { ctx := context.Background() s.SetupSuite(ctx) - s.Run("Chain A to B Relayer Info", func() { + s.Require().True(s.Run("Verify Chain A to Chain B Relayer Info", func() { info, err := s.AtoBRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) s.Require().NoError(err) s.Require().NotNil(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() { + s.Require().True(s.Run("Verify Chain B to Chain A Relayer Info", func() { info, err := s.BtoARelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) s.Require().NoError(err) s.Require().NotNil(info) s.Require().Equal(s.SimdB.Config().ChainID, info.SourceChain.ChainId) s.Require().Equal(s.SimdA.Config().ChainID, info.TargetChain.ChainId) - }) + })) } func (s *CosmosRelayerTestSuite) TestICS20RecvAndAckPacket() { diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index aacbc1a1..2fa697e1 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -28,13 +28,16 @@ import ( sdkmath "cosmossdk.io/math" banktypes "cosmossdk.io/x/bank/types" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" + commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types" commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" ibcexported "github.com/cosmos/ibc-go/v9/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v9/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v9/testing" "github.com/strangelove-ventures/interchaintest/v9/ibc" @@ -69,10 +72,12 @@ type MultichainTestSuite struct { ibcStoreContract *ibcstore.Contract escrowContractAddr ethcommon.Address - EthToChainARelayerClient relayertypes.RelayerServiceClient - ChainAToEthRelayerClient relayertypes.RelayerServiceClient - EthToChainBRelayerClient relayertypes.RelayerServiceClient - ChainBToEthRelayerClient relayertypes.RelayerServiceClient + EthToChainARelayerClient relayertypes.RelayerServiceClient + ChainAToEthRelayerClient relayertypes.RelayerServiceClient + EthToChainBRelayerClient relayertypes.RelayerServiceClient + ChainBToEthRelayerClient relayertypes.RelayerServiceClient + ChainAToChainBRelayerClient relayertypes.RelayerServiceClient + ChainBToChainARelayerClient relayertypes.RelayerServiceClient SimdARelayerSubmitter ibc.Wallet SimdBRelayerSubmitter ibc.Wallet @@ -294,6 +299,105 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) + s.Require().True(s.Run("Create Light Client of Chain A on Chain B", func() { + simdAHeader, err := s.FetchCosmosHeader(ctx, simdA) + s.Require().NoError(err) + + var ( + clientStateAny *codectypes.Any + consensusStateAny *codectypes.Any + ) + s.Require().True(s.Run("Construct the client and consensus state", func() { + tmConfig := ibctesting.NewTendermintConfig() + revision := clienttypes.ParseChainID(simdAHeader.ChainID) + height := clienttypes.NewHeight(revision, uint64(simdAHeader.Height)) + + clientState := ibctm.NewClientState( + simdAHeader.ChainID, + tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift, + height, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, + ) + clientStateAny, err = codectypes.NewAnyWithValue(clientState) + s.Require().NoError(err) + + consensusState := ibctm.NewConsensusState(simdAHeader.Time, commitmenttypes.NewMerkleRoot([]byte(ibctm.SentinelRoot)), simdAHeader.ValidatorsHash) + consensusStateAny, err = codectypes.NewAnyWithValue(consensusState) + s.Require().NoError(err) + })) + + _, err = s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &clienttypes.MsgCreateClient{ + ClientState: clientStateAny, + ConsensusState: consensusStateAny, + Signer: s.SimdBRelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Create Light Client of Chain B on Chain A", func() { + simdBHeader, err := s.FetchCosmosHeader(ctx, simdB) + s.Require().NoError(err) + + var ( + clientStateAny *codectypes.Any + consensusStateAny *codectypes.Any + ) + s.Require().True(s.Run("Construct the client and consensus state", func() { + tmConfig := ibctesting.NewTendermintConfig() + revision := clienttypes.ParseChainID(simdBHeader.ChainID) + height := clienttypes.NewHeight(revision, uint64(simdBHeader.Height)) + + clientState := ibctm.NewClientState( + simdBHeader.ChainID, + tmConfig.TrustLevel, tmConfig.TrustingPeriod, tmConfig.UnbondingPeriod, tmConfig.MaxClockDrift, + height, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, + ) + clientStateAny, err = codectypes.NewAnyWithValue(clientState) + s.Require().NoError(err) + + consensusState := ibctm.NewConsensusState(simdBHeader.Time, commitmenttypes.NewMerkleRoot([]byte(ibctm.SentinelRoot)), simdBHeader.ValidatorsHash) + consensusStateAny, err = codectypes.NewAnyWithValue(consensusState) + s.Require().NoError(err) + })) + + _, err = s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 200_000, &clienttypes.MsgCreateClient{ + ClientState: clientStateAny, + ConsensusState: consensusStateAny, + Signer: s.SimdARelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Create Channel and register counterparty on Chain A", func() { + merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte(ibcexported.StoreKey), []byte("")) + + // We can do this because we know what the counterparty channel ID will be + _, err := s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ + ClientId: ibctesting.FirstClientID, + MerklePathPrefix: merklePathPrefix, + Signer: s.SimdARelayerSubmitter.FormattedAddress(), + }, &channeltypesv2.MsgRegisterCounterparty{ + ChannelId: ibctesting.SecondChannelID, + CounterpartyChannelId: ibctesting.SecondChannelID, + Signer: s.SimdARelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Create Channel and register counterparty on Chain B", func() { + merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte(ibcexported.StoreKey), []byte("")) + + _, err := s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ + ClientId: ibctesting.FirstClientID, + MerklePathPrefix: merklePathPrefix, + Signer: s.SimdBRelayerSubmitter.FormattedAddress(), + }, &channeltypesv2.MsgRegisterCounterparty{ + ChannelId: ibctesting.SecondChannelID, + CounterpartyChannelId: ibctesting.SecondChannelID, + Signer: s.SimdBRelayerSubmitter.FormattedAddress(), + }) + s.Require().NoError(err) + })) + var relayerProcess *os.Process var configInfo relayer.MultichainConfigInfo s.Require().True(s.Run("Start Relayer", func() { @@ -306,10 +410,12 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator configInfo = relayer.MultichainConfigInfo{ EthToChainAPort: 3000, ChainAToEthPort: 3001, - ChainATmRPC: simdA.GetHostRPCAddress(), - ChainASignerAddress: s.SimdARelayerSubmitter.FormattedAddress(), EthToChainBPort: 3002, ChainBToEthPort: 3003, + ChainAToChainBPort: 3004, + ChainBToChainAPort: 3005, + ChainATmRPC: simdA.GetHostRPCAddress(), + ChainASignerAddress: s.SimdARelayerSubmitter.FormattedAddress(), ChainBTmRPC: simdB.GetHostRPCAddress(), ChainBSignerAddress: s.SimdBRelayerSubmitter.FormattedAddress(), ICS26Address: s.contractAddresses.Ics26Router, @@ -352,6 +458,12 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.ChainBToEthRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainBToEthGRPCAddress()) s.Require().NoError(err) + + s.ChainAToChainBRelayerClient, err = relayer.GetGRPCClient(configInfo.ChainAToChainBGRPCAddress()) + s.Require().NoError(err) + + s.ChainBToChainARelayerClient, err = relayer.GetGRPCClient(configInfo.ChainBToChainAGRPCAddress()) + s.Require().NoError(err) })) } @@ -494,6 +606,22 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { s.Require().Equal(eth.ChainID.String(), info.SourceChain.ChainId) s.Require().Equal(simdB.Config().ChainID, info.TargetChain.ChainId) })) + + s.Require().True(s.Run("Verify Chain A to Chain B Relayer Info", func() { + info, err := s.ChainAToChainBRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(simdA.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(simdB.Config().ChainID, info.TargetChain.ChainId) + })) + + s.Require().True(s.Run("Verify Chain B to Chain A Relayer Info", func() { + info, err := s.ChainBToChainARelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) + s.Require().NoError(err) + s.Require().NotNil(info) + s.Require().Equal(simdB.Config().ChainID, info.SourceChain.ChainId) + s.Require().Equal(simdA.Config().ChainID, info.TargetChain.ChainId) + })) } func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { diff --git a/e2e/interchaintestv8/relayer/multichain_config.go b/e2e/interchaintestv8/relayer/multichain_config.go index 5bd7a518..c137581e 100644 --- a/e2e/interchaintestv8/relayer/multichain_config.go +++ b/e2e/interchaintestv8/relayer/multichain_config.go @@ -16,6 +16,10 @@ type MultichainConfigInfo struct { EthToChainBPort uint64 // gRPC port for the Chain B to Eth relayer module ChainBToEthPort uint64 + // gRPC port for the Chain A to Chain B relayer module + ChainAToChainBPort uint64 + // gRPC port for the Chain B to Chain A relayer module + ChainBToChainAPort uint64 // Chain A tendermint RPC URL ChainATmRPC string // Chain B tendermint RPC URL @@ -71,3 +75,13 @@ func (c *MultichainConfigInfo) EthToChainBGRPCAddress() string { func (c *MultichainConfigInfo) ChainBToEthGRPCAddress() string { return fmt.Sprintf("127.0.0.1:%d", c.ChainBToEthPort) } + +// ChainAToChainBGRPCAddress returns the address for the chain A to chain B relayer gRPC server. +func (c *MultichainConfigInfo) ChainAToChainBGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.ChainAToChainBPort) +} + +// ChainBToChainAGRPCAddress returns the address for the chain B to chain A relayer gRPC server. +func (c *MultichainConfigInfo) ChainBToChainAGRPCAddress() string { + return fmt.Sprintf("127.0.0.1:%d", c.ChainBToChainAPort) +} diff --git a/e2e/interchaintestv8/relayer/multichain_config.tmpl b/e2e/interchaintestv8/relayer/multichain_config.tmpl index e2495f1b..45546db3 100644 --- a/e2e/interchaintestv8/relayer/multichain_config.tmpl +++ b/e2e/interchaintestv8/relayer/multichain_config.tmpl @@ -47,6 +47,24 @@ "eth_rpc_url": "{{ .EthRPC }}", "sp1_private_key": "{{ .SP1PrivateKey }}" } + }, + { + "name": "cosmos_to_cosmos", + "port": {{ .ChainAToChainBPort }}, + "config": { + "src_rpc_url": "{{ .ChainATmRPC }}", + "target_rpc_url": "{{ .ChainBTmRPC }}", + "signer_address": "{{ .ChainBSignerAddress }}" + } + }, + { + "name": "cosmos_to_cosmos", + "port": {{ .ChainBToChainAPort }}, + "config": { + "src_rpc_url": "{{ .ChainBTmRPC }}", + "target_rpc_url": "{{ .ChainATmRPC }}", + "signer_address": "{{ .ChainASignerAddress }}" + } } ] } From edd30f3741ef887ca70da76e962abcd1c2721f45 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 17:34:05 +0800 Subject: [PATCH 13/22] fix: fixed solidity tests --- test/solidity-ibc/ICS20TransferTest.t.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/solidity-ibc/ICS20TransferTest.t.sol b/test/solidity-ibc/ICS20TransferTest.t.sol index 7f652074..731903df 100644 --- a/test/solidity-ibc/ICS20TransferTest.t.sol +++ b/test/solidity-ibc/ICS20TransferTest.t.sol @@ -336,7 +336,7 @@ contract ICS20TransferTest is Test { // test invalid token contract defaultPacketData.denom = "invalid"; packet.payloads[0].value = abi.encode(defaultPacketData); - vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20InvalidAddress.selector, "invalid")); + vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20DenomNotFound.selector, "invalid")); ics20Transfer.onSendPacket( IIBCAppCallbacks.OnSendPacketCallback({ sourceChannel: packet.sourceChannel, @@ -506,7 +506,7 @@ contract ICS20TransferTest is Test { // test invalid contract/denom defaultPacketData.denom = "invalid"; packet.payloads[0].value = abi.encode(defaultPacketData); - vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20InvalidAddress.selector, "invalid")); + vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20DenomNotFound.selector, "invalid")); ics20Transfer.onAcknowledgementPacket( IIBCAppCallbacks.OnAcknowledgementPacketCallback({ sourceChannel: packet.sourceChannel, @@ -606,7 +606,7 @@ contract ICS20TransferTest is Test { // test invalid contract defaultPacketData.denom = "invalid"; packet.payloads[0].value = abi.encode(defaultPacketData); - vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20InvalidAddress.selector, "invalid")); + vm.expectRevert(abi.encodeWithSelector(IICS20Errors.ICS20DenomNotFound.selector, "invalid")); ics20Transfer.onTimeoutPacket( IIBCAppCallbacks.OnTimeoutPacketCallback({ sourceChannel: packet.sourceChannel, From 9bbab5b04b9639db612927b7f1b59e28ef1ec2b3 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 18:31:55 +0800 Subject: [PATCH 14/22] feat: attempt to add new test --- .github/workflows/e2e.yml | 1 + e2e/interchaintestv8/multichain_test.go | 173 ++++++++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index bb9f17e9..39b9280c 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -82,6 +82,7 @@ jobs: - TestWithCosmosRelayerTestSuite/Test_10_ICS20TimeoutPacket - TestWithMultichainTestSuite/TestDeploy_Groth16 - TestWithMultichainTestSuite/TestTransferCosmosToEthToCosmos_Groth16 + - TestWithMultichainTestSuite/TestTransferEthToCosmosToCosmos_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16 - TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk - TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16 diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 2fa697e1..21bd5863 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -830,6 +830,179 @@ func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { s.Require().NoError(err) s.Require().NotNil(resp.Balance) s.Require().Equal(testvalues.TransferAmount, resp.Balance.Amount.Int64()) + s.Require().Equal(finalDenom.IBCDenom(), resp.Balance.Denom) + })) + })) +} + +func (s *MultichainTestSuite) TestTransferEthToCosmosToCosmos_Groth16() { + ctx := context.Background() + proofType := operator.ProofTypeGroth16 + + s.SetupSuite(ctx, proofType) + + eth, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] + + ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer) + transferAmount := big.NewInt(testvalues.TransferAmount) + ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey) + simdAUser, simdBUser := s.CosmosUsers[0], s.CosmosUsers[1] + + s.Require().True(s.Run("Approve the ICS20Transfer.sol contract to spend the erc20 tokens", func() { + tx, err := s.erc20Contract.Approve(s.GetTransactOpts(s.key, eth), ics20Address, transferAmount) + s.Require().NoError(err) + + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status) + + allowance, err := s.erc20Contract.Allowance(nil, ethereumUserAddress, ics20Address) + s.Require().NoError(err) + s.Require().Equal(transferAmount, allowance) + })) + + var ethSendTxHash []byte + s.Require().True(s.Run("Send from Ethereum to SimdA", func() { + timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) + + msgSendPacket := s.createICS20MsgSendPacket( + ethereumUserAddress, + s.contractAddresses.Erc20, + transferAmount, + simdAUser.FormattedAddress(), + ibctesting.FirstClientID, + timeout, + "", + ) + + tx, err := s.ics26Contract.SendPacket(s.GetTransactOpts(s.key, eth), msgSendPacket) + s.Require().NoError(err) + receipt, err := eth.GetTxReciept(ctx, tx.Hash()) + s.Require().NoError(err) + s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status) + + ethSendTxHash = tx.Hash().Bytes() + + s.True(s.Run("Verify balances on Ethereum", func() { + // User balance on Ethereum + userBalance, err := s.erc20Contract.BalanceOf(nil, ethereumUserAddress) + s.Require().NoError(err) + s.Require().Equal(testvalues.InitialBalance-transferAmount.Int64(), userBalance.Int64()) + + // ICS20 contract balance on Ethereum + escrowBalance, err := s.erc20Contract.BalanceOf(nil, s.escrowContractAddr) + s.Require().NoError(err) + s.Require().Equal(transferAmount, escrowBalance) + })) + })) + + s.Require().True(s.Run("Receive packets on SimdA", func() { + var relayTxBodyBz []byte + s.Require().True(s.Run("Retrieve relay tx", func() { + resp, err := s.EthToChainARelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: [][]byte{ethSendTxHash}, + TargetChannelId: ibctesting.FirstChannelID, + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) + + relayTxBodyBz = resp.Tx + })) + + s.Require().True(s.Run("Broadcast relay tx", func() { + _ = s.BroadcastSdkTxBody(ctx, simdA, s.SimdARelayerSubmitter, 2_000_000, relayTxBodyBz) + // NOTE: We don't need to check the response since we don't need to acknowledge the packet + })) + + s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + denomOnSimdA := transfertypes.NewDenom(s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)) + + // User balance on Cosmos chain + resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simdA, &banktypes.QueryBalanceRequest{ + Address: simdAUser.FormattedAddress(), + Denom: denomOnSimdA.IBCDenom(), + }) + s.Require().NoError(err) + s.Require().NotNil(resp.Balance) + s.Require().Equal(transferAmount.Uint64(), resp.Balance.Amount.Uint64()) + s.Require().Equal(denomOnSimdA.IBCDenom(), resp.Balance.Denom) + })) + })) + + var simdASendTxHash []byte + s.Require().True(s.Run("Send from SimdA to SimdB", func() { + denomOnSimdA := transfertypes.NewDenom(s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)) + timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) + + transferPayload := ics20lib.ICS20LibFungibleTokenPacketData{ + Denom: denomOnSimdA.IBCDenom(), + Amount: transferAmount, + Sender: simdAUser.FormattedAddress(), + Receiver: simdBUser.FormattedAddress(), + Memo: "", + } + transferBz, err := ics20lib.EncodeFungibleTokenPacketData(transferPayload) + s.Require().NoError(err) + + payload := channeltypesv2.Payload{ + SourcePort: transfertypes.PortID, + DestinationPort: transfertypes.PortID, + Version: transfertypes.V1, + Encoding: transfertypes.EncodingABI, + Value: transferBz, + } + + resp, err := s.BroadcastMessages(ctx, simdA, simdAUser, 2_000_000, &channeltypesv2.MsgSendPacket{ + SourceChannel: ibctesting.SecondChannelID, + TimeoutTimestamp: timeout, + Payloads: []channeltypesv2.Payload{ + payload, + }, + Signer: simdAUser.FormattedAddress(), + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.TxHash) + + simdASendTxHash, err = hex.DecodeString(resp.TxHash) + s.Require().NoError(err) + })) + + s.Require().True(s.Run("Receive packet on SimdB", func() { + var txBodyBz []byte + s.Require().True(s.Run("Retrieve relay tx to SimdB", func() { + resp, err := s.ChainAToChainBRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: [][]byte{simdASendTxHash}, + TargetChannelId: ibctesting.SecondChannelID, + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) + + txBodyBz = resp.Tx + })) + + s.Require().True(s.Run("Broadcast relay tx on SimdB", func() { + _ = s.BroadcastSdkTxBody(ctx, simdB, s.SimdBRelayerSubmitter, 2_000_000, txBodyBz) + // NOTE: We don't need to check the response since we don't need to acknowledge the packet + })) + + s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + finalDenom := transfertypes.NewDenom( + simdA.Config().Denom, + transfertypes.NewHop(transfertypes.PortID, ibctesting.SecondChannelID), + transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID), + ) + + // User balance on Cosmos chain + resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simdB, &banktypes.QueryBalanceRequest{ + Address: simdBUser.FormattedAddress(), + Denom: finalDenom.IBCDenom(), + }) + s.Require().NoError(err) + s.Require().NotNil(resp.Balance) + s.Require().Equal(testvalues.TransferAmount, resp.Balance.Amount.Int64()) + s.Require().Equal(finalDenom.IBCDenom(), resp.Balance.Denom) })) })) } From 884a1a012fd851cb7c79785dd299b6c036dc34e8 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 19:37:04 +0800 Subject: [PATCH 15/22] imp: fix deployment --- e2e/interchaintestv8/multichain_test.go | 35 ++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 21bd5863..2cb97860 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/cosmos/gogoproto/proto" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcerc20" "github.com/cosmos/solidity-ibc-eureka/abigen/ibcstore" "github.com/cosmos/solidity-ibc-eureka/abigen/ics20lib" @@ -325,7 +326,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) - _, err = s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &clienttypes.MsgCreateClient{ + _, err = s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 2_000_000, &clienttypes.MsgCreateClient{ ClientState: clientStateAny, ConsensusState: consensusStateAny, Signer: s.SimdBRelayerSubmitter.FormattedAddress(), @@ -359,7 +360,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().NoError(err) })) - _, err = s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 200_000, &clienttypes.MsgCreateClient{ + _, err = s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 2_000_000, &clienttypes.MsgCreateClient{ ClientState: clientStateAny, ConsensusState: consensusStateAny, Signer: s.SimdARelayerSubmitter.FormattedAddress(), @@ -372,7 +373,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator // We can do this because we know what the counterparty channel ID will be _, err := s.BroadcastMessages(ctx, simdA, s.SimdARelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ - ClientId: ibctesting.FirstClientID, + ClientId: ibctesting.SecondClientID, MerklePathPrefix: merklePathPrefix, Signer: s.SimdARelayerSubmitter.FormattedAddress(), }, &channeltypesv2.MsgRegisterCounterparty{ @@ -387,7 +388,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator merklePathPrefix := commitmenttypesv2.NewMerklePath([]byte(ibcexported.StoreKey), []byte("")) _, err := s.BroadcastMessages(ctx, simdB, s.SimdBRelayerSubmitter, 200_000, &channeltypesv2.MsgCreateChannel{ - ClientId: ibctesting.FirstClientID, + ClientId: ibctesting.SecondClientID, MerklePathPrefix: merklePathPrefix, Signer: s.SimdBRelayerSubmitter.FormattedAddress(), }, &channeltypesv2.MsgRegisterCounterparty{ @@ -575,6 +576,32 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { s.Require().Equal(ibctesting.SecondClientID, channelResp.Channel.CounterpartyChannelId) })) + s.Require().True(s.Run("Verify Light Client of Chain A on Chain B", func() { + clientStateResp, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, simdB, &clienttypes.QueryClientStateRequest{ + ClientId: ibctesting.SecondClientID, + }) + s.Require().NoError(err) + s.Require().NotZero(clientStateResp.ClientState.Value) + + var clientState ibctm.ClientState + err = proto.Unmarshal(clientStateResp.ClientState.Value, &clientState) + s.Require().NoError(err) + s.Require().Equal(simdA.Config().ChainID, clientState.ChainId) + })) + + s.Require().True(s.Run("Verify Light Client of Chain B on Chain A", func() { + clientStateResp, err := e2esuite.GRPCQuery[clienttypes.QueryClientStateResponse](ctx, simdA, &clienttypes.QueryClientStateRequest{ + ClientId: ibctesting.SecondClientID, + }) + s.Require().NoError(err) + s.Require().NotZero(clientStateResp.ClientState.Value) + + var clientState ibctm.ClientState + err = proto.Unmarshal(clientStateResp.ClientState.Value, &clientState) + s.Require().NoError(err) + s.Require().Equal(simdB.Config().ChainID, clientState.ChainId) + })) + s.Require().True(s.Run("Verify SimdA to Eth Relayer Info", func() { info, err := s.ChainAToEthRelayerClient.Info(context.Background(), &relayertypes.InfoRequest{}) s.Require().NoError(err) From fc8018677402fec4afc16800674622691ef7f936 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 19:46:59 +0800 Subject: [PATCH 16/22] fix: denom --- e2e/interchaintestv8/multichain_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 2cb97860..734273fe 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -1016,7 +1016,7 @@ func (s *MultichainTestSuite) TestTransferEthToCosmosToCosmos_Groth16() { s.Require().True(s.Run("Verify balances on Cosmos chain", func() { finalDenom := transfertypes.NewDenom( - simdA.Config().Denom, + s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, ibctesting.SecondChannelID), transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID), ) From cfec36aad534491301afd58ccd163243a9d5e81a Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 15 Jan 2025 20:53:01 +0800 Subject: [PATCH 17/22] fix: attempt --- e2e/interchaintestv8/multichain_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 734273fe..6c77d38d 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -963,7 +963,10 @@ func (s *MultichainTestSuite) TestTransferEthToCosmosToCosmos_Groth16() { timeout := uint64(time.Now().Add(30 * time.Minute).Unix()) transferPayload := ics20lib.ICS20LibFungibleTokenPacketData{ - Denom: denomOnSimdA.IBCDenom(), + // Denom: denomOnSimdA.IBCDenom(), + // BUG: Allowing user to choose the above is a bug in ibc-go + // https://github.com/cosmos/ibc-go/issues/7848 + Denom: denomOnSimdA.Path(), Amount: transferAmount, Sender: simdAUser.FormattedAddress(), Receiver: simdBUser.FormattedAddress(), From 2ac7129d250ab4c96d96a42cd770b0fcbb3e4efe Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 16 Jan 2025 12:01:32 +0800 Subject: [PATCH 18/22] style: rename variables --- e2e/interchaintestv8/multichain_test.go | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/e2e/interchaintestv8/multichain_test.go b/e2e/interchaintestv8/multichain_test.go index 6c77d38d..a39cd485 100644 --- a/e2e/interchaintestv8/multichain_test.go +++ b/e2e/interchaintestv8/multichain_test.go @@ -61,17 +61,17 @@ type MultichainTestSuite struct { // The private key of the faucet account of interchaintest deployer *ecdsa.PrivateKey - contractAddresses ethereum.DeployedContracts - simdBSP1Ics07Address string - - simdASP1Ics07Contract *sp1ics07tendermint.Contract - simdBSP1Ics07Contract *sp1ics07tendermint.Contract - icsCoreContract *icscore.Contract - ics26Contract *ics26router.Contract - ics20Contract *ics20transfer.Contract - erc20Contract *erc20.Contract - ibcStoreContract *ibcstore.Contract - escrowContractAddr ethcommon.Address + contractAddresses ethereum.DeployedContracts + chainBSP1Ics07Address string + + chainASP1Ics07Contract *sp1ics07tendermint.Contract + chainBSP1Ics07Contract *sp1ics07tendermint.Contract + icsCoreContract *icscore.Contract + ics26Contract *ics26router.Contract + ics20Contract *ics20transfer.Contract + erc20Contract *erc20.Contract + ibcStoreContract *ibcstore.Contract + escrowContractAddr ethcommon.Address EthToChainARelayerClient relayertypes.RelayerServiceClient ChainAToEthRelayerClient relayertypes.RelayerServiceClient @@ -163,7 +163,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.contractAddresses, err = ethereum.GetEthContractsFromDeployOutput(string(stdout)) s.Require().NoError(err) - s.simdASP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint), eth.RPCClient) + s.chainASP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.contractAddresses.Ics07Tendermint), eth.RPCClient) s.Require().NoError(err) s.icsCoreContract, err = icscore.NewContract(ethcommon.HexToAddress(s.contractAddresses.IcsCore), eth.RPCClient) s.Require().NoError(err) @@ -209,12 +209,12 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator s.Require().Fail("invalid prover type: %s", prover) } - s.simdBSP1Ics07Address, err = ethereum.GetOnlySp1Ics07AddressFromStdout(string(stdout)) + s.chainBSP1Ics07Address, err = ethereum.GetOnlySp1Ics07AddressFromStdout(string(stdout)) s.Require().NoError(err) - s.Require().NotEmpty(s.simdBSP1Ics07Address) - s.Require().True(ethcommon.IsHexAddress(s.simdBSP1Ics07Address)) + s.Require().NotEmpty(s.chainBSP1Ics07Address) + s.Require().True(ethcommon.IsHexAddress(s.chainBSP1Ics07Address)) - s.simdBSP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.simdBSP1Ics07Address), eth.RPCClient) + s.chainBSP1Ics07Contract, err = sp1ics07tendermint.NewContract(ethcommon.HexToAddress(s.chainBSP1Ics07Address), eth.RPCClient) s.Require().NoError(err) })) @@ -257,7 +257,7 @@ func (s *MultichainTestSuite) SetupSuite(ctx context.Context, proofType operator CounterpartyId: ibctesting.FirstChannelID, MerklePrefix: [][]byte{[]byte(ibcexported.StoreKey), []byte("")}, } - lightClientAddress := ethcommon.HexToAddress(s.simdBSP1Ics07Address) + lightClientAddress := ethcommon.HexToAddress(s.chainBSP1Ics07Address) tx, err := s.icsCoreContract.AddChannel(s.GetTransactOpts(s.deployer, eth), ibcexported.Tendermint, channel, lightClientAddress) s.Require().NoError(err) @@ -477,7 +477,7 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { eth, simdA, simdB := s.EthChain, s.CosmosChains[0], s.CosmosChains[1] s.Require().True(s.Run("Verify SimdA SP1 Client", func() { - clientState, err := s.simdASP1Ics07Contract.GetClientState(nil) + clientState, err := s.chainASP1Ics07Contract.GetClientState(nil) s.Require().NoError(err) stakingParams, err := simdA.StakingQueryParams(ctx) @@ -494,7 +494,7 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { })) s.Require().True(s.Run("Verify SimdB SP1 Client", func() { - clientState, err := s.simdBSP1Ics07Contract.GetClientState(nil) + clientState, err := s.chainBSP1Ics07Contract.GetClientState(nil) s.Require().NoError(err) stakingParams, err := simdB.StakingQueryParams(ctx) @@ -525,7 +525,7 @@ func (s *MultichainTestSuite) TestDeploy_Groth16() { clientAddress, err = s.icsCoreContract.GetClient(nil, ibctesting.SecondClientID) s.Require().NoError(err) - s.Require().Equal(s.simdBSP1Ics07Address, strings.ToLower(clientAddress.Hex())) + s.Require().Equal(s.chainBSP1Ics07Address, strings.ToLower(clientAddress.Hex())) counterpartyInfo, err = s.icsCoreContract.GetChannel(nil, ibctesting.SecondClientID) s.Require().NoError(err) @@ -751,10 +751,10 @@ func (s *MultichainTestSuite) TestTransferCosmosToEthToCosmos_Groth16() { transferCoin := sdk.NewCoin(simdA.Config().Denom, sdkmath.NewIntFromBigInt(transferAmount)) denomOnEthereum := transfertypes.NewDenom(transferCoin.Denom, transfertypes.NewHop(packet.Payloads[0].DestPort, packet.DestChannel)) - ibcERC20Addr, err := s.ics20Contract.IbcERC20Contract(nil, denomOnEthereum.IBCDenom()) + ibcERC20EthAddress, err := s.ics20Contract.IbcERC20Contract(nil, denomOnEthereum.IBCDenom()) s.Require().NoError(err) - ibcERC20Address = ibcERC20Addr.Hex() + ibcERC20Address = ibcERC20EthAddress.Hex() s.Require().NotEmpty(ibcERC20Address) ibcERC20, err = ibcerc20.NewContract(ethcommon.HexToAddress(ibcERC20Address), eth.RPCClient) From ee242cafa1b6aef65678681cdd25e292ec7cb733 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 16 Jan 2025 12:28:40 +0800 Subject: [PATCH 19/22] refactor: cosmos tests --- e2e/interchaintestv8/cosmos_relayer_test.go | 166 +++++++++----------- e2e/interchaintestv8/ibc_eureka_test.go | 4 +- e2e/interchaintestv8/relayer_test.go | 2 +- 3 files changed, 73 insertions(+), 99 deletions(-) diff --git a/e2e/interchaintestv8/cosmos_relayer_test.go b/e2e/interchaintestv8/cosmos_relayer_test.go index 5aa251f2..e2b241e6 100644 --- a/e2e/interchaintestv8/cosmos_relayer_test.go +++ b/e2e/interchaintestv8/cosmos_relayer_test.go @@ -8,7 +8,6 @@ import ( "testing" "time" - "github.com/cosmos/gogoproto/proto" "github.com/cosmos/solidity-ibc-eureka/abigen/ics20lib" "github.com/stretchr/testify/suite" @@ -17,7 +16,6 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - txtypes "github.com/cosmos/cosmos-sdk/types/tx" transfertypes "github.com/cosmos/ibc-go/v9/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" @@ -298,7 +296,7 @@ func (s *CosmosRelayerTestSuite) ICS20RecvAndAckPacketTest(ctx context.Context, txHashes = append(txHashes, txHash) } - s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + s.Require().True(s.Run("Verify balances on Chain A", func() { resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdA, &banktypes.QueryBalanceRequest{ Address: simdAUser.FormattedAddress(), Denom: s.SimdA.Config().Denom, @@ -309,84 +307,72 @@ func (s *CosmosRelayerTestSuite) ICS20RecvAndAckPacketTest(ctx context.Context, })) })) - var txBodyBz []byte - s.Require().True(s.Run("Retrieve relay tx to Chain B", func() { - resp, err := s.AtoBRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ - SourceTxIds: txHashes, - TargetChannelId: ibctesting.FirstChannelID, - }) - s.Require().NoError(err) - s.Require().NotEmpty(resp.Tx) - s.Require().Empty(resp.Address) - - txBodyBz = resp.Tx - })) - var ackTxHash []byte - s.Require().True(s.Run("Broadcast relay tx on Chain B", func() { - var txBody txtypes.TxBody - err := proto.Unmarshal(txBodyBz, &txBody) - s.Require().NoError(err) - - var msgs []sdk.Msg - for _, msg := range txBody.Messages { - var sdkMsg sdk.Msg - err = s.SimdB.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) + s.Require().True(s.Run("Receive packets on Chain B", func() { + var txBodyBz []byte + s.Require().True(s.Run("Retrieve relay tx", func() { + resp, err := s.AtoBRelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: txHashes, + TargetChannelId: ibctesting.FirstChannelID, + }) s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) - msgs = append(msgs, sdkMsg) - } + txBodyBz = resp.Tx + })) - resp, err := s.BroadcastMessages(ctx, s.SimdB, s.SimdBSubmitter, 2_000_000, msgs...) - s.Require().NoError(err) + s.Require().True(s.Run("Broadcast relay tx", func() { + resp := s.BroadcastSdkTxBody(ctx, s.SimdB, s.SimdBSubmitter, 2_000_000, txBodyBz) - ackTxHash, err = hex.DecodeString(resp.TxHash) - s.Require().NoError(err) - s.Require().NotEmpty(ackTxHash) - - s.Require().True(s.Run("Verify balances on Cosmos chain", func() { - ibcDenom := transfertypes.NewDenom(s.SimdA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)).IBCDenom() - // User balance on Cosmos chain - resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdB, &banktypes.QueryBalanceRequest{ - Address: simdBUser.FormattedAddress(), - Denom: ibcDenom, - }) + var err error + ackTxHash, err = hex.DecodeString(resp.TxHash) s.Require().NoError(err) - s.Require().NotNil(resp.Balance) - s.Require().Equal(totalTransferAmount, resp.Balance.Amount.Int64()) - s.Require().Equal(ibcDenom, resp.Balance.Denom) + s.Require().NotEmpty(ackTxHash) + + s.Require().True(s.Run("Verify balances on Chain B", func() { + ibcDenom := transfertypes.NewDenom(s.SimdA.Config().Denom, transfertypes.NewHop(transfertypes.PortID, ibctesting.FirstChannelID)).IBCDenom() + // User balance on Cosmos chain + resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdB, &banktypes.QueryBalanceRequest{ + Address: simdBUser.FormattedAddress(), + Denom: ibcDenom, + }) + s.Require().NoError(err) + s.Require().NotNil(resp.Balance) + s.Require().Equal(totalTransferAmount, resp.Balance.Amount.Int64()) + s.Require().Equal(ibcDenom, resp.Balance.Denom) + })) })) })) - var ackTxBodyBz []byte - s.Require().True(s.Run("Retrieve ack tx to Chain A", func() { - resp, err := s.BtoARelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ - SourceTxIds: [][]byte{ackTxHash}, - TargetChannelId: ibctesting.FirstChannelID, - }) - s.Require().NoError(err) - s.Require().NotEmpty(resp.Tx) - s.Require().Empty(resp.Address) - - ackTxBodyBz = resp.Tx - })) - - s.Require().True(s.Run("Broadcast ack tx on Chain A", func() { - var txBody txtypes.TxBody - err := proto.Unmarshal(ackTxBodyBz, &txBody) - s.Require().NoError(err) + s.Require().True(s.Run("Acknowledge packets on Chain A", func() { + s.Require().True(s.Run("Verify commitments exists", func() { + for i := 0; i < numOfTransfers; i++ { + resp, err := e2esuite.GRPCQuery[channeltypesv2.QueryPacketCommitmentResponse](ctx, s.SimdA, &channeltypesv2.QueryPacketCommitmentRequest{ + ChannelId: ibctesting.FirstChannelID, + Sequence: uint64(i) + 1, + }) + s.Require().NoError(err) + s.Require().NotEmpty(resp.Commitment) + } + })) - var msgs []sdk.Msg - for _, msg := range txBody.Messages { - var sdkMsg sdk.Msg - err = s.SimdA.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) + var ackTxBodyBz []byte + s.Require().True(s.Run("Retrieve ack tx to Chain A", func() { + resp, err := s.BtoARelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + SourceTxIds: [][]byte{ackTxHash}, + TargetChannelId: ibctesting.FirstChannelID, + }) s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) - msgs = append(msgs, sdkMsg) - } + ackTxBodyBz = resp.Tx + })) - _, err = s.BroadcastMessages(ctx, s.SimdA, s.SimdASubmitter, 2_000_000, msgs...) - s.Require().NoError(err) + s.Require().True(s.Run("Broadcast ack tx on Chain A", func() { + _ = s.BroadcastSdkTxBody(ctx, s.SimdA, s.SimdASubmitter, 2_000_000, ackTxBodyBz) + })) s.Require().True(s.Run("Verify commitments removed", func() { for i := 0; i < numOfTransfers; i++ { @@ -462,7 +448,7 @@ func (s *CosmosRelayerTestSuite) ICS20TimeoutPacketTest(ctx context.Context, num txHashes = append(txHashes, txHash) } - s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + s.Require().True(s.Run("Verify balances on Chain A", func() { resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdA, &banktypes.QueryBalanceRequest{ Address: simdAUser.FormattedAddress(), Denom: s.SimdA.Config().Denom, @@ -476,37 +462,25 @@ func (s *CosmosRelayerTestSuite) ICS20TimeoutPacketTest(ctx context.Context, num // Wait until timeout time.Sleep(30 * time.Second) - var timeoutTxBodyBz []byte - s.Require().True(s.Run("Retrieve timeout tx to Chain A", func() { - resp, err := s.BtoARelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ - TimeoutTxIds: txHashes, - TargetChannelId: ibctesting.FirstChannelID, - }) - s.Require().NoError(err) - s.Require().NotEmpty(resp.Tx) - s.Require().Empty(resp.Address) - - timeoutTxBodyBz = resp.Tx - })) - - s.Require().True(s.Run("Broadcast timeout tx on Chain A", func() { - var txBody txtypes.TxBody - err := proto.Unmarshal(timeoutTxBodyBz, &txBody) - s.Require().NoError(err) - - var msgs []sdk.Msg - for _, msg := range txBody.Messages { - var sdkMsg sdk.Msg - err = s.SimdA.Config().EncodingConfig.InterfaceRegistry.UnpackAny(msg, &sdkMsg) + s.Require().True(s.Run("Timeout packet on Chain A", func() { + var timeoutTxBodyBz []byte + s.Require().True(s.Run("Retrieve timeout tx", func() { + resp, err := s.BtoARelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{ + TimeoutTxIds: txHashes, + TargetChannelId: ibctesting.FirstChannelID, + }) s.Require().NoError(err) + s.Require().NotEmpty(resp.Tx) + s.Require().Empty(resp.Address) - msgs = append(msgs, sdkMsg) - } + timeoutTxBodyBz = resp.Tx + })) - _, err = s.BroadcastMessages(ctx, s.SimdA, s.SimdASubmitter, 2_000_000, msgs...) - s.Require().NoError(err) + s.Require().True(s.Run("Broadcast timeout tx", func() { + _ = s.BroadcastSdkTxBody(ctx, s.SimdA, s.SimdASubmitter, 2_000_000, timeoutTxBodyBz) + })) - s.Require().True(s.Run("Verify balances on Cosmos chain", func() { + s.Require().True(s.Run("Verify balances on Chain A", func() { resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdA, &banktypes.QueryBalanceRequest{ Address: simdAUser.FormattedAddress(), Denom: s.SimdA.Config().Denom, diff --git a/e2e/interchaintestv8/ibc_eureka_test.go b/e2e/interchaintestv8/ibc_eureka_test.go index 32a328df..c128abd4 100644 --- a/e2e/interchaintestv8/ibc_eureka_test.go +++ b/e2e/interchaintestv8/ibc_eureka_test.go @@ -684,7 +684,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT Sequence: uint64(i) + 1, }) s.Require().NoError(err) - s.Require().NotNil(resp.Commitment) + s.Require().NotEmpty(resp.Commitment) } })) @@ -877,7 +877,7 @@ func (s *IbcEurekaTestSuite) ICS20TransferNativeCosmosCoinsToEthereumAndBackTest Sequence: 1, }) s.Require().NoError(err) - s.Require().NotNil(resp.Commitment) + s.Require().NotEmpty(resp.Commitment) })) var ackRelayTxBodyBz []byte diff --git a/e2e/interchaintestv8/relayer_test.go b/e2e/interchaintestv8/relayer_test.go index 049e17d0..6e7e14f8 100644 --- a/e2e/interchaintestv8/relayer_test.go +++ b/e2e/interchaintestv8/relayer_test.go @@ -681,7 +681,7 @@ func (s *RelayerTestSuite) ICS20TransferERC20TokenBatchedAckToCosmosTest( Sequence: uint64(i) + 1, }) s.Require().NoError(err) - s.Require().NotNil(resp.Commitment) + s.Require().NotEmpty(resp.Commitment) } })) From 279673feccc79f6771e6cbe39214bd239d127065 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 16 Jan 2025 14:02:12 +0800 Subject: [PATCH 20/22] fix: attempt --- justfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/justfile b/justfile index 7e96525c..70fbb6d9 100644 --- a/justfile +++ b/justfile @@ -14,13 +14,13 @@ build-operator: # Build riscv elf files using `~/.sp1/bin/cargo-prove` build-sp1-programs: - cd programs/sp1-programs/update-client && ~/.sp1/bin/cargo-prove prove build --elf-name update-client-riscv32im-succinct-zkvm-elf + ~/.sp1/bin/cargo-prove prove build --elf-name update-client-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-update-client @echo "ELF created at 'elf/update-client-riscv32im-succinct-zkvm-elf'" - cd programs/sp1-programs/membership && ~/.sp1/bin/cargo-prove prove build --elf-name membership-riscv32im-succinct-zkvm-elf + ~/.sp1/bin/cargo-prove prove build --elf-name membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-membership @echo "ELF created at 'elf/membership-riscv32im-succinct-zkvm-elf'" - cd programs/sp1-programs/uc-and-membership && ~/.sp1/bin/cargo-prove prove build --elf-name uc-and-membership-riscv32im-succinct-zkvm-elf + ~/.sp1/bin/cargo-prove prove build --elf-name uc-and-membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-uc-and-membership @echo "ELF created at 'elf/uc-and-membership-riscv32im-succinct-zkvm-elf'" - cd programs/sp1-programs/misbehaviour && ~/.sp1/bin/cargo-prove prove build --elf-name misbehaviour-riscv32im-succinct-zkvm-elf + ~/.sp1/bin/cargo-prove prove build --elf-name misbehaviour-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-misbehaviour @echo "ELF created at 'elf/misbehaviour-riscv32im-succinct-zkvm-elf'" # Build and optimize the eth wasm light client using `cosmwasm/optimizer`. Requires `docker` and `gzip` From f8e4c4f0465de70cadc52885268e1d56ded146d2 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 16 Jan 2025 14:28:00 +0800 Subject: [PATCH 21/22] imp: disable build scripts --- justfile | 8 ++++---- packages/sp1-ics07-tendermint-prover/build.rs | 8 +++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/justfile b/justfile index 70fbb6d9..ccf58847 100644 --- a/justfile +++ b/justfile @@ -14,13 +14,13 @@ build-operator: # Build riscv elf files using `~/.sp1/bin/cargo-prove` build-sp1-programs: - ~/.sp1/bin/cargo-prove prove build --elf-name update-client-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-update-client + ~/.sp1/bin/cargo-prove prove build --elf-name update-client-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-update-client --output-directory elf --locked @echo "ELF created at 'elf/update-client-riscv32im-succinct-zkvm-elf'" - ~/.sp1/bin/cargo-prove prove build --elf-name membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-membership + ~/.sp1/bin/cargo-prove prove build --elf-name membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-membership --output-directory elf --locked @echo "ELF created at 'elf/membership-riscv32im-succinct-zkvm-elf'" - ~/.sp1/bin/cargo-prove prove build --elf-name uc-and-membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-uc-and-membership + ~/.sp1/bin/cargo-prove prove build --elf-name uc-and-membership-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-uc-and-membership --output-directory elf --locked @echo "ELF created at 'elf/uc-and-membership-riscv32im-succinct-zkvm-elf'" - ~/.sp1/bin/cargo-prove prove build --elf-name misbehaviour-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-misbehaviour + ~/.sp1/bin/cargo-prove prove build --elf-name misbehaviour-riscv32im-succinct-zkvm-elf -p sp1-ics07-tendermint-misbehaviour --output-directory elf --locked @echo "ELF created at 'elf/misbehaviour-riscv32im-succinct-zkvm-elf'" # Build and optimize the eth wasm light client using `cosmwasm/optimizer`. Requires `docker` and `gzip` diff --git a/packages/sp1-ics07-tendermint-prover/build.rs b/packages/sp1-ics07-tendermint-prover/build.rs index ecf7f8d0..ffce852e 100644 --- a/packages/sp1-ics07-tendermint-prover/build.rs +++ b/packages/sp1-ics07-tendermint-prover/build.rs @@ -1,13 +1,15 @@ -use sp1_helper::{build_program_with_args, BuildArgs}; +//use sp1_helper::{build_program_with_args, BuildArgs}; // Build script to build the programs if they change. // Requires SP1 toolchain to be installed. fn main() { + /* // Build the update-client program. build_program_with_args( "../../programs/sp1-programs/update-client", BuildArgs { elf_name: "update-client-riscv32im-succinct-zkvm-elf".to_string(), + locked: true, ..Default::default() }, ); @@ -16,6 +18,7 @@ fn main() { "../../programs/sp1-programs/membership", BuildArgs { elf_name: "membership-riscv32im-succinct-zkvm-elf".to_string(), + locked: true, ..Default::default() }, ); @@ -24,6 +27,7 @@ fn main() { "../../programs/sp1-programs/uc-and-membership", BuildArgs { elf_name: "uc-and-membership-riscv32im-succinct-zkvm-elf".to_string(), + locked: true, ..Default::default() }, ); @@ -32,7 +36,9 @@ fn main() { "../../programs/sp1-programs/misbehaviour", BuildArgs { elf_name: "misbehaviour-riscv32im-succinct-zkvm-elf".to_string(), + locked: true, ..Default::default() }, ) + */ } From dc06031f06c53e59a229a9d55cb9bb40b0c686eb Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 16 Jan 2025 14:36:38 +0800 Subject: [PATCH 22/22] ci: fix workflows --- .github/workflows/e2e.yml | 8 ++++++++ .github/workflows/rust.yml | 21 +++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 39b9280c..eabdef28 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -131,6 +131,14 @@ jobs: ~/.sp1/bin/sp1up --token ${{ secrets.GITHUB_TOKEN }} ~/.sp1/bin/cargo-prove prove --version + # TODO: This is a workaround until build macros are re-enabled (#218) + - name: Install just + if: steps.cache-relayer.outputs.cache-hit != 'true' + uses: extractions/setup-just@v2 + - name: Build SP1 Programs + if: steps.cache-relayer.outputs.cache-hit != 'true' + run: just build-sp1-programs + - name: Install operator if: steps.cache-relayer.outputs.cache-hit != 'true' uses: actions-rs/cargo@v1 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 744462e8..7f6d3f02 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -20,7 +20,7 @@ jobs: - name: Install SP1 toolchain shell: bash run: | - curl -L https://raw.githubusercontent.com/succinctlabs/sp1/v3.4.0/sp1up/install | bash + curl -L https://sp1.succinct.xyz | bash ~/.sp1/bin/sp1up --token ${{ secrets.GITHUB_TOKEN }} ~/.sp1/bin/cargo-prove prove --version @@ -48,13 +48,16 @@ jobs: - name: Install SP1 toolchain shell: bash run: | - curl -L https://raw.githubusercontent.com/succinctlabs/sp1/v3.4.0/sp1up/install | bash + curl -L https://sp1.succinct.xyz | bash ~/.sp1/bin/sp1up --token ${{ secrets.GITHUB_TOKEN }} ~/.sp1/bin/cargo-prove prove --version - name: "Set up environment" uses: ./.github/setup - name: Install just uses: extractions/setup-just@v2 + # TODO: This is a workaround until build macros are re-enabled (#218) + - name: Build SP1 Programs + run: just build-sp1-programs - name: Run unit tests run: just test-cargo env: @@ -72,9 +75,14 @@ jobs: - name: Install SP1 toolchain shell: bash run: | - curl -L https://raw.githubusercontent.com/succinctlabs/sp1/v3.4.0/sp1up/install | bash + curl -L https://sp1.succinct.xyz | bash ~/.sp1/bin/sp1up --token ${{ secrets.GITHUB_TOKEN }} ~/.sp1/bin/cargo-prove prove --version + # TODO: This is a workaround until build macros are re-enabled (#218) + - name: Install just + uses: extractions/setup-just@v2 + - name: Build SP1 Programs + run: just build-sp1-programs - name: Build uses: actions-rs/cargo@v1 with: @@ -93,9 +101,14 @@ jobs: - name: Install SP1 toolchain shell: bash run: | - curl -L https://raw.githubusercontent.com/succinctlabs/sp1/v3.4.0/sp1up/install | bash + curl -L https://sp1.succinct.xyz | bash ~/.sp1/bin/sp1up --token ${{ secrets.GITHUB_TOKEN }} ~/.sp1/bin/cargo-prove prove --version + # TODO: This is a workaround until build macros are re-enabled (#218) + - name: Install just + uses: extractions/setup-just@v2 + - name: Build SP1 Programs + run: just build-sp1-programs - name: Build uses: actions-rs/cargo@v1 with: