From 93db30c4257a149b6844747631f02d6b4e84b876 Mon Sep 17 00:00:00 2001 From: Hoang Do Date: Fri, 27 Sep 2024 13:10:23 +0700 Subject: [PATCH] Sequencer Rotation happy flow with one sequencer coming and syncing over P2P (#397) Co-authored-by: anhductn2001 Co-authored-by: ducnt131 <62016666+anhductn2001@users.noreply.github.com> --- Makefile | 3 + go.mod | 2 +- go.sum | 4 +- tests/data/metadata_sequencer1.json | 2 +- tests/disconnection_test.go | 2 +- tests/eibc_ack_error_test.go | 3 + tests/eibc_fulfillment_test.go | 6 +- tests/fullnode_sync_block_sync_test.go | 4 +- tests/fullnode_sync_gossip_test.go | 12 +- tests/sequencer_rotation_test.go | 488 +++++++++++++++++++++++-- 10 files changed, 486 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 63093518..ee0f9776 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,9 @@ e2e-test: clean-e2e e2e-test-ibc-success-evm: clean-e2e cd tests && go test -timeout=45m -race -v -run TestIBCTransferSuccess_EVM . +e2e-test-one-sqc-rotation-success-evm: clean-e2e + cd tests && go test -timeout=45m -race -v -run Test_SqcRotation_OneSqc_Success_EVM . + e2e-test-light-client-same-chain-id-transfer: clean-e2e cd tests && go test -timeout=45m -race -v -run TestIBCTransferRA_3rdSameChainID_EVM . diff --git a/go.mod b/go.mod index e6ab6f7b..299d84ec 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ replace ( require ( github.com/decentrio/e2e-testing-live v0.0.0-20240718080249-ee255229c869 - github.com/decentrio/rollup-e2e-testing v0.0.0-20240924090607-6658e898c353 + github.com/decentrio/rollup-e2e-testing v0.0.0-20240925065439-bea0cdea5436 github.com/dymensionxyz/dymension/v3 v3.1.0-rc03.0.20240911123104-4782bc4e587f github.com/dymensionxyz/dymint v1.2.0-rc01.0.20240919105350-66f9b353655d ) diff --git a/go.sum b/go.sum index c4b88808..349dba73 100644 --- a/go.sum +++ b/go.sum @@ -773,8 +773,8 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decentrio/e2e-testing-live v0.0.0-20240718080249-ee255229c869 h1:qWpUYGOsrSC+1Vmd2TjhbsSpntvvx9PsX3AoeMunFxc= github.com/decentrio/e2e-testing-live v0.0.0-20240718080249-ee255229c869/go.mod h1:HZNYnPwmSxkwTPjSD5yolauc1Vx1ZzKL4FFMxTq4H5Y= -github.com/decentrio/rollup-e2e-testing v0.0.0-20240924090607-6658e898c353 h1:uA+obWLk1tbZDN1SgewNQLvmDbEIqoxcsD8+/wxenSo= -github.com/decentrio/rollup-e2e-testing v0.0.0-20240924090607-6658e898c353/go.mod h1:QmBrZgZplhtgHRWC0Z7LC7TDsKuC8sDyQvZyXXaqw/c= +github.com/decentrio/rollup-e2e-testing v0.0.0-20240925065439-bea0cdea5436 h1:6RhXRXX88ADn3xlL1FS6ybzZQuX4TOIA1JOdSWxyGuU= +github.com/decentrio/rollup-e2e-testing v0.0.0-20240925065439-bea0cdea5436/go.mod h1:QmBrZgZplhtgHRWC0Z7LC7TDsKuC8sDyQvZyXXaqw/c= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= diff --git a/tests/data/metadata_sequencer1.json b/tests/data/metadata_sequencer1.json index de4cf4d3..2378b534 100644 --- a/tests/data/metadata_sequencer1.json +++ b/tests/data/metadata_sequencer1.json @@ -1,5 +1,5 @@ { - "moniker": "sequencer", + "moniker": "sequencer1111", "details": "This is a description of the Rollapp.", "p2p_seeds": ["seed1"], "rpcs": ["https://rpc.wpd.evm.rollapp.noisnemyd.xyz:443", "https://rpc.wpd.wasm.rollapp.noisnemyd.xyz:443"], diff --git a/tests/disconnection_test.go b/tests/disconnection_test.go index ddbc12ea..6809a051 100644 --- a/tests/disconnection_test.go +++ b/tests/disconnection_test.go @@ -248,7 +248,7 @@ func TestDisconnection_Wasm(t *testing.T) { dymintTomlOverrides["settlement_gas_prices"] = "0adym" dymintTomlOverrides["max_idle_time"] = "3s" dymintTomlOverrides["max_proof_time"] = "500ms" - dymintTomlOverrides["batch_submit_time"] = "5s" + dymintTomlOverrides["batch_submit_time"] = "50s" dymintTomlOverrides["batch_submit_bytes"] = "1000" dymintTomlOverrides["block_batch_max_size_bytes"] = "1000" dymintTomlOverrides["max_batch_skew"] = "1" diff --git a/tests/eibc_ack_error_test.go b/tests/eibc_ack_error_test.go index 982d1cf4..4a38be71 100644 --- a/tests/eibc_ack_error_test.go +++ b/tests/eibc_ack_error_test.go @@ -1675,6 +1675,9 @@ func TestEIBC_AckError_Dym_Wasm(t *testing.T) { require.True(t, balance.Equal(zeroBal), fmt.Sprintf("Value mismatch. Expected %s, actual %s", zeroBal, balance)) // catch ACK errors + err = testutil.WaitForBlocks(ctx, 10, dymension) + require.NoError(t, err) + rollappHeight, err = rollapp1.Height(ctx) require.NoError(t, err) diff --git a/tests/eibc_fulfillment_test.go b/tests/eibc_fulfillment_test.go index cedc374f..1e8f5016 100644 --- a/tests/eibc_fulfillment_test.go +++ b/tests/eibc_fulfillment_test.go @@ -1684,14 +1684,14 @@ func TestEIBCFulfillment_two_rollapps_EVM(t *testing.T) { rollappHeight, err := rollapp1.GetNode().Height(ctx) require.NoError(t, err) - rollapp2Height, err := rollapp2.GetNode().Height(ctx) - require.NoError(t, err) - // wait until the packet is finalized isFinalized, err := dymension.WaitUntilRollappHeightIsFinalized(ctx, rollapp1.GetChainID(), rollappHeight, 300) require.NoError(t, err) require.True(t, isFinalized) + rollapp2Height, err := rollapp2.GetNode().Height(ctx) + require.NoError(t, err) + isFinalized, err = dymension.WaitUntilRollappHeightIsFinalized(ctx, rollapp2.GetChainID(), rollapp2Height, 300) require.NoError(t, err) require.True(t, isFinalized) diff --git a/tests/fullnode_sync_block_sync_test.go b/tests/fullnode_sync_block_sync_test.go index e59b4cbf..c4f6ed79 100644 --- a/tests/fullnode_sync_block_sync_test.go +++ b/tests/fullnode_sync_block_sync_test.go @@ -272,7 +272,7 @@ func TestSync_BlockSync_EVM(t *testing.T) { require.NoError(t, err) // require.Error(t, err) - containerID = fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -618,7 +618,7 @@ func TestSync_BlockSync_fn_disconnect_EVM(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) diff --git a/tests/fullnode_sync_gossip_test.go b/tests/fullnode_sync_gossip_test.go index 8d0db872..9a7a8a38 100644 --- a/tests/fullnode_sync_gossip_test.go +++ b/tests/fullnode_sync_gossip_test.go @@ -268,7 +268,7 @@ func TestSync_Celes_Rt_Gossip_EVM(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -604,7 +604,7 @@ func TestSync_Celes_Rt_Gossip_Wasm(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappwasm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappwasm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -928,7 +928,7 @@ func TestSync_Sqc_Disconnect_Gossip_EVM(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -1279,7 +1279,7 @@ func TestSync_Sqc_Disconnect_Gossip_Wasm(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappwasm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappwasm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -1630,7 +1630,7 @@ func TestSync_Fullnode_Disconnect_Gossip_EVM(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -1982,7 +1982,7 @@ func TestSync_Fullnode_Disconnect_Gossip_Wasm(t *testing.T) { }, nil, "", nil, true, 780) require.NoError(t, err) - containerID = fmt.Sprintf("rollappwasm_1234-1-val-0-%s", t.Name()) + containerID = fmt.Sprintf("ra-rollappwasm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) diff --git a/tests/sequencer_rotation_test.go b/tests/sequencer_rotation_test.go index a2cc4eb5..2f272704 100644 --- a/tests/sequencer_rotation_test.go +++ b/tests/sequencer_rotation_test.go @@ -453,7 +453,7 @@ func Test_SeqRotation_NoSeq_P2P_EVM(t *testing.T) { }, nil, "", nil, true, 195) require.NoError(t, err) - containerID := fmt.Sprintf("rollappevm_1234-1-val-0-%s", t.Name()) + containerID := fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) // Get the container details containerJSON, err := client.ContainerInspect(context.Background(), containerID) @@ -528,6 +528,469 @@ func Test_SeqRotation_NoSeq_P2P_EVM(t *testing.T) { // Create some user accounts on both chains users := test.GetAndFundTestUsers(t, ctx, t.Name(), walletAmount, dymension, rollapp1) + // Get our Bech32 encoded user addresses + dymensionUser, rollappUser := users[0], users[1] + + dymensionUserAddr := dymensionUser.FormattedAddress() + rollappUserAddr := rollappUser.FormattedAddress() + + channel, err := ibc.GetTransferChannel(ctx, r, eRep, dymension.Config().ChainID, rollapp1.Config().ChainID) + require.NoError(t, err) + + err = r.StartRelayer(ctx, eRep, ibcPath) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Send a normal ibc tx from RA -> Hub + transferData := ibc.WalletData{ + Address: dymensionUserAddr, + Denom: rollapp1.Config().Denom, + Amount: transferAmount, + } + + // Compose an IBC transfer and send from rollapp -> Hub + _, err = rollapp1.SendIBCTransfer(ctx, channel.ChannelID, rollappUserAddr, transferData, ibc.TransferOptions{}) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + rollappHeight, err := rollapp1.GetNode().Height(ctx) + require.NoError(t, err) + + // Assert balance was updated on the hub + testutil.AssertBalance(t, ctx, rollapp1, rollappUserAddr, rollapp1.Config().Denom, walletAmount.Sub(transferData.Amount)) + + // wait until the packet is finalized + isFinalized, err := dymension.WaitUntilRollappHeightIsFinalized(ctx, rollapp1.GetChainID(), rollappHeight, 300) + require.NoError(t, err) + require.True(t, isFinalized) + + _, err = dymension.GetNode().FinalizePacketsUntilHeight(ctx, dymensionUserAddr, rollapp1.GetChainID(), fmt.Sprint(rollappHeight)) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Get the IBC denom for urax on Hub + rollappTokenDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, rollapp1.Config().Denom) + rollappIBCDenom := transfertypes.ParseDenomTrace(rollappTokenDenom).IBCDenom() + + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, rollappIBCDenom, transferAmount.Sub(bridgingFee)) + + // Get original account balances + dymensionOrigBal, err := dymension.GetBalance(ctx, dymensionUserAddr, dymension.Config().Denom) + require.NoError(t, err) + + // Compose an IBC transfer and send from dymension -> rollapp + transferData = ibc.WalletData{ + Address: rollappUserAddr, + Denom: dymension.Config().Denom, + Amount: transferAmount, + } + + // Compose an IBC transfer and send from Hub -> rollapp + _, err = dymension.SendIBCTransfer(ctx, channel.ChannelID, dymensionUserAddr, transferData, ibc.TransferOptions{}) + require.NoError(t, err) + + // Assert balance was updated on the hub + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, dymension.Config().Denom, dymensionOrigBal.Sub(transferData.Amount)) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Get the IBC denom + dymensionTokenDenom := transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, dymension.Config().Denom) + dymensionIBCDenom := transfertypes.ParseDenomTrace(dymensionTokenDenom).IBCDenom() + + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, dymension.Config().Denom, dymensionOrigBal.Sub(transferData.Amount)) + erc20MAcc, err := rollapp1.Validators[0].QueryModuleAccount(ctx, "erc20") + require.NoError(t, err) + erc20MAccAddr := erc20MAcc.Account.BaseAccount.Address + testutil.AssertBalance(t, ctx, rollapp1, erc20MAccAddr, dymensionIBCDenom, transferData.Amount) + + // Unbond sequencer1 + err = dymension.Unbond(ctx, "sequencer", rollapp1.GetSequencerKeyDir()) + require.NoError(t, err) + + seqAddr, err := dymension.AccountKeyBech32WithKeyDir(ctx, "sequencer", rollapp1.GetSequencerKeyDir()) + require.NoError(t, err) + + queryGetSequencerResponse, err := dymension.QueryShowSequencer(ctx, seqAddr) + require.NoError(t, err) + require.Equal(t, "OPERATING_STATUS_BONDED", queryGetSequencerResponse.Sequencer.Status) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + lastBlock, err := rollapp1.Height(ctx) + require.NoError(t, err) + + time.Sleep(180 * time.Second) + + queryGetSequencerResponse, err = dymension.QueryShowSequencer(ctx, seqAddr) + require.NoError(t, err) + require.Equal(t, "OPERATING_STATUS_UNBONDING", queryGetSequencerResponse.Sequencer.Status) + + // Chain halted + err = testutil.WaitForBlocks(ctx, 5, dymension, rollapp1) + require.Error(t, err) + + time.Sleep(300 * time.Second) + + queryGetSequencerResponse, err = dymension.QueryShowSequencer(ctx, seqAddr) + require.NoError(t, err) + require.Equal(t, "OPERATING_STATUS_UNBONDED", queryGetSequencerResponse.Sequencer.Status) + + cmd := append([]string{rollapp1.FullNodes[0].Chain.Config().Bin}, "dymint", "show-sequencer", "--home", rollapp1.FullNodes[0].HomeDir()) + pub1, _, err := rollapp1.GetNode().Exec(ctx, cmd, nil) + require.NoError(t, err) + + err = dymension.GetNode().CreateKeyWithKeyDir(ctx, "sequencer", rollapp1.GetNode().HomeDir()) + require.NoError(t, err) + + sequencer, err := dymension.AccountKeyBech32WithKeyDir(ctx, "sequencer", rollapp1.GetNode().HomeDir()) + require.NoError(t, err) + + fund := ibc.WalletData{ + Address: sequencer, + Denom: dymension.Config().Denom, + Amount: math.NewInt(10_000_000_000_000).MulRaw(100_000_000), + } + err = dymension.SendFunds(ctx, "faucet", fund) + require.NoError(t, err) + + // Wait a few blocks for relayer to start and for user accounts to be created + err = testutil.WaitForBlocks(ctx, 5, dymension) + require.NoError(t, err) + + command := []string{"sequencer", "create-sequencer", string(pub1), rollapp1.Config().ChainID, "1000000000adym", rollapp1.GetSequencerKeyDir() + "/metadata_sequencer1.json", + "--broadcast-mode", "async", "--keyring-dir", rollapp1.GetNode().HomeDir() + "/sequencer_keys"} + + _, err = dymension.FullNodes[0].ExecTx(ctx, "sequencer", command...) + require.NoError(t, err) + + res, err := dymension.QueryShowSequencerByRollapp(ctx, rollapp1.Config().ChainID) + require.NoError(t, err) + require.Equal(t, len(res.Sequencers), 2, "should have 2 sequences") + + err = rollapp1.StopAllNodes(ctx) + require.NoError(t, err) + + _ = rollapp1.StartAllNodes(ctx) + + time.Sleep(30 * time.Second) + + afterBlock, err := rollapp1.Height(ctx) + require.NoError(t, err) + require.True(t, afterBlock > lastBlock) + + // Compose an IBC transfer and send from rollapp -> Hub + _, err = rollapp1.SendIBCTransfer(ctx, channel.ChannelID, rollappUserAddr, transferData, ibc.TransferOptions{}) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Check IBC after switch + rollappHeight, err = rollapp1.GetNode().Height(ctx) + require.NoError(t, err) + + // Assert balance was updated on the hub + testutil.AssertBalance(t, ctx, rollapp1, rollappUserAddr, rollapp1.Config().Denom, walletAmount.Sub(transferData.Amount)) + + // wait until the packet is finalized + isFinalized, err = dymension.WaitUntilRollappHeightIsFinalized(ctx, rollapp1.GetChainID(), rollappHeight, 300) + require.NoError(t, err) + require.True(t, isFinalized) + + _, err = dymension.GetNode().FinalizePacketsUntilHeight(ctx, dymensionUserAddr, rollapp1.GetChainID(), fmt.Sprint(rollappHeight)) + require.NoError(t, err) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Get the IBC denom for urax on Hub + rollappTokenDenom = transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, rollapp1.Config().Denom) + rollappIBCDenom = transfertypes.ParseDenomTrace(rollappTokenDenom).IBCDenom() + + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, rollappIBCDenom, transferAmount.Sub(bridgingFee)) + + // Get original account balances + dymensionOrigBal, err = dymension.GetBalance(ctx, dymensionUserAddr, dymension.Config().Denom) + require.NoError(t, err) + + // Compose an IBC transfer and send from dymension -> rollapp + transferData = ibc.WalletData{ + Address: rollappUserAddr, + Denom: dymension.Config().Denom, + Amount: transferAmount, + } + + // Compose an IBC transfer and send from Hub -> rollapp + _, err = dymension.SendIBCTransfer(ctx, channel.ChannelID, dymensionUserAddr, transferData, ibc.TransferOptions{}) + require.NoError(t, err) + + // Assert balance was updated on the hub + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, dymension.Config().Denom, dymensionOrigBal.Sub(transferData.Amount)) + + err = testutil.WaitForBlocks(ctx, 10, dymension, rollapp1) + require.NoError(t, err) + + // Get the IBC denom + dymensionTokenDenom = transfertypes.GetPrefixedDenom(channel.Counterparty.PortID, channel.Counterparty.ChannelID, dymension.Config().Denom) + dymensionIBCDenom = transfertypes.ParseDenomTrace(dymensionTokenDenom).IBCDenom() + + testutil.AssertBalance(t, ctx, dymension, dymensionUserAddr, dymension.Config().Denom, dymensionOrigBal.Sub(transferData.Amount)) + erc20MAcc, err = rollapp1.Validators[0].QueryModuleAccount(ctx, "erc20") + require.NoError(t, err) + erc20MAccAddr = erc20MAcc.Account.BaseAccount.Address + testutil.AssertBalance(t, ctx, rollapp1, erc20MAccAddr, dymensionIBCDenom, transferData.Amount) +} + +func Test_SqcRotation_OneSqc_Success_EVM(t *testing.T) { + if testing.Short() { + t.Skip() + } + + ctx := context.Background() + + // setup config for rollapp 1 + dymintTomlOverrides := make(testutil.Toml) + dymintTomlOverrides["settlement_layer"] = "dymension" + dymintTomlOverrides["settlement_node_address"] = fmt.Sprintf("http://dymension_100-1-val-0-%s:26657", t.Name()) + dymintTomlOverrides["rollapp_id"] = "rollappevm_1234-1" + dymintTomlOverrides["settlement_gas_prices"] = "0adym" + dymintTomlOverrides["max_idle_time"] = "3s" + dymintTomlOverrides["max_proof_time"] = "500ms" + dymintTomlOverrides["batch_submit_time"] = "50s" + dymintTomlOverrides["p2p_blocksync_enabled"] = "true" + + configFileOverrides := make(map[string]any) + configFileOverrides["config/dymint.toml"] = dymintTomlOverrides + + modifyHubGenesisKV := append( + dymensionGenesisKV, + cosmos.GenesisKV{ + Key: "app_state.sequencer.params.unbonding_time", + Value: "300s", + }, + cosmos.GenesisKV{ + Key: "app_state.staking.params.unbonding_time", + Value: "300s", + }, + ) + + modifyRAGenesisKV := append( + rollappEVMGenesisKV, + cosmos.GenesisKV{ + Key: "app_state.sequencers.params.unbonding_time", + Value: "300s", + }, + cosmos.GenesisKV{ + Key: "app_state.staking.params.unbonding_time", + Value: "300s", + }, + ) + + // Create chain factory with dymension + numHubVals := 1 + numHubFullNodes := 1 + numRollAppVals := 1 + numRollAppFn := 1 + + cf := test.NewBuiltinChainFactory(zaptest.NewLogger(t), []*test.ChainSpec{ + { + Name: "rollapp1", + ChainConfig: ibc.ChainConfig{ + Type: "rollapp-dym", + Name: "rollapp-temp", + ChainID: "rollappevm_1234-1", + Images: []ibc.DockerImage{rollappEVMImage}, + Bin: "rollappd", + Bech32Prefix: "ethm", + Denom: "urax", + CoinType: "60", + GasPrices: "0.0urax", + GasAdjustment: 1.1, + TrustingPeriod: "112h", + EncodingConfig: encodingConfig(), + NoHostMount: false, + ModifyGenesis: modifyRollappEVMGenesis(modifyRAGenesisKV), + ConfigFileOverrides: configFileOverrides, + }, + NumValidators: &numRollAppVals, + NumFullNodes: &numRollAppFn, + }, + { + Name: "dymension-hub", + ChainConfig: ibc.ChainConfig{ + Type: "hub-dym", + Name: "dymension", + ChainID: "dymension_100-1", + Images: []ibc.DockerImage{dymensionImage}, + Bin: "dymd", + Bech32Prefix: "dym", + Denom: "adym", + CoinType: "60", + GasPrices: "0.0adym", + EncodingConfig: encodingConfig(), + GasAdjustment: 1.1, + TrustingPeriod: "112h", + NoHostMount: false, + ModifyGenesis: modifyDymensionGenesis(modifyHubGenesisKV), + ConfigFileOverrides: nil, + }, + NumValidators: &numHubVals, + NumFullNodes: &numHubFullNodes, + }, + }) + + // Get chains from the chain factory + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + rollapp1 := chains[0].(*dym_rollapp.DymRollApp) + dymension := chains[1].(*dym_hub.DymHub) + + // Relayer Factory + client, network := test.DockerSetup(t) + + // relayer for rollapp 1 + r := test.NewBuiltinRelayerFactory(ibc.CosmosRly, zaptest.NewLogger(t), + relayer.CustomDockerImage(RelayerMainRepo, relayerVersion, "100:1000"), relayer.ImagePull(pullRelayerImage), + ).Build(t, client, "relayer", network) + + ic := test.NewSetup(). + AddRollUp(dymension, rollapp1). + AddRelayer(r, "relayer"). + AddLink(test.InterchainLink{ + Chain1: dymension, + Chain2: rollapp1, + Relayer: r, + Path: ibcPath, + }) + + rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) + + err = ic.Build(ctx, eRep, test.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + }, nil, "", nil, true, 195) + require.NoError(t, err) + + containerID := fmt.Sprintf("ra-rollappevm_1234-1-val-0-%s", t.Name()) + + // Get the container details + containerJSON, err := client.ContainerInspect(context.Background(), containerID) + require.NoError(t, err) + + // Extract the IP address from the network settings + // If the container is using a custom network, the IP might be under a specific network name + var ipAddress string + for _, network := range containerJSON.NetworkSettings.Networks { + ipAddress = network.IPAddress + break // Assuming we only need the IP from the first network + } + + nodeId, err := rollapp1.Validators[0].GetNodeId(ctx) + require.NoError(t, err) + nodeId = strings.TrimRight(nodeId, "\n") + p2p_bootstrap_node := fmt.Sprintf("/ip4/%s/tcp/26656/p2p/%s", ipAddress, nodeId) + + rollapp1HomeDir := strings.Split(rollapp1.HomeDir(), "/") + rollapp1FolderName := rollapp1HomeDir[len(rollapp1HomeDir)-1] + + file, err := os.Open(fmt.Sprintf("/tmp/%s/config/dymint.toml", rollapp1FolderName)) + require.NoError(t, err) + defer file.Close() + + lines := []string{} + scanner := bufio.NewScanner(file) + for scanner.Scan() { + lines = append(lines, scanner.Text()) + } + + for i, line := range lines { + if strings.HasPrefix(line, "p2p_bootstrap_nodes =") { + lines[i] = fmt.Sprintf("p2p_bootstrap_nodes = \"%s\"", p2p_bootstrap_node) + } + } + + output := strings.Join(lines, "\n") + file, err = os.Create(fmt.Sprintf("/tmp/%s/config/dymint.toml", rollapp1FolderName)) + require.NoError(t, err) + defer file.Close() + + _, err = file.Write([]byte(output)) + require.NoError(t, err) + + // Start full node + err = rollapp1.FullNodes[0].StopContainer(ctx) + require.NoError(t, err) + + err = rollapp1.FullNodes[0].StartContainer(ctx) + require.NoError(t, err) + + addrDym, _ := r.GetWallet(dymension.GetChainID()) + err = dymension.GetNode().SendFunds(ctx, "faucet", ibc.WalletData{ + Address: addrDym.FormattedAddress(), + Amount: math.NewInt(10_000_000_000_000), + Denom: dymension.Config().Denom, + }) + require.NoError(t, err) + + addrRA, _ := r.GetWallet(rollapp1.GetChainID()) + err = rollapp1.GetNode().SendFunds(ctx, "faucet", ibc.WalletData{ + Address: addrRA.FormattedAddress(), + Amount: math.NewInt(10_000_000_000_000), + Denom: rollapp1.Config().Denom, + }) + require.NoError(t, err) + + // Check IBC Transfer before switch + CreateChannel(ctx, t, r, eRep, dymension.CosmosChain, rollapp1.CosmosChain, ibcPath) + + // Create some user accounts on both chains + // users := test.GetAndFundTestUsers(t, ctx, t.Name(), walletAmount, dymension, rollapp1) + + cmd := append([]string{rollapp1.FullNodes[0].Chain.Config().Bin}, "dymint", "show-sequencer", "--home", rollapp1.FullNodes[0].HomeDir()) + pub1, _, err := rollapp1.GetNode().Exec(ctx, cmd, nil) + require.NoError(t, err) + + err = dymension.GetNode().CreateKeyWithKeyDir(ctx, "sequencer", rollapp1.GetNode().HomeDir()) + require.NoError(t, err) + + sequencer, err := dymension.AccountKeyBech32WithKeyDir(ctx, "sequencer", rollapp1.GetNode().HomeDir()) + require.NoError(t, err) + + fund := ibc.WalletData{ + Address: sequencer, + Denom: dymension.Config().Denom, + Amount: math.NewInt(10_000_000_000_000).MulRaw(100_000_000), + } + err = dymension.SendFunds(ctx, "faucet", fund) + require.NoError(t, err) + + // Wait a few blocks for relayer to start and for user accounts to be created + err = testutil.WaitForBlocks(ctx, 5, dymension) + require.NoError(t, err) + + command := []string{"sequencer", "create-sequencer", string(pub1), rollapp1.Config().ChainID, "1000000000adym", rollapp1.GetSequencerKeyDir() + "/metadata_sequencer1.json", + "--broadcast-mode", "async", "--keyring-dir", rollapp1.GetNode().HomeDir() + "/sequencer_keys"} + + _, err = dymension.FullNodes[0].ExecTx(ctx, "sequencer", command...) + require.NoError(t, err) + + res, err := dymension.QueryShowSequencerByRollapp(ctx, rollapp1.Config().ChainID) + require.NoError(t, err) + require.Equal(t, len(res.Sequencers), 2, "should have 2 sequences") + // Get our Bech32 encoded user addresses // dymensionUser, rollappUser := users[0], users[1] @@ -635,29 +1098,6 @@ func Test_SeqRotation_NoSeq_P2P_EVM(t *testing.T) { require.NoError(t, err) require.Equal(t, "OPERATING_STATUS_UNBONDED", queryGetSequencerResponse.Sequencer.Status) - cmd := append([]string{rollapp1.FullNodes[0].Chain.Config().Bin}, "dymint", "show-sequencer", "--home", rollapp1.FullNodes[0].HomeDir()) - pub1, _, err := rollapp1.GetNode().Exec(ctx, cmd, nil) - require.NoError(t, err) - - // Create some user accounts on both chains - users = test.GetAndFundTestUsers(t, ctx, t.Name(), walletAmount, dymension) - - // Wait a few blocks for relayer to start and for user accounts to be created - err = testutil.WaitForBlocks(ctx, 5, dymension) - require.NoError(t, err) - - sequencer1 := users[0] - - command := []string{"sequencer", "create-sequencer", string(pub1), rollapp1.Config().ChainID, "1000000000adym", rollapp1.GetSequencerKeyDir() + "/metadata_sequencer.json", - "--broadcast-mode", "async"} - - _, err = dymension.FullNodes[0].ExecTx(ctx, sequencer1.KeyName(), command...) - require.NoError(t, err) - - res, err := dymension.QueryShowSequencerByRollapp(ctx, rollapp1.Config().ChainID) - require.NoError(t, err) - require.Equal(t, len(res.Sequencers), 2, "should have 2 sequences") - err = rollapp1.StopAllNodes(ctx) require.NoError(t, err)