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

e2e: adding e2e upgrade test for ibc-go v7 #2902

Merged
merged 27 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b75938b
scaff
charleenfei Dec 6, 2022
75db3a9
update test
charleenfei Dec 7, 2022
bd2834e
add test for automatic migration of solomachine clientstate version
charleenfei Dec 7, 2022
b3b63e2
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 7, 2022
59546d8
fix comment on util function
charleenfei Dec 7, 2022
9013bcb
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 8, 2022
376b7cd
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 8, 2022
8a24eef
add clientID generation functions
charleenfei Dec 8, 2022
f3be122
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 8, 2022
bb07835
update
charleenfei Dec 8, 2022
546c4a6
Merge branch 'charly/e2e-6-7' of github.com:cosmos/ibc-go into charly…
charleenfei Dec 8, 2022
01e50c1
update re: pr comments
charleenfei Dec 8, 2022
86cccb9
update godoc
charleenfei Dec 8, 2022
d5cca8b
update ibctest to latest commit
charleenfei Dec 8, 2022
623b6b7
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 8, 2022
deaa5ca
update chainconfig
charleenfei Dec 8, 2022
e6f1d2b
Merge branch 'main' into charly/update_ibctest
charleenfei Dec 9, 2022
c9cc0b5
update to commit fixing broadcastTx
charleenfei Dec 11, 2022
7960c22
Merge branch 'charly/update_ibctest' into charly/e2e-6-7
charleenfei Dec 11, 2022
1788963
update e2e upgrades workflow
charleenfei Dec 12, 2022
d30011b
update workflow to set relayer tag as not required
charleenfei Dec 12, 2022
f13dc99
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 12, 2022
b21ebe1
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 12, 2022
d25710b
update sprintf message
charleenfei Dec 12, 2022
1a43b17
Merge branch 'charly/e2e-6-7' of github.com:cosmos/ibc-go into charly…
charleenfei Dec 12, 2022
e037284
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 12, 2022
a2bf19c
Merge branch 'main' into charly/e2e-6-7
charleenfei Dec 12, 2022
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
8 changes: 7 additions & 1 deletion .github/workflows/e2e-upgrade.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ jobs:
chain-binary: icad
chain-a-tag: v0.3.5
chain-b-tag: v0.3.5
chain-upgrade-tag: v0.4.2
chain-upgrade-tag: v0.4.0
- test: TestV6ToV7ChainUpgrade
chain-image: ghcr.io/cosmos/ibc-go-simd
chain-binary: simd
chain-a-tag: v6.0.0
chain-b-tag: v6.0.0
chain-upgrade-tag: v7.0.0
Comment on lines +22 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for adding this!

steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
Expand Down
176 changes: 176 additions & 0 deletions e2e/tests/upgrades/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ import (
"github.com/cosmos/ibc-go/e2e/testvalues"
controllertypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/controller/types"
icatypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/types"
v7migrations "github.com/cosmos/ibc-go/v6/modules/core/02-client/migrations/v7"
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v6/modules/core/exported"
solomachine "github.com/cosmos/ibc-go/v6/modules/light-clients/06-solomachine"
ibctesting "github.com/cosmos/ibc-go/v6/testing"
simappupgrades "github.com/cosmos/ibc-go/v6/testing/simapp/upgrades"
v7upgrades "github.com/cosmos/ibc-go/v6/testing/simapp/upgrades/v7"
)

const (
Expand Down Expand Up @@ -70,6 +75,10 @@ func (s *UpgradeTestSuite) UpgradeChain(ctx context.Context, chain *cosmos.Cosmo
err = chain.StartAllNodes(ctx)
s.Require().NoError(err, "error starting upgraded node(s)")

// we are reinitializing the clients because we need to update the hostGRPCAddress after
// the upgrade and subsequent restarting of nodes
s.InitGRPCClients(chain)
chatton marked this conversation as resolved.
Show resolved Hide resolved

timeoutCtx, timeoutCtxCancel = context.WithTimeout(ctx, time.Minute*2)
defer timeoutCtxCancel()

Expand Down Expand Up @@ -386,6 +395,160 @@ func (s *UpgradeTestSuite) TestV5ToV6ChainUpgrade() {
})
}

