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

Add ICS27 e2e test with governance #2808

Merged
merged 23 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
df9f768
wip
chatton Sep 7, 2022
426237b
wip
chatton Sep 8, 2022
f93b519
chore: merge main
chatton Oct 13, 2022
527db9a
chore: uncommenting test
chatton Oct 13, 2022
2a25091
chore: test correctly working
chatton Oct 13, 2022
76ceb52
wip: e2e governance test not yet passing
chatton Oct 14, 2022
de2e56a
chore: sleep in test
chatton Oct 14, 2022
67f3c1d
chore: adding configure factory opt to broadcaster
chatton Oct 25, 2022
15dc975
chore: merging main
chatton Nov 21, 2022
362cba9
chore: wip gov test
chatton Nov 21, 2022
d25eba7
test: performing second SendTx via governance
chatton Nov 22, 2022
24b1348
chore: moving test into separate file
chatton Nov 22, 2022
3c18482
chore: reverted changes to run-e2e.sh
chatton Nov 22, 2022
409f205
chore: reverted temporary changing of validator number
chatton Nov 22, 2022
debea05
Merge branch 'main' into cian/issue#2063-add-ics27-e2e-test-with-gove…
chatton Nov 22, 2022
0ce623d
chore: adding time between relayer start and ica account verification
chatton Nov 22, 2022
abb89a8
chore: bump default relayer version to v2.1.2
chatton Nov 22, 2022
2cc5a14
chore: removing unused function
chatton Nov 22, 2022
b5954d9
chore: addressing PR feedback
chatton Nov 22, 2022
5ab176b
Merge branch 'main' into cian/issue#2063-add-ics27-e2e-test-with-gove…
chatton Nov 22, 2022
b0eea6e
Merge branch 'main' into cian/issue#2063-add-ics27-e2e-test-with-gove…
chatton Nov 22, 2022
192d19b
chore: addressing PR feedback
chatton Nov 23, 2022
a4ae2b3
Merge branch 'main' into cian/issue#2063-add-ics27-e2e-test-with-gove…
chatton Nov 23, 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
45 changes: 4 additions & 41 deletions e2e/tests/interchain_accounts/gov_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/gogo/protobuf/proto"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit on separation of imports

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Based on the three categories of imports stdlib / external libs / our libs, I would say that these imports are correctly grouped.

WDYT?

"github.com/strangelove-ventures/ibctest/v6"
"github.com/strangelove-ventures/ibctest/v6/chain/cosmos"
"github.com/strangelove-ventures/ibctest/v6/ibc"
"github.com/strangelove-ventures/ibctest/v6/test"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -40,7 +38,6 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration()
relayer, _ := s.SetupChainsRelayerAndChannel(ctx)
chainA, chainB := s.GetChains()
controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
controllerAddress := controllerAccount.Bech32Address(chainA.Config().Bech32Prefix)

chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)
chainBAddress := chainBAccount.Bech32Address(chainB.Config().Bech32Prefix)
Expand All @@ -49,27 +46,10 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration()
s.Require().NoError(err)
s.Require().NotNil(govModuleAddress)

t.Run("submit proposal for MsgRegisterInterchainAccount", func(t *testing.T) {
t.Run("execute proposal for MsgRegisterInterchainAccount", func(t *testing.T) {
version := icatypes.NewDefaultMetadataString(ibctesting.FirstConnectionID, ibctesting.FirstConnectionID)
msgRegisterAccount := controllertypes.NewMsgRegisterInterchainAccount(ibctesting.FirstConnectionID, govModuleAddress.String(), version)
msgs := []sdk.Msg{msgRegisterAccount}
msgSubmitProposal, err := govtypesv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(sdk.NewCoin(chainA.Config().Denom, govtypesv1.DefaultMinDepositTokens)), controllerAddress, "")
s.Require().NoError(err)

resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgSubmitProposal)
s.AssertValidTxResponse(resp)
s.Require().NoError(err)
})

t.Run("vote for proposal for MsgRegisterInterchainAccount", func(t *testing.T) {
s.Require().NoError(chainA.VoteOnProposalAllValidators(ctx, "1", cosmos.ProposalVoteYes))

time.Sleep(testvalues.VotingPeriod)
time.Sleep(5 * time.Second)

proposal, err := s.QueryProposalV1(ctx, chainA, 1)
s.Require().NoError(err)
s.Require().Equal(govtypesv1.StatusPassed, proposal.Status)
s.ExecuteGovProposalV1(ctx, msgRegisterAccount, chainA, controllerAccount, 1)
})

t.Run("start relayer", func(t *testing.T) {
Expand Down Expand Up @@ -101,7 +81,7 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration()
s.Require().NoError(err)
})

