From e4a655b800d40d2979894bee3c74c6dfaaa7e5d1 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 10 Oct 2024 08:18:14 +0200 Subject: [PATCH] Housekeeping: backport IBC transfer e2e (#151) --- CHANGELOG.md | 1 + contrib/images/babylond/Dockerfile | 4 +- .../images/e2e-initialization/init.Dockerfile | 5 +- test/e2e/configurer/chain/chain.go | 2 +- test/e2e/ibc_transfer_e2e_test.go | 130 +++++++++++++++++- 5 files changed, 132 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f6061b64..9b6bd8cd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ insert from the v1 upgrade handler. ### Improvements +* [#151](https://github.com/babylonlabs-io/babylon/pull/151) Improve IBC transfer e2e test * [#130](https://github.com/babylonlabs-io/babylon/pull/130) Fix bugs in the transaction fee refunding mechanism for covenant signatures and finality signatures * [#125](https://github.com/babylonlabs-io/babylon/pull/125) Implement ADR-028 and diff --git a/contrib/images/babylond/Dockerfile b/contrib/images/babylond/Dockerfile index 9fb29c340..0d274fa48 100644 --- a/contrib/images/babylond/Dockerfile +++ b/contrib/images/babylond/Dockerfile @@ -26,6 +26,8 @@ RUN LEDGER_ENABLED=$LEDGER_ENABLED \ FROM debian:bookworm-slim AS wasm-link +ARG VERSION + # Create a user RUN addgroup --gid 1137 --system babylon && adduser --uid 1137 --gid 1137 --system --home /home/babylon babylon @@ -51,4 +53,4 @@ COPY --from=build-env /go/src/github.com/babylonlabs-io/babylon/build/babylond / WORKDIR /home/babylon RUN chown -R babylon /home/babylon RUN chmod g+s /home/babylon -USER babylon \ No newline at end of file +USER babylon diff --git a/contrib/images/e2e-initialization/init.Dockerfile b/contrib/images/e2e-initialization/init.Dockerfile index 2a496a1ab..1457299be 100644 --- a/contrib/images/e2e-initialization/init.Dockerfile +++ b/contrib/images/e2e-initialization/init.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21 as build-env +FROM golang:1.21 AS build-env ARG E2E_SCRIPT_NAME # Version to build. Default is empty @@ -18,6 +18,7 @@ RUN LEDGER_ENABLED=false LINK_STATICALLY=false E2E_SCRIPT_NAME=${E2E_SCRIPT_NAME FROM debian:bookworm-slim AS wasm-link +ARG VERSION # Create a user RUN addgroup --gid 1137 --system babylon && adduser --uid 1137 --gid 1137 --system --home /home/babylon babylon @@ -47,4 +48,4 @@ COPY --from=build-env /go/src/github.com/babylonlabs-io/babylon/build/${E2E_SCRI # As a workaround, we create the entrypoint.sh script to bypass these issues. RUN echo "#!/bin/bash\n${E2E_SCRIPT_NAME} \"\$@\"" >> entrypoint.sh && chmod +x entrypoint.sh -ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["./entrypoint.sh"] diff --git a/test/e2e/configurer/chain/chain.go b/test/e2e/configurer/chain/chain.go index 137d002e0..b93aeb0bc 100644 --- a/test/e2e/configurer/chain/chain.go +++ b/test/e2e/configurer/chain/chain.go @@ -176,7 +176,7 @@ func (c *Config) GetPersistentPeers() []string { func (c *Config) GetNodeAtIndex(nodeIndex int) (*NodeConfig, error) { if nodeIndex > len(c.NodeConfigs) { - return nil, fmt.Errorf("node index (%d) is greter than the number of nodes available (%d)", nodeIndex, len(c.NodeConfigs)) + return nil, fmt.Errorf("node index (%d) is greater than the number of nodes available (%d)", nodeIndex, len(c.NodeConfigs)) } return c.NodeConfigs[nodeIndex], nil } diff --git a/test/e2e/ibc_transfer_e2e_test.go b/test/e2e/ibc_transfer_e2e_test.go index 921026dce..60f29d237 100644 --- a/test/e2e/ibc_transfer_e2e_test.go +++ b/test/e2e/ibc_transfer_e2e_test.go @@ -1,6 +1,8 @@ package e2e import ( + "math" + "strings" "time" "github.com/babylonlabs-io/babylon/test/e2e/configurer" @@ -39,16 +41,132 @@ func (s *IBCTransferTestSuite) TearDownSuite() { } } +func getFirstIBCDenom(balance sdk.Coins) string { + // Look up the ugly IBC denom + denoms := balance.Denoms() + var denomB string + for _, d := range denoms { + if strings.HasPrefix(d, "ibc/") { + denomB = d + break + } + } + return denomB +} + func (s *IBCTransferTestSuite) Test1IBCTransfer() { - bbnChain := s.configurer.GetChainConfig(0) + denom := "ubbn" + amount := int64(1_000_000) + delta := float64(10000) // Tolerance to account for gas fees + + transferCoin := sdk.NewInt64Coin(denom, amount) + + bbnChainA := s.configurer.GetChainConfig(0) + bbnChainB := s.configurer.GetChainConfig(1) + + babylonNodeA, err := bbnChainA.GetNodeAtIndex(2) + s.NoError(err) + babylonNodeB, err := bbnChainB.GetNodeAtIndex(2) + s.NoError(err) + + val := initialization.ValidatorWalletName + + // Check balance of val in chain-A (Node 3) + addrA := babylonNodeA.GetWallet(val) + balanceA, err := babylonNodeA.QueryBalances(addrA) + s.Require().NoError(err) + // Confirm val on A has enough funds + s.Assert().GreaterOrEqual(balanceA.AmountOf(denom).Int64(), amount) + + addrB := babylonNodeB.GetWallet(val) + balanceB, err := babylonNodeB.QueryBalances(addrB) + s.Require().NoError(err) + // Only one denom in B + s.Require().Len(balanceB, 1) - babylonNode, err := bbnChain.GetNodeAtIndex(2) + // Send transfer from val in chain-A (Node 3) to val in chain-B (Node 3) + babylonNodeA.SendIBCTransfer(val, addrB, "transfer", transferCoin) + + s.Require().Eventually(func() bool { + // Check that the transfer is successful. + // Amounts have been discounted from val in chain-A and added (as a wrapped denom) to val in chain-B + balanceA2, err := babylonNodeA.QueryBalances(addrA) + if err != nil { + return false + } + return math.Abs(float64(balanceA.Sub(transferCoin).AmountOf(denom).Int64()- + balanceA2.AmountOf(denom).Int64())) < delta + }, 10*time.Second, 1*time.Second, "Transfer was not successful") + + s.Require().Eventually(func() bool { + balanceB2, err := babylonNodeB.QueryBalances(addrB) + if err != nil { + return false + } + // Check that there are now two denoms in B + if len(balanceB2) != 2 { + return false + } + denomB := getFirstIBCDenom(balanceB2) + // Check the balance of the IBC denom + return math.Abs(float64(balanceB2.AmountOf(denomB).Int64()- + transferCoin.Amount.Int64())) < delta + }, 10*time.Second, 1*time.Second, "Transfer was not successful") +} + +func (s *IBCTransferTestSuite) Test2IBCTransferBack() { + nativeDenom := "ubbn" + delta := float64(10000) // Tolerance to account for gas fees + + bbnChainA := s.configurer.GetChainConfig(0) + bbnChainB := s.configurer.GetChainConfig(1) + + babylonNodeA, err := bbnChainA.GetNodeAtIndex(0) + s.NoError(err) + babylonNodeB, err := bbnChainB.GetNodeAtIndex(2) s.NoError(err) - sender := initialization.ValidatorWalletName - babylonNode.SendIBCTransfer(sender, sender, "", sdk.NewInt64Coin("ubbn", 1000)) + val := initialization.ValidatorWalletName + + addrB := babylonNodeB.GetWallet(val) + balanceB, err := babylonNodeB.QueryBalances(addrB) + s.Require().NoError(err) + // Two denoms in B + s.Require().Len(balanceB, 2) + // Look for the ugly IBC one + denom := getFirstIBCDenom(balanceB) + amount := balanceB.AmountOf(denom).Int64() - int64(delta) // have to pay gas fees + + transferCoin := sdk.NewInt64Coin(denom, amount) + + // Send transfer from val in chain-B (Node 3) to val in chain-A (Node 1) + addrA := babylonNodeA.GetWallet(val) + balanceA, err := babylonNodeA.QueryBalances(addrA) + s.Require().NoError(err) + + babylonNodeB.SendIBCTransfer(val, addrA, "transfer back", transferCoin) - time.Sleep(1 * time.Minute) + s.Require().Eventually(func() bool { + balanceB2, err := babylonNodeB.QueryBalances(addrB) + if err != nil { + return false + } + return math.Abs(float64(balanceB.Sub(transferCoin).AmountOf(denom).Int64()- + balanceB2.AmountOf(denom).Int64())) < delta + }, 10*time.Second, 1*time.Second, "Transfer back was not successful") - // TODO: check the transfer is successful. Right now this is done by manually looking at the log + nativeCoin := sdk.NewInt64Coin(nativeDenom, amount) + s.Require().Eventually(func() bool { + balanceA2, err := babylonNodeA.QueryBalances(addrA) + if err != nil { + return false + } + // Check that there's still one denom in A + if len(balanceA2) != 1 { + return false + } + // Check that the balance of the native denom has increased + return math.Abs(float64(balanceA.Add(nativeCoin).AmountOf(nativeDenom).Int64()- + balanceA2.AmountOf(nativeDenom).Int64())) < delta + }, 10*time.Second, 1*time.Second, "Transfer back was not successful") }