refactor(evidence)!: use collections for state management (#16336)

Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
testinginprod 2023-05-30 13:57:10 +02:00 committed by GitHub
parent 46c8ec8fc9
commit 28178f7ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 85 additions and 300 deletions

View File

@ -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)

View File

@ -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`

View File

@ -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
}

View File

@ -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() {},

View File

@ -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

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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() {

View File

@ -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.

View File

@ -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]))
}
}
}

View File

@ -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)
}
})
}
}

View File

@ -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")
)

View File

@ -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
}