x/evidence: StoreDecoder simulation (#6035)
* x/evidence: simulations * update app * evidence store decoder * add evidence to sim import export * fix test * prevent zero values on randomized genesis * return empty evidences for genesis state * address comments from review
This commit is contained in:
parent
f6e9ee7623
commit
8c736bb72f
|
@ -219,6 +219,7 @@ functionality that requires an online connection.
|
|||
* (client) [\#5895](https://github.com/cosmos/cosmos-sdk/issues/5895) show config options in the config command's help screen.
|
||||
* (types/rest) [\#5900](https://github.com/cosmos/cosmos-sdk/pull/5900) Add Check*Error function family to spare developers from replicating tons of boilerplate code.
|
||||
* (x/evidence) [\#5952](https://github.com/cosmos/cosmos-sdk/pull/5952) Tendermint Consensus parameters can now be changed via parameter change proposals through `x/gov`.
|
||||
* (x/evidence) [\#5961](https://github.com/cosmos/cosmos-sdk/issues/5961) Add `StoreDecoder` simulation for evidence module.
|
||||
* (x/auth/ante) [\#6040](https://github.com/cosmos/cosmos-sdk/pull/6040) `AccountKeeper` interface used for `NewAnteHandler` and handler's decorators to add support of using custom `AccountKeeper` implementations.
|
||||
* (simulation) [\#6002](https://github.com/cosmos/cosmos-sdk/pull/6002) Add randomized consensus params into simulation.
|
||||
|
||||
|
|
|
@ -271,7 +271,7 @@ func NewSimApp(
|
|||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
|
||||
upgrade.NewAppModule(app.UpgradeKeeper),
|
||||
evidence.NewAppModule(app.EvidenceKeeper),
|
||||
evidence.NewAppModule(appCodec, app.EvidenceKeeper),
|
||||
ibc.NewAppModule(app.IBCKeeper),
|
||||
params.NewAppModule(app.ParamsKeeper),
|
||||
transferModule,
|
||||
|
@ -313,6 +313,7 @@ func NewSimApp(
|
|||
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
|
||||
params.NewAppModule(app.ParamsKeeper),
|
||||
evidence.NewAppModule(appCodec, app.EvidenceKeeper),
|
||||
)
|
||||
|
||||
app.sm.RegisterStoreDecoders()
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
|
@ -156,6 +157,7 @@ func TestAppImportExport(t *testing.T) {
|
|||
{app.keys[bank.StoreKey], newApp.keys[bank.StoreKey], [][]byte{bank.BalancesPrefix}},
|
||||
{app.keys[paramtypes.StoreKey], newApp.keys[paramtypes.StoreKey], [][]byte{}},
|
||||
{app.keys[gov.StoreKey], newApp.keys[gov.StoreKey], [][]byte{}},
|
||||
{app.keys[evidence.StoreKey], newApp.keys[evidence.StoreKey], [][]byte{}},
|
||||
}
|
||||
|
||||
for _, skp := range storeKeysPrefixes {
|
||||
|
|
|
@ -3,14 +3,17 @@ package evidence
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/client"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/client/rest"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/simulation"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -18,11 +21,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
|
||||
// TODO: Enable simulation once concrete types are defined.
|
||||
// _ module.AppModuleSimulation = AppModuleSimulation{}
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
_ module.AppModuleSimulation = AppModule{}
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -31,9 +32,11 @@ var (
|
|||
|
||||
// AppModuleBasic implements the AppModuleBasic interface for the evidence module.
|
||||
type AppModuleBasic struct {
|
||||
cdc Codec
|
||||
evidenceHandlers []client.EvidenceHandler // client evidence submission handlers
|
||||
}
|
||||
|
||||
// NewAppModuleBasic crates a AppModuleBasic without the codec.
|
||||
func NewAppModuleBasic(evidenceHandlers ...client.EvidenceHandler) AppModuleBasic {
|
||||
return AppModuleBasic{
|
||||
evidenceHandlers: evidenceHandlers,
|
||||
|
@ -103,9 +106,9 @@ type AppModule struct {
|
|||
keeper Keeper
|
||||
}
|
||||
|
||||
func NewAppModule(keeper Keeper) AppModule {
|
||||
func NewAppModule(cdc Codec, keeper Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: NewAppModuleBasic(),
|
||||
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
||||
keeper: keeper,
|
||||
}
|
||||
}
|
||||
|
@ -166,3 +169,33 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
|
|||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________
|
||||
|
||||
// AppModuleSimulation functions
|
||||
|
||||
// GenerateGenesisState creates a randomized GenState of the evidence module.
|
||||
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
|
||||
simulation.RandomizedGenState(simState)
|
||||
}
|
||||
|
||||
// ProposalContents returns all the evidence content functions used to
|
||||
// simulate governance proposals.
|
||||
func (am AppModule) ProposalContents(simState module.SimulationState) []simtypes.WeightedProposalContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RandomizedParams creates randomized evidence param changes for the simulator.
|
||||
func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for evidence module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
|
||||
sdr[StoreKey] = simulation.NewDecodeStore(am.cdc)
|
||||
}
|
||||
|
||||
// WeightedOperations returns the all the gov module operations with their respective weights.
|
||||
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
tmkv "github.com/tendermint/tendermint/libs/kv"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
)
|
||||
|
||||
// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's
|
||||
// Value to the corresponding evidence type.
|
||||
func NewDecodeStore(cdc types.Codec) func(kvA, kvB tmkv.Pair) string {
|
||||
return func(kvA, kvB tmkv.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]))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package simulation_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmkv "github.com/tendermint/tendermint/libs/kv"
|
||||
|
||||
codecstd "github.com/cosmos/cosmos-sdk/codec/std"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
)
|
||||
|
||||
func TestDecodeStore(t *testing.T) {
|
||||
cdc := codecstd.NewAppCodec(codecstd.MakeCodec(simapp.ModuleBasics))
|
||||
dec := simulation.NewDecodeStore(cdc)
|
||||
|
||||
delPk1 := ed25519.GenPrivKey().PubKey()
|
||||
|
||||
ev := types.Equivocation{
|
||||
Height: 10,
|
||||
Time: time.Now().UTC(),
|
||||
Power: 1000,
|
||||
ConsensusAddress: sdk.ConsAddress(delPk1.Address()),
|
||||
}
|
||||
|
||||
evBz, err := cdc.MarshalEvidence(&ev)
|
||||
require.NoError(t, err)
|
||||
|
||||
kvPairs := tmkv.Pairs{
|
||||
tmkv.Pair{
|
||||
Key: types.KeyPrefixEvidence,
|
||||
Value: evBz,
|
||||
},
|
||||
tmkv.Pair{
|
||||
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[i], kvPairs[i]) }, tt.name)
|
||||
default:
|
||||
require.Equal(t, tt.expectedLog, dec(kvPairs[i], kvPairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package simulation
|
||||
|
||||
// DONTCOVER
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/exported"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
)
|
||||
|
||||
// Simulation parameter constants
|
||||
const evidence = "evidence"
|
||||
|
||||
// GenEvidences returns an empty slice of evidences.
|
||||
func GenEvidences(_ *rand.Rand, _ []simtypes.Account) []exported.Evidence {
|
||||
return []exported.Evidence{}
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for evidence
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var ev []exported.Evidence
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, evidence, &ev, simState.Rand,
|
||||
func(r *rand.Rand) { ev = GenEvidences(r, simState.Accounts) },
|
||||
)
|
||||
|
||||
evidenceGenesis := types.GenesisState{Evidence: ev}
|
||||
|
||||
fmt.Printf("Selected randomly generated %s parameters:\n%s\n", types.ModuleName, codec.MustMarshalJSONIndent(simState.Cdc, evidenceGenesis))
|
||||
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(evidenceGenesis)
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence/exported"
|
||||
)
|
||||
|
||||
|
@ -27,7 +29,10 @@ func DefaultGenesisState() GenesisState {
|
|||
// Validate performs basic gensis state validation returning an error upon any
|
||||
// failure.
|
||||
func (gs GenesisState) Validate() error {
|
||||
for _, e := range gs.Evidence {
|
||||
for i, e := range gs.Evidence {
|
||||
if e == nil {
|
||||
return fmt.Errorf("evidence %d cannot be nil", i)
|
||||
}
|
||||
if err := e.ValidateBasic(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue