diff --git a/tests/integration/evidence/keeper/infraction_test.go b/tests/integration/evidence/keeper/infraction_test.go index 1ea9c25c9d..13816e90ad 100644 --- a/tests/integration/evidence/keeper/infraction_test.go +++ b/tests/integration/evidence/keeper/infraction_test.go @@ -140,10 +140,10 @@ func initFixture(t testing.TB) *fixture { evidencetypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), keeper.NewMsgServerImpl(*evidenceKeeper)) evidencetypes.RegisterQueryServer(integrationApp.QueryHelper(), keeper.NewQuerier(evidenceKeeper)) - slashingKeeper.SetParams(sdkCtx, testutil.TestParams()) + assert.NilError(t, slashingKeeper.SetParams(sdkCtx, testutil.TestParams())) // set default staking params - stakingKeeper.SetParams(sdkCtx, stakingtypes.DefaultParams()) + assert.NilError(t, stakingKeeper.SetParams(sdkCtx, stakingtypes.DefaultParams())) return &fixture{ app: integrationApp, @@ -171,14 +171,15 @@ func TestHandleDoubleSign(t *testing.T) { selfDelegation := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true) // execute end-blocker and verify validator attributes - f.stakingKeeper.EndBlocker(f.sdkCtx) + _, err := f.stakingKeeper.EndBlocker(f.sdkCtx) + assert.NilError(t, err) 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) + assert.NilError(t, 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) @@ -199,7 +200,7 @@ func TestHandleDoubleSign(t *testing.T) { }) ctx = ctx.WithCometInfo(nci) - f.evidenceKeeper.BeginBlocker(ctx.WithCometInfo(nci)) + assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx.WithCometInfo(nci))) // should be jailed and tombstoned assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed()) @@ -210,7 +211,7 @@ func TestHandleDoubleSign(t *testing.T) { assert.Assert(t, newTokens.LT(oldTokens)) // submit duplicate evidence - f.evidenceKeeper.BeginBlocker(ctx) + assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx)) // tokens should be the same (capped slash) assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens)) @@ -231,9 +232,11 @@ func TestHandleDoubleSign(t *testing.T) { tstaking.Undelegate(sdk.AccAddress(operatorAddr), operatorAddr, totalBond, true) // query evidence from store - evidences, err := f.evidenceKeeper.GetAllEvidence(ctx) + iter, err := f.evidenceKeeper.Evidences.Iterate(ctx, nil) assert.NilError(t, err) - assert.Assert(t, len(evidences) == 1) + values, err := iter.Values() + assert.NilError(t, err) + assert.Assert(t, len(values) == 1) } func TestHandleDoubleSign_TooOld(t *testing.T) { @@ -252,7 +255,8 @@ func TestHandleDoubleSign_TooOld(t *testing.T) { amt := tstaking.CreateValidatorWithValPower(operatorAddr, val, power, true) // execute end-blocker and verify validator attributes - f.stakingKeeper.EndBlocker(f.sdkCtx) + _, err := f.stakingKeeper.EndBlocker(f.sdkCtx) + assert.NilError(t, err) assert.DeepEqual(t, f.bankKeeper.GetAllBalances(ctx, sdk.AccAddress(operatorAddr)), sdk.NewCoins(sdk.NewCoin(stakingParams.BondDenom, initAmt.Sub(amt))), @@ -268,7 +272,7 @@ func TestHandleDoubleSign_TooOld(t *testing.T) { }}, }) - f.app.BaseApp.StoreConsensusParams(ctx, *simtestutil.DefaultConsensusParams) + assert.NilError(t, f.app.BaseApp.StoreConsensusParams(ctx, *simtestutil.DefaultConsensusParams)) cp := f.app.BaseApp.GetConsensusParams(ctx) ctx = ctx.WithCometInfo(nci) @@ -276,7 +280,7 @@ func TestHandleDoubleSign_TooOld(t *testing.T) { ctx = ctx.WithBlockTime(ctx.BlockTime().Add(cp.Evidence.MaxAgeDuration + 1)) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + cp.Evidence.MaxAgeNumBlocks + 1) - f.evidenceKeeper.BeginBlocker(ctx) + assert.NilError(t, f.evidenceKeeper.BeginBlocker(ctx)) assert.Assert(t, f.stakingKeeper.Validator(ctx, operatorAddr).IsJailed() == false) assert.Assert(t, f.slashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())) == false) diff --git a/x/evidence/CHANGELOG.md b/x/evidence/CHANGELOG.md index 5b13229f2b..1f1cf2d4f8 100644 --- a/x/evidence/CHANGELOG.md +++ b/x/evidence/CHANGELOG.md @@ -34,3 +34,5 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#16008](https://github.com/cosmos/cosmos-sdk/pull/16008) NewKeeper now takes in a KVStoreService instead of KVStoreKey, most functions use context.Context instead of sdk.Context and `IterateEvidence` callback function now returns an error to stop interation (`errors.ErrStopIterating`). * (keeper) [#15825](https://github.com/cosmos/cosmos-sdk/pull/15825) Evidence constructor now requires an `address.Codec` (`import "cosmossdk.io/core/address"`) +* [#16336](https://github.com/cosmos/cosmos-sdk/pull/16336) Use collections for state management: + * Removed: keeper `SetEvidence`, `GetEvidence`, `IterateEvidences`, `GetAllEvidences`, `MustMarshalEvidence`, `MustUnmarshalEvidence`, `MarshalEvidence`, `UnmarshalEvidence` diff --git a/x/evidence/genesis.go b/x/evidence/genesis.go index 666f1806f4..63ec6f5273 100644 --- a/x/evidence/genesis.go +++ b/x/evidence/genesis.go @@ -1,13 +1,13 @@ package evidence import ( + "errors" "fmt" + "cosmossdk.io/collections" "cosmossdk.io/x/evidence/exported" "cosmossdk.io/x/evidence/keeper" "cosmossdk.io/x/evidence/types" - "github.com/cosmos/gogoproto/proto" - codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -24,33 +24,29 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs *types.GenesisState) { if !ok { panic("expected evidence") } - if _, err := k.GetEvidence(ctx, evi.Hash()); err == nil { + if _, err := k.Evidences.Get(ctx, evi.Hash()); err == nil { panic(fmt.Sprintf("evidence with hash %s already exists", evi.Hash())) } - k.SetEvidence(ctx, evi) + if err := k.Evidences.Set(ctx, evi.Hash(), evi); err != nil { + panic(err) + } } } // ExportGenesis returns the evidence module's exported genesis. func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { - e, err := k.GetAllEvidence(ctx) - if err != nil { + gs := new(types.GenesisState) + err := k.Evidences.Walk(ctx, nil, func(_ []byte, value exported.Evidence) (stop bool, err error) { + anyEvi, err := codectypes.NewAnyWithValue(value) + if err != nil { + return false, err + } + gs.Evidence = append(gs.Evidence, anyEvi) + return false, nil + }) + if err != nil && !errors.Is(err, collections.ErrInvalidIterator) { panic(err) } - evidence := make([]*codectypes.Any, len(e)) - for i, evi := range e { - msg, ok := evi.(proto.Message) - if !ok { - panic(fmt.Errorf("cannot proto marshal %T", evi)) - } - any, err := codectypes.NewAnyWithValue(msg) - if err != nil { - panic(err) - } - evidence[i] = any - } - return &types.GenesisState{ - Evidence: evidence, - } + return gs } diff --git a/x/evidence/genesis_test.go b/x/evidence/genesis_test.go index 489c213d4f..ae0791067d 100644 --- a/x/evidence/genesis_test.go +++ b/x/evidence/genesis_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "cosmossdk.io/collections" "cosmossdk.io/depinject" "cosmossdk.io/log" "cosmossdk.io/x/evidence" @@ -73,7 +74,7 @@ func (suite *GenesisTestSuite) TestInitGenesis() { true, func() { for _, e := range testEvidence { - _, err := suite.keeper.GetEvidence(suite.ctx, e.Hash()) + _, err := suite.keeper.Evidences.Get(suite.ctx, e.Hash()) suite.NoError(err) } }, @@ -93,9 +94,8 @@ func (suite *GenesisTestSuite) TestInitGenesis() { }, false, func() { - ev, err := suite.keeper.GetAllEvidence(suite.ctx) - suite.Empty(ev) - suite.NoError(err) + _, err := suite.keeper.Evidences.Iterate(suite.ctx, nil) + suite.Require().ErrorIs(err, collections.ErrInvalidIterator) }, }, } @@ -133,12 +133,13 @@ func (suite *GenesisTestSuite) TestExportGenesis() { { "success", func() { - suite.keeper.SetEvidence(suite.ctx, &types.Equivocation{ + ev := &types.Equivocation{ Height: 1, Power: 100, Time: time.Now().UTC(), ConsensusAddress: pk.PubKey().Address().String(), - }) + } + suite.Require().NoError(suite.keeper.Evidences.Set(suite.ctx, ev.Hash(), ev)) }, true, func() {}, diff --git a/x/evidence/keeper/grpc_query.go b/x/evidence/keeper/grpc_query.go index 2599fd13aa..728742d4c0 100644 --- a/x/evidence/keeper/grpc_query.go +++ b/x/evidence/keeper/grpc_query.go @@ -5,14 +5,13 @@ import ( "encoding/hex" "fmt" - "cosmossdk.io/store/prefix" + "cosmossdk.io/x/evidence/exported" "cosmossdk.io/x/evidence/types" proto "github.com/cosmos/gogoproto/proto" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" codectypes "github.com/cosmos/cosmos-sdk/codec/types" - "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" ) @@ -20,15 +19,15 @@ import ( var _ types.QueryServer = Querier{} type Querier struct { - *Keeper + k *Keeper } func NewQuerier(keeper *Keeper) Querier { - return Querier{Keeper: keeper} + return Querier{k: keeper} } // Evidence implements the Query/Evidence gRPC method -func (k Keeper) Evidence(c context.Context, req *types.QueryEvidenceRequest) (*types.QueryEvidenceResponse, error) { +func (k Querier) Evidence(c context.Context, req *types.QueryEvidenceRequest) (*types.QueryEvidenceResponse, error) { if req == nil { return nil, status.Errorf(codes.InvalidArgument, "empty request") } @@ -44,7 +43,7 @@ func (k Keeper) Evidence(c context.Context, req *types.QueryEvidenceRequest) (*t return nil, fmt.Errorf("invalid evidence hash: %w", err) } - evidence, _ := k.GetEvidence(ctx, decodedHash) + evidence, _ := k.k.Evidences.Get(ctx, decodedHash) if evidence == nil { return nil, status.Errorf(codes.NotFound, "evidence %s not found", req.Hash) } @@ -63,35 +62,22 @@ func (k Keeper) Evidence(c context.Context, req *types.QueryEvidenceRequest) (*t } // AllEvidence implements the Query/AllEvidence gRPC method -func (k Keeper) AllEvidence(c context.Context, req *types.QueryAllEvidenceRequest) (*types.QueryAllEvidenceResponse, error) { +func (k Querier) AllEvidence(ctx context.Context, req *types.QueryAllEvidenceRequest) (*types.QueryAllEvidenceResponse, error) { if req == nil { return nil, status.Errorf(codes.InvalidArgument, "empty request") } var evidence []*codectypes.Any - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(c)) - evidenceStore := prefix.NewStore(store, types.KeyPrefixEvidence) - - pageRes, err := query.Paginate(evidenceStore, req.Pagination, func(key, value []byte) error { - result, err := k.UnmarshalEvidence(value) + _, pageRes, err := query.CollectionFilteredPaginate(ctx, k.k.Evidences, req.Pagination, func(_ []byte, value exported.Evidence) (include bool, err error) { + evidenceAny, err := codectypes.NewAnyWithValue(value) if err != nil { - return err - } - - msg, ok := result.(proto.Message) - if !ok { - return status.Errorf(codes.Internal, "can't protomarshal %T", msg) - } - - evidenceAny, err := codectypes.NewAnyWithValue(msg) - if err != nil { - return err + return false, err } evidence = append(evidence, evidenceAny) - return nil + return false, nil // we don't include results because we're appending them }) if err != nil { - return &types.QueryAllEvidenceResponse{}, err + return nil, err } return &types.QueryAllEvidenceResponse{Evidence: evidence, Pagination: pageRes}, nil diff --git a/x/evidence/keeper/infraction.go b/x/evidence/keeper/infraction.go index c91b033f5b..04f18db3ea 100644 --- a/x/evidence/keeper/infraction.go +++ b/x/evidence/keeper/infraction.go @@ -144,5 +144,5 @@ func (k Keeper) handleEquivocationEvidence(ctx context.Context, evidence *types. if err != nil { return err } - return k.SetEvidence(ctx, evidence) + return k.Evidences.Set(ctx, evidence.Hash(), evidence) } diff --git a/x/evidence/keeper/keeper.go b/x/evidence/keeper/keeper.go index ba3a170ea5..ad7f3d70e1 100644 --- a/x/evidence/keeper/keeper.go +++ b/x/evidence/keeper/keeper.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "cosmossdk.io/collections" "cosmossdk.io/core/address" "cosmossdk.io/core/store" "cosmossdk.io/log" @@ -14,11 +15,7 @@ import ( "cosmossdk.io/core/comet" "cosmossdk.io/errors" - "cosmossdk.io/store/prefix" - storetypes "cosmossdk.io/store/types" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -34,6 +31,9 @@ type Keeper struct { addressCodec address.Codec cometInfo comet.BlockInfoService + + Schema collections.Schema + Evidences collections.Map[[]byte, exported.Evidence] } // NewKeeper creates a new Keeper object. @@ -41,14 +41,22 @@ func NewKeeper( cdc codec.BinaryCodec, storeService store.KVStoreService, stakingKeeper types.StakingKeeper, slashingKeeper types.SlashingKeeper, ac address.Codec, ci comet.BlockInfoService, ) *Keeper { - return &Keeper{ + sb := collections.NewSchemaBuilder(storeService) + k := &Keeper{ cdc: cdc, storeService: storeService, stakingKeeper: stakingKeeper, slashingKeeper: slashingKeeper, addressCodec: ac, cometInfo: ci, + Evidences: collections.NewMap(sb, types.KeyPrefixEvidence, "evidences", collections.BytesKey, codec.CollInterfaceValue[exported.Evidence](cdc)), } + schema, err := sb.Build() + if err != nil { + panic(err) + } + k.Schema = schema + return k } // Logger returns a module-specific logger. @@ -90,7 +98,7 @@ func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error) // registered Handler exists or if the Handler fails. Otherwise, the evidence is // persisted. func (k Keeper) SubmitEvidence(ctx context.Context, evidence exported.Evidence) error { - if _, err := k.GetEvidence(ctx, evidence.Hash()); err == nil { + if _, err := k.Evidences.Get(ctx, evidence.Hash()); err == nil { return errors.Wrap(types.ErrEvidenceExists, strings.ToUpper(hex.EncodeToString(evidence.Hash()))) } if !k.router.HasRoute(evidence.Route()) { @@ -110,100 +118,5 @@ func (k Keeper) SubmitEvidence(ctx context.Context, evidence exported.Evidence) ), ) - return k.SetEvidence(ctx, evidence) -} - -// SetEvidence sets Evidence by hash in the module's KVStore. -func (k Keeper) SetEvidence(ctx context.Context, evidence exported.Evidence) error { - store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - prefixStore := prefix.NewStore(store, types.KeyPrefixEvidence) - prefixStore.Set(evidence.Hash(), k.MustMarshalEvidence(evidence)) - return nil -} - -// GetEvidence retrieves Evidence by hash if it exists. If no Evidence exists for -// the given hash, (nil, types.ErrNoEvidenceExists) is returned. -func (k Keeper) GetEvidence(ctx context.Context, hash []byte) (exported.Evidence, error) { - store := k.storeService.OpenKVStore(ctx) - bz, err := store.Get(types.EvidenceKey(hash)) - if len(bz) == 0 { - return nil, types.ErrNoEvidenceExists - } - - if err != nil { - return nil, err - } - - return k.UnmarshalEvidence(bz) -} - -// IterateEvidence provides an interator over all stored Evidence objects. For -// each Evidence object, cb will be called. If the cb returns true, the iterator -// will close and stop. -func (k Keeper) IterateEvidence(ctx context.Context, cb func(exported.Evidence) error) error { - store := k.storeService.OpenKVStore(ctx) - iterator, err := store.Iterator(types.KeyPrefixEvidence, storetypes.PrefixEndBytes(types.KeyPrefixEvidence)) - if err != nil { - return err - } - - defer iterator.Close() - for ; iterator.Valid(); iterator.Next() { - evidence, err := k.UnmarshalEvidence(iterator.Value()) - if err != nil { - return err - } - - err = cb(evidence) - if errors.IsOf(err, errors.ErrStopIterating) { - return nil - } else if err != nil { - return err - } - } - return nil -} - -// GetAllEvidence returns all stored Evidence objects. -func (k Keeper) GetAllEvidence(ctx context.Context) (evidence []exported.Evidence, err error) { - err = k.IterateEvidence(ctx, func(e exported.Evidence) error { - evidence = append(evidence, e) - return nil - }) - - return evidence, err -} - -// MustUnmarshalEvidence attempts to decode and return an Evidence object from -// raw encoded bytes. It panics on error. -func (k Keeper) MustUnmarshalEvidence(bz []byte) exported.Evidence { - evidence, err := k.UnmarshalEvidence(bz) - if err != nil { - panic(fmt.Errorf("failed to decode evidence: %w", err)) - } - - return evidence -} - -// MustMarshalEvidence attempts to encode an Evidence object and returns the -// raw encoded bytes. It panics on error. -func (k Keeper) MustMarshalEvidence(evidence exported.Evidence) []byte { - bz, err := k.MarshalEvidence(evidence) - if err != nil { - panic(fmt.Errorf("failed to encode evidence: %w", err)) - } - - return bz -} - -// MarshalEvidence protobuf serializes an Evidence interface -func (k Keeper) MarshalEvidence(evidenceI exported.Evidence) ([]byte, error) { - return k.cdc.MarshalInterface(evidenceI) -} - -// UnmarshalEvidence returns an Evidence interface from raw encoded evidence -// bytes of a Proto-based Evidence type -func (k Keeper) UnmarshalEvidence(bz []byte) (exported.Evidence, error) { - var evi exported.Evidence - return evi, k.cdc.UnmarshalInterface(bz, &evi) + return k.Evidences.Set(ctx, evidence.Hash(), evidence) } diff --git a/x/evidence/keeper/keeper_test.go b/x/evidence/keeper/keeper_test.go index 6714c2aedc..e72b311561 100644 --- a/x/evidence/keeper/keeper_test.go +++ b/x/evidence/keeper/keeper_test.go @@ -6,6 +6,7 @@ import ( "fmt" "time" + "cosmossdk.io/collections" "cosmossdk.io/x/evidence" "cosmossdk.io/x/evidence/exported" "cosmossdk.io/x/evidence/keeper" @@ -125,7 +126,7 @@ func (suite *KeeperTestSuite) SetupTest() { suite.accountKeeper = accountKeeper queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, suite.encCfg.InterfaceRegistry) - types.RegisterQueryServer(queryHelper, evidenceKeeper) + types.RegisterQueryServer(queryHelper, keeper.NewQuerier(evidenceKeeper)) suite.queryClient = types.NewQueryClient(queryHelper) suite.evidenceKeeper = *evidenceKeeper @@ -167,7 +168,7 @@ func (suite *KeeperTestSuite) TestSubmitValidEvidence() { suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e)) - res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash()) + res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash()) suite.NoError(err) suite.Equal(e, res) } @@ -186,7 +187,7 @@ func (suite *KeeperTestSuite) TestSubmitValidEvidence_Duplicate() { suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e)) suite.Error(suite.evidenceKeeper.SubmitEvidence(ctx, e)) - res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash()) + res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash()) suite.NoError(err) suite.Equal(e, res) } @@ -204,8 +205,8 @@ func (suite *KeeperTestSuite) TestSubmitInvalidEvidence() { err := suite.evidenceKeeper.SubmitEvidence(ctx, e) suite.ErrorIs(err, types.ErrInvalidEvidence) - res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash()) - suite.ErrorIs(err, types.ErrNoEvidenceExists) + res, err := suite.evidenceKeeper.Evidences.Get(ctx, e.Hash()) + suite.ErrorIs(err, collections.ErrNotFound) suite.Nil(res) } @@ -214,9 +215,12 @@ func (suite *KeeperTestSuite) TestIterateEvidence() { numEvidence := 100 suite.populateEvidence(ctx, numEvidence) - evidence, err := suite.evidenceKeeper.GetAllEvidence(ctx) - suite.Len(evidence, numEvidence) - suite.NoError(err) + 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() { diff --git a/x/evidence/module.go b/x/evidence/module.go index 7038e0575f..5dbee9d7c1 100644 --- a/x/evidence/module.go +++ b/x/evidence/module.go @@ -144,7 +144,7 @@ func (am AppModule) Name() string { // RegisterServices registers module services. func (am AppModule) RegisterServices(registrar grpc.ServiceRegistrar) error { types.RegisterMsgServer(registrar, keeper.NewMsgServerImpl(am.keeper)) - types.RegisterQueryServer(registrar, am.keeper) + types.RegisterQueryServer(registrar, keeper.NewQuerier(&am.keeper)) return nil } @@ -183,7 +183,7 @@ func (AppModule) GenerateGenesisState(simState *module.SimulationState) { // RegisterStoreDecoder registers a decoder for evidence module's types func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { - sdr[types.StoreKey] = simulation.NewDecodeStore(am.keeper) + sdr[types.StoreKey] = simtypes.NewStoreDecoderFuncFromCollectionsSchema(am.keeper.Schema) } // WeightedOperations returns the all the gov module operations with their respective weights. diff --git a/x/evidence/simulation/decoder.go b/x/evidence/simulation/decoder.go deleted file mode 100644 index 0ae7201972..0000000000 --- a/x/evidence/simulation/decoder.go +++ /dev/null @@ -1,38 +0,0 @@ -package simulation - -import ( - "bytes" - "fmt" - - "cosmossdk.io/x/evidence/exported" - "cosmossdk.io/x/evidence/types" - - "github.com/cosmos/cosmos-sdk/types/kv" -) - -type EvidenceUnmarshaler interface { - UnmarshalEvidence([]byte) (exported.Evidence, error) -} - -// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's -// Value to the corresponding evidence type. -func NewDecodeStore(cdc EvidenceUnmarshaler) func(kvA, kvB kv.Pair) string { - return func(kvA, kvB kv.Pair) string { - switch { - case bytes.Equal(kvA.Key[:1], types.KeyPrefixEvidence): - evidenceA, err := cdc.UnmarshalEvidence(kvA.Value) - if err != nil { - panic(fmt.Sprintf("cannot unmarshal evidence: %s", err.Error())) - } - - evidenceB, err := cdc.UnmarshalEvidence(kvB.Value) - if err != nil { - panic(fmt.Sprintf("cannot unmarshal evidence: %s", err.Error())) - } - - return fmt.Sprintf("%v\n%v", evidenceA, evidenceB) - default: - panic(fmt.Sprintf("invalid %s key prefix %X", types.ModuleName, kvA.Key[:1])) - } - } -} diff --git a/x/evidence/simulation/decoder_test.go b/x/evidence/simulation/decoder_test.go deleted file mode 100644 index bfcd1d88d2..0000000000 --- a/x/evidence/simulation/decoder_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package simulation_test - -import ( - "fmt" - "testing" - "time" - - "cosmossdk.io/depinject" - "cosmossdk.io/log" - "cosmossdk.io/x/evidence/keeper" - "cosmossdk.io/x/evidence/simulation" - "cosmossdk.io/x/evidence/testutil" - "cosmossdk.io/x/evidence/types" - "github.com/stretchr/testify/require" - - "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/kv" -) - -func TestDecodeStore(t *testing.T) { - var evidenceKeeper keeper.Keeper - err := depinject.Inject(depinject.Configs( - testutil.AppConfig, - depinject.Supply(log.NewNopLogger()), - ), &evidenceKeeper) - require.NoError(t, err) - - dec := simulation.NewDecodeStore(evidenceKeeper) - - delPk1 := ed25519.GenPrivKey().PubKey() - - ev := &types.Equivocation{ - Height: 10, - Time: time.Now().UTC(), - Power: 1000, - ConsensusAddress: sdk.ConsAddress(delPk1.Address()).String(), - } - - evBz, err := evidenceKeeper.MarshalEvidence(ev) - require.NoError(t, err) - - kvPairs := kv.Pairs{ - Pairs: []kv.Pair{ - { - Key: types.KeyPrefixEvidence, - Value: evBz, - }, - { - Key: []byte{0x99}, - Value: []byte{0x99}, - }, - }, - } - tests := []struct { - name string - expectedLog string - }{ - {"Evidence", fmt.Sprintf("%v\n%v", ev, ev)}, - {"other", ""}, - } - - for i, tt := range tests { - i, tt := i, tt - t.Run(tt.name, func(t *testing.T) { - switch i { - case len(tests) - 1: - require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) - default: - require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name) - } - }) - } -} diff --git a/x/evidence/types/errors.go b/x/evidence/types/errors.go index 178ca4e84e..7624c1eaa3 100644 --- a/x/evidence/types/errors.go +++ b/x/evidence/types/errors.go @@ -6,6 +6,5 @@ import "cosmossdk.io/errors" var ( ErrNoEvidenceHandlerExists = errors.Register(ModuleName, 2, "unregistered handler for evidence type") ErrInvalidEvidence = errors.Register(ModuleName, 3, "invalid evidence") - ErrNoEvidenceExists = errors.Register(ModuleName, 4, "evidence does not exist") ErrEvidenceExists = errors.Register(ModuleName, 5, "evidence already exists") ) diff --git a/x/evidence/types/keys.go b/x/evidence/types/keys.go index 42fb556022..7255f9a86d 100644 --- a/x/evidence/types/keys.go +++ b/x/evidence/types/keys.go @@ -1,24 +1,16 @@ package types +import "cosmossdk.io/collections" + const ( // ModuleName defines the module name ModuleName = "evidence" // StoreKey defines the primary module store key StoreKey = ModuleName - - // RouterKey defines the module's message routing key - RouterKey = ModuleName ) // KVStore key prefixes var ( - KeyPrefixEvidence = []byte{0x00} + KeyPrefixEvidence = collections.NewPrefix(0) ) - -func EvidenceKey(hash []byte) (key []byte) { - key = make([]byte, len(KeyPrefixEvidence)+len(hash)) - copy(key, KeyPrefixEvidence) - copy(key[len(KeyPrefixEvidence):], hash) - return -}