// TestV6ToV7ChainUpgrade will test that an upgrade from a v6 ibc-go binary to a v7 ibc-go binary is successful
// and that the automatic migrations associated with the 02-client module are performed. Namely that the solo machine
// proto definition is migrated in state from the v2 to v3 definition. This is checked by creating a solo machine client
// before the upgrade and asserting that its TypeURL has been changed after the upgrade. The test also ensure packets
// can be sent before and after the upgrade without issue
func (s *UpgradeTestSuite) TestV6ToV7ChainUpgrade() {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
t := s.T()
testCfg := testconfig.FromEnv()

ctx := context.Background()
relayer, channelA := s.SetupChainsRelayerAndChannel(ctx)
chainA, chainB := s.GetChains()

var (
chainADenom = chainA.Config().Denom
chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB
)

chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
chainAAddress := chainAWallet.Bech32Address(chainA.Config().Bech32Prefix)

chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)
chainBAddress := chainBWallet.Bech32Address(chainB.Config().Bech32Prefix)

// create second tendermint client
createClientOptions := ibc.CreateClientOptions{
TrustingPeriod: ibctesting.TrustingPeriod.String(),
}

s.SetupClients(ctx, relayer, createClientOptions)

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

t.Run("check that both tendermint clients are active", func(t *testing.T) {
status, err := s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(0))
s.Require().NoError(err)
s.Require().Equal(exported.Active.String(), status)

status, err = s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(1))
s.Require().NoError(err)
s.Require().Equal(exported.Active.String(), status)
})

// create solo machine client using the solomachine implementation from ibctesting
// TODO: the solomachine clientID should be updated when after fix of this issue: https://github.com/cosmos/ibc-go/issues/2907
solo := ibctesting.NewSolomachine(t, testsuite.Codec(), "solomachine", "testing", 1)

legacyConsensusState := &v7migrations.ConsensusState{
PublicKey: solo.ConsensusState().PublicKey,
Diversifier: solo.ConsensusState().Diversifier,
Timestamp: solo.ConsensusState().Timestamp,
}

legacyClientState := &v7migrations.ClientState{
Sequence: solo.ClientState().Sequence,
IsFrozen: solo.ClientState().IsFrozen,
ConsensusState: legacyConsensusState,
AllowUpdateAfterProposal: true,
}

msgCreateSoloMachineClient, err := clienttypes.NewMsgCreateClient(legacyClientState, legacyConsensusState, chainAAddress)
s.Require().NoError(err)

resp, err := s.BroadcastMessages(
ctx,
chainA,
chainAWallet,
msgCreateSoloMachineClient,
)

s.AssertValidTxResponse(resp)
s.Require().NoError(err)

t.Run("check that the solomachine is now active and that the clientstate is a pre-upgrade v2 solomachine clientstate", func(t *testing.T) {
status, err := s.QueryClientStatus(ctx, chainA, testvalues.SolomachineClientID(2))
s.Require().NoError(err)
s.Require().Equal(exported.Active.String(), status)

res, err := s.ClientState(ctx, chainA, testvalues.SolomachineClientID(2))
s.Require().NoError(err)
s.Require().Equal(fmt.Sprint("/", proto.MessageName(&v7migrations.ClientState{})), res.ClientState.TypeUrl)
})

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

t.Run("IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) {
transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "")
s.Require().NoError(err)
s.AssertValidTxResponse(transferTxResp)
})

t.Run("tokens are escrowed", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance)
})

t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer)
})

t.Run("packets are relayed", func(t *testing.T) {
s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1)

actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom())
s.Require().NoError(err)

expected := testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance)
})

// create separate user specifically for the upgrade proposal to more easily verify starting
// and end balances of the chainA users.
chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)

t.Run("upgrade chainA", func(t *testing.T) {
s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, v7upgrades.UpgradeName, testCfg.ChainAConfig.Tag, testCfg.UpgradeTag)
})

t.Run("check that the tendermint clients are active again after upgrade", func(t *testing.T) {
status, err := s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(0))
s.Require().NoError(err)
s.Require().Equal(exported.Active.String(), status)

status, err = s.QueryClientStatus(ctx, chainA, testvalues.TendermintClientID(1))
s.Require().NoError(err)
s.Require().Equal(exported.Active.String(), status)
})

t.Run("IBC token transfer from chainA to chainB, to make sure the upgrade did not break the packet flow", func(t *testing.T) {
transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "")
s.Require().NoError(err)
s.AssertValidTxResponse(transferTxResp)
})

t.Run("packets are relayed", func(t *testing.T) {
s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1)

actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom())
s.Require().NoError(err)

