cosmos-sdk/x/evidence/keeper/keeper.go

182 lines
5.8 KiB
Go
Raw Normal View History

package keeper
import (
"fmt"
refactor: Remove store type aliases (#10295) <!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description Closes: #9362 <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [X] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [X] added `!` to the type prefix if API or client breaking change - [X] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [X] provided a link to the relevant issue or specification - [X] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [X] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [X] added a changelog entry to `CHANGELOG.md` - [X] included comments for [documenting Go code](https://blog.golang.org/godoc) - [X] updated the relevant documentation or specification - [X] reviewed "Files changed" and left comments if necessary - [X] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
2021-10-04 09:36:38 -07:00
storetypes "github.com/cosmos/cosmos-sdk/store/types"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/libs/log"
2020-05-05 12:13:36 -07:00
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
)
// Keeper defines the evidence module's keeper. The keeper is responsible for
// managing persistence, state transitions and query handling for the evidence
// module.
type Keeper struct {
cdc codec.BinaryCodec
refactor: Remove store type aliases (#10295) <!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description Closes: #9362 <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [X] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [X] added `!` to the type prefix if API or client breaking change - [X] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [X] provided a link to the relevant issue or specification - [X] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [X] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [X] added a changelog entry to `CHANGELOG.md` - [X] included comments for [documenting Go code](https://blog.golang.org/godoc) - [X] updated the relevant documentation or specification - [X] reviewed "Files changed" and left comments if necessary - [X] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
2021-10-04 09:36:38 -07:00
storeKey storetypes.StoreKey
router types.Router
stakingKeeper types.StakingKeeper
slashingKeeper types.SlashingKeeper
}
func NewKeeper(
refactor: Remove store type aliases (#10295) <!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description Closes: #9362 <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [X] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [X] added `!` to the type prefix if API or client breaking change - [X] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [X] provided a link to the relevant issue or specification - [X] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [X] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [X] added a changelog entry to `CHANGELOG.md` - [X] included comments for [documenting Go code](https://blog.golang.org/godoc) - [X] updated the relevant documentation or specification - [X] reviewed "Files changed" and left comments if necessary - [X] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
2021-10-04 09:36:38 -07:00
cdc codec.BinaryCodec, storeKey storetypes.StoreKey, stakingKeeper types.StakingKeeper,
slashingKeeper types.SlashingKeeper,
) *Keeper {
return &Keeper{
cdc: cdc,
storeKey: storeKey,
stakingKeeper: stakingKeeper,
slashingKeeper: slashingKeeper,
}
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+types.ModuleName)
}
// SetRouter sets the Evidence Handler router for the x/evidence module. Note,
// we allow the ability to set the router after the Keeper is constructed as a
// given Handler may need access the Keeper before being constructed. The router
// may only be set once and will be sealed if it's not already sealed.
func (k *Keeper) SetRouter(rtr types.Router) {
// It is vital to seal the Evidence Handler router as to not allow further
// handlers to be registered after the keeper is created since this
// could create invalid or non-deterministic behavior.
if !rtr.Sealed() {
rtr.Seal()
}
if k.router != nil {
panic(fmt.Sprintf("attempting to reset router on x/%s", types.ModuleName))
}
k.router = rtr
}
// GetEvidenceHandler returns a registered Handler for a given Evidence type. If
// no handler exists, an error is returned.
func (k Keeper) GetEvidenceHandler(evidenceRoute string) (types.Handler, error) {
if !k.router.HasRoute(evidenceRoute) {
return nil, sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidenceRoute)
}
return k.router.GetRoute(evidenceRoute), nil
}
// SubmitEvidence attempts to match evidence against the keepers router and execute
// 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 {
return sdkerrors.Wrap(types.ErrEvidenceExists, evidence.Hash().String())
}
if !k.router.HasRoute(evidence.Route()) {
return sdkerrors.Wrap(types.ErrNoEvidenceHandlerExists, evidence.Route())
}
handler := k.router.GetRoute(evidence.Route())
if err := handler(ctx, evidence); err != nil {
return sdkerrors.Wrap(types.ErrInvalidEvidence, err.Error())
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSubmitEvidence,
sdk.NewAttribute(types.AttributeKeyEvidenceHash, evidence.Hash().String()),
),
)
k.SetEvidence(ctx, evidence)
return nil
}
// 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))
}
// 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 tmbytes.HexBytes) (exported.Evidence, bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixEvidence)
bz := store.Get(hash)
if len(bz) == 0 {
return nil, false
}
return k.MustUnmarshalEvidence(bz), true
}
// 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 := sdk.KVStorePrefixIterator(store, nil)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
evidence := k.MustUnmarshalEvidence(iterator.Value())
if cb(evidence) {
break
}
}
}
// GetAllEvidence returns all stored Evidence objects.
func (k Keeper) GetAllEvidence(ctx sdk.Context) (evidence []exported.Evidence) {
k.IterateEvidence(ctx, func(e exported.Evidence) bool {
evidence = append(evidence, e)
return false
})
return evidence
}
// 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 {
2020-05-05 12:13:36 -07:00
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 {
2020-05-05 12:13:36 -07:00
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
2020-05-05 12:13:36 -07:00
func (k Keeper) MarshalEvidence(evidenceI exported.Evidence) ([]byte, error) {
return k.cdc.MarshalInterface(evidenceI)
2020-05-05 12:13:36 -07:00
}
// 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) {
2020-05-05 12:13:36 -07:00
var evi exported.Evidence
return evi, k.cdc.UnmarshalInterface(bz, &evi)
2020-05-05 12:13:36 -07:00
}