cosmos-sdk/x/evidence/keeper/keeper_test.go

241 lines
7.1 KiB
Go

package keeper_test
import (
"context"
"encoding/hex"
"fmt"
"time"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
"cosmossdk.io/collections"
coreaddress "cosmossdk.io/core/address"
"cosmossdk.io/core/header"
coretesting "cosmossdk.io/core/testing"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/evidence"
"cosmossdk.io/x/evidence/exported"
"cosmossdk.io/x/evidence/keeper"
evidencetestutil "cosmossdk.io/x/evidence/testutil"
"cosmossdk.io/x/evidence/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec/address"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"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"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
)
var (
pubkeys = []cryptotypes.PubKey{
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"),
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"),
newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB52"),
}
valAddress = sdk.ValAddress(pubkeys[0].Address())
)
func newPubKey(pk string) (res cryptotypes.PubKey) {
pkBytes, err := hex.DecodeString(pk)
if err != nil {
panic(err)
}
pubkey := &ed25519.PubKey{Key: pkBytes}
return pubkey
}
func testEquivocationHandler(_ interface{}) types.Handler {
return func(ctx context.Context, e exported.Evidence) error {
if err := e.ValidateBasic(); err != nil {
return err
}
ee, ok := e.(*types.Equivocation)
if !ok {
return fmt.Errorf("unexpected evidence type: %T", e)
}
if ee.Height%2 == 0 {
return fmt.Errorf("unexpected even evidence height: %d", ee.Height)
}
return nil
}
}
type KeeperTestSuite struct {
suite.Suite
ctx sdk.Context
addressCodec coreaddress.Codec
consAddressCodec coreaddress.ConsensusAddressCodec
evidenceKeeper keeper.Keeper
accountKeeper *evidencetestutil.MockAccountKeeper
slashingKeeper *evidencetestutil.MockSlashingKeeper
stakingKeeper *evidencetestutil.MockStakingKeeper
queryClient types.QueryClient
encCfg moduletestutil.TestEncodingConfig
msgServer types.MsgServer
}
func (suite *KeeperTestSuite) SetupTest() {
encCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, evidence.AppModule{})
key := storetypes.NewKVStoreKey(types.StoreKey)
env := runtime.NewEnvironment(runtime.NewKVStoreService(key), coretesting.NewNopLogger())
tkey := storetypes.NewTransientStoreKey("evidence_transient_store")
testCtx := testutil.DefaultContextWithDB(suite.T(), key, tkey)
suite.ctx = testCtx.Ctx
suite.addressCodec = address.NewBech32Codec("cosmos")
suite.consAddressCodec = address.NewBech32Codec("cosmosvalcons")
ctrl := gomock.NewController(suite.T())
stakingKeeper := evidencetestutil.NewMockStakingKeeper(ctrl)
slashingKeeper := evidencetestutil.NewMockSlashingKeeper(ctrl)
accountKeeper := evidencetestutil.NewMockAccountKeeper(ctrl)
ck := evidencetestutil.NewMockConsensusKeeper(ctrl)
evidenceKeeper := keeper.NewKeeper(
encCfg.Codec,
env,
stakingKeeper,
slashingKeeper,
ck,
address.NewBech32Codec("cosmos"),
address.NewBech32Codec("cosmosvalcons"),
)
suite.stakingKeeper = stakingKeeper
suite.slashingKeeper = slashingKeeper
router := types.NewRouter()
router = router.AddRoute(types.RouteEquivocation, testEquivocationHandler(evidenceKeeper))
evidenceKeeper.SetRouter(router)
suite.ctx = testCtx.Ctx.WithHeaderInfo(header.Info{Height: 1})
suite.encCfg = moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, evidence.AppModule{})
suite.accountKeeper = accountKeeper
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.encCfg.InterfaceRegistry)
types.RegisterQueryServer(queryHelper, keeper.NewQuerier(evidenceKeeper))
suite.queryClient = types.NewQueryClient(queryHelper)
suite.evidenceKeeper = *evidenceKeeper
suite.msgServer = keeper.NewMsgServerImpl(suite.evidenceKeeper)
}
func (suite *KeeperTestSuite) populateEvidence(ctx sdk.Context, numEvidence int) []exported.Evidence {
evidence := make([]exported.Evidence, numEvidence)
for i := 0; i < numEvidence; i++ {
pk := ed25519.GenPrivKey()
consAddr, err := suite.consAddressCodec.BytesToString(pk.PubKey().Address())
suite.Require().NoError(err)
evidence[i] = &types.Equivocation{
Height: 11,
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: consAddr,
}
suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, evidence[i]))
}
return evidence
}
func (suite *KeeperTestSuite) TestSubmitValidEvidence() {
ctx := suite.ctx.WithIsCheckTx(false)
pk := ed25519.GenPrivKey()
consAddr, err := suite.consAddressCodec.BytesToString(pk.PubKey().Address())
suite.Require().NoError(err)
e := &types.Equivocation{
Height: 1,
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: consAddr,
}
suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e))
res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash())
suite.NoError(err)
suite.Equal(e, res)
}
func (suite *KeeperTestSuite) TestSubmitValidEvidence_Duplicate() {
ctx := suite.ctx.WithIsCheckTx(false)
pk := ed25519.GenPrivKey()
consAddr, err := suite.consAddressCodec.BytesToString(pk.PubKey().Address())
suite.Require().NoError(err)
e := &types.Equivocation{
Height: 1,
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: consAddr,
}
suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e))
suite.Error(suite.evidenceKeeper.SubmitEvidence(ctx, e))
res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash())
suite.NoError(err)
suite.Equal(e, res)
}
func (suite *KeeperTestSuite) TestSubmitInvalidEvidence() {
ctx := suite.ctx.WithIsCheckTx(false)
pk := ed25519.GenPrivKey()
consAddr, err := suite.consAddressCodec.BytesToString(pk.PubKey().Address())
suite.Require().NoError(err)
e := &types.Equivocation{
Height: 0,
Power: 100,
Time: time.Now().UTC(),
ConsensusAddress: consAddr,
}
err = suite.evidenceKeeper.SubmitEvidence(ctx, e)
suite.ErrorIs(err, types.ErrInvalidEvidence)
res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash())
suite.ErrorIs(err, collections.ErrNotFound)
suite.Nil(res)
}
func (suite *KeeperTestSuite) TestIterateEvidence() {
ctx := suite.ctx.WithIsCheckTx(false)
numEvidence := 100
suite.populateEvidence(ctx, numEvidence)
var evidences []exported.Evidence
suite.Require().NoError(suite.evidenceKeeper.Evidences.Walk(ctx, nil, func(key []byte, value exported.Evidence) (stop bool, err error) {
evidences = append(evidences, value)
return false, nil
}))
suite.Len(evidences, numEvidence)
}
func (suite *KeeperTestSuite) TestGetEvidenceHandler() {
handler, err := suite.evidenceKeeper.GetEvidenceHandler((&types.Equivocation{}).Route())
suite.NoError(err)
suite.NotNil(handler)
handler, err = suite.evidenceKeeper.GetEvidenceHandler("invalidHandler")
suite.Error(err)
suite.Nil(handler)
}