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/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, } } //--------------------------------------------------------------------- // 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 }