refactor(tests/integrations): Port gov integration tests with server v2 setup (#22850)

This commit is contained in:
son trinh 2024-12-13 15:13:18 +07:00 committed by GitHub
parent 570585090a
commit 957e241716
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 575 additions and 563 deletions

View File

@ -18,6 +18,7 @@ import (
"cosmossdk.io/core/branch"
"cosmossdk.io/core/comet"
"cosmossdk.io/core/event"
"cosmossdk.io/core/gas"
"cosmossdk.io/core/header"
"cosmossdk.io/core/registry"
"cosmossdk.io/core/router"
@ -214,6 +215,7 @@ func ProvideEnvironment(
kvService store.KVStoreService,
memKvService store.MemoryStoreService,
headerService header.Service,
gasService gas.Service,
eventService event.Service,
branchService branch.Service,
routerBuilder RouterServiceBuilder,
@ -222,7 +224,7 @@ func ProvideEnvironment(
Logger: logger,
BranchService: branchService,
EventService: eventService,
GasService: stf.NewGasMeterService(),
GasService: gasService,
HeaderService: headerService,
QueryRouterService: routerBuilder.BuildQueryRouter(),
MsgRouterService: routerBuilder.BuildMsgRouter([]byte(key.Name())),
@ -296,6 +298,7 @@ func DefaultServiceBindings() depinject.Config {
eventService = services.NewGenesisEventService(stf.NewEventService())
storeBuilder = root.NewBuilder()
branchService = stf.BranchService{}
gasService = stf.NewGasMeterService()
)
return depinject.Supply(
kvServiceFactory,
@ -305,5 +308,6 @@ func DefaultServiceBindings() depinject.Config {
eventService,
storeBuilder,
branchService,
gasService,
)
}

View File

@ -51,6 +51,7 @@ require (
cosmossdk.io/x/staking v0.0.0-20240226161501-23359a0b6d91
github.com/cometbft/cometbft/api v1.0.0-rc2
github.com/cosmos/cosmos-db v1.1.0
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.0
github.com/jhump/protoreflect v1.17.0
@ -126,7 +127,6 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect

View File

@ -1,126 +0,0 @@
package gov_test
import (
"bytes"
"log"
"sort"
"testing"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
"cosmossdk.io/depinject"
sdklog "cosmossdk.io/log"
"cosmossdk.io/math"
_ "cosmossdk.io/x/accounts"
_ "cosmossdk.io/x/bank"
_ "cosmossdk.io/x/consensus"
"cosmossdk.io/x/gov/types"
v1 "cosmossdk.io/x/gov/types/v1"
"cosmossdk.io/x/gov/types/v1beta1"
_ "cosmossdk.io/x/protocolpool"
_ "cosmossdk.io/x/staking"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/x/auth"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
valTokens = sdk.TokensFromConsensusPower(42, sdk.DefaultPowerReduction)
TestProposal = v1beta1.NewTextProposal("Test", "description")
TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z", &stakingtypes.Metadata{})
TestCommissionRates = stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec())
)
// mkTestLegacyContent creates a MsgExecLegacyContent for testing purposes.
func mkTestLegacyContent(t *testing.T) *v1.MsgExecLegacyContent {
t.Helper()
msgContent, err := v1.NewLegacyContent(TestProposal, authtypes.NewModuleAddress(types.ModuleName).String())
assert.NilError(t, err)
return msgContent
}
var pubkeys = []cryptotypes.PubKey{
ed25519.GenPrivKey().PubKey(),
ed25519.GenPrivKey().PubKey(),
ed25519.GenPrivKey().PubKey(),
}
// SortAddresses - Sorts Addresses
func SortAddresses(addrs []sdk.AccAddress) {
byteAddrs := make([][]byte, len(addrs))
for i, addr := range addrs {
byteAddrs[i] = addr.Bytes()
}
SortByteArrays(byteAddrs)
for i, byteAddr := range byteAddrs {
addrs[i] = byteAddr
}
}
// implement `Interface` in sort package.
type sortByteArrays [][]byte
func (b sortByteArrays) Len() int {
return len(b)
}
func (b sortByteArrays) Less(i, j int) bool {
// bytes package already implements Comparable for []byte.
switch bytes.Compare(b[i], b[j]) {
case -1:
return true
case 0, 1:
return false
default:
log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
return false
}
}
func (b sortByteArrays) Swap(i, j int) {
b[j], b[i] = b[i], b[j]
}
// SortByteArrays - sorts the provided byte array
func SortByteArrays(src [][]byte) [][]byte {
sorted := sortByteArrays(src)
sort.Sort(sorted)
return sorted
}
func createTestSuite(t *testing.T) suite {
t.Helper()
res := suite{}
app, err := simtestutil.SetupWithConfiguration(
depinject.Configs(
configurator.NewAppConfig(
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.GovModule(),
configurator.ConsensusModule(),
configurator.ProtocolPoolModule(),
),
depinject.Supply(sdklog.NewNopLogger()),
),
simtestutil.DefaultStartUpConfig(),
&res.AccountKeeper, &res.BankKeeper, &res.GovKeeper, &res.StakingKeeper,
)
require.NoError(t, err)
res.app = app
return res
}

View File

@ -1,180 +0,0 @@
package keeper_test
import (
"context"
"testing"
"go.uber.org/mock/gomock"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/bank"
bankkeeper "cosmossdk.io/x/bank/keeper"
banktypes "cosmossdk.io/x/bank/types"
"cosmossdk.io/x/consensus"
consensusparamkeeper "cosmossdk.io/x/consensus/keeper"
consensusparamtypes "cosmossdk.io/x/consensus/types"
"cosmossdk.io/x/gov"
"cosmossdk.io/x/gov/keeper"
"cosmossdk.io/x/gov/types"
v1 "cosmossdk.io/x/gov/types/v1"
"cosmossdk.io/x/gov/types/v1beta1"
minttypes "cosmossdk.io/x/mint/types"
poolkeeper "cosmossdk.io/x/protocolpool/keeper"
pooltypes "cosmossdk.io/x/protocolpool/types"
"cosmossdk.io/x/staking"
stakingkeeper "cosmossdk.io/x/staking/keeper"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/baseapp"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil/integration"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
type fixture struct {
ctx sdk.Context
queryClient v1.QueryClient
legacyQueryClient v1beta1.QueryClient
accountKeeper authkeeper.AccountKeeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
govKeeper *keeper.Keeper
}
func initFixture(tb testing.TB) *fixture {
tb.Helper()
keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, pooltypes.StoreKey, types.StoreKey, consensusparamtypes.StoreKey,
)
encodingCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}, gov.AppModule{})
cdc := encodingCfg.Codec
logger := log.NewTestLogger(tb)
authority := authtypes.NewModuleAddress(types.ModuleName)
maccPerms := map[string][]string{
pooltypes.ModuleName: {},
pooltypes.StreamAccount: {},
pooltypes.ProtocolPoolDistrAccount: {},
minttypes.ModuleName: {authtypes.Minter},
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
types.ModuleName: {authtypes.Burner},
}
// gomock initializations
ctrl := gomock.NewController(tb)
acctsModKeeper := authtestutil.NewMockAccountsModKeeper(ctrl)
accNum := uint64(0)
acctsModKeeper.EXPECT().NextAccountNumber(gomock.Any()).AnyTimes().DoAndReturn(func(ctx context.Context) (uint64, error) {
currentNum := accNum
accNum++
return currentNum, nil
})
accountKeeper := authkeeper.NewAccountKeeper(
runtime.NewEnvironment(runtime.NewKVStoreService(keys[authtypes.StoreKey]), log.NewNopLogger()),
cdc,
authtypes.ProtoBaseAccount,
acctsModKeeper,
maccPerms,
addresscodec.NewBech32Codec(sdk.Bech32MainPrefix),
sdk.Bech32MainPrefix,
authority.String(),
)
blockedAddresses := map[string]bool{
accountKeeper.GetAuthority(): false,
}
bankKeeper := bankkeeper.NewBaseKeeper(
runtime.NewEnvironment(runtime.NewKVStoreService(keys[banktypes.StoreKey]), log.NewNopLogger()),
cdc,
accountKeeper,
blockedAddresses,
authority.String(),
)
router := baseapp.NewMsgServiceRouter()
queryRouter := baseapp.NewGRPCQueryRouter()
consensusParamsKeeper := consensusparamkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), log.NewNopLogger(), runtime.EnvWithQueryRouterService(queryRouter), runtime.EnvWithMsgRouterService(router)), authtypes.NewModuleAddress("gov").String())
stakingKeeper := stakingkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), log.NewNopLogger()), accountKeeper, bankKeeper, consensusParamsKeeper, authority.String(), addresscodec.NewBech32Codec(sdk.Bech32PrefixValAddr), addresscodec.NewBech32Codec(sdk.Bech32PrefixConsAddr), runtime.NewContextAwareCometInfoService())
poolKeeper := poolkeeper.NewKeeper(cdc, runtime.NewEnvironment(runtime.NewKVStoreService(keys[pooltypes.StoreKey]), log.NewNopLogger()), accountKeeper, bankKeeper, authority.String())
// Create MsgServiceRouter, but don't populate it before creating the gov
// keeper.
router.SetInterfaceRegistry(cdc.InterfaceRegistry())
queryRouter.SetInterfaceRegistry(cdc.InterfaceRegistry())
govKeeper := keeper.NewKeeper(
cdc,
runtime.NewEnvironment(runtime.NewKVStoreService(keys[types.StoreKey]), log.NewNopLogger(), runtime.EnvWithQueryRouterService(queryRouter), runtime.EnvWithMsgRouterService(router)),
accountKeeper,
bankKeeper,
stakingKeeper,
poolKeeper,
keeper.DefaultConfig(),
authority.String(),
)
govRouter := v1beta1.NewRouter()
govRouter.AddRoute(types.RouterKey, v1beta1.ProposalHandler)
govKeeper.SetLegacyRouter(govRouter)
authModule := auth.NewAppModule(cdc, accountKeeper, acctsModKeeper, authsims.RandomGenesisAccounts, nil)
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper)
stakingModule := staking.NewAppModule(cdc, stakingKeeper)
govModule := gov.NewAppModule(cdc, govKeeper, accountKeeper, bankKeeper, poolKeeper)
consensusModule := consensus.NewAppModule(cdc, consensusParamsKeeper)
integrationApp := integration.NewIntegrationApp(logger, keys, cdc,
encodingCfg.InterfaceRegistry.SigningContext().AddressCodec(),
encodingCfg.InterfaceRegistry.SigningContext().ValidatorAddressCodec(),
map[string]appmodule.AppModule{
authtypes.ModuleName: authModule,
banktypes.ModuleName: bankModule,
stakingtypes.ModuleName: stakingModule,
types.ModuleName: govModule,
consensusparamtypes.ModuleName: consensusModule,
},
baseapp.NewMsgServiceRouter(),
baseapp.NewGRPCQueryRouter(),
)
sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context())
msgSrvr := keeper.NewMsgServerImpl(govKeeper)
legacyMsgSrvr := keeper.NewLegacyMsgServerImpl(authority.String(), msgSrvr)
// Register MsgServer and QueryServer
v1.RegisterMsgServer(router, msgSrvr)
v1beta1.RegisterMsgServer(router, legacyMsgSrvr)
v1.RegisterQueryServer(integrationApp.QueryHelper(), keeper.NewQueryServer(govKeeper))
v1beta1.RegisterQueryServer(integrationApp.QueryHelper(), keeper.NewLegacyQueryServer(govKeeper))
queryClient := v1.NewQueryClient(integrationApp.QueryHelper())
legacyQueryClient := v1beta1.NewQueryClient(integrationApp.QueryHelper())
return &fixture{
ctx: sdkCtx,
queryClient: queryClient,
legacyQueryClient: legacyQueryClient,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
stakingKeeper: stakingKeeper,
govKeeper: govKeeper,
}
}

