Skip to content

Commit 273f9d1

Browse files
committed
wip: fixing test
1 parent 63dc16e commit 273f9d1

4 files changed

Lines changed: 213 additions & 19 deletions

File tree

tests/integration/gm_gaia_health_test.go

Lines changed: 154 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"github.com/celestiaorg/tastora/framework/testutil/config"
78
"os"
89
"os/exec"
910
"path/filepath"
1011
"testing"
1112
"time"
1213

1314
sdkmath "cosmossdk.io/math"
15+
"github.com/BurntSushi/toml"
1416
"github.com/celestiaorg/tastora/framework/docker/container"
1517
"github.com/celestiaorg/tastora/framework/docker/cosmos"
1618
"github.com/celestiaorg/tastora/framework/docker/ibc"
@@ -19,12 +21,15 @@ import (
1921
"github.com/celestiaorg/tastora/framework/testutil/sdkacc"
2022
"github.com/celestiaorg/tastora/framework/testutil/wait"
2123
"github.com/celestiaorg/tastora/framework/types"
24+
cometcfg "github.com/cometbft/cometbft/config"
2225
"github.com/cosmos/cosmos-sdk/crypto/keyring"
2326
sdk "github.com/cosmos/cosmos-sdk/types"
2427
"github.com/cosmos/cosmos-sdk/types/module/testutil"
2528
"github.com/cosmos/cosmos-sdk/x/auth"
2629
"github.com/cosmos/cosmos-sdk/x/bank"
2730
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
31+
"github.com/cosmos/ibc-go/v8/modules/apps/transfer"
32+
ibctransfer "github.com/cosmos/ibc-go/v8/modules/apps/transfer"
2833
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
2934
clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
3035
"github.com/stretchr/testify/require"
@@ -49,8 +54,24 @@ func (s *DockerIntegrationTestSuite) TestAttesterSystem() {
4954
}
5055
}()
5156

52-
// Wait 10 seconds for GM chain to initialize
53-
time.Sleep(8 * time.Second)
57+
// Wait for GM chain RPC to be ready
58+
s.T().Log("Waiting for GM chain RPC to be ready...")
59+
var rpcReady bool
60+
for i := 0; i < 30; i++ { // 30 second timeout
61+
node := gmChain.GetNodes()[0]
62+
rpcClient, _ := node.GetRPCClient()
63+
if rpcClient != nil {
64+
// Test if RPC client is actually working by making a simple call
65+
_, err := rpcClient.Status(ctx)
66+
if err == nil {
67+
rpcReady = true
68+
s.T().Log("GM chain RPC is ready")
69+
break
70+
}
71+
}
72+
time.Sleep(1 * time.Second)
73+
}
74+
require.True(s.T(), rpcReady, "GM chain RPC failed to become ready within 30 seconds")
5475

5576
kr, err := gmChain.GetNodes()[0].GetKeyring()
5677
require.NoError(s.T(), err)
@@ -104,6 +125,10 @@ func (s *DockerIntegrationTestSuite) TestAttesterSystem() {
104125
err = hermes.Init(ctx, s.celestiaChain, gmChain)
105126
require.NoError(s.T(), err, "failed to initialize relayer")
106127

128+
// Switch hermes to pull mode to avoid WebSocket connection issues
129+
err = s.configureHermesForPullMode(ctx, hermes)
130+
require.NoError(s.T(), err, "failed to configure hermes for pull mode")
131+
107132
connection, channel := setupIBCConnection(s.T(), ctx, s.celestiaChain, gmChain, hermes)
108133
s.T().Logf("Established IBC connection %s and channel %s between Celestia and GM chain", connection.ConnectionID, channel.ChannelID)
109134

@@ -168,7 +193,8 @@ func (s *DockerIntegrationTestSuite) getAttester(ctx context.Context, gmChain *c
168193
s.T().Log("Setting up attester keyring with validator key...")
169194

170195
// Create an in-memory keyring for the attester
171-
testEncCfg := testutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{})
196+
// Include transfer module so MsgTransfer is registered in the interface registry
197+
testEncCfg := testutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{}, ibctransfer.AppModuleBasic{})
172198
attesterKeyring := keyring.NewInMemory(testEncCfg.Codec)
173199

174200
// Import the validator key into the attester keyring
@@ -216,6 +242,54 @@ func deriveAttesterAccountFromArmor(armoredKey string) (sdk.AccAddress, error) {
216242
return keyAddr, nil
217243
}
218244

