241 lines
7.1 KiB
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)
|
|
}
|