View File

@ -1,43 +0,0 @@
package gov_test
import (
"testing"
"gotest.tools/v3/assert"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
_ "cosmossdk.io/x/accounts"
"cosmossdk.io/x/gov/types"
_ "cosmossdk.io/x/mint"
_ "cosmossdk.io/x/protocolpool"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
var accountKeeper authkeeper.AccountKeeper
app, err := simtestutil.SetupAtGenesis(
depinject.Configs(
configurator.NewAppConfig(
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.GovModule(),
configurator.ConsensusModule(),
configurator.ProtocolPoolModule(),
),
depinject.Supply(log.NewNopLogger()),
),
&accountKeeper,
)
assert.NilError(t, err)
ctx := app.BaseApp.NewContext(false)
acc := accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName))
assert.Assert(t, acc != nil)
}

View File

@ -17,6 +17,7 @@ import (
corebranch "cosmossdk.io/core/branch"
"cosmossdk.io/core/comet"
corecontext "cosmossdk.io/core/context"
"cosmossdk.io/core/gas"
"cosmossdk.io/core/header"
"cosmossdk.io/core/server"
corestore "cosmossdk.io/core/store"
@ -99,6 +100,8 @@ type StartupConfig struct {
RouterServiceBuilder runtime.RouterServiceBuilder
// HeaderService defines the custom header service to be used in the app.
HeaderService header.Service
GasService gas.Service
}
func DefaultStartUpConfig(t *testing.T) StartupConfig {
@ -129,6 +132,7 @@ func DefaultStartUpConfig(t *testing.T) StartupConfig {
stf.NewMsgRouterService, stf.NewQueryRouterService(),
),
HeaderService: services.NewGenesisHeaderService(stf.HeaderService{}),
GasService: stf.NewGasMeterService(),
}
}
@ -193,9 +197,11 @@ func NewApp(
startupConfig.BranchService,
startupConfig.RouterServiceBuilder,
startupConfig.HeaderService,
startupConfig.GasService,
),
depinject.Invoke(
std.RegisterInterfaces,
std.RegisterLegacyAminoCodec,
),
),
append(extraOutputs, &appBuilder, &cdc, &txConfigOptions, &txConfig, &storeBuilder)...); err != nil {
@ -336,7 +342,7 @@ func (a *App) Deliver(
require.NoError(t, err)
a.lastHeight++
// update block height if integration context is present
// update block height and block time if integration context is present
iCtx, ok := ctx.Value(contextKey).(*integrationContext)
if ok {
iCtx.header.Height = int64(a.lastHeight)

View File

@ -147,6 +147,12 @@ type genesisTxCodec struct {
tx.ConfigOptions
}
func NewGenesisTxCodec(txConfigOptions tx.ConfigOptions) *genesisTxCodec {
return &genesisTxCodec{
txConfigOptions,
}
}
// Decode implements transaction.Codec.
func (t *genesisTxCodec) Decode(bz []byte) (stateMachineTx, error) {
var out stateMachineTx

View File

@ -1,6 +1,7 @@
package gov_test
package gov
import (
"context"
"testing"
"time"
@ -16,20 +17,21 @@ import (
stakingtypes "cosmossdk.io/x/staking/types"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestUnregisteredProposal_InactiveProposalFails(t *testing.T) {
suite := createTestSuite(t)
ctx := suite.app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
addr0Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[0])
addr0Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[0])
require.NoError(t, err)
// manually set proposal in store
startTime, endTime := time.Now().Add(-4*time.Hour), ctx.BlockHeader().Time
startTime, endTime := time.Now().Add(-4*time.Hour), time.Now()
proposal, err := v1.NewProposal([]sdk.Msg{
&v1.Proposal{}, // invalid proposal message
}, 1, startTime, startTime, "", "Unsupported proposal", "Unsupported proposal", addr0Str, v1.ProposalType_PROPOSAL_TYPE_STANDARD)
@ -50,13 +52,14 @@ func TestUnregisteredProposal_InactiveProposalFails(t *testing.T) {
}
func TestUnregisteredProposal_ActiveProposalFails(t *testing.T) {
suite := createTestSuite(t)
ctx := suite.app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
addr0Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[0])
addr0Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[0])
require.NoError(t, err)
// manually set proposal in store
startTime, endTime := time.Now().Add(-4*time.Hour), ctx.BlockHeader().Time
header := integration.HeaderInfoFromContext(ctx)
startTime, endTime := time.Now().Add(-4*time.Hour), header.Time
proposal, err := v1.NewProposal([]sdk.Msg{
&v1.Proposal{}, // invalid proposal message
}, 1, startTime, startTime, "", "Unsupported proposal", "Unsupported proposal", addr0Str, v1.ProposalType_PROPOSAL_TYPE_STANDARD)
@ -80,9 +83,8 @@ func TestUnregisteredProposal_ActiveProposalFails(t *testing.T) {
}
func TestTickExpiredDepositPeriod(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
@ -102,23 +104,22 @@ func TestTickExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res)
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(1) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
params, _ := suite.GovKeeper.Params.Get(ctx)
newHeader = ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader = integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
err = suite.GovKeeper.EndBlocker(ctx)
require.NoError(t, err)
}
func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
@ -137,9 +138,9 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res)
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(2) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(2) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
newProposalMsg2, err := v1.NewMsgSubmitProposal(
[]sdk.Msg{mkTestLegacyContent(t)},
@ -156,23 +157,22 @@ func TestTickMultipleExpiredDepositPeriod(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res)
newHeader = ctx.HeaderInfo()
newHeader = integration.HeaderInfoFromContext(ctx)
params, _ := suite.GovKeeper.Params.Get(ctx)
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(time.Duration(-1) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
require.NoError(t, suite.GovKeeper.EndBlocker(ctx))
newHeader = ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(5) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader = integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(5) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
require.NoError(t, suite.GovKeeper.EndBlocker(ctx))
}
func TestTickPassedDepositPeriod(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
@ -193,11 +193,11 @@ func TestTickPassedDepositPeriod(t *testing.T) {
proposalID := res.ProposalId
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(1) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
addr1Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[1])
addr1Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[1])
require.NoError(t, err)
newDepositMsg := v1.NewMsgDeposit(addr1Str, proposalID, sdk.Coins{sdk.NewInt64Coin(sdk.DefaultBondDenom, 100000)})
@ -207,9 +207,8 @@ func TestTickPassedDepositPeriod(t *testing.T) {
}
func TestProposalDepositRefundFailEndBlocker(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens)
govMsgSvr := keeper.NewMsgServerImpl(suite.GovKeeper)
@ -246,15 +245,15 @@ func TestProposalDepositRefundFailEndBlocker(t *testing.T) {
require.NoError(t, err)
// fast forward to the end of the voting period
newHeader := ctx.HeaderInfo()
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = proposal.VotingEndTime.Add(time.Duration(100) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
ctx = integration.SetHeaderInfo(ctx, newHeader)
err = suite.GovKeeper.EndBlocker(ctx)
require.NoError(t, err) // no error, means does not halt the chain
events := ctx.EventManager().Events()
attr, ok := events.GetAttributes(types.AttributeKeyProposalDepositError)
events := integration.EventsFromContext(ctx)
attr, ok := integration.GetAttributes(events, types.AttributeKeyProposalDepositError)
require.True(t, ok)
require.Contains(t, attr[0].Value, "failed to refund or burn deposits")
}
@ -275,9 +274,8 @@ func TestTickPassedVotingPeriod(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
depositMultiplier := getDepositMultiplier(tc.proposalType)
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens.Mul(math.NewInt(depositMultiplier)))
@ -294,11 +292,11 @@ func TestTickPassedVotingPeriod(t *testing.T) {
proposalID := res.ProposalId
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(1) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
addr1Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[1])
addr1Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[1])
require.NoError(t, err)
newDepositMsg := v1.NewMsgDeposit(addr1Str, proposalID, proposalCoins)
@ -312,9 +310,9 @@ func TestTickPassedVotingPeriod(t *testing.T) {
votingPeriod = params.ExpeditedVotingPeriod
}
newHeader = ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(*votingPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader = integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(*votingPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
proposal, err := suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.NoError(t, err)
@ -354,9 +352,8 @@ func TestProposalPassedEndblocker(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
depositMultiplier := getDepositMultiplier(tc.proposalType)
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 10, valTokens.Mul(math.NewInt(depositMultiplier)))
@ -366,8 +363,8 @@ func TestProposalPassedEndblocker(t *testing.T) {
stakingMsgSvr := stakingkeeper.NewMsgServerImpl(suite.StakingKeeper)
valAddr := sdk.ValAddress(addrs[0])
proposer := addrs[0]
acc := suite.AccountKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AccountKeeper.SetAccount(ctx, acc)
acc := suite.AuthKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AuthKeeper.SetAccount(ctx, acc)
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
_, err := suite.StakingKeeper.EndBlocker(ctx)
@ -380,7 +377,7 @@ func TestProposalPassedEndblocker(t *testing.T) {
require.NoError(t, err)
proposalCoins := sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, suite.StakingKeeper.TokensFromConsensusPower(ctx, 10*depositMultiplier))}
addr0Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[0])
addr0Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[0])
require.NoError(t, err)
newDepositMsg := v1.NewMsgDeposit(addr0Str, proposal.Id, proposalCoins)
@ -398,10 +395,10 @@ func TestProposalPassedEndblocker(t *testing.T) {
err = suite.GovKeeper.AddVote(ctx, proposal.Id, addrs[0], v1.NewNonSplitVoteOption(v1.OptionYes), "")
require.NoError(t, err)
newHeader := ctx.HeaderInfo()
newHeader := integration.HeaderInfoFromContext(ctx)
params, _ := suite.GovKeeper.Params.Get(ctx)
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
err = suite.GovKeeper.EndBlocker(ctx)
require.NoError(t, err)
@ -413,9 +410,8 @@ func TestProposalPassedEndblocker(t *testing.T) {
}
func TestEndBlockerProposalHandlerFailed(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 1, valTokens)
SortAddresses(addrs)
@ -431,8 +427,8 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
toAddrStr, err := ac.BytesToString(addrs[0])
require.NoError(t, err)
acc := suite.AccountKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AccountKeeper.SetAccount(ctx, acc)
acc := suite.AuthKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AuthKeeper.SetAccount(ctx, acc)
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
_, err = suite.StakingKeeper.EndBlocker(ctx)
@ -442,7 +438,7 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
require.NoError(t, err)
proposalCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, suite.StakingKeeper.TokensFromConsensusPower(ctx, 10)))
addr0Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[0])
addr0Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[0])
require.NoError(t, err)
newDepositMsg := v1.NewMsgDeposit(addr0Str, proposal.Id, proposalCoins)
@ -455,16 +451,16 @@ func TestEndBlockerProposalHandlerFailed(t *testing.T) {
require.NoError(t, err)
params, _ := suite.GovKeeper.Params.Get(ctx)
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
// validate that the proposal fails/has been rejected
err = suite.GovKeeper.EndBlocker(ctx)
require.NoError(t, err)
// check proposal events
events := ctx.EventManager().Events()
attr, eventOk := events.GetAttributes(types.AttributeKeyProposalLog)
events := integration.EventsFromContext(ctx)
attr, eventOk := integration.GetAttributes(events, types.AttributeKeyProposalLog)
require.True(t, eventOk)
require.Contains(t, attr[0].Value, "failed on execution")
@ -499,9 +495,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
depositMultiplier := getDepositMultiplier(v1.ProposalType_PROPOSAL_TYPE_EXPEDITED)
addrs := simtestutil.AddTestAddrs(suite.BankKeeper, suite.StakingKeeper, ctx, 3, valTokens.Mul(math.NewInt(depositMultiplier)))
params, err := suite.GovKeeper.Params.Get(ctx)
@ -514,8 +509,8 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
valAddr := sdk.ValAddress(addrs[0])
proposer := addrs[0]
acc := suite.AccountKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AccountKeeper.SetAccount(ctx, acc)
acc := suite.AuthKeeper.NewAccountWithAddress(ctx, addrs[0])
suite.AuthKeeper.SetAccount(ctx, acc)
// Create a validator so that able to vote on proposal.
createValidators(t, stakingMsgSvr, ctx, []sdk.ValAddress{valAddr}, []int64{10})
_, err = suite.StakingKeeper.EndBlocker(ctx)
@ -538,11 +533,11 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
proposalID := res.ProposalId
newHeader := ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(time.Duration(1) * time.Second)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader := integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(time.Duration(1) * time.Second)
ctx = integration.SetHeaderInfo(ctx, newHeader)
addr1Str, err := suite.AccountKeeper.AddressCodec().BytesToString(addrs[1])
addr1Str, err := suite.AuthKeeper.AddressCodec().BytesToString(addrs[1])
require.NoError(t, err)
newDepositMsg := v1.NewMsgDeposit(addr1Str, proposalID, proposalCoins)
@ -550,9 +545,9 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, res1)
newHeader = ctx.HeaderInfo()
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(*params.ExpeditedVotingPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader = integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(*params.ExpeditedVotingPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
proposal, err := suite.GovKeeper.Proposals.Get(ctx, res.ProposalId)
require.Nil(t, err)
@ -604,8 +599,9 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
require.Equal(t, expectedIntermediateMofuleAccCoings, intermediateModuleAccCoins)
// block header time at the voting period
newHeader.Time = ctx.HeaderInfo().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = ctx.WithHeaderInfo(newHeader)
newHeader = integration.HeaderInfoFromContext(ctx)
newHeader.Time = newHeader.Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)
ctx = integration.SetHeaderInfo(ctx, newHeader)
if tc.regularEventuallyPassing {
// Validator votes YES, letting the converted regular proposal pass.
@ -646,7 +642,7 @@ func TestExpeditedProposal_PassAndConversionToRegular(t *testing.T) {
}
}
func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx sdk.Context, addrs []sdk.ValAddress, powerAmt []int64) {
func createValidators(t *testing.T, stakingMsgSvr stakingtypes.MsgServer, ctx context.Context, addrs []sdk.ValAddress, powerAmt []int64) {
t.Helper()
require.True(t, len(addrs) <= len(pubkeys), "Not enough pubkeys specified at top of file.")

View File

@ -0,0 +1,207 @@
package gov
import (
"bytes"
"context"
"log"
"sort"
"testing"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
"cosmossdk.io/core/router"
"cosmossdk.io/core/transaction"
"cosmossdk.io/depinject"
sdklog "cosmossdk.io/log"
"cosmossdk.io/math"
"cosmossdk.io/runtime/v2"
_ "cosmossdk.io/x/accounts"
_ "cosmossdk.io/x/bank"
bankkeeper "cosmossdk.io/x/bank/keeper"
banktypes "cosmossdk.io/x/bank/types"
_ "cosmossdk.io/x/consensus"
_ "cosmossdk.io/x/gov"
"cosmossdk.io/x/gov/keeper"
"cosmossdk.io/x/gov/types"
v1 "cosmossdk.io/x/gov/types/v1"
"cosmossdk.io/x/gov/types/v1beta1"
_ "cosmossdk.io/x/mint"
_ "cosmossdk.io/x/protocolpool"
_ "cosmossdk.io/x/staking"
stakingkeeper "cosmossdk.io/x/staking/keeper"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
sdk "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var (
valTokens = sdk.TokensFromConsensusPower(42, sdk.DefaultPowerReduction)
TestProposal = v1beta1.NewTextProposal("Test", "description")
TestDescription = stakingtypes.NewDescription("T", "E", "S", "T", "Z", &stakingtypes.Metadata{})
TestCommissionRates = stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec())
)
// mkTestLegacyContent creates a MsgExecLegacyContent for testing purposes.
func mkTestLegacyContent(t *testing.T) *v1.MsgExecLegacyContent {
t.Helper()
msgContent, err := v1.NewLegacyContent(TestProposal, authtypes.NewModuleAddress(types.ModuleName).String())
assert.NilError(t, err)
return msgContent
}
var pubkeys = []cryptotypes.PubKey{
ed25519.GenPrivKey().PubKey(),
ed25519.GenPrivKey().PubKey(),
ed25519.GenPrivKey().PubKey(),
}
// SortAddresses - Sorts Addresses
func SortAddresses(addrs []sdk.AccAddress) {
byteAddrs := make([][]byte, len(addrs))
for i, addr := range addrs {
byteAddrs[i] = addr.Bytes()
}
SortByteArrays(byteAddrs)
for i, byteAddr := range byteAddrs {
addrs[i] = byteAddr
}
}
// implement `Interface` in sort package.
type sortByteArrays [][]byte
func (b sortByteArrays) Len() int {
return len(b)
}
func (b sortByteArrays) Less(i, j int) bool {
// bytes package already implements Comparable for []byte.
switch bytes.Compare(b[i], b[j]) {
case -1:
return true
case 0, 1:
return false
default:
log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
return false
}
}
func (b sortByteArrays) Swap(i, j int) {
b[j], b[i] = b[i], b[j]
}
// SortByteArrays - sorts the provided byte array
func SortByteArrays(src [][]byte) [][]byte {
sorted := sortByteArrays(src)
sort.Sort(sorted)
return sorted
}
type suite struct {
cdc codec.Codec
app *integration.App
ctx context.Context
AuthKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
GovKeeper *keeper.Keeper
StakingKeeper *stakingkeeper.Keeper
txConfigOptions tx.ConfigOptions
}
func createTestSuite(t *testing.T, genesisBehavior int) suite {
t.Helper()
res := suite{}
moduleConfigs := []configurator.ModuleOption{
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.TxModule(),
configurator.BankModule(),
configurator.GovModule(),
configurator.MintModule(),
configurator.ConsensusModule(),
configurator.ProtocolPoolModule(),
}
startupCfg := integration.DefaultStartUpConfig(t)
msgRouterService := integration.NewRouterService()
res.registerMsgRouterService(msgRouterService)
var routerFactory runtime.RouterServiceFactory = func(_ []byte) router.Service {
return msgRouterService
}
queryRouterService := integration.NewRouterService()
res.registerQueryRouterService(queryRouterService)
serviceBuilder := runtime.NewRouterBuilder(routerFactory, queryRouterService)
startupCfg.BranchService = &integration.BranchService{}
startupCfg.RouterServiceBuilder = serviceBuilder
startupCfg.HeaderService = &integration.HeaderService{}
startupCfg.GasService = &integration.GasService{}
startupCfg.GenesisBehavior = genesisBehavior
app, err := integration.NewApp(
depinject.Configs(configurator.NewAppV2Config(moduleConfigs...), depinject.Supply(sdklog.NewNopLogger())),
startupCfg,
&res.AuthKeeper, &res.BankKeeper, &res.GovKeeper, &res.StakingKeeper, &res.cdc, &res.txConfigOptions,
)
require.NoError(t, err)
res.ctx = app.StateLatestContext(t)
res.app = app
return res
}
func (s *suite) registerMsgRouterService(router *integration.RouterService) {
// register custom router service
bankSendHandler := func(ctx context.Context, req transaction.Msg) (transaction.Msg, error) {
msg, ok := req.(*banktypes.MsgSend)
if !ok {
return nil, integration.ErrInvalidMsgType
}
msgServer := bankkeeper.NewMsgServerImpl(s.BankKeeper)
resp, err := msgServer.Send(ctx, msg)
return resp, err
}
router.RegisterHandler(bankSendHandler, "/cosmos.bank.v1beta1.MsgSend")
// register custom router service
govSubmitProposalHandler := func(ctx context.Context, req transaction.Msg) (transaction.Msg, error) {
msg, ok := req.(*v1.MsgExecLegacyContent)
if !ok {
return nil, integration.ErrInvalidMsgType
}
msgServer := keeper.NewMsgServerImpl(s.GovKeeper)
resp, err := msgServer.ExecLegacyContent(ctx, msg)
return resp, err
}
router.RegisterHandler(govSubmitProposalHandler, "/cosmos.gov.v1.MsgExecLegacyContent")
}
func (f *suite) registerQueryRouterService(router *integration.RouterService) {
}

View File

@ -1,86 +1,43 @@
package gov_test
package gov
import (
"crypto/sha256"
"encoding/json"
"testing"
"time"
abci "github.com/cometbft/cometbft/api/cometbft/abci/v1"
"github.com/stretchr/testify/require"
"gotest.tools/v3/assert"
"cosmossdk.io/core/header"
corestore "cosmossdk.io/core/store"
coretesting "cosmossdk.io/core/testing"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/core/server"
"cosmossdk.io/core/transaction"
sdkmath "cosmossdk.io/math"
_ "cosmossdk.io/x/accounts"
_ "cosmossdk.io/x/bank"
bankkeeper "cosmossdk.io/x/bank/keeper"
banktypes "cosmossdk.io/x/bank/types"
_ "cosmossdk.io/x/consensus"
"cosmossdk.io/x/gov"
"cosmossdk.io/x/gov/keeper"
"cosmossdk.io/x/gov/types"
v1 "cosmossdk.io/x/gov/types/v1"
_ "cosmossdk.io/x/staking"
stakingkeeper "cosmossdk.io/x/staking/keeper"
stakingtypes "cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
type suite struct {
cdc codec.Codec
app *runtime.App
AccountKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
GovKeeper *keeper.Keeper
StakingKeeper *stakingkeeper.Keeper
appBuilder *runtime.AppBuilder
}
var appConfig = configurator.NewAppConfig(
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.GovModule(),
configurator.MintModule(),
configurator.ConsensusModule(),
configurator.ProtocolPoolModule(),
)
func TestImportExportQueues(t *testing.T) {
var err error
s1 := suite{}
s1.app, err = simtestutil.SetupWithConfiguration(
depinject.Configs(
appConfig,
depinject.Supply(log.NewNopLogger()),
),
simtestutil.DefaultStartUpConfig(),
&s1.AccountKeeper, &s1.BankKeeper, &s1.GovKeeper, &s1.StakingKeeper, &s1.cdc, &s1.appBuilder,
)
assert.NilError(t, err)
s1 := createTestSuite(t, integration.Genesis_COMMIT)
ctx := s1.ctx
ctx := s1.app.BaseApp.NewContext(false)
addrs := simtestutil.AddTestAddrs(s1.BankKeeper, s1.StakingKeeper, ctx, 1, valTokens)
_, err = s1.app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: s1.app.LastBlockHeight() + 1,
})
assert.NilError(t, err)
ctx = s1.app.BaseApp.NewContext(false)
// Create two proposals, put the second into the voting period
proposal1, err := s1.GovKeeper.SubmitProposal(ctx, []sdk.Msg{mkTestLegacyContent(t)}, "", "test", "description", addrs[0], v1.ProposalType_PROPOSAL_TYPE_STANDARD)
assert.NilError(t, err)
@ -103,7 +60,7 @@ func TestImportExportQueues(t *testing.T) {
assert.Assert(t, proposal1.Status == v1.StatusDepositPeriod)
assert.Assert(t, proposal2.Status == v1.StatusVotingPeriod)
authGenState, err := s1.AccountKeeper.ExportGenesis(ctx)
authGenState, err := s1.AuthKeeper.ExportGenesis(ctx)
require.NoError(t, err)
bankGenState, err := s1.BankKeeper.ExportGenesis(ctx)
require.NoError(t, err)
@ -111,8 +68,10 @@ func TestImportExportQueues(t *testing.T) {
require.NoError(t, err)
// export the state and import it into a new app
govGenState, _ := gov.ExportGenesis(ctx, s1.GovKeeper)
genesisState := s1.appBuilder.DefaultGenesis()
govGenState, err := gov.ExportGenesis(ctx, s1.GovKeeper)
require.NoError(t, err)
genesisState := s1.app.DefaultGenesis()
genesisState[authtypes.ModuleName] = s1.cdc.MustMarshalJSON(authGenState)
genesisState[banktypes.ModuleName] = s1.cdc.MustMarshalJSON(bankGenState)
@ -122,49 +81,34 @@ func TestImportExportQueues(t *testing.T) {
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
assert.NilError(t, err)
s2 := suite{}
db := coretesting.NewMemDB()
conf2 := simtestutil.DefaultStartUpConfig()
conf2.DB = db
s2.app, err = simtestutil.SetupWithConfiguration(
depinject.Configs(
appConfig,
depinject.Supply(log.NewNopLogger()),
),
conf2,
&s2.AccountKeeper, &s2.BankKeeper, &s2.GovKeeper, &s2.StakingKeeper, &s2.cdc, &s2.appBuilder,
)
assert.NilError(t, err)
s2 := createTestSuite(t, integration.Genesis_SKIP)
clearDB(t, db)
err = s2.app.CommitMultiStore().LoadLatestVersion()
assert.NilError(t, err)
_, err = s2.app.InitChain(
&abci.InitChainRequest{
Validators: []abci.ValidatorUpdate{},
ConsensusParams: simtestutil.DefaultConsensusParams,
AppStateBytes: stateBytes,
emptyHash := sha256.Sum256(nil)
_, newstate, err := s2.app.InitGenesis(
ctx,
&server.BlockRequest[transaction.Tx]{
Height: 1,
Time: time.Now(),
Hash: emptyHash[:],
ChainId: "test-chain",
AppHash: emptyHash[:],
IsGenesis: true,
},
stateBytes,
integration.NewGenesisTxCodec(s2.txConfigOptions),
)
assert.NilError(t, err)
_, err = s2.app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: s2.app.LastBlockHeight() + 1,
})
_, err = s2.app.Commit(newstate)
assert.NilError(t, err)
_, err = s2.app.FinalizeBlock(&abci.FinalizeBlockRequest{
Height: s2.app.LastBlockHeight() + 1,
})
assert.NilError(t, err)
ctx2 := s2.app.BaseApp.NewContext(false)
ctx2 := s2.app.StateLatestContext(t)
params, err = s2.GovKeeper.Params.Get(ctx2)
assert.NilError(t, err)
// Jump the time forward past the DepositPeriod and VotingPeriod
ctx2 = ctx2.WithHeaderInfo(header.Info{Time: ctx2.BlockHeader().Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)})
h := integration.HeaderInfoFromContext(ctx2)
ctx2 = integration.SetHeaderInfo(ctx2, header.Info{Time: h.Time.Add(*params.MaxDepositPeriod).Add(*params.VotingPeriod)})
// Make sure that they are still in the DepositPeriod and VotingPeriod respectively
proposal1, err = s2.GovKeeper.Proposals.Get(ctx2, proposalID1)
@ -189,29 +133,12 @@ func TestImportExportQueues(t *testing.T) {
assert.Assert(t, proposal2.Status == v1.StatusRejected)
}
func clearDB(t *testing.T, db corestore.KVStoreWithBatch) {
t.Helper()
iter, err := db.Iterator(nil, nil)
assert.NilError(t, err)
defer iter.Close()
var keys [][]byte
for ; iter.Valid(); iter.Next() {
keys = append(keys, iter.Key())
}
for _, k := range keys {
assert.NilError(t, db.Delete(k))
}
}
func TestImportExportQueues_ErrorUnconsistentState(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.NewContext(false)
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
params := v1.DefaultParams()
err := gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, &v1.GenesisState{
err := gov.InitGenesis(ctx, suite.AuthKeeper, suite.BankKeeper, suite.GovKeeper, &v1.GenesisState{
Deposits: v1.Deposits{
{
ProposalId: 1234,
@ -227,7 +154,7 @@ func TestImportExportQueues_ErrorUnconsistentState(t *testing.T) {
Params: &params,
})
require.Error(t, err)
err = gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState())
err = gov.InitGenesis(ctx, suite.AuthKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState())
require.NoError(t, err)
genState, err := gov.ExportGenesis(ctx, suite.GovKeeper)
require.NoError(t, err)

View File

@ -1,4 +1,4 @@
package keeper_test
package keeper
import (
"testing"
@ -59,7 +59,7 @@ func createValidators(t *testing.T, f *fixture, powers []int64) ([]sdk.AccAddres
assert.NilError(t, f.stakingKeeper.SetNewValidatorByPowerIndex(f.ctx, val3))
for _, addr := range addrs {
f.accountKeeper.SetAccount(f.ctx, f.accountKeeper.NewAccountWithAddress(f.ctx, addr))
f.authKeeper.SetAccount(f.ctx, f.authKeeper.NewAccountWithAddress(f.ctx, addr))
}
_, _ = f.stakingKeeper.Delegate(f.ctx, addrs[0], f.stakingKeeper.TokensFromConsensusPower(f.ctx, powers[0]), stakingtypes.Unbonded, val1, true)

View File

@ -0,0 +1,109 @@
package keeper
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"cosmossdk.io/core/router"
"cosmossdk.io/core/transaction"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/runtime/v2"
_ "cosmossdk.io/x/accounts"
_ "cosmossdk.io/x/bank"
bankkeeper "cosmossdk.io/x/bank/keeper"
_ "cosmossdk.io/x/consensus"
_ "cosmossdk.io/x/gov"
govkeeper "cosmossdk.io/x/gov/keeper"
v1 "cosmossdk.io/x/gov/types/v1"
"cosmossdk.io/x/gov/types/v1beta1"
_ "cosmossdk.io/x/protocolpool"
_ "cosmossdk.io/x/staking"
stakingkeeper "cosmossdk.io/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
_ "github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
)
type fixture struct {
ctx context.Context
app *integration.App
queryServer v1.QueryServer
legacyQueryServer v1beta1.QueryServer
authKeeper authkeeper.AccountKeeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
govKeeper *govkeeper.Keeper
}
func initFixture(t *testing.T) *fixture {
t.Helper()
res := fixture{}
moduleConfigs := []configurator.ModuleOption{
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.StakingModule(),
configurator.BankModule(),
configurator.TxModule(),
configurator.GovModule(),
configurator.ConsensusModule(),
configurator.ProtocolPoolModule(),
}
startupCfg := integration.DefaultStartUpConfig(t)
msgRouterService := integration.NewRouterService()
res.registerMsgRouterService(msgRouterService)
var routerFactory runtime.RouterServiceFactory = func(_ []byte) router.Service {
return msgRouterService
}
queryRouterService := integration.NewRouterService()
res.registerQueryRouterService(queryRouterService)
serviceBuilder := runtime.NewRouterBuilder(routerFactory, queryRouterService)
startupCfg.BranchService = &integration.BranchService{}
startupCfg.RouterServiceBuilder = serviceBuilder
startupCfg.HeaderService = &integration.HeaderService{}
app, err := integration.NewApp(
depinject.Configs(configurator.NewAppV2Config(moduleConfigs...), depinject.Supply(log.NewNopLogger())),
startupCfg,
&res.authKeeper, &res.bankKeeper, &res.govKeeper, &res.stakingKeeper)
require.NoError(t, err)
res.app = app
res.ctx = app.StateLatestContext(t)
res.queryServer = govkeeper.NewQueryServer(res.govKeeper)
res.legacyQueryServer = govkeeper.NewLegacyQueryServer(res.govKeeper)
return &res
}
func (f *fixture) registerMsgRouterService(router *integration.RouterService) {
// register custom router service
govSubmitProposalHandler := func(ctx context.Context, req transaction.Msg) (transaction.Msg, error) {
msg, ok := req.(*v1.MsgExecLegacyContent)
if !ok {
return nil, integration.ErrInvalidMsgType
}
msgServer := govkeeper.NewMsgServerImpl(f.govKeeper)
resp, err := msgServer.ExecLegacyContent(ctx, msg)
return resp, err
}
router.RegisterHandler(govSubmitProposalHandler, "/cosmos.gov.v1.MsgExecLegacyContent")
}
func (f *fixture) registerQueryRouterService(router *integration.RouterService) {
}

View File

@ -1,7 +1,6 @@
package keeper_test
package keeper
import (
gocontext "context"
"fmt"
"testing"
@ -16,7 +15,7 @@ func TestLegacyGRPCQueryTally(t *testing.T) {
t.Parallel()
f := initFixture(t)
ctx, queryClient := f.ctx, f.legacyQueryClient
ctx, queryServer := f.ctx, f.legacyQueryServer
addrs, _ := createValidators(t, f, []int64{5, 5, 5})
var (
@ -62,7 +61,7 @@ func TestLegacyGRPCQueryTally(t *testing.T) {
t.Run(fmt.Sprintf("Case %s", testCase.msg), func(t *testing.T) {
testCase.malleate()
tally, err := queryClient.TallyResult(gocontext.Background(), req)
tally, err := queryServer.TallyResult(f.ctx, req)
if testCase.expPass {
assert.NilError(t, err)

View File

@ -1,4 +1,4 @@
package keeper_test
package keeper
import (
"testing"
@ -6,6 +6,7 @@ import (
"gotest.tools/v3/assert"
"cosmossdk.io/math"
_ "cosmossdk.io/x/gov"
v1 "cosmossdk.io/x/gov/types/v1"
stakingtypes "cosmossdk.io/x/staking/types"

View File

@ -0,0 +1,23 @@
package gov
import (
"testing"
"gotest.tools/v3/assert"
_ "cosmossdk.io/x/accounts"
"cosmossdk.io/x/gov/types"
_ "cosmossdk.io/x/mint"
_ "cosmossdk.io/x/protocolpool"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
suite := createTestSuite(t, integration.Genesis_COMMIT)
ctx := suite.ctx
acc := suite.AuthKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName))
assert.Assert(t, acc != nil)
}

View File

@ -1,10 +1,13 @@
package integration
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/cosmos/gogoproto/jsonpb"
gogoproto "github.com/cosmos/gogoproto/proto"
"cosmossdk.io/core/branch"
@ -17,6 +20,7 @@ import (
"cosmossdk.io/core/server"
corestore "cosmossdk.io/core/store"
"cosmossdk.io/core/transaction"
"cosmossdk.io/server/v2/stf"
stfgas "cosmossdk.io/server/v2/stf/gas"
)
@ -72,6 +76,7 @@ type integrationContext struct {
state corestore.WriterMap
gasMeter gas.Meter
header header.Info
events []event.Event
}
func SetHeaderInfo(ctx context.Context, h header.Info) context.Context {
@ -95,6 +100,31 @@ func SetCometInfo(ctx context.Context, c comet.Info) context.Context {
return context.WithValue(ctx, corecontext.CometInfoKey, c)
}
func EventsFromContext(ctx context.Context) []event.Event {
iCtx, ok := ctx.Value(contextKey).(*integrationContext)
if !ok {
return nil
}
return iCtx.events
}
func GetAttributes(e []event.Event, key string) ([]event.Attribute, bool) {
attrs := make([]event.Attribute, 0)
for _, event := range e {
attributes, err := event.Attributes()
if err != nil {
return nil, false
}
for _, attr := range attributes {
if attr.Key == key {
attrs = append(attrs, attr)
}
}
}
return attrs, len(attrs) > 0
}
func GasMeterFromContext(ctx context.Context) gas.Meter {
iCtx, ok := ctx.Value(contextKey).(*integrationContext)
if !ok {
@ -130,22 +160,63 @@ var (
_ event.Manager = &eventManager{}
)
type eventService struct{}
// EventManager implements event.Service.
func (e *eventService) EventManager(context.Context) event.Manager {
return &eventManager{}
type eventService struct {
}
type eventManager struct{}
// EventManager implements event.Service.
func (e *eventService) EventManager(ctx context.Context) event.Manager {
iCtx, ok := ctx.Value(contextKey).(*integrationContext)
if !ok {
panic("context is not an integration context")
}
return &eventManager{ctx: iCtx}
}
type eventManager struct {
ctx *integrationContext
}
// Emit implements event.Manager.
func (e *eventManager) Emit(event transaction.Msg) error {
func (e *eventManager) Emit(tev transaction.Msg) error {
ev := event.Event{
Type: gogoproto.MessageName(tev),
Attributes: func() ([]event.Attribute, error) {
outerEvent, err := stf.TypedEventToEvent(tev)
if err != nil {
return nil, err
}
return outerEvent.Attributes()
},
Data: func() (json.RawMessage, error) {
buf := new(bytes.Buffer)
jm := &jsonpb.Marshaler{OrigName: true, EmitDefaults: true, AnyResolver: nil}
if err := jm.Marshal(buf, tev); err != nil {
return nil, err
}
return buf.Bytes(), nil
},
}
e.ctx.events = append(e.ctx.events, ev)
return nil
}
// EmitKV implements event.Manager.
func (e *eventManager) EmitKV(eventType string, attrs ...event.Attribute) error {
ev := event.Event{
Type: eventType,
Attributes: func() ([]event.Attribute, error) {
return attrs, nil
},
Data: func() (json.RawMessage, error) {
return json.Marshal(attrs)
},
}
e.ctx.events = append(e.ctx.events, ev)
return nil
}
@ -232,3 +303,15 @@ func (h *HeaderService) HeaderInfo(ctx context.Context) header.Info {
}
return iCtx.header
}
var _ gas.Service = &GasService{}
type GasService struct{}
func (g *GasService) GasMeter(ctx context.Context) gas.Meter {
return GasMeterFromContext(ctx)
}
func (g *GasService) GasConfig(ctx context.Context) gas.GasConfig {
return gas.GasConfig{}
}

View File

@ -35,7 +35,7 @@ func AddTestAddrsFromPubKeys(bankKeeper BankKeeper, stakingKeeper StakingKeeper,
// AddTestAddrs constructs and returns accNum amount of accounts with an
// initial balance of accAmt in random order
func AddTestAddrs(bankKeeper BankKeeper, stakingKeeper StakingKeeper, ctx sdk.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
func AddTestAddrs(bankKeeper BankKeeper, stakingKeeper StakingKeeper, ctx context.Context, accNum int, accAmt math.Int) []sdk.AccAddress {
return addTestAddrs(bankKeeper, stakingKeeper, ctx, accNum, accAmt, CreateRandomAccounts)
}