t.Run("submit proposal for MsgSendTx", func(t *testing.T) {
t.Run("execute proposal for MsgSendTx", func(t *testing.T) {
msgBankSend := &banktypes.MsgSend{
FromAddress: interchainAccAddr,
ToAddress: chainBAddress,
Expand All @@ -119,24 +99,7 @@ func (s *InterchainAccountsGovTestSuite) TestInterchainAccountsGovIntegration()
}

msgSendTx := controllertypes.NewMsgSendTx(govModuleAddress.String(), ibctesting.FirstConnectionID, uint64(time.Hour.Nanoseconds()), packetData)
msgs := []sdk.Msg{msgSendTx}
msgSubmitProposal, err := govtypesv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(sdk.NewCoin(chainA.Config().Denom, govtypesv1.DefaultMinDepositTokens)), controllerAddress, "")
s.Require().NoError(err)

resp, err := s.BroadcastMessages(ctx, chainA, controllerAccount, msgSubmitProposal)
s.AssertValidTxResponse(resp)
s.Require().NoError(err)
})

t.Run("vote for proposal for MsgSendTx", func(t *testing.T) {
s.Require().NoError(chainA.VoteOnProposalAllValidators(ctx, "2", cosmos.ProposalVoteYes))

time.Sleep(testvalues.VotingPeriod)
time.Sleep(5 * time.Second)

proposal, err := s.QueryProposalV1(ctx, chainA, 2)
s.Require().NoError(err)
s.Require().Equal(govtypesv1.StatusPassed, proposal.Status)
s.ExecuteGovProposalV1(ctx, msgSendTx, chainA, controllerAccount, 2)
})

t.Run("verify tokens transferred", func(t *testing.T) {
Expand Down
12 changes: 11 additions & 1 deletion e2e/testsuite/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,20 @@ import (
)

func Codec() *codec.ProtoCodec {
cdc, _ := codecAndEncodingConfig()
return cdc
}

func EncodingConfig() simappparams.EncodingConfig {
_, cfg := codecAndEncodingConfig()
return cfg
}

func codecAndEncodingConfig() (*codec.ProtoCodec, simappparams.EncodingConfig) {
cfg := simappparams.MakeTestEncodingConfig()
banktypes.RegisterInterfaces(cfg.InterfaceRegistry)
govv1beta1.RegisterInterfaces(cfg.InterfaceRegistry)
authtypes.RegisterInterfaces(cfg.InterfaceRegistry)
cdc := codec.NewProtoCodec(cfg.InterfaceRegistry)
return cdc
return cdc, cfg
}
75 changes: 45 additions & 30 deletions e2e/testsuite/testsuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"time"

"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypesv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
govtypesv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
grouptypes "github.com/cosmos/cosmos-sdk/x/group"
paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types"
Expand All @@ -34,7 +35,6 @@ import (
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
simappparams "github.com/cosmos/ibc-go/v6/testing/simapp/params"
)

const (
Expand Down Expand Up @@ -76,8 +76,8 @@ type GRPCClients struct {
InterTxQueryClient intertxtypes.QueryClient

// SDK query clients
GovQueryClient govtypes.QueryClient
GovQueryClientV1 govtypesv1.QueryClient
GovQueryClient govtypesv1beta1.QueryClient
GovQueryClientV1 govtypesv1.QueryClient
GroupsQueryClient grouptypes.QueryClient
ParamsQueryClient paramsproposaltypes.QueryClient
AuthQueryClient authtypes.QueryClient
Expand Down Expand Up @@ -386,7 +386,7 @@ func (s *E2ETestSuite) initGRPCClients(chain *cosmos.CosmosChain) {
FeeQueryClient: feetypes.NewQueryClient(grpcConn),
ICAQueryClient: controllertypes.NewQueryClient(grpcConn),
InterTxQueryClient: intertxtypes.NewQueryClient(grpcConn),
GovQueryClient: govtypes.NewQueryClient(grpcConn),
GovQueryClient: govtypesv1beta1.NewQueryClient(grpcConn),
GovQueryClientV1: govtypesv1.NewQueryClient(grpcConn),
GroupsQueryClient: grouptypes.NewQueryClient(grpcConn),
ParamsQueryClient: paramsproposaltypes.NewQueryClient(grpcConn),
Expand Down Expand Up @@ -457,12 +457,12 @@ func GetNativeChainBalance(ctx context.Context, chain ibc.Chain, user *ibc.Walle
}

// ExecuteGovProposal submits the given governance proposal using the provided user and uses all validators to vote yes on the proposal.
// It ensure the proposal successfully passes.
func (s *E2ETestSuite) ExecuteGovProposal(ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, content govtypes.Content) {
// It ensures the proposal successfully passes.
func (s *E2ETestSuite) ExecuteGovProposal(ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, content govtypesv1beta1.Content) {
sender, err := sdk.AccAddressFromBech32(user.Bech32Address(chain.Config().Bech32Prefix))
s.Require().NoError(err)

msgSubmitProposal, err := govtypes.NewMsgSubmitProposal(content, sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, govtypes.DefaultMinDepositTokens)), sender)
msgSubmitProposal, err := govtypesv1beta1.NewMsgSubmitProposal(content, sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, govtypesv1beta1.DefaultMinDepositTokens)), sender)
s.Require().NoError(err)

txResp, err := s.BroadcastMessages(ctx, chain, user, msgSubmitProposal)
Expand All @@ -474,56 +474,71 @@ func (s *E2ETestSuite) ExecuteGovProposal(ctx context.Context, chain *cosmos.Cos

proposal, err := s.QueryProposal(ctx, chain, 1)
s.Require().NoError(err)
s.Require().Equal(govtypes.StatusVotingPeriod, proposal.Status)
s.Require().Equal(govtypesv1beta1.StatusVotingPeriod, proposal.Status)

err = chain.VoteOnProposalAllValidators(ctx, "1", cosmos.ProposalVoteYes)
s.Require().NoError(err)

// ensure voting period has not passed before validators finished voting
proposal, err = s.QueryProposal(ctx, chain, 1)
s.Require().NoError(err)
s.Require().Equal(govtypes.StatusVotingPeriod, proposal.Status)
s.Require().Equal(govtypesv1beta1.StatusVotingPeriod, proposal.Status)

time.Sleep(testvalues.VotingPeriod) // pass proposal

proposal, err = s.QueryProposal(ctx, chain, 1)
s.Require().NoError(err)
s.Require().Equal(govtypes.StatusPassed, proposal.Status)
s.Require().Equal(govtypesv1beta1.StatusPassed, proposal.Status)
}

// ExecuteGovProposalV1 submits a governance proposal using the provided user and message and uses all validators
// to vote yes on the proposal. It ensures the proposal successfully passes.
func (s *E2ETestSuite) ExecuteGovProposalV1(ctx context.Context, msg sdk.Msg, chain *cosmos.CosmosChain, user *ibc.Wallet, proposalID uint64) {
sender, err := sdk.AccAddressFromBech32(user.Bech32Address(chain.Config().Bech32Prefix))
s.Require().NoError(err)

msgs := []sdk.Msg{msg}
msgSubmitProposal, err := govtypesv1.NewMsgSubmitProposal(msgs, sdk.NewCoins(sdk.NewCoin(chain.Config().Denom, govtypesv1.DefaultMinDepositTokens)), sender.String(), "")
s.Require().NoError(err)

resp, err := s.BroadcastMessages(ctx, chain, user, msgSubmitProposal)
s.AssertValidTxResponse(resp)
s.Require().NoError(err)

s.Require().NoError(chain.VoteOnProposalAllValidators(ctx, strconv.Itoa(int(proposalID)), cosmos.ProposalVoteYes))

time.Sleep(testvalues.VotingPeriod)

proposal, err := s.QueryProposalV1(ctx, chain, proposalID)
s.Require().NoError(err)
s.Require().Equal(govtypesv1.StatusPassed, proposal.Status)
}
Comment on lines +496 to +515
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@colin-axner added this helper function as suggested 👍


// QueryModuleAccountAddress returns the sdk.AccAddress of a given module name.
func (s *E2ETestSuite) QueryModuleAccountAddress(ctx context.Context, moduleName string, chain *cosmos.CosmosChain) (sdk.AccAddress, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nice addition :)

authClient := s.GetChainGRCPClients(chain).AuthQueryClient

moduleAccountsResponse, err := authClient.ModuleAccounts(ctx, &authtypes.QueryModuleAccountsRequest{})
resp, err := authClient.ModuleAccountByName(ctx, &authtypes.QueryModuleAccountByNameRequest{
Name: moduleName,
})
if err != nil {
return nil, err
}

cfg := simappparams.MakeTestEncodingConfig()
authtypes.RegisterInterfaces(cfg.InterfaceRegistry)

for _, acc := range moduleAccountsResponse.Accounts {
var account authtypes.AccountI
err := cfg.InterfaceRegistry.UnpackAny(acc, &account)
if err != nil {
return nil, err
}
moduleAccount, ok := account.(authtypes.ModuleAccountI)
if !ok {
return nil, errors.New(fmt.Sprintf("failed to cast account: %T as ModuleAccount", moduleAccount))
}
cfg := EncodingConfig()

if moduleAccount.GetName() == moduleName {
return moduleAccount.GetAddress(), nil
}
var account authtypes.AccountI
if err := cfg.InterfaceRegistry.UnpackAny(resp.Account, &account); err != nil {
return nil, err
}
moduleAccount, ok := account.(authtypes.ModuleAccountI)
if !ok {
return nil, errors.New(fmt.Sprintf("failed to cast account: %T as ModuleAccount", moduleAccount))
}

return nil, errors.New(fmt.Sprintf("failed to find address for module account: %s", moduleName))
return moduleAccount.GetAddress(), nil
}


// GetIBCToken returns the denomination of the full token denom sent to the receiving channel
func GetIBCToken(fullTokenDenom string, portID, channelID string) transfertypes.DenomTrace {
return transfertypes.ParseDenomTrace(fmt.Sprintf("%s/%s/%s", portID, channelID, fullTokenDenom))
Expand Down