cosmos-sdk/simapp/utils.go
Federico Kunze 722a633f54
Sim refactor 3: move weighted operations to modules (#4869)
* move GenesisState generators to modules

* minor change on slashing genState generator

* move simulation params back to modules (#4839)

move simulation params back to modules (#4839)

* cleanup params

* various fixes

* move store decoders to modules

* fix

* module pattern

* split generators for param change

* param changes

* revert util pkg

* banksim

* compile

* update Decoders params

* fix

* address @colin-axner comments

* move weighted operations to modules

* cleanup

* cleanup

* Update cmd_test.go

* simulation manager

* mino fixes

* cleanup

* add GenerateGenesisState to simulation manager

* Apply suggestions from code review

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* address @rigelrozanski comments

* changelog

* Apply suggestions from code review

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* restructure modules simulation pkgs

* remove cycle deps

* rename funcs and add missing params

* modularize simulator param changes

* build

* fix params keys

* make format

* various fixes

* fix tests

* minor updates to sim_test

* cleanup

* more cleanup

* modularize genesis generators

* minor cleanup

* remove cdc from generators

* remove cdc

* add get or generate

* fix non-determinism in simulation

* changelog and x/simulation godoc

* cleanup operations

* update operations to use baseapp

* updates and cleanup operations

* update operations

* restructure sim ops params

* rename sim /operations/msg.go to /operations.go

* move GenTx to a helper pkg to avoid circle deps

* rm msg.ValidateBasic

* changelog

* random fees; delete auth's DeductFees sim operation

* add chain-id for sig verification

* Update x/simulation/account.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* fix bank, gov and distr errors

* fix staking and slashing errors; increase prob for send enabled

* increase gas x10

* make format

* fix some distr and staking edge cases

* fix all edge cases

* golang ci

* rename acc vars; default no fees to 0stake

* cleanup; check for exchange rate and skip invalid ops

* fixes

* check for max entries

* add pubkey to genaccounts

* fix gov bug

* update staking sim ops

* fix small redelegation error

* fix small self delegation on unjail

* rm inf loop on random val/accs

* copy array

* add ok boolean to RandomValidator return values

* format

* build

* add WeightedOperations to AppModuleSimulation

* define each module proposals content as part of the module pattern

* Update x/bank/simulation/operations.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Update simapp/helpers/test_helpers.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* address @colin-axner comments

* add genaccount pubkey validation

* fix test

* update operations and move RandomFees to x/simulation

* update gov ops

* address @alexanderbez comments

* avoid modifications to config

* reorder params

* modularized sim operations working

* changelog

* Update types/module/simulation.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* Update x/simulation/params.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* Update x/simulation/params.go

Co-Authored-By: frog power 4000 <rigel.rozanski@gmail.com>

* update /types/module

* Update x/distribution/simulation/genesis.go

Co-Authored-By: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>

* remove named return values

* ensure all operations are simulated

* golangci

* add nolint

* disable whitespace and funlen linter

* disable godox

* add TODO on unjail

* update ops weights

* remove dup

* update godoc

* remove unused func

* build fixes

* move weights to the same file

* scopelint

* changelog

* address @AdityaSripal comments

* address @alexanderbez comments
2019-12-05 10:29:54 +01:00

155 lines
5.9 KiB
Go

package simapp
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/simulation"
)
//---------------------------------------------------------------------
// Flags
// List of available flags for the simulator
var (
FlagGenesisFileValue string
FlagParamsFileValue string
FlagExportParamsPathValue string
FlagExportParamsHeightValue int
FlagExportStatePathValue string
FlagExportStatsPathValue string
FlagSeedValue int64
FlagInitialBlockHeightValue int
FlagNumBlocksValue int
FlagBlockSizeValue int
FlagLeanValue bool
FlagCommitValue bool
FlagOnOperationValue bool // TODO: Remove in favor of binary search for invariant violation
FlagAllInvariantsValue bool
FlagEnabledValue bool
FlagVerboseValue bool
FlagPeriodValue uint
FlagGenesisTimeValue int64
)
// GetSimulatorFlags gets the values of all the available simulation flags
func GetSimulatorFlags() {
// config fields
flag.StringVar(&FlagGenesisFileValue, "Genesis", "", "custom simulation genesis file; cannot be used with params file")
flag.StringVar(&FlagParamsFileValue, "Params", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
flag.StringVar(&FlagExportParamsPathValue, "ExportParamsPath", "", "custom file path to save the exported params JSON")
flag.IntVar(&FlagExportParamsHeightValue, "ExportParamsHeight", 0, "height to which export the randomly generated params")
flag.StringVar(&FlagExportStatePathValue, "ExportStatePath", "", "custom file path to save the exported app state JSON")
flag.StringVar(&FlagExportStatsPathValue, "ExportStatsPath", "", "custom file path to save the exported simulation statistics JSON")
flag.Int64Var(&FlagSeedValue, "Seed", 42, "simulation random seed")
flag.IntVar(&FlagInitialBlockHeightValue, "InitialBlockHeight", 1, "initial block to start the simulation")
flag.IntVar(&FlagNumBlocksValue, "NumBlocks", 500, "number of new blocks to simulate from the initial block height")
flag.IntVar(&FlagBlockSizeValue, "BlockSize", 200, "operations per block")
flag.BoolVar(&FlagLeanValue, "Lean", false, "lean simulation log output")
flag.BoolVar(&FlagCommitValue, "Commit", false, "have the simulation commit")
flag.BoolVar(&FlagOnOperationValue, "SimulateEveryOperation", false, "run slow invariants every operation")
flag.BoolVar(&FlagAllInvariantsValue, "PrintAllInvariants", false, "print all invariants if a broken invariant is found")
// simulation flags
flag.BoolVar(&FlagEnabledValue, "Enabled", false, "enable the simulation")
flag.BoolVar(&FlagVerboseValue, "Verbose", false, "verbose log output")
flag.UintVar(&FlagPeriodValue, "Period", 0, "run slow invariants only once every period assertions")
flag.Int64Var(&FlagGenesisTimeValue, "GenesisTime", 0, "override genesis UNIX time instead of using a random UNIX time")
}
// NewConfigFromFlags creates a simulation from the retrieved values of the flags.
func NewConfigFromFlags() simulation.Config {
return simulation.Config{
GenesisFile: FlagGenesisFileValue,
ParamsFile: FlagParamsFileValue,
ExportParamsPath: FlagExportParamsPathValue,
ExportParamsHeight: FlagExportParamsHeightValue,
ExportStatePath: FlagExportStatePathValue,
ExportStatsPath: FlagExportStatsPathValue,
Seed: FlagSeedValue,
InitialBlockHeight: FlagInitialBlockHeightValue,
NumBlocks: FlagNumBlocksValue,
BlockSize: FlagBlockSizeValue,
Lean: FlagLeanValue,
Commit: FlagCommitValue,
OnOperation: FlagOnOperationValue,
AllInvariants: FlagAllInvariantsValue,
}
}
// SimulationOperations retrieves the simulation params from the provided file path
// and returns all the modules weighted operations
func SimulationOperations(app *SimApp, cdc *codec.Codec, config simulation.Config) []simulation.WeightedOperation {
simState := module.SimulationState{
AppParams: make(simulation.AppParams),
Cdc: cdc,
}
if config.ParamsFile != "" {
bz, err := ioutil.ReadFile(config.ParamsFile)
if err != nil {
panic(err)
}
app.cdc.MustUnmarshalJSON(bz, &simState.AppParams)
}
simState.ParamChanges = app.sm.GenerateParamChanges(config.Seed)
simState.Contents = app.sm.GetProposalContents(simState)
return app.sm.WeightedOperations(simState)
}
//---------------------------------------------------------------------
// Simulation Utils
// ExportStateToJSON util function to export the app state to JSON
func ExportStateToJSON(app *SimApp, path string) error {
fmt.Println("exporting app state...")
appState, _, err := app.ExportAppStateAndValidators(false, nil)
if err != nil {
return err
}
return ioutil.WriteFile(path, []byte(appState), 0644)
}
// ExportParamsToJSON util function to export the simulation parameters to JSON
func ExportParamsToJSON(params simulation.Params, path string) error {
fmt.Println("exporting simulation params...")
paramsBz, err := json.MarshalIndent(params, "", " ")
if err != nil {
return err
}
return ioutil.WriteFile(path, paramsBz, 0644)
}
// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the
// each's module store key and the prefix bytes of the KVPair's key.
func GetSimulationLog(storeName string, sdr sdk.StoreDecoderRegistry, cdc *codec.Codec, kvAs, kvBs []cmn.KVPair) (log string) {
for i := 0; i < len(kvAs); i++ {
if len(kvAs[i].Value) == 0 && len(kvBs[i].Value) == 0 {
// skip if the value doesn't have any bytes
continue
}
decoder, ok := sdr[storeName]
if ok {
log += decoder(cdc, kvAs[i], kvBs[i])
} else {
log += fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvAs[i].Key, kvAs[i].Value, kvBs[i].Key, kvBs[i].Value)
}
}
return
}