133 lines
5.2 KiB
Go
133 lines
5.2 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/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 int
|
|
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")
|
|
|
|
// SimApp flags
|
|
flag.BoolVar(&flagEnabledValue, "Enabled", false, "enable the simulation")
|
|
flag.BoolVar(&flagVerboseValue, "Verbose", false, "verbose log output")
|
|
flag.IntVar(&flagPeriodValue, "Period", 1, "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
|
|
}
|