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

test(e2e): ack error cases on vouchers #371

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4a4aa9f
add tests wip
mconcat Mar 6, 2025
b724f82
wip
mconcat Mar 6, 2025
e405610
ack test with invalid destination from cosmos to eth, voucher restored
mconcat Mar 7, 2025
7128654
lint
mconcat Mar 7, 2025
62ed008
Merge branch 'main' into e2e-test-error-ack-remint
mconcat Mar 7, 2025
0afe1ab
Merge branch 'main' into e2e-test-error-ack-remint
gjermundgaraba Mar 10, 2025
f99dfcf
Merge branch 'main' into e2e-test-error-ack-remint
gjermundgaraba Mar 12, 2025
eb16e1b
apply comments - separate out the failing route
mconcat Mar 13, 2025
b34c619
update workflow
mconcat Mar 13, 2025
10403fa
Merge branch 'e2e-test-error-ack-remint' of github.com:cosmos/solidit…
mconcat Mar 13, 2025
5810d55
Merge branch 'main' into e2e-test-error-ack-remint
mconcat Mar 13, 2025
0de69f4
temporarily made the test work; ack recovery is not working
mconcat Mar 13, 2025
aa7f7dc
Merge branch 'e2e-test-error-ack-remint' of github.com:cosmos/solidit…
mconcat Mar 13, 2025
fc9a197
Merge branch 'main' of github.com:cosmos/solidity-ibc-eureka into e2e…
mconcat Mar 13, 2025
bb70916
uncomment ack related tests
mconcat Mar 13, 2025
d7f4da9
Merge branch 'main' into e2e-test-error-ack-remint
gjermundgaraba Mar 13, 2025
648961c
fix test
mconcat Mar 14, 2025
cc6b9b2
Merge branch 'e2e-test-error-ack-remint' of github.com:cosmos/solidit…
mconcat Mar 14, 2025
1f53990
Merge branch 'main' into e2e-test-error-ack-remint
mconcat Mar 14, 2025
a187b6b
Merge branch 'main' of github.com:cosmos/solidity-ibc-eureka into e2e…
mconcat Mar 21, 2025
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
199 changes: 198 additions & 1 deletion e2e/interchaintestv8/ibc_eureka_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ func (s *IbcEurekaTestSuite) TestICS20TransferUint256TokenfromEthereumToCosmosAn
}

// ICS20TransferERC20TokenfromEthereumToCosmosAndBackTest tests the ICS20 transfer functionality by transferring
// ERC20 tokens with n packets from Ethereum to Cosmos chain and then back from Cosmos chain to Ethereum
// ERC20 tokens with n packets from Ethereum to Cosmos chain and then back from Cosmos chain to Ethereum.
func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackTest(
ctx context.Context, proofType operator.SupportedProofType, numOfTransfers int, transferAmount *big.Int,
) {
Expand Down Expand Up @@ -745,6 +745,203 @@ func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenfromEthereumToCosmosAndBackT
}))
}

func (s *IbcEurekaTestSuite) TestICS20TransferERC20TokenFromEthereumToCosmosAndBackFails_Groth16() {
ctx := context.Background()
s.ICS20TransferERC20TokenFromEthereumToCosmosAndBackFailsTest(ctx, operator.ProofTypeGroth16, 1, big.NewInt(testvalues.TransferAmount))
}

func (s *IbcEurekaTestSuite) ICS20TransferERC20TokenFromEthereumToCosmosAndBackFailsTest(
ctx context.Context, proofType operator.SupportedProofType, numOfTransfers int, transferAmount *big.Int,
) {
s.SetupSuite(ctx, proofType)

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

ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router)
ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer)
erc20Address := ethcommon.HexToAddress(s.contractAddresses.Erc20)

totalTransferAmount := new(big.Int).Mul(transferAmount, big.NewInt(int64(numOfTransfers)))
ethereumUserAddress := crypto.PubkeyToAddress(s.key.PublicKey)
cosmosUserWallet := s.CosmosUsers[0]
cosmosUserAddress := cosmosUserWallet.FormattedAddress()

ics20transferAbi, err := abi.JSON(strings.NewReader(ics20transfer.ContractABI))
s.Require().NoError(err)

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, totalTransferAmount)
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(totalTransferAmount, allowance)
}))

var ethSendTxHash []byte
s.Require().True(s.Run(fmt.Sprintf("Send %d transfers on Ethereum", numOfTransfers), func() {
timeout := uint64(time.Now().Add(30 * time.Minute).Unix())
transferMulticall := make([][]byte, numOfTransfers)

msgSendPacket := ics20transfer.IICS20TransferMsgsSendTransferMsg{
Denom: erc20Address,
Amount: transferAmount,
Receiver: cosmosUserAddress,
TimeoutTimestamp: timeout,
SourceClient: testvalues.CustomClientID,
Memo: "",
}

encodedMsg, err := ics20transferAbi.Pack("sendTransfer", msgSendPacket)
s.Require().NoError(err)
for i := 0; i < numOfTransfers; i++ {
transferMulticall[i] = encodedMsg
}

tx, err := s.ics20Contract.Multicall(s.GetTransactOpts(s.key, eth), transferMulticall)
s.Require().NoError(err)
receipt, err := eth.GetTxReciept(ctx, tx.Hash())
s.Require().NoError(err)
s.T().Logf("Multicall send %d transfers gas used: %d", numOfTransfers, receipt.GasUsed)
ethSendTxHash = tx.Hash().Bytes()
}))

