Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

imp: fixed multi-chain support and added tests #215

Merged
merged 23 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ jobs:
- TestWithCosmosRelayerTestSuite/Test_10_ICS20RecvAndAckPacket
- TestWithCosmosRelayerTestSuite/TestICS20TimeoutPacket
- TestWithCosmosRelayerTestSuite/Test_10_ICS20TimeoutPacket
- TestWithMultichainTestSuite/TestDeploy_Groth16
- TestWithMultichainTestSuite/TestTransferCosmosToEthToCosmos_Groth16
- TestWithMultichainTestSuite/TestTransferEthToCosmosToCosmos_Groth16
- TestWithSP1ICS07TendermintTestSuite/TestDeploy_Groth16
- TestWithSP1ICS07TendermintTestSuite/TestDeploy_Plonk
- TestWithSP1ICS07TendermintTestSuite/TestUpdateClient_Groth16
Expand Down Expand Up @@ -128,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
Expand Down
21 changes: 17 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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:
Expand Down
10 changes: 7 additions & 3 deletions contracts/ICS20Transfer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you add a test that catches this so we both document the behavior and make sure there are no regressions on this?

Copy link
Member Author

@srdtrk srdtrk Jan 16, 2025

Choose a reason for hiding this comment

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

I actually wanna revisit this code and potentially change it. I'll create an issue for this as I believe likely the same issue which effects ibc-go also might be effecting this repo. And this should begin a new design discussion which should be out of scope for this PR. Therefore the issue I will create is going to:

Copy link
Member Author

Choose a reason for hiding this comment

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

(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);
}

Expand Down
180 changes: 74 additions & 106 deletions e2e/interchaintestv8/cosmos_relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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"
Expand Down Expand Up @@ -219,27 +217,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.T().Logf("Relayer Info: %+v", info)

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

s.Run("Chain B to A Relayer Info", func() {
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.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)
})
}))
}

func (s *CosmosRelayerTestSuite) TestICS20RecvAndAckPacket() {
Expand Down Expand Up @@ -304,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,
Expand All @@ -315,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++ {
Expand Down Expand Up @@ -468,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,
Expand All @@ -482,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,
Expand Down
Loading
Loading