diff --git a/tests/e2e/evidence/cli_test.go b/tests/e2e/evidence/cli_test.go deleted file mode 100644 index a1ff2157cd58..000000000000 --- a/tests/e2e/evidence/cli_test.go +++ /dev/null @@ -1,77 +0,0 @@ -//go:build e2e -// +build e2e - -package evidence - -import ( - "strings" - "testing" - - "cosmossdk.io/simapp" - "cosmossdk.io/x/evidence/client/cli" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" - "gotest.tools/v3/assert" -) - -type fixture struct { - cfg network.Config - network *network.Network -} - -func initFixture(t *testing.T) *fixture { - cfg := network.DefaultConfig(simapp.NewTestNetworkFixture) - cfg.NumValidators = 1 - - network, err := network.New(t, t.TempDir(), cfg) - assert.NilError(t, err) - assert.NilError(t, network.WaitForNextBlock()) - - return &fixture{ - cfg: cfg, - network: network, - } -} - -func TestGetQueryCmd(t *testing.T) { - t.Parallel() - f := initFixture(t) - defer f.network.Cleanup() - - val := f.network.Validators[0] - - testCases := map[string]struct { - args []string - expectedOutput string - expectErr bool - }{ - "non-existent evidence": { - []string{"DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660"}, - "evidence DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660 not found", - true, - }, - "all evidence (default pagination)": { - []string{}, - "evidence: []\npagination:\n next_key: null\n total: \"0\"", - false, - }, - } - - for name, tc := range testCases { - tc := tc - - t.Run(name, func(t *testing.T) { - cmd := cli.GetQueryCmd() - clientCtx := val.ClientCtx - - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) - if tc.expectErr { - assert.Assert(t, err != nil) - } else { - assert.NilError(t, err) - } - - assert.Assert(t, strings.Contains(strings.TrimSpace(out.String()), tc.expectedOutput)) - }) - } -} diff --git a/tests/integration/evidence/keeper/infraction_test.go b/tests/integration/evidence/keeper/infraction_test.go index 1d889cc2c795..8b0ab614337e 100644 --- a/tests/integration/evidence/keeper/infraction_test.go +++ b/tests/integration/evidence/keeper/infraction_test.go @@ -7,29 +7,43 @@ import ( "time" "cosmossdk.io/core/comet" - "cosmossdk.io/depinject" "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + "cosmossdk.io/x/evidence" "cosmossdk.io/x/evidence/exported" "cosmossdk.io/x/evidence/keeper" - "cosmossdk.io/x/evidence/testutil" - "cosmossdk.io/x/evidence/types" + evidencetypes "cosmossdk.io/x/evidence/types" abci "github.com/cometbft/cometbft/abci/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "gotest.tools/v3/assert" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil/integration" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" 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" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/bank" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/cosmos/cosmos-sdk/x/slashing" slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + "github.com/cosmos/cosmos-sdk/x/slashing/testutil" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + "github.com/cosmos/cosmos-sdk/x/staking" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) var ( @@ -51,51 +65,101 @@ var ( ) type fixture struct { - ctx sdk.Context - app *runtime.App - - evidenceKeeper keeper.Keeper - bankKeeper bankkeeper.Keeper - accountKeeper authkeeper.AccountKeeper - slashingKeeper slashingkeeper.Keeper - stakingKeeper *stakingkeeper.Keeper - interfaceRegistry codectypes.InterfaceRegistry + app *integration.App + + sdkCtx sdk.Context + cdc codec.Codec + + bankKeeper bankkeeper.Keeper + evidenceKeeper *keeper.Keeper + slashingKeeper slashingkeeper.Keeper + stakingKeeper *stakingkeeper.Keeper } -func initFixture(t assert.TestingT) *fixture { - f := &fixture{} - var evidenceKeeper keeper.Keeper - - app, err := simtestutil.Setup( - depinject.Configs( - testutil.AppConfig, - depinject.Supply(log.NewNopLogger()), - ), - &evidenceKeeper, - &f.interfaceRegistry, - &f.accountKeeper, - &f.bankKeeper, - &f.slashingKeeper, - &f.stakingKeeper, +func initFixture(t testing.TB) *fixture { + keys := storetypes.NewKVStoreKeys( + authtypes.StoreKey, banktypes.StoreKey, paramtypes.StoreKey, consensusparamtypes.StoreKey, evidencetypes.StoreKey, stakingtypes.StoreKey, slashingtypes.StoreKey, ) - assert.NilError(t, err) + cdc := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, evidence.AppModuleBasic{}).Codec + + logger := log.NewTestLogger(t) + cms := integration.CreateMultiStore(keys, logger) + + newCtx := sdk.NewContext(cms, cmtproto.Header{}, true, logger) + + authority := authtypes.NewModuleAddress("gov") + + maccPerms := map[string][]string{ + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + } + + accountKeeper := authkeeper.NewAccountKeeper( + cdc, + runtime.NewKVStoreService(keys[authtypes.StoreKey]), + authtypes.ProtoBaseAccount, + maccPerms, + sdk.Bech32MainPrefix, + authority.String(), + ) + + blockedAddresses := map[string]bool{ + accountKeeper.GetAuthority(): false, + } + bankKeeper := bankkeeper.NewBaseKeeper( + cdc, + runtime.NewKVStoreService(keys[banktypes.StoreKey]), + accountKeeper, + blockedAddresses, + authority.String(), + log.NewNopLogger(), + ) + + stakingKeeper := stakingkeeper.NewKeeper(cdc, keys[stakingtypes.StoreKey], accountKeeper, bankKeeper, authority.String()) - router := types.NewRouter() - router = router.AddRoute(types.RouteEquivocation, testEquivocationHandler(evidenceKeeper)) + slashingKeeper := slashingkeeper.NewKeeper(cdc, codec.NewLegacyAmino(), keys[slashingtypes.StoreKey], stakingKeeper, authority.String()) + + evidenceKeeper := keeper.NewKeeper(cdc, keys[evidencetypes.StoreKey], stakingKeeper, slashingKeeper, address.NewBech32Codec("cosmos"), runtime.ProvideCometInfoService()) + router := evidencetypes.NewRouter() + router = router.AddRoute(evidencetypes.RouteEquivocation, testEquivocationHandler(evidenceKeeper)) evidenceKeeper.SetRouter(router) - f.ctx = app.BaseApp.NewContext(false, cmtproto.Header{Height: 1}) - f.app = app - f.evidenceKeeper = evidenceKeeper + authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil) + bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil) + stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper, nil) + slashingModule := slashing.NewAppModule(cdc, slashingKeeper, accountKeeper, bankKeeper, stakingKeeper, nil, cdc.InterfaceRegistry()) + evidenceModule := evidence.NewAppModule(*evidenceKeeper) + + integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, authModule, bankModule, stakingModule, slashingModule, evidenceModule) + + sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context()) + + // Register MsgServer and QueryServer + evidencetypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), keeper.NewMsgServerImpl(*evidenceKeeper)) + evidencetypes.RegisterQueryServer(integrationApp.QueryHelper(), keeper.NewQuerier(evidenceKeeper)) - return f + slashingKeeper.SetParams(sdkCtx, testutil.TestParams()) + + // set default staking params + stakingKeeper.SetParams(sdkCtx, stakingtypes.DefaultParams()) + + return &fixture{ + app: integrationApp, + sdkCtx: sdkCtx, + cdc: cdc, + bankKeeper: bankKeeper, + evidenceKeeper: evidenceKeeper, + slashingKeeper: slashingKeeper, + stakingKeeper: stakingKeeper, + } } func TestHandleDoubleSign(t *testing.T) { t.Parallel() f := initFixture(t) - ctx := f.ctx.WithIsCheckTx(false).WithBlockHeight(1) + ctx := f.sdkCtx.WithIsCheckTx(false).WithBlockHeight(1) populateValidators(t, f) power := int64(100) @@ -106,13 +170,18 @@ func TestHandleDoubleSign(t *testing.T) { selfDelegation := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true) // execute end-blocker and verify validator attributes - f.stakingKeeper.EndBlocker(f.ctx) + f.stakingKeeper.EndBlocker(f.sdkCtx) assert.DeepEqual(t, f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)).String(), sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(selfDelegation))).String(), ) assert.DeepEqual(t, selfDelegation, f.stakingKeeper.Validator(ctx, operatorAddr).GetBondedTokens()) + f.slashingKeeper.AddPubkey(f.sdkCtx, val) + + info := slashingtypes.NewValidatorSigningInfo(sdk.ConsAddress(val.Address()), f.sdkCtx.BlockHeight(), int64(0), time.Unix(0, 0), false, int64(0)) + f.slashingKeeper.SetValidatorSigningInfo(f.sdkCtx, sdk.ConsAddress(val.Address()), info) + // handle a signature to set signing info f.slashingKeeper.HandleValidatorSignature(ctx, val.Address(), selfDelegation.Int64(), true) @@ -123,14 +192,13 @@ func TestHandleDoubleSign(t *testing.T) { ByzantineValidators: []abci.Misbehavior{{ Validator: abci.Validator{Address: val.Address(), Power: power}, Type: abci.MisbehaviorType_DUPLICATE_VOTE, - Time: time.Unix(0, 0), - Height: 0, + Time: time.Now().UTC(), + Height: 1, }}, }) ctx = ctx.WithCometInfo(nci) - - f.evidenceKeeper.BeginBlocker(ctx) + f.evidenceKeeper.BeginBlocker(ctx.WithCometInfo(nci)) // should be jailed and tombstoned assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed()) @@ -170,18 +238,19 @@ func TestHandleDoubleSign_TooOld(t *testing.T) { t.Parallel() f := initFixture(t) - ctx := f.ctx.WithIsCheckTx(false).WithBlockHeight(1).WithBlockTime(time.Now()) + ctx := f.sdkCtx.WithIsCheckTx(false).WithBlockHeight(1).WithBlockTime(time.Now()) populateValidators(t, f) power := int64(100) stakingParams := f.stakingKeeper.GetParams(ctx) operatorAddr, val := valAddresses[0], pubkeys[0] + tstaking := stakingtestutil.NewHelper(t, ctx, f.stakingKeeper) amt := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true) // execute end-blocker and verify validator attributes - f.stakingKeeper.EndBlocker(f.ctx) + f.stakingKeeper.EndBlocker(f.sdkCtx) assert.DeepEqual(t, f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)), sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))), @@ -197,6 +266,7 @@ func TestHandleDoubleSign_TooOld(t *testing.T) { }}, }) + f.app.BaseApp.StoreConsensusParams(ctx, *simtestutil.DefaultConsensusParams) cp := f.app.BaseApp.GetConsensusParams(ctx) ctx = ctx.WithCometInfo(nci) @@ -214,10 +284,10 @@ func populateValidators(t assert.TestingT, f *fixture) { // add accounts and set total supply totalSupplyAmt := initAmt.MulRaw(int64(len(valAddresses))) totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, totalSupplyAmt)) - assert.NilError(t, f.bankKeeper.MintCoins(f.ctx, minttypes.ModuleName, totalSupply)) + assert.NilError(t, f.bankKeeper.MintCoins(f.sdkCtx, minttypes.ModuleName, totalSupply)) for _, addr := range valAddresses { - assert.NilError(t, f.bankKeeper.SendCoinsFromModuleToAccount(f.ctx, minttypes.ModuleName, (sdk.AccAddress)(addr), initCoins)) + assert.NilError(t, f.bankKeeper.SendCoinsFromModuleToAccount(f.sdkCtx, minttypes.ModuleName, (sdk.AccAddress)(addr), initCoins)) } } @@ -232,13 +302,13 @@ func newPubKey(pk string) (res cryptotypes.PubKey) { return pubkey } -func testEquivocationHandler(_ interface{}) types.Handler { +func testEquivocationHandler(_ interface{}) evidencetypes.Handler { return func(ctx sdk.Context, e exported.Evidence) error { if err := e.ValidateBasic(); err != nil { return err } - ee, ok := e.(*types.Equivocation) + ee, ok := e.(*evidencetypes.Equivocation) if !ok { return fmt.Errorf("unexpected evidence type: %T", e) } diff --git a/testutil/integration/router.go b/testutil/integration/router.go index efae2d5cc9b7..bbe8ae2815d6 100644 --- a/testutil/integration/router.go +++ b/testutil/integration/router.go @@ -16,9 +16,14 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/runtime" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" ) const appName = "integration-app" @@ -67,11 +72,24 @@ func NewIntegrationApp(sdkCtx sdk.Context, logger log.Logger, keys map[string]*s router.SetInterfaceRegistry(interfaceRegistry) bApp.SetMsgServiceRouter(router) - if err := bApp.LoadLatestVersion(); err != nil { - panic(fmt.Errorf("failed to load application version from store: %w", err)) + if keys[consensusparamtypes.StoreKey] != nil { + + // set baseApp param store + consensusParamsKeeper := consensusparamkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), authtypes.NewModuleAddress("gov").String(), runtime.EventService{}) + bApp.SetParamStore(consensusParamsKeeper.ParamsStore) + + if err := bApp.LoadLatestVersion(); err != nil { + panic(fmt.Errorf("failed to load application version from store: %w", err)) + } + bApp.InitChain(cmtabcitypes.RequestInitChain{ChainId: appName, ConsensusParams: simtestutil.DefaultConsensusParams}) + + } else { + if err := bApp.LoadLatestVersion(); err != nil { + panic(fmt.Errorf("failed to load application version from store: %w", err)) + } + bApp.InitChain(cmtabcitypes.RequestInitChain{ChainId: appName}) } - bApp.InitChain(cmtabcitypes.RequestInitChain{ChainId: appName}) bApp.Commit() ctx := sdkCtx.WithBlockHeader(cmtproto.Header{ChainID: appName}).WithIsCheckTx(true) diff --git a/x/evidence/keeper/grpc_query.go b/x/evidence/keeper/grpc_query.go index 309d927b3702..72bde1e0dd43 100644 --- a/x/evidence/keeper/grpc_query.go +++ b/x/evidence/keeper/grpc_query.go @@ -16,7 +16,15 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" ) -var _ types.QueryServer = Keeper{} +var _ types.QueryServer = Querier{} + +type Querier struct { + *Keeper +} + +func NewQuerier(keeper *Keeper) Querier { + return Querier{Keeper: keeper} +} // Evidence implements the Query/Evidence gRPC method func (k Keeper) Evidence(c context.Context, req *types.QueryEvidenceRequest) (*types.QueryEvidenceResponse, error) { diff --git a/x/evidence/keeper/grpc_query_test.go b/x/evidence/keeper/grpc_query_test.go index 41e984ad9245..8be75de194da 100644 --- a/x/evidence/keeper/grpc_query_test.go +++ b/x/evidence/keeper/grpc_query_test.go @@ -47,6 +47,17 @@ func (suite *KeeperTestSuite) TestQueryEvidence() { func(res *types.QueryEvidenceResponse) { }, }, + { + "non-existent evidence", + func() { + reqHash := "DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660" + req = types.NewQueryEvidenceRequest(reqHash) + }, + false, + "evidence DF0C23E8634E480F84B9D5674A7CDC9816466DEC28A3358F73260F68D28D7660 not found", + func(res *types.QueryEvidenceResponse) { + }, + }, { "success", func() {