refactor(x/evidence)!: use KVStoreService and context.Context (#16008)

Co-authored-by: marbar3778 <marbar3778@yahoo.com>
This commit is contained in:
Facundo Medica 2023-05-17 17:13:01 -03:00 committed by GitHub
parent 09ca393a19
commit 3c4330680f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 122 additions and 84 deletions

View File

@ -78,6 +78,7 @@ The following modules `NewKeeper` function now take a `KVStoreService` instead o
* `x/bank`
* `x/consensus`
* `x/distribution`
* `x/evidence`
* `x/feegrant`
* `x/gov`
* `x/nft`
@ -98,6 +99,7 @@ The following modules' `Keeper` methods now take in a `context.Context` instead
* `x/authz`
* `x/bank`
* `x/distribution`
* `x/evidence`
* `x/gov`
**Users using depinject do not need any changes, this is automatically done for them.**

View File

@ -14,6 +14,7 @@ import (
"cosmossdk.io/client/v2/autocli"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/log"
authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec"
abci "github.com/cometbft/cometbft/abci/types"
@ -350,7 +351,7 @@ func NewSimApp(
// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec, keys[evidencetypes.StoreKey], app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper.GetAddressCodec(), runtime.ProvideCometInfoService(),
appCodec, runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), app.StakingKeeper, app.SlashingKeeper, app.AccountKeeper.GetAddressCodec(), runtime.ProvideCometInfoService(),
)
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper

View File

@ -1,6 +1,7 @@
package keeper_test
import (
"context"
"encoding/hex"
"fmt"
"testing"
@ -120,7 +121,7 @@ func initFixture(t testing.TB) *fixture {
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())
evidenceKeeper := keeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), stakingKeeper, slashingKeeper, address.NewBech32Codec("cosmos"), runtime.ProvideCometInfoService())
router := evidencetypes.NewRouter()
router = router.AddRoute(evidencetypes.RouteEquivocation, testEquivocationHandler(evidenceKeeper))
evidenceKeeper.SetRouter(router)
@ -303,7 +304,7 @@ func newPubKey(pk string) (res cryptotypes.PubKey) {
}
func testEquivocationHandler(_ interface{}) evidencetypes.Handler {
return func(ctx sdk.Context, e exported.Evidence) error {
return func(ctx context.Context, e exported.Evidence) error {
if err := e.ValidateBasic(); err != nil {
return err
}

View File

@ -32,4 +32,5 @@ Ref: https://keepachangelog.com/en/1.0.0/
### API Breaking Changes
* [#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"`)

View File

@ -107,7 +107,7 @@ by the `Handler` should be persisted.
// for executing all corresponding business logic necessary for verifying the
// evidence as valid. In addition, the Handler may execute any necessary
// slashing and potential jailing.
type Handler func(sdk.Context, Evidence) error
type Handler func(context.Context, Evidence) error
```
@ -152,7 +152,7 @@ as follows:
```go
func SubmitEvidence(ctx Context, evidence Evidence) error {
if _, ok := GetEvidence(ctx, evidence.Hash()); ok {
if _, err := GetEvidence(ctx, evidence.Hash()); err == nil {
return errorsmod.Wrap(types.ErrEvidenceExists, strings.ToUpper(hex.EncodeToString(evidence.Hash())))
}
if !router.HasRoute(evidence.Route()) {

View File

@ -22,7 +22,8 @@ A full setup of the evidence module may look something as follows:
// First, create the keeper
evidenceKeeper := evidence.NewKeeper(
appCodec, keys[evidence.StoreKey], &app.StakingKeeper, app.SlashingKeeper,
appCodec, runtime.NewKVStoreService(keys[evidencetypes.StoreKey]),
&app.StakingKeeper, app.SlashingKeeper,
)
// Second, create the evidence Handler and register all desired routes.

View File

@ -24,7 +24,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs *types.GenesisState) {
if !ok {
panic("expected evidence")
}
if _, ok := k.GetEvidence(ctx, evi.Hash()); ok {
if _, err := k.GetEvidence(ctx, evi.Hash()); err == nil {
panic(fmt.Sprintf("evidence with hash %s already exists", evi.Hash()))
}

View File

@ -73,8 +73,8 @@ func (suite *GenesisTestSuite) TestInitGenesis() {
true,
func() {
for _, e := range testEvidence {
_, ok := suite.keeper.GetEvidence(suite.ctx, e.Hash())
suite.True(ok)
_, err := suite.keeper.GetEvidence(suite.ctx, e.Hash())
suite.NoError(err)
}
},
},

View File

@ -14,22 +14,26 @@ import (
// BeginBlocker iterates through and handles any newly discovered evidence of
// misbehavior submitted by CometBFT. Currently, only equivocation is handled.
func (k Keeper) BeginBlocker(goCtx context.Context) {
func (k Keeper) BeginBlocker(goCtx context.Context) error {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
bi := k.cometInfo.GetCometBlockInfo(goCtx).GetEvidence()
ctx := sdk.UnwrapSDKContext(goCtx)
for i := 0; i < bi.Len(); i++ {
switch bi.Get(i).Type() {
// It's still ongoing discussion how should we treat and slash attacks with
// premeditation. So for now we agree to treat them in the same way.
case comet.LightClientAttack, comet.DuplicateVote:
evidence := types.FromABCIEvidence(bi.Get(i))
k.handleEquivocationEvidence(ctx, evidence)
err := k.handleEquivocationEvidence(goCtx, evidence)
if err != nil {
return err
}
default:
ctx := sdk.UnwrapSDKContext(goCtx)
k.Logger(ctx).Error(fmt.Sprintf("ignored unknown evidence type: %x", bi.Get(i).Type()))
}
}
return nil
}

View File

@ -12,6 +12,7 @@ import (
"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"
)
@ -66,12 +67,9 @@ func (k Keeper) AllEvidence(c context.Context, req *types.QueryAllEvidenceReques
if req == nil {
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(c)
k.GetAllEvidence(ctx)
var evidence []*codectypes.Any
store := ctx.KVStore(k.storeKey)
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 {

View File

@ -1,6 +1,7 @@
package keeper
import (
"context"
"fmt"
"cosmossdk.io/x/evidence/types"
@ -23,19 +24,20 @@ import (
//
// TODO: Some of the invalid constraints listed above may need to be reconsidered
// in the case of a lunatic attack.
func (k Keeper) handleEquivocationEvidence(ctx sdk.Context, evidence *types.Equivocation) {
logger := k.Logger(ctx)
func (k Keeper) handleEquivocationEvidence(ctx context.Context, evidence *types.Equivocation) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
logger := k.Logger(sdkCtx)
consAddr := evidence.GetConsensusAddress()
validator := k.stakingKeeper.ValidatorByConsAddr(ctx, consAddr)
validator := k.stakingKeeper.ValidatorByConsAddr(sdkCtx, consAddr)
if validator == nil || validator.IsUnbonded() {
// Defensive: Simulation doesn't take unbonding periods into account, and
// CometBFT might break this assumption at some point.
return
return nil
}
if !validator.GetOperator().Empty() {
if _, err := k.slashingKeeper.GetPubkey(ctx, consAddr.Bytes()); err != nil {
if _, err := k.slashingKeeper.GetPubkey(sdkCtx, consAddr.Bytes()); err != nil {
// Ignore evidence that cannot be handled.
//
// NOTE: We used to panic with:
@ -46,20 +48,20 @@ func (k Keeper) handleEquivocationEvidence(ctx sdk.Context, evidence *types.Equi
// getting this coordination right, it is easier to relax the
// constraints and ignore evidence that cannot be handled.
logger.Error(fmt.Sprintf("ignore evidence; expected public key for validator %s not found", consAddr))
return
return nil
}
}
// calculate the age of the evidence
infractionHeight := evidence.GetHeight()
infractionTime := evidence.GetTime()
ageDuration := ctx.BlockHeader().Time.Sub(infractionTime)
ageBlocks := ctx.BlockHeader().Height - infractionHeight
ageDuration := sdkCtx.BlockHeader().Time.Sub(infractionTime)
ageBlocks := sdkCtx.BlockHeader().Height - infractionHeight
// Reject evidence if the double-sign is too old. Evidence is considered stale
// if the difference in time and number of blocks is greater than the allowed
// parameters defined.
cp := ctx.ConsensusParams()
cp := sdkCtx.ConsensusParams()
if cp.Evidence != nil {
if ageDuration > cp.Evidence.MaxAgeDuration && ageBlocks > cp.Evidence.MaxAgeNumBlocks {
logger.Info(
@ -70,23 +72,23 @@ func (k Keeper) handleEquivocationEvidence(ctx sdk.Context, evidence *types.Equi
"infraction_time", infractionTime,
"max_age_duration", cp.Evidence.MaxAgeDuration,
)
return
return nil
}
}
if ok := k.slashingKeeper.HasValidatorSigningInfo(ctx, consAddr); !ok {
if ok := k.slashingKeeper.HasValidatorSigningInfo(sdkCtx, consAddr); !ok {
panic(fmt.Sprintf("expected signing info for validator %s but not found", consAddr))
}
// ignore if the validator is already tombstoned
if k.slashingKeeper.IsTombstoned(ctx, consAddr) {
if k.slashingKeeper.IsTombstoned(sdkCtx, consAddr) {
logger.Info(
"ignored equivocation; validator already tombstoned",
"validator", consAddr,
"infraction_height", infractionHeight,
"infraction_time", infractionTime,
)
return
return nil
}
logger.Info(
@ -109,9 +111,9 @@ func (k Keeper) handleEquivocationEvidence(ctx sdk.Context, evidence *types.Equi
// ABCI, and now received as evidence. The fraction is passed in to separately
// to slash unbonding and rebonding delegations.
k.slashingKeeper.SlashWithInfractionReason(
ctx,
sdkCtx,
consAddr,
k.slashingKeeper.SlashFractionDoubleSign(ctx),
k.slashingKeeper.SlashFractionDoubleSign(sdkCtx),
evidence.GetValidatorPower(), distributionHeight,
stakingtypes.Infraction_INFRACTION_DOUBLE_SIGN,
)
@ -119,10 +121,10 @@ func (k Keeper) handleEquivocationEvidence(ctx sdk.Context, evidence *types.Equi
// Jail the validator if not already jailed. This will begin unbonding the
// validator if not already unbonding (tombstoned).
if !validator.IsJailed() {
k.slashingKeeper.Jail(ctx, consAddr)
k.slashingKeeper.Jail(sdkCtx, consAddr)
}
k.slashingKeeper.JailUntil(ctx, consAddr, types.DoubleSignJailEndTime)
k.slashingKeeper.Tombstone(ctx, consAddr)
k.SetEvidence(ctx, evidence)
k.slashingKeeper.JailUntil(sdkCtx, consAddr, types.DoubleSignJailEndTime)
k.slashingKeeper.Tombstone(sdkCtx, consAddr)
return k.SetEvidence(ctx, evidence)
}

View File

@ -1,11 +1,13 @@
package keeper
import (
"context"
"encoding/hex"
"fmt"
"strings"
"cosmossdk.io/core/address"
"cosmossdk.io/core/store"
"cosmossdk.io/log"
"cosmossdk.io/x/evidence/exported"
"cosmossdk.io/x/evidence/types"
@ -16,6 +18,7 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -24,7 +27,7 @@ import (
// module.
type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
storeService store.KVStoreService
router types.Router
stakingKeeper types.StakingKeeper
slashingKeeper types.SlashingKeeper
@ -35,12 +38,12 @@ type Keeper struct {
// NewKeeper creates a new Keeper object.
func NewKeeper(
cdc codec.BinaryCodec, storeKey storetypes.StoreKey, stakingKeeper types.StakingKeeper,
cdc codec.BinaryCodec, storeService store.KVStoreService, stakingKeeper types.StakingKeeper,
slashingKeeper types.SlashingKeeper, ac address.Codec, ci comet.BlockInfoService,
) *Keeper {
return &Keeper{
cdc: cdc,
storeKey: storeKey,
storeService: storeService,
stakingKeeper: stakingKeeper,
slashingKeeper: slashingKeeper,
addressCodec: ac,
@ -49,8 +52,9 @@ func NewKeeper(
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+types.ModuleName)
func (k Keeper) Logger(ctx context.Context) log.Logger {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return sdkCtx.Logger().With("module", "x/"+types.ModuleName)
}
// SetRouter sets the Evidence Handler router for the x/evidence module. Note,
@ -85,8 +89,8 @@ func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error)
// the corresponding registered Evidence Handler. An error is returned if no
// registered Handler exists or if the Handler fails. Otherwise, the evidence is
// persisted.
func (k Keeper) SubmitEvidence(ctx sdk.Context, evidence exported.Evidence) error {
if _, ok := k.GetEvidence(ctx, evidence.Hash()); ok {
func (k Keeper) SubmitEvidence(ctx context.Context, evidence exported.Evidence) error {
if _, err := k.GetEvidence(ctx, evidence.Hash()); err == nil {
return errors.Wrap(types.ErrEvidenceExists, strings.ToUpper(hex.EncodeToString(evidence.Hash())))
}
if !k.router.HasRoute(evidence.Route()) {
@ -98,58 +102,73 @@ func (k Keeper) SubmitEvidence(ctx sdk.Context, evidence exported.Evidence) erro
return errors.Wrap(types.ErrInvalidEvidence, err.Error())
}
ctx.EventManager().EmitEvent(
sdkCtx := sdk.UnwrapSDKContext(ctx)
sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSubmitEvidence,
sdk.NewAttribute(types.AttributeKeyEvidenceHash, strings.ToUpper(hex.EncodeToString(evidence.Hash()))),
),
)
k.SetEvidence(ctx, evidence)
return nil
return k.SetEvidence(ctx, evidence)
}
// SetEvidence sets Evidence by hash in the module's KVStore.
func (k Keeper) SetEvidence(ctx sdk.Context, evidence exported.Evidence) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence)
store.Set(evidence.Hash(), k.MustMarshalEvidence(evidence))
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, false) is returned.
func (k Keeper) GetEvidence(ctx sdk.Context, hash []byte) (exported.Evidence, bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence)
bz := store.Get(hash)
// 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, false
return nil, types.ErrNoEvidenceExists
}
return k.MustUnmarshalEvidence(bz), true
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 sdk.Context, cb func(exported.Evidence) bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence)
iterator := storetypes.KVStorePrefixIterator(store, nil)
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 := k.MustUnmarshalEvidence(iterator.Value())
evidence, err := k.UnmarshalEvidence(iterator.Value())
if err != nil {
return err
}
if cb(evidence) {
break
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 sdk.Context) (evidence []exported.Evidence) {
k.IterateEvidence(ctx, func(e exported.Evidence) bool {
func (k Keeper) GetAllEvidence(ctx context.Context) (evidence []exported.Evidence) {
k.IterateEvidence(ctx, func(e exported.Evidence) error {
evidence = append(evidence, e)
return false
return nil
})
return evidence

View File

@ -1,6 +1,7 @@
package keeper_test
import (
"context"
"encoding/hex"
"fmt"
"time"
@ -20,6 +21,7 @@ import (
"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"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
@ -51,7 +53,7 @@ func newPubKey(pk string) (res cryptotypes.PubKey) {
}
func testEquivocationHandler(_ interface{}) types.Handler {
return func(ctx sdk.Context, e exported.Evidence) error {
return func(ctx context.Context, e exported.Evidence) error {
if err := e.ValidateBasic(); err != nil {
return err
}
@ -87,6 +89,7 @@ type KeeperTestSuite struct {
func (suite *KeeperTestSuite) SetupTest() {
encCfg := moduletestutil.MakeTestEncodingConfig(evidence.AppModuleBasic{})
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
tkey := storetypes.NewTransientStoreKey("evidence_transient_store")
testCtx := testutil.DefaultContextWithDB(suite.T(), key, tkey)
suite.ctx = testCtx.Ctx
@ -101,7 +104,7 @@ func (suite *KeeperTestSuite) SetupTest() {
evidenceKeeper := keeper.NewKeeper(
encCfg.Codec,
key,
storeService,
stakingKeeper,
slashingKeeper,
address.NewBech32Codec("cosmos"),
@ -164,8 +167,8 @@ func (suite *KeeperTestSuite) TestSubmitValidEvidence() {
suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e))
res, ok := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.True(ok)
res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.NoError(err)
suite.Equal(e, res)
}
@ -183,8 +186,8 @@ func (suite *KeeperTestSuite) TestSubmitValidEvidence_Duplicate() {
suite.Nil(suite.evidenceKeeper.SubmitEvidence(ctx, e))
suite.Error(suite.evidenceKeeper.SubmitEvidence(ctx, e))
res, ok := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.True(ok)
res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.NoError(err)
suite.Equal(e, res)
}
@ -198,10 +201,11 @@ func (suite *KeeperTestSuite) TestSubmitInvalidEvidence() {
ConsensusAddress: sdk.ConsAddress(pk.PubKey().Address().Bytes()).String(),
}
suite.Error(suite.evidenceKeeper.SubmitEvidence(ctx, e))
err := suite.evidenceKeeper.SubmitEvidence(ctx, e)
suite.ErrorIs(err, types.ErrInvalidEvidence)
res, ok := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.False(ok)
res, err := suite.evidenceKeeper.GetEvidence(ctx, e.Hash())
suite.ErrorIs(err, types.ErrNoEvidenceExists)
suite.Nil(res)
}

View File

@ -16,7 +16,7 @@ import (
"cosmossdk.io/core/comet"
"cosmossdk.io/depinject"
store "cosmossdk.io/store/types"
store "cosmossdk.io/core/store"
eviclient "cosmossdk.io/x/evidence/client"
"cosmossdk.io/x/evidence/client/cli"
"cosmossdk.io/x/evidence/keeper"
@ -171,9 +171,7 @@ func (AppModule) ConsensusVersion() uint64 { return 1 }
// BeginBlock executes all ABCI BeginBlock logic respective to the evidence module.
func (am AppModule) BeginBlock(ctx context.Context) error {
am.keeper.BeginBlocker(ctx)
return nil
return am.keeper.BeginBlocker(ctx)
}
// AppModuleSimulation functions
@ -206,8 +204,8 @@ func init() {
type ModuleInputs struct {
depinject.In
Key *store.KVStoreKey
Cdc codec.Codec
StoreService store.KVStoreService
Cdc codec.Codec
StakingKeeper types.StakingKeeper
SlashingKeeper types.SlashingKeeper
@ -224,7 +222,7 @@ type ModuleOutputs struct {
}
func ProvideModule(in ModuleInputs) ModuleOutputs {
k := keeper.NewKeeper(in.Cdc, in.Key, in.StakingKeeper, in.SlashingKeeper, in.AddressCodec, in.BlockInfoService)
k := keeper.NewKeeper(in.Cdc, in.StoreService, in.StakingKeeper, in.SlashingKeeper, in.AddressCodec, in.BlockInfoService)
m := NewAppModule(*k)
return ModuleOutputs{EvidenceKeeper: *k, Module: m}

View File

@ -15,3 +15,10 @@ const (
var (
KeyPrefixEvidence = []byte{0x00}
)
func EvidenceKey(hash []byte) (key []byte) {
key = make([]byte, len(KeyPrefixEvidence)+len(hash))
copy(key, KeyPrefixEvidence)
copy(key[len(KeyPrefixEvidence):], hash)
return
}

View File

@ -1,6 +1,7 @@
package types
import (
"context"
"fmt"
"cosmossdk.io/x/evidence/exported"
@ -13,7 +14,7 @@ type (
// for executing all corresponding business logic necessary for verifying the
// evidence as valid. In addition, the Handler may execute any necessary
// slashing and potential jailing.
Handler func(sdk.Context, exported.Evidence) error
Handler func(context.Context, exported.Evidence) error
// Router defines a contract for which any Evidence handling module must
// implement in order to route Evidence to registered Handlers.

View File

@ -1,16 +1,15 @@
package types_test
import (
"context"
"testing"
"cosmossdk.io/x/evidence/exported"
"cosmossdk.io/x/evidence/types"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func testHandler(sdk.Context, exported.Evidence) error { return nil }
func testHandler(context.Context, exported.Evidence) error { return nil }
func TestRouterSeal(t *testing.T) {
r := types.NewRouter()