var ackTxHash []byte
s.Require().True(s.Run("Receive packets on Cosmos chain", func() {
var relayTxBodyBz []byte
s.Require().True(s.Run("Retrieve relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: eth.ChainID.String(),
DstChain: simd.Config().ChainID,
SourceTxIds: [][]byte{ethSendTxHash},
TargetClientId: testvalues.FirstWasmClientID,
})
s.Require().NoError(err)

relayTxBodyBz = resp.Tx
}))

s.Require().True(s.Run("Broadcast relay tx", func() {
resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, relayTxBodyBz)

ackTxHash, err = hex.DecodeString(resp.TxHash)
s.Require().NoError(err)
}))
}))

s.Require().True(s.Run("Transfer tokens back from Cosmos chain with invalid destination should fail", func() {
denomOnCosmos := transfertypes.NewDenom(s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, testvalues.FirstWasmClientID))
timeout := uint64(time.Now().Add(30 * time.Minute).Unix())
ibcCoin := sdk.NewCoin(denomOnCosmos.Path(), sdkmath.NewIntFromBigInt(transferAmount))

transferPayload := transfertypes.FungibleTokenPacketData{
Denom: ibcCoin.Denom,
Amount: ibcCoin.Amount.String(),
Sender: cosmosUserWallet.FormattedAddress(),
Receiver: ibctesting.InvalidID,
Memo: "",
}
encodedPayload, err := transfertypes.EncodeABIFungibleTokenPacketData(&transferPayload)
s.Require().NoError(err)

payload := channeltypesv2.Payload{
SourcePort: transfertypes.PortID,
DestinationPort: transfertypes.PortID,
Version: transfertypes.V1,
Encoding: transfertypes.EncodingABI,
Value: encodedPayload,
}

transferMsgs := make([]sdk.Msg, 1)
transferMsgs[0] = &channeltypesv2.MsgSendPacket{
SourceClient: testvalues.FirstWasmClientID,
TimeoutTimestamp: timeout,
Payloads: []channeltypesv2.Payload{
payload,
},
Signer: cosmosUserWallet.FormattedAddress(),
}

var relayTxHash []byte
s.Require().True(s.Run("Broadcast transfer msgs", func() {
resp, err := s.BroadcastMessages(ctx, simd, cosmosUserWallet, 20_000_000, transferMsgs...)
s.Require().NoError(err)
s.Require().NotEmpty(resp.TxHash)

relayTxHash, err = hex.DecodeString(resp.TxHash)
s.Require().NoError(err)
}))

var relayTxBodyBz []byte
s.Require().True(s.Run("Broadcast relay tx", func() {
s.Require().True(s.Run("Retrieve relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: simd.Config().ChainID,
DstChain: eth.ChainID.String(),
SourceTxIds: [][]byte{relayTxHash},
TargetClientId: testvalues.CustomClientID,
})
s.Require().NoError(err)
s.Require().NotEmpty(resp.Tx)
s.Require().NotEmpty(resp.Address)

relayTxBodyBz = resp.Tx
}))
}))

var ackRelayTxHash []byte
s.Require().True(s.Run("Submit relay tx to eth", func() {
receipt, err := eth.BroadcastTx(ctx, s.EthRelayerSubmitter, 15_000_000, ics26Address, relayTxBodyBz)
s.Require().NoError(err)
s.Require().Equal(ethtypes.ReceiptStatusSuccessful, receipt.Status, fmt.Sprintf("Tx failed: %+v", receipt))
s.T().Logf("Multicall ack %d packets gas used: %d", numOfTransfers, receipt.GasUsed)

ackRelayTxHash = receipt.TxHash.Bytes()
}))

var ackRelayTxBodyBz []byte
s.Require().True(s.Run("Acknowledge packet to Cosmos chain", func() {
s.Require().True(s.Run("Retrieve relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: eth.ChainID.String(),
DstChain: simd.Config().ChainID,
SourceTxIds: [][]byte{ackRelayTxHash},
TargetClientId: testvalues.FirstWasmClientID,
})
s.Require().NoError(err)
s.Require().NotEmpty(resp.Tx)

ackRelayTxBodyBz = resp.Tx
}))

s.Require().True(s.Run("Submit acknowledgement relay tx to Cosmos", func() {
resp := s.BroadcastSdkTxBody(ctx, simd, s.SimdRelayerSubmitter, 20_000_000, ackRelayTxBodyBz)

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() {
// User balance on Cosmos chain
resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simd, &banktypes.QueryBalanceRequest{
Address: cosmosUserAddress,
Denom: denomOnCosmos.IBCDenom(),
})
s.Require().NoError(err)
s.Require().NotNil(resp.Balance)
// Vouchers should be restored to the user's balance
s.Require().Equal(totalTransferAmount, resp.Balance.Amount.BigInt())
s.Require().Equal(denomOnCosmos.IBCDenom(), resp.Balance.Denom)
}))
}))
}

func (s *IbcEurekaTestSuite) TestICS20TransferNativeCosmosCoinsToEthereumAndBack_Groth16() {
ctx := context.Background()
s.ICS20TransferNativeCosmosCoinsToEthereumAndBackTest(ctx, operator.ProofTypeGroth16, big.NewInt(testvalues.TransferAmount))
Expand Down
Loading