github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/evidence/internal/keeper/keeper.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 6 tmbytes "github.com/fibonacci-chain/fbc/libs/tendermint/libs/bytes" 7 "github.com/fibonacci-chain/fbc/libs/tendermint/libs/log" 8 9 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/prefix" 11 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 12 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/evidence/exported" 14 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/evidence/internal/types" 15 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/params" 16 ) 17 18 // Keeper defines the evidence module's keeper. The keeper is responsible for 19 // managing persistence, state transitions and query handling for the evidence 20 // module. 21 type Keeper struct { 22 cdc *codec.Codec 23 storeKey sdk.StoreKey 24 paramSpace params.Subspace 25 router types.Router 26 stakingKeeper types.StakingKeeper 27 slashingKeeper types.SlashingKeeper 28 } 29 30 func NewKeeper( 31 cdc *codec.Codec, storeKey sdk.StoreKey, paramSpace params.Subspace, 32 stakingKeeper types.StakingKeeper, slashingKeeper types.SlashingKeeper, 33 ) *Keeper { 34 35 // set KeyTable if it has not already been set 36 if !paramSpace.HasKeyTable() { 37 paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable()) 38 } 39 40 return &Keeper{ 41 cdc: cdc, 42 storeKey: storeKey, 43 paramSpace: paramSpace, 44 stakingKeeper: stakingKeeper, 45 slashingKeeper: slashingKeeper, 46 } 47 } 48 49 // Logger returns a module-specific logger. 50 func (k Keeper) Logger(ctx sdk.Context) log.Logger { 51 return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) 52 } 53 54 // SetRouter sets the Evidence Handler router for the x/evidence module. Note, 55 // we allow the ability to set the router after the Keeper is constructed as a 56 // given Handler may need access the Keeper before being constructed. The router 57 // may only be set once and will be sealed if it's not already sealed. 58 func (k *Keeper) SetRouter(rtr types.Router) { 59 // It is vital to seal the Evidence Handler router as to not allow further 60 // handlers to be registered after the keeper is created since this 61 // could create invalid or non-deterministic behavior. 62 if !rtr.Sealed() { 63 rtr.Seal() 64 } 65 if k.router != nil { 66 panic(fmt.Sprintf("attempting to reset router on x/%s", types.ModuleName)) 67 } 68 69 k.router = rtr 70 } 71 72 // GetEvidenceHandler returns a registered Handler for a given Evidence type. If 73 // no handler exists, an error is returned. 74 func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error) { 75 if !k.router.HasRoute(evidenceRoute) { 76 return nil, sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidenceRoute) 77 } 78 79 return k.router.GetRoute(evidenceRoute), nil 80 } 81 82 // SubmitEvidence attempts to match evidence against the keepers router and execute 83 // the corresponding registered Evidence Handler. An error is returned if no 84 // registered Handler exists or if the Handler fails. Otherwise, the evidence is 85 // persisted. 86 func (k Keeper) SubmitEvidence(ctx sdk.Context, evidence exported.Evidence) error { 87 if _, ok := k.GetEvidence(ctx, evidence.Hash()); ok { 88 return sdkerrors.Wrap(types.ErrEvidenceExists, evidence.Hash().String()) 89 } 90 if !k.router.HasRoute(evidence.Route()) { 91 return sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidence.Route()) 92 } 93 94 handler := k.router.GetRoute(evidence.Route()) 95 if err := handler(ctx, evidence); err != nil { 96 return sdkerrors.Wrap(types.ErrInvalidEvidence, err.Error()) 97 } 98 99 ctx.EventManager().EmitEvent( 100 sdk.NewEvent( 101 types.EventTypeSubmitEvidence, 102 sdk.NewAttribute(types.AttributeKeyEvidenceHash, evidence.Hash().String()), 103 ), 104 ) 105 106 k.SetEvidence(ctx, evidence) 107 return nil 108 } 109 110 // SetEvidence sets Evidence by hash in the module's KVStore. 111 func (k Keeper) SetEvidence(ctx sdk.Context, evidence exported.Evidence) { 112 store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence) 113 bz := k.cdc.MustMarshalBinaryLengthPrefixed(evidence) 114 store.Set(evidence.Hash(), bz) 115 } 116 117 // GetEvidence retrieves Evidence by hash if it exists. If no Evidence exists for 118 // the given hash, (nil, false) is returned. 119 func (k Keeper) GetEvidence(ctx sdk.Context, hash tmbytes.HexBytes) (evidence exported.Evidence, found bool) { 120 store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence) 121 122 bz := store.Get(hash) 123 if len(bz) == 0 { 124 return nil, false 125 } 126 127 k.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &evidence) 128 return evidence, true 129 } 130 131 // IterateEvidence provides an interator over all stored Evidence objects. For 132 // each Evidence object, cb will be called. If the cb returns true, the iterator 133 // will close and stop. 134 func (k Keeper) IterateEvidence(ctx sdk.Context, cb func(exported.Evidence) bool) { 135 store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence) 136 iterator := sdk.KVStorePrefixIterator(store, nil) 137 138 defer iterator.Close() 139 for ; iterator.Valid(); iterator.Next() { 140 var evidence exported.Evidence 141 k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &evidence) 142 143 if cb(evidence) { 144 break 145 } 146 } 147 } 148 149 // GetAllEvidence returns all stored Evidence objects. 150 func (k Keeper) GetAllEvidence(ctx sdk.Context) (evidence []exported.Evidence) { 151 k.IterateEvidence(ctx, func(e exported.Evidence) bool { 152 evidence = append(evidence, e) 153 return false 154 }) 155 return evidence 156 }