expected := testvalues.IBCTransferAmount * 2
s.Require().Equal(expected, actualBalance)
})

t.Run("check that the v2 solo machine clientstate has been updated to the v3 solo machine clientstate", func(t *testing.T) {
res, err := s.ClientState(ctx, chainA, testvalues.SolomachineClientID(2))
s.Require().NoError(err)
s.Require().Equal(fmt.Sprint("/", proto.MessageName(&solomachine.ClientState{})), res.ClientState.TypeUrl)
})
}

// RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain.
func (s *UpgradeTestSuite) RegisterInterchainAccount(ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, msgRegisterAccount *intertxtypes.MsgRegisterAccount) error {
txResp, err := s.BroadcastMessages(ctx, chain, user, msgRegisterAccount)
Expand All @@ -405,3 +568,16 @@ func getICAVersion(chainAVersion, chainBVersion string) string {
// explicitly set the version string because the host chain might not yet support incentivized channels.
return icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID)
}

// ClientState queries the current ClientState by clientID
func (s *UpgradeTestSuite) ClientState(ctx context.Context, chain ibc.Chain, clientID string) (*clienttypes.QueryClientStateResponse, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

fetching client state might be something we want to do in other tests, I'm happy to leave it here for now, but it might be worth moving this to the E2ETestSuite WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i could move this one and Status as well, I think they are generic enough functions

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah you mean to return QueryClientStatusRequest and use one function?

colin-axner marked this conversation as resolved.
Show resolved Hide resolved
queryClient := s.GetChainGRCPClients(chain).ClientQueryClient
res, err := queryClient.ClientState(ctx, &clienttypes.QueryClientStateRequest{
ClientId: clientID,
})
if err != nil {
return res, err
}

return res, nil
}
13 changes: 13 additions & 0 deletions e2e/testsuite/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ func (s *E2ETestSuite) QueryClientState(ctx context.Context, chain ibc.Chain, cl
return clientState, nil
}

// QueryClientStatus queries the status of the client by clientID
func (s *E2ETestSuite) QueryClientStatus(ctx context.Context, chain ibc.Chain, clientID string) (string, error) {
queryClient := s.GetChainGRCPClients(chain).ClientQueryClient
res, err := queryClient.ClientStatus(ctx, &clienttypes.QueryClientStatusRequest{
ClientId: clientID,
})
if err != nil {
return "", err
}

return res.Status, nil
}

// QueryChannel queries the channel on a given chain for the provided portID and channelID
func (s *E2ETestSuite) QueryChannel(ctx context.Context, chain ibc.Chain, portID, channelID string) (channeltypes.Channel, error) {
queryClient := s.GetChainGRCPClients(chain).ChannelQueryClient
Expand Down
8 changes: 4 additions & 4 deletions e2e/testsuite/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channel
time.Sleep(time.Second * 10)
}

s.initGRPCClients(chainA)
s.initGRPCClients(chainB)
s.InitGRPCClients(chainA)
s.InitGRPCClients(chainB)

chainAChannels, err := r.GetChannels(ctx, eRep, chainA.Config().ChainID)
s.Require().NoError(err)
Expand Down Expand Up @@ -361,9 +361,9 @@ func (s *E2ETestSuite) GetChainGRCPClients(chain ibc.Chain) GRPCClients {
return cs
}

// initGRPCClients establishes GRPC clients with the given chain.
// InitGRPCClients establishes GRPC clients with the given chain.
// The created GRPCClients can be retrieved with GetChainGRCPClients.
func (s *E2ETestSuite) initGRPCClients(chain *cosmos.CosmosChain) {
func (s *E2ETestSuite) InitGRPCClients(chain *cosmos.CosmosChain) {
// Create a connection to the gRPC server.
grpcConn, err := grpc.Dial(
chain.GetHostGRPCAddress(),
Expand Down
9 changes: 9 additions & 0 deletions e2e/testvalues/values.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package testvalues

import (
"fmt"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -34,3 +35,11 @@ func DefaultFee(denom string) feetypes.Fee {
func DefaultTransferAmount(denom string) sdk.Coin {
return sdk.Coin{Denom: denom, Amount: sdk.NewInt(IBCTransferAmount)}
}

func TendermintClientID(id int) string {
return fmt.Sprintf("07-tendermint-%d", id)
}

func SolomachineClientID(id int) string {
return fmt.Sprint("06-solomachine-%d", id)
}