245+
func (s *DockerIntegrationTestSuite) configureHermesForPullMode(ctx context.Context, hermes *relayer.Hermes) error {
246+
s.T().Log("Configuring hermes to use pull mode and increased clock drift...")
247+
248+
// Read the current config
249+
configBz, err := hermes.ReadFile(ctx, ".hermes/config.toml")
250+
if err != nil {
251+
return fmt.Errorf("failed to read hermes config: %w", err)
252+
}
253+
254+
// Unmarshal into map
255+
var config map[string]interface{}
256+
if err := toml.Unmarshal(configBz, &config); err != nil {
257+
return fmt.Errorf("failed to unmarshal hermes config: %w", err)
258+
}
259+
260+
// Update chains to use pull mode and increase clock drift
261+
chains, ok := config["chains"].([]map[string]interface{})
262+
if !ok {
263+
return fmt.Errorf("chains not found in config or not in expected format")
264+
}
265+
266+
for i := range chains {
267+
// Update event_source to pull mode with tighter interval
268+
chains[i]["event_source"] = map[string]interface{}{
269+
"mode": "pull",
270+
"interval": "200ms",
271+
}
272+
273+
// Update clock_drift to handle timing differences between chains
274+
chains[i]["clock_drift"] = "60s"
275+
}
276+
277+
// Remarshal into bytes
278+
updatedConfigBz, err := toml.Marshal(config)
279+
if err != nil {
280+
return fmt.Errorf("failed to marshal updated hermes config: %w", err)
281+
}
282+
283+
// Write the updated config
284+
err = hermes.WriteFile(ctx, ".hermes/config.toml", updatedConfigBz)
285+
if err != nil {
286+
return fmt.Errorf("failed to write updated hermes config: %w", err)
287+
}
288+
289+
s.T().Log("Successfully configured hermes to use pull mode with 60s clock drift tolerance")
290+
return nil
291+
}
292+
219293
func (s *DockerIntegrationTestSuite) buildGMImage() {
220294
evnodeVersion := getenvDefault("EVNODE_VERSION", "v1.0.0-beta.4")
221295
igniteVersion := getenvDefault("IGNITE_VERSION", "v29.3.1")
@@ -247,7 +321,7 @@ func (s *DockerIntegrationTestSuite) getGmChain(ctx context.Context) *cosmos.Cha
247321
s.T().Log("Creating GM chain connected to DA network...")
248322
sdk.GetConfig().SetBech32PrefixForAccount("celestia", "celestiapub")
249323
gmImg := container.NewImage("evabci/gm", "local", "1000:1000")
250-
testEncCfg := testutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{})
324+
testEncCfg := testutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{}, transfer.AppModuleBasic{})
251325
gmChain, err := cosmos.NewChainBuilder(s.T()).
252326
WithEncodingConfig(&testEncCfg).
253327
WithDockerClient(s.dockerClient).
@@ -276,6 +350,42 @@ func (s *DockerIntegrationTestSuite) getGmChain(ctx context.Context) *cosmos.Cha
276350
"--minimum-gas-prices", "0.001stake",
277351
"--log_level", "*:info",
278352
).
353+
WithPostInit(func(ctx context.Context, node *cosmos.ChainNode) error {
354+
// 1) Ensure ABCI responses and tx events are retained and indexed for Hermes
355+
if err := config.Modify(ctx, node, "config/config.toml", func(cfg *cometcfg.Config) {
356+
cfg.Storage.DiscardABCIResponses = false
357+
// Enable key-value tx indexer so Hermes can query IBC packet events
358+
cfg.TxIndex.Indexer = "kv"
359+
// Increase RPC BroadcastTxCommit timeout to accommodate CI slowness
360+
if cfg.RPC != nil {
361+
cfg.RPC.TimeoutBroadcastTxCommit = 120000000000 // 120s in nanoseconds
362+
}
363+
}); err != nil {
364+
return err
365+
}
366+
// 2) Ensure app-level index-events include IBC packet events
367+
appToml, err := node.ReadFile(ctx, "config/app.toml")
368+
if err != nil {
369+
return err
370+
}
371+
var appCfg map[string]interface{}
372+
if err := toml.Unmarshal(appToml, &appCfg); err != nil {
373+
return err
374+
}
375+
appCfg["index-events"] = []string{
376+
"message.action",
377+
"send_packet",
378+
"recv_packet",
379+
"write_acknowledgement",
380+
"acknowledge_packet",
381+
"timeout_packet",
382+
}
383+
updated, err := toml.Marshal(appCfg)
384+
if err != nil {
385+
return err
386+
}
387+
return node.WriteFile(ctx, "config/app.toml", updated)
388+
}).
279389
WithNode(cosmos.NewChainNodeConfigBuilder().
280390
WithPostInit(AddSingleSequencer).
281391
Build()).
@@ -365,6 +475,9 @@ func setupIBCConnection(t *testing.T, ctx context.Context, chainA, chainB types.
365475
require.NoError(t, err)
366476
require.NotEmpty(t, connection.ConnectionID, "Connection ID should not be empty")
367477

478+
// give chains a moment to persist connection state and client updates
479+
_ = wait.ForBlocks(ctx, 2, chainA, chainB)
480+
368481
// Create an ICS20 channel for token transfers
369482
channelOpts := ibc.CreateChannelOptions{
370483
SourcePortName: "transfer",
@@ -409,6 +522,9 @@ func (s *DockerIntegrationTestSuite) testIBCTransfers(ctx context.Context, celes
409522
err = hermes.Start(ctx)
410523
require.NoError(s.T(), err)
411524

525+
// Allow Hermes to sync initial heights before sending packets
526+
_ = wait.ForBlocks(ctx, 2, celestiaChain, gmChain)
527+
412528
// Test 1: Transfer from Celestia to GM chain
413529
s.T().Log("=== Testing transfer from Celestia to GM chain ===")
414530

@@ -428,16 +544,18 @@ func (s *DockerIntegrationTestSuite) testIBCTransfers(ctx context.Context, celes
428544
"",
429545
)
430546

431-
resp, err := celestiaChain.BroadcastMessages(ctx, celestiaWallet, transferMsg)
547+
// Use a longer per-tx timeout to avoid 60s default aborts on busy or lagging nodes
548+
ctxTx, cancelTx := context.WithTimeout(ctx, 2*time.Minute)
549+
defer cancelTx()
550+
resp, err := celestiaChain.BroadcastMessages(ctxTx, celestiaWallet, transferMsg)
432551
require.NoError(s.T(), err)
433552
require.Equal(s.T(), uint32(0), resp.Code, "IBC transfer failed: %s", resp.RawLog)
434553

435554
s.T().Logf("IBC transfer broadcast successful. TX hash: %s", resp.TxHash)
436555

437-
// Wait for transfer to be relayed
438-
s.T().Log("Waiting for transfer to be relayed...")
439-
err = wait.ForBlocks(ctx, 10, celestiaChain, gmChain)
440-
require.NoError(s.T(), err)
556+
// Wait until GM balance reflects the transfer (poll with timeout)
557+
s.T().Log("Waiting for GM balance to update...")
558+
require.NoError(s.T(), s.waitForBalanceIncrease(ctx, gmChain, gmAddr, celestiaToGMIBCDenom, initialGMBalance, transferAmount, 2*time.Minute))
441559

442560
// Check final balance
443561
finalGMBalance := s.getBalance(ctx, gmChain, gmAddr, celestiaToGMIBCDenom)
@@ -470,16 +588,18 @@ func (s *DockerIntegrationTestSuite) testIBCTransfers(ctx context.Context, celes
470588
"",
471589
)
472590

473-
resp, err = gmChain.BroadcastMessages(ctx, gmWallet, reverseTransferMsg)
591+
// Use the same extended timeout for the reverse transfer
592+
ctxTx2, cancelTx2 := context.WithTimeout(ctx, 2*time.Minute)
593+
defer cancelTx2()
594+
resp, err = gmChain.BroadcastMessages(ctxTx2, gmWallet, reverseTransferMsg)
474595
require.NoError(s.T(), err)
475596
require.Equal(s.T(), uint32(0), resp.Code, "Reverse IBC transfer failed: %s", resp.RawLog)
476597

477598
s.T().Logf("Reverse IBC transfer broadcast successful. TX hash: %s", resp.TxHash)
478599

479-
// Wait for reverse transfer to be relayed
480-
s.T().Log("Waiting for reverse transfer to be relayed...")
481-
err = wait.ForBlocks(ctx, 10, celestiaChain, gmChain)
482-
require.NoError(s.T(), err)
600+
// Wait until Celestia balance reflects the transfer (poll with timeout)
601+
s.T().Log("Waiting for Celestia balance to update...")
602+
require.NoError(s.T(), s.waitForBalanceIncrease(ctx, celestiaChain, celestiaAddr, gmToCelestiaIBCDenom, initialCelestiaBalance, transferAmount, 2*time.Minute))
483603

484604
// Check final balance
485605
finalCelestiaBalance := s.getBalance(ctx, celestiaChain, celestiaAddr, gmToCelestiaIBCDenom)
@@ -493,6 +613,26 @@ func (s *DockerIntegrationTestSuite) testIBCTransfers(ctx context.Context, celes
493613
s.T().Log("=== IBC Transfer Tests Completed Successfully ===")
494614
}
495615

616+
// waitForBalanceIncrease polls the balance until it increases by expectedIncrease or timeout expires.
617+
func (s *DockerIntegrationTestSuite) waitForBalanceIncrease(ctx context.Context, chain *cosmos.Chain, address sdk.AccAddress, denom string, initial sdkmath.Int, expectedIncrease sdkmath.Int, timeout time.Duration) error {
618+
deadline := time.Now().Add(timeout)
619+
target := initial.Add(expectedIncrease)
620+
for {
621+
current := s.getBalance(ctx, chain, address, denom)
622+
if current.GTE(target) {
623+
return nil
624+
}
625+
if time.Now().After(deadline) {
626+
return fmt.Errorf("balance did not reach target within %s: got %s, want %s (%s)", timeout, current.String(), target.String(), denom)
627+
}
628+
select {
629+
case <-ctx.Done():
630+
return ctx.Err()
631+
case <-time.After(1 * time.Second):
632+
}
633+
}
634+
}
635+
496636
// getBalance queries the balance of an address for a specific denom
497637
func (s *DockerIntegrationTestSuite) getBalance(ctx context.Context, chain *cosmos.Chain, address sdk.AccAddress, denom string) sdkmath.Int {
498638
node := chain.GetNode()

tests/integration/go.mod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ go 1.24.6
44

55
require (
66
github.com/celestiaorg/tastora v0.3.0
7+
github.com/cosmos/ibc-go/v8 v8.7.0
78
github.com/moby/moby v27.5.1+incompatible
89
github.com/stretchr/testify v1.11.1
910
go.uber.org/zap v1.27.0
1011
)
1112

1213
require (
13-
github.com/cosmos/ibc-go/v8 v8.7.0
1414
github.com/libp2p/go-libp2p v0.43.0
1515
github.com/multiformats/go-multihash v0.2.3
1616
)
@@ -37,6 +37,7 @@ require (
3737
github.com/aws/smithy-go v1.22.5 // indirect
3838
github.com/celestiaorg/go-square/v2 v2.2.0 // indirect
3939
github.com/celestiaorg/nmt v0.24.1 // indirect
40+
github.com/chzyer/readline v1.5.1 // indirect
4041
github.com/cosmos/ibc-go/modules/capability v1.0.1 // indirect
4142
github.com/golang/mock v1.6.0 // indirect
4243
github.com/google/orderedcode v0.0.1 // indirect
@@ -49,6 +50,7 @@ require (
4950
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
5051
github.com/lib/pq v1.10.9 // indirect
5152
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
53+
github.com/manifoldco/promptui v0.9.0 // indirect
5254
github.com/minio/highwayhash v1.0.3 // indirect
5355
github.com/minio/sha256-simd v1.0.1 // indirect
5456
github.com/mr-tron/base58 v1.2.0 // indirect
@@ -78,7 +80,7 @@ require (
7880
filippo.io/edwards25519 v1.1.0 // indirect
7981
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
8082
github.com/99designs/keyring v1.2.1 // indirect
81-
github.com/BurntSushi/toml v1.5.0 // indirect
83+
github.com/BurntSushi/toml v1.5.0
8284
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
8385
github.com/DataDog/zstd v1.5.5 // indirect
8486
github.com/Microsoft/go-winio v0.6.2 // indirect
@@ -231,7 +233,7 @@ require (
231233

232234
replace (
233235
cosmossdk.io/x/upgrade => github.com/celestiaorg/cosmos-sdk/x/upgrade v0.1.0
234-
github.com/celestiaorg/tastora => ../../../tastora
236+
//github.com/celestiaorg/tastora => ../../../tastora
235237

236238
github.com/cometbft/cometbft => github.com/celestiaorg/celestia-core v1.56.1-tm-v0.38.17
237239
github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.29.4-sdk-v0.50.14

tests/integration/go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ github.com/celestiaorg/go-square/v2 v2.2.0 h1:zJnUxCYc65S8FgUfVpyG/osDcsnjzo/JSX
152152
github.com/celestiaorg/go-square/v2 v2.2.0/go.mod h1:j8kQUqJLYtcvCQMQV6QjEhUdaF7rBTXF74g8LbkR0Co=
153153
github.com/celestiaorg/nmt v0.24.1 h1:MhGKqp257eq2EQQKcva1H/BSYFqIt0Trk8/t3IWfWSw=
154154
github.com/celestiaorg/nmt v0.24.1/go.mod h1:IhLnJDgCdP70crZFpgihFmU6G+PGeXN37tnMRm+/4iU=
155+
github.com/celestiaorg/tastora v0.3.0 h1:ZfwlRXjddTCRzj2+5pNbdr75nwPeEpsLx93Fpo8GxEM=
156+
github.com/celestiaorg/tastora v0.3.0/go.mod h1:28BiTBJ4Yz6K5iT57NwS1NVLJFN/hmZHx9j0CVz4QXM=
155157
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
156158
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
157159
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
@@ -163,8 +165,15 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
163165
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
164166
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
165167
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
168+
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
169+
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
170+
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
171+
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
166172
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
167173
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
174+
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
175+
github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
176+
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
168177
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
169178
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
170179
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
@@ -1036,6 +1045,7 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc
10361045
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10371046
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10381047
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1048+
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10391049
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10401050
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10411051
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

0 commit comments

Comments
 (0)