Skip to content

Commit

Permalink
test: add e2e test for ibc, wasm (#361)
Browse files Browse the repository at this point in the history
* feat: add e2e ibc fee test

* feat: add e2e gov test

* fead: add grants test

* fead: add ica test

* fix lint

* fix go mod

* update comment
  • Loading branch information
hoank101 authored Apr 8, 2024
1 parent 08c2c0e commit 0af69ef
Show file tree
Hide file tree
Showing 29 changed files with 1,248 additions and 33 deletions.
15 changes: 12 additions & 3 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,10 @@ var (
// MigalooApp extended ABCI application
type MigalooApp struct {
*baseapp.BaseApp
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
txConfig client.TxConfig

interfaceRegistry types.InterfaceRegistry

invCheckPeriod uint
Expand Down Expand Up @@ -342,8 +344,9 @@ func NewMigalooApp(
wasmOpts []wasmkeeper.Option,
baseAppOptions ...func(*baseapp.BaseApp),
) *MigalooApp {
appCodec, legacyAmino, txConfig := encodingConfig.Codec, encodingConfig.Amino, encodingConfig.TxConfig
appCodec, legacyAmino := encodingConfig.Codec, encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
txConfig := encodingConfig.TxConfig

bApp := baseapp.NewBaseApp(appName, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
Expand All @@ -368,6 +371,7 @@ func NewMigalooApp(
BaseApp: bApp,
legacyAmino: legacyAmino,
appCodec: appCodec,
txConfig: txConfig,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
keys: keys,
Expand Down Expand Up @@ -1112,6 +1116,11 @@ func (app *MigalooApp) AppCodec() codec.Codec {
return app.appCodec
}

// TxConfig returns MigalooApp's TxConfig
func (app *MigalooApp) TxConfig() client.TxConfig {
return app.txConfig
}

// RegisterSwaggerAPI registers swagger route with API Server
func RegisterSwaggerAPI(rtr *mux.Router) {
cosmosStatikFs, err := fs.New()
Expand Down
59 changes: 36 additions & 23 deletions app/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"testing"
"time"

simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"

"cosmossdk.io/math"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/client"
Expand All @@ -18,7 +20,6 @@ import (
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
config "github.com/White-Whale-Defi-Platform/migaloo-chain/v4/app/params"
dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
Expand Down Expand Up @@ -108,10 +109,10 @@ func SetupApp(t *testing.T) *MigalooApp {
acc := authtypes.NewBaseAccount(senderPrivKey.PubKey().Address().Bytes(), senderPrivKey.PubKey(), 0, 0)
balance := banktypes.Balance{
Address: acc.GetAddress().String(),
Coins: sdk.NewCoins(sdk.NewCoin(config.BaseDenom, sdk.NewInt(100000000000000))),
Coins: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100000000000000))),
}

app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
app := SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, "", nil, balance)

return app
}
Expand All @@ -120,29 +121,36 @@ func SetupApp(t *testing.T) *MigalooApp {
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit in the default token of the app from first genesis
// account. A Nop logger is set in app.
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *MigalooApp {
func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs []authtypes.GenesisAccount, chainID string, opts []wasmkeeper.Option, balances ...banktypes.Balance) *MigalooApp {
t.Helper()

migalooApp, genesisState := setup(true)
migalooApp, genesisState := setup(true, chainID, opts...)
genesisState = genesisStateWithValSet(t, migalooApp, genesisState, valSet, genAccs, balances...)

consensusParams := simtestutil.DefaultConsensusParams
consensusParams.Block.MaxGas = 100 * simtestutil.DefaultGenTxGas

stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)

if chainID == "" {
chainID = SimAppChainID
}

// init chain will set the validator set and initialize the genesis accounts
migalooApp.InitChain(
abci.RequestInitChain{
ChainId: SimAppChainID,
ChainId: chainID,
Validators: []abci.ValidatorUpdate{},
ConsensusParams: DefaultConsensusParams,
ConsensusParams: consensusParams,
AppStateBytes: stateBytes,
},
)

// commit genesis changes
migalooApp.Commit()
migalooApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{
ChainID: SimAppChainID,
ChainID: chainID,
Height: migalooApp.LastBlockHeight() + 1,
AppHash: migalooApp.LastCommitID().Hash,
ValidatorsHash: valSet.Hash(),
Expand All @@ -152,10 +160,10 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
return migalooApp
}

func setup(withGenesis bool, opts ...wasmkeeper.Option) (*MigalooApp, GenesisState) {
func setup(withGenesis bool, chainID string, opts ...wasmkeeper.Option) (*MigalooApp, GenesisState) {
db := dbm.NewMemDB()
migalooApp := NewMigalooApp(log.NewNopLogger(), db, nil, true, map[int64]bool{},
DefaultNodeHome, 5, MakeEncodingConfig(), EmptyBaseAppOptions{}, opts)
DefaultNodeHome, 5, MakeEncodingConfig(), EmptyBaseAppOptions{}, opts, baseapp.SetChainID(chainID))

if withGenesis {
return migalooApp, NewDefaultGenesisState()
Expand Down Expand Up @@ -206,31 +214,36 @@ func genesisStateWithValSet(t *testing.T,
defaultStParams.MaxValidators,
defaultStParams.MaxEntries,
defaultStParams.HistoricalEntries,
config.BaseDenom,
sdk.DefaultBondDenom,
defaultStParams.MinCommissionRate,
)

// set validators and delegations
stakingGenesis := stakingtypes.NewGenesisState(stParams, validators, delegations)
genesisState[stakingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(stakingGenesis)

totalSupply := sdk.NewCoins()
for _, b := range balances {
// add genesis acc tokens to total supply
totalSupply = totalSupply.Add(b.Coins...)
}

for range delegations {
// add delegated tokens to total supply
totalSupply = totalSupply.Add(sdk.NewCoin(config.BaseDenom, bondAmt))
signingInfos := make([]slashingtypes.SigningInfo, len(valSet.Validators))
for i, val := range valSet.Validators {
signingInfos[i] = slashingtypes.SigningInfo{
Address: sdk.ConsAddress(val.Address).String(),
ValidatorSigningInfo: slashingtypes.ValidatorSigningInfo{},
}
}
slashingGenesis := slashingtypes.NewGenesisState(slashingtypes.DefaultParams(), signingInfos, nil)
genesisState[slashingtypes.ModuleName] = app.AppCodec().MustMarshalJSON(slashingGenesis)

// add bonded amount to bonded pool module account
balances = append(balances, banktypes.Balance{
Address: authtypes.NewModuleAddress(stakingtypes.BondedPoolName).String(),
Coins: sdk.Coins{sdk.NewCoin(config.BaseDenom, bondAmt)},
Coins: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, bondAmt.MulRaw(int64(len(valSet.Validators))))},
})

totalSupply := sdk.NewCoins()
for _, b := range balances {
// add genesis acc tokens to total supply
totalSupply = totalSupply.Add(b.Coins...)
}

// update total supply
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply, []banktypes.Metadata{},
banktypes.DefaultGenesisState().SendEnabled)
Expand Down Expand Up @@ -386,13 +399,13 @@ func (s *KeeperTestHelper) AllocateRewardsToValidator(valAddr sdk.ValAddress, re
s.Require().True(found)

// allocate reward tokens to distribution module
coins := sdk.Coins{sdk.NewCoin(config.BaseDenom, rewardAmt)}
coins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, rewardAmt)}
err := banktestutil.FundModuleAccount(s.App.BankKeeper, s.Ctx, distrtypes.ModuleName, coins)
s.Require().NoError(err)

// allocate rewards to validator
s.Ctx = s.Ctx.WithBlockHeight(s.Ctx.BlockHeight() + 1)
decTokens := sdk.DecCoins{{Denom: config.BaseDenom, Amount: sdk.NewDec(20000)}}
decTokens := sdk.DecCoins{{Denom: sdk.DefaultBondDenom, Amount: sdk.NewDec(20000)}}
s.App.DistrKeeper.AllocateTokensToValidator(s.Ctx, validator, decTokens)
}

Expand Down
41 changes: 41 additions & 0 deletions app/test_support.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package app

import (
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"

"github.com/cosmos/cosmos-sdk/baseapp"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
)

func (app *MigalooApp) GetIBCKeeper() *ibckeeper.Keeper {
return app.IBCKeeper
}

func (app *MigalooApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper {
return app.ScopedIBCKeeper
}

func (app *MigalooApp) GetBaseApp() *baseapp.BaseApp {
return app.BaseApp
}

func (app *MigalooApp) GetBankKeeper() bankkeeper.Keeper {
return app.BankKeeper
}

func (app *MigalooApp) GetStakingKeeper() *stakingkeeper.Keeper {
return app.StakingKeeper
}

func (app *MigalooApp) GetAccountKeeper() authkeeper.AccountKeeper {
return app.AccountKeeper
}

func (app *MigalooApp) GetWasmKeeper() wasmkeeper.Keeper {
return app.WasmKeeper
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ require (

require (
cosmossdk.io/errors v1.0.1
github.com/CosmWasm/wasmvm v1.5.2
github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7 v7.1.3
github.com/cosmos/ibc-apps/modules/async-icq/v7 v7.1.1
github.com/golang/protobuf v1.5.4
Expand All @@ -68,7 +69,6 @@ require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.2 // indirect
github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect
github.com/CosmWasm/wasmvm v1.5.2 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go v1.44.203 // indirect
Expand Down
139 changes: 139 additions & 0 deletions tests/e2e/gov_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package e2e_test

import (
"testing"
"time"

"github.com/White-Whale-Defi-Platform/migaloo-chain/v4/tests/e2e"

wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"

"github.com/CosmWasm/wasmd/x/wasm/ibctesting"
"github.com/White-Whale-Defi-Platform/migaloo-chain/v4/app"
)

func TestGovVoteByContract(t *testing.T) {
// Given a contract with delegation
// And a gov proposal
// When the contract sends a vote for the proposal
// Then the vote is taken into account

coord := ibctesting.NewCoordinatorX(t, 1, e2e.DefaultMigalooAppFactory)
chain := coord.GetChain(ibctesting.GetChainID(1))
contractAddr := e2e.InstantiateReflectContract(t, chain)
chain.Fund(contractAddr, sdk.NewIntFromUint64(1_000_000_000))
// a contract with a high delegation amount
delegateMsg := wasmvmtypes.CosmosMsg{
Staking: &wasmvmtypes.StakingMsg{
Delegate: &wasmvmtypes.DelegateMsg{
Validator: sdk.ValAddress(chain.Vals.Validators[0].Address).String(),
Amount: wasmvmtypes.Coin{
Denom: sdk.DefaultBondDenom,
Amount: "1000000000",
},
},
},
}
e2e.MustExecViaReflectContract(t, chain, contractAddr, delegateMsg)

signer := chain.SenderAccount.GetAddress().String()
app := chain.App.(*app.MigalooApp)
govKeeper, accountKeeper := app.GovKeeper, app.AccountKeeper
communityPoolBalance := chain.Balance(accountKeeper.GetModuleAccount(chain.GetContext(), distributiontypes.ModuleName).GetAddress(), sdk.DefaultBondDenom)
require.False(t, communityPoolBalance.IsZero())

initialDeposit := govKeeper.GetParams(chain.GetContext()).MinDeposit
govAcctAddr := govKeeper.GetGovernanceAccount(chain.GetContext()).GetAddress()

specs := map[string]struct {
vote *wasmvmtypes.VoteMsg
expPass bool
}{
"yes": {
vote: &wasmvmtypes.VoteMsg{
Vote: wasmvmtypes.Yes,
},
expPass: true,
},
"no": {
vote: &wasmvmtypes.VoteMsg{
Vote: wasmvmtypes.No,
},
expPass: false,
},
"abstain": {
vote: &wasmvmtypes.VoteMsg{
Vote: wasmvmtypes.Abstain,
},
expPass: true,
},
"no with veto": {
vote: &wasmvmtypes.VoteMsg{
Vote: wasmvmtypes.NoWithVeto,
},
expPass: false,
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
// given a unique recipient
recipientAddr := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address().Bytes())
// and a new proposal
payloadMsg := &distributiontypes.MsgCommunityPoolSpend{
Authority: govAcctAddr.String(),
Recipient: recipientAddr.String(),
Amount: sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())),
}
msg, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{payloadMsg},
initialDeposit,
signer,
"",
"my proposal",
"testing",
)
require.NoError(t, err)
rsp, gotErr := chain.SendMsgs(msg)
require.NoError(t, gotErr)
require.Len(t, rsp.MsgResponses, 1)
got, ok := rsp.MsgResponses[0].GetCachedValue().(*v1.MsgSubmitProposalResponse)
require.True(t, ok)
propID := got.ProposalId

// with other delegators voted yes
_, err = chain.SendMsgs(v1.NewMsgVote(chain.SenderAccount.GetAddress(), propID, v1.VoteOption_VOTE_OPTION_YES, ""))
require.NoError(t, err)

// when contract votes
spec.vote.ProposalId = propID
voteMsg := wasmvmtypes.CosmosMsg{
Gov: &wasmvmtypes.GovMsg{
Vote: spec.vote,
},
}
e2e.MustExecViaReflectContract(t, chain, contractAddr, voteMsg)

// then proposal executed after voting period
proposal, ok := govKeeper.GetProposal(chain.GetContext(), propID)
require.True(t, ok)
coord.IncrementTimeBy(proposal.VotingEndTime.Sub(chain.GetContext().BlockTime()) + time.Minute)
coord.CommitBlock(chain)

// and recipient balance updated
recipientBalance := chain.Balance(recipientAddr, sdk.DefaultBondDenom)
if !spec.expPass {
assert.True(t, recipientBalance.IsZero())
return
}
expBalanceAmount := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())
assert.Equal(t, expBalanceAmount.String(), recipientBalance.String())
})
}
}
Loading

0 comments on commit 0af69ef

Please sign in to comment.