github.com/Finschia/finschia-sdk@v0.48.1/x/evidence/keeper/keeper.go (about)

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