Documentation ¶
Overview ¶
Package simulation implements a full fledged Cosmos SDK application used for executing simulation test suites.
Simulation App ¶
The SimApp type defines an application used for running extensive simulation testing suites. It contains all core modules, including governance, staking, slashing, and distribution.
Simulation is executed with various inputs including the number of blocks to simulate, the block size, whether the app should commit or not, the invariant checking period, and a seed which is used as a source of pseudo-randomness.
In addition to the various inputs, simulation runs mainly in three modes:
1. Completely random where the initial state, module parameters and simulation parameters are pseudo-randomly generated.
2. From a genesis file where the initial state and the module parameters are defined. This mode is helpful for running simulations on a known state such as a live network export where a new (mostly likely breaking) version of the application needs to be tested.
3. From a params file where the initial state is pseudo-randomly generated but the module and simulation parameters can be provided manually. This allows for a more controlled and deterministic simulation setup while allowing the state space to still be pseudo-randomly simulated.
The simulation test suite also supports testing determinism and import/export functionality.
Randomness ¶
Currently, simulation uses a single seed (integer) as a source for a PRNG by which all random operations are executed from. Any call to the PRNG changes all future operations as the internal state of the PRNG is modified. For example, if a new message type is created and needs to be simulated, the new introduced PRNG call will change all subsequent operations.
This may can often be problematic when testing fixes to simulation faults. One current solution to this is to use a params file as mentioned above. In the future the simulation suite is expected to support a series of PRNGs that can be used uniquely per module and simulation component so that they will not effect each others state execution outcome.
Usage ¶
To execute a completely pseudo-random simulation:
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \ -run=TestFullAppSimulation \ -Enabled=true \ -NumBlocks=100 \ -BlockSize=200 \ -Commit=true \ -Seed=99 \ -Period=5 \ -v -timeout 24h
To execute simulation from a genesis file:
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \ -run=TestFullAppSimulation \ -Enabled=true \ -NumBlocks=100 \ -BlockSize=200 \ -Commit=true \ -Seed=99 \ -Period=5 \ -Genesis=/path/to/genesis.json \ -v -timeout 24h
To execute simulation from a simulation params file:
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \ -run=TestFullAppSimulation \ -Enabled=true \ -NumBlocks=100 \ -BlockSize=200 \ -Commit=true \ -Seed=99 \ -Period=5 \ -Params=/path/to/params.json \ -v -timeout 24h
To export the simulation params to a file at a given block height:
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \ -run=TestFullAppSimulation \ -Enabled=true \ -NumBlocks=100 \ -BlockSize=200 \ -Commit=true \ -Seed=99 \ -Period=5 \ -ExportParamsPath=/path/to/params.json \ -ExportParamsHeight=50 \ -v -timeout 24h
To export the simulation app state (i.e genesis) to a file:
$ go test -mod=readonly github.com/cosmos/cosmos-sdk/simapp \ -run=TestFullAppSimulation \ -Enabled=true \ -NumBlocks=100 \ -BlockSize=200 \ -Commit=true \ -Seed=99 \ -Period=5 \ -ExportStatePath=/path/to/genesis.json \ v -timeout 24h
Params ¶
Params that are provided to simulation from a JSON file are used to used to set both module parameters and simulation parameters. See sim_test.go for the full set of parameters that can be provided.
Index ¶
- Constants
- Variables
- func DefaultRandomConsensusParams(r *rand.Rand, appState json.RawMessage, cdc codec.JSONCodec) *abci.ConsensusParams
- func GetSimulatorFlags()
- func PrintStats(db dbm.DB)
- func RandomRequestBeginBlock(r *rand.Rand, params Params, validators mockValidators, pastTimes []time.Time, ...) abci.RequestBeginBlock
- func RandomSimAccounts(r *rand.Rand, n int) []simulation.Account
- func SimulateFromSeed(tb testing.TB, w io.Writer, appCreator simtypes.AppCreator, ...) (lastCommitId storetypes.CommitID, stopEarly bool, err error)
- type AppStateFn
- type Config
- type DummyLogWriter
- type EmptyAppOptions
- type ExecutionDbConfig
- type ExportConfig
- type InitChainFn
- type InitFunctions
- type InitializationConfig
- type LogWriter
- type OperationEntry
- func BeginBlockEntry(height int64) OperationEntry
- func EndBlockEntry(height int64) OperationEntry
- func MsgEntry(height, order int64, opMsg simulation.OperationMsg) OperationEntry
- func NewOperationEntry(entry string, height, order int64, op json.RawMessage) OperationEntry
- func QueuedMsgEntry(height int64, opMsg simulation.OperationMsg) OperationEntry
- type OperationQueue
- type Params
- func (p Params) BlockSizeTransitionMatrix() simulation.TransitionMatrix
- func (p Params) EvidenceFraction() float64
- func (p Params) InitialLivenessWeightings() []int
- func (p Params) LivenessTransitionMatrix() simulation.TransitionMatrix
- func (p Params) NumKeys() int
- func (p Params) PastEvidenceFraction() float64
- type RandomAccountFn
- type StandardLogWriter
Constants ¶
const ( BeginBlockEntryKind = "begin_block" EndBlockEntryKind = "end_block" MsgEntryKind = "msg" QueuedMsgEntryKind = "queued_msg" )
entry kinds for use within OperationEntry
const AverageBlockTime = 6 * time.Second
Variables ¶
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 FlagWriteStatsToDB bool FlagEnabledValue bool FlagVerboseValue bool FlagPeriodValue uint FlagGenesisTimeValue int64 )
List of available flags for the simulator
Functions ¶
func DefaultRandomConsensusParams ¶
func DefaultRandomConsensusParams(r *rand.Rand, appState json.RawMessage, cdc codec.JSONCodec) *abci.ConsensusParams
DefaultRandomConsensusParams returns random simulation consensus parameters, it extracts the Evidence from the Staking genesis state.
func GetSimulatorFlags ¶
func GetSimulatorFlags()
GetSimulatorFlags gets the values of all the available simulation flags
func PrintStats ¶
PrintStats prints the corresponding statistics from the app DB.
func RandomRequestBeginBlock ¶
func RandomRequestBeginBlock(r *rand.Rand, params Params, validators mockValidators, pastTimes []time.Time, pastVoteInfos [][]abci.VoteInfo, event func(route, op, evResult string), header tmproto.Header, ) abci.RequestBeginBlock
RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction
func RandomSimAccounts ¶
func RandomSimAccounts(r *rand.Rand, n int) []simulation.Account
RandomAccounts generates n random accounts
func SimulateFromSeed ¶
func SimulateFromSeed( tb testing.TB, w io.Writer, appCreator simtypes.AppCreator, initFunctions InitFunctions, config Config, ) (lastCommitId storetypes.CommitID, stopEarly bool, err error)
SimulateFromSeed tests an application by running the provided operations, testing the provided invariants, but using the provided config.Seed. TODO: Inputs should be: * SimManager for module configs * Config file for params * whatever is needed for logging (tb + w rn) OR: * Could be a struct or something with options, to give caller ability to step through / instrument benchmarking if they wanted to, and add a cleanup function.
Types ¶
type AppStateFn ¶
type AppStateFn func(simManager simtypes.ModuleGenesisGenerator, r *rand.Rand, accs []legacysim.Account, config InitializationConfig) ( appState json.RawMessage, accounts []legacysim.Account, chainId string, genesisTimestamp time.Time, )
AppStateFn returns the app state json bytes and the genesis accounts
type Config ¶
type Config struct { InitializationConfig InitializationConfig ExportConfig ExportConfig ExecutionDbConfig ExecutionDbConfig Seed int64 // simulation random seed NumBlocks int // number of new blocks to simulate from the initial block height BlockSize int // operations per block Lean bool // lean simulation log output OnOperation bool // run slow invariants every operation AllInvariants bool // print all failed invariants if a broken invariant is found }
func NewConfigFromFlags ¶
func NewConfigFromFlags() Config
NewConfigFromFlags creates a simulation from the retrieved values of the flags.
func SetupSimulation ¶
func SetupSimulation(dirPrefix, dbName string) (cfg Config, db dbm.DB, logger log.Logger, cleanup func(), err error)
SetupSimulation creates the config, db (levelDB), temporary directory and logger for the simulation tests. If `FlagEnabledValue` is false it skips the current test. Returns error on an invalid db intantiation or temp dir creation.
type EmptyAppOptions ¶
type EmptyAppOptions struct{}
EmptyAppOptions is a stub implementing AppOptions
func (EmptyAppOptions) Get ¶
func (ao EmptyAppOptions) Get(o string) interface{}
Get implements AppOptions
type ExecutionDbConfig ¶
type ExecutionDbConfig struct {
UseMerkleTree bool // Use merkle tree underneath, vs using a "fake" merkle tree
}
func NewExecutionDbConfigFromFlags ¶
func NewExecutionDbConfigFromFlags() ExecutionDbConfig
type ExportConfig ¶
type ExportConfig = stats.ExportConfig
func NewExportConfigFromFlags ¶
func NewExportConfigFromFlags() ExportConfig
type InitChainFn ¶
type InitChainFn func(simManager simtypes.ModuleGenesisGenerator, r *rand.Rand, accs []legacysim.Account, config InitializationConfig) ( accounts []legacysim.Account, req abci.RequestInitChain)
type InitFunctions ¶
type InitFunctions struct { // Why does this take in Numkeys / why isn't this part of the initial state function / config to decide? RandomAccountFn RandomAccountFn InitChainFn InitChainFn }
TODO: Consider adding consensus parameters / simulator params / tendermint params to this.
func DefaultSimInitFunctions ¶
func DefaultSimInitFunctions(moduleAccountAddresses map[string]bool) InitFunctions
TODO: cleanup args in the future, should ideally just be a slice.
type InitializationConfig ¶
type InitializationConfig struct { GenesisFile string // custom simulation genesis file; cannot be used with params file ParamsFile string // custom simulation params file which overrides any random params; cannot be used with genesis InitialBlockHeight int // initial block to start the simulation ChainID string // chain-id used on the simulation }
Config for how to initialize the simulator state
func NewInitializationConfigFromFlags ¶
func NewInitializationConfigFromFlags() InitializationConfig
type LogWriter ¶
type LogWriter interface { AddEntry(OperationEntry) PrintLogs() }
log writter
func NewLogWriter ¶
LogWriter - return a dummy or standard log writer given the testingmode
type OperationEntry ¶
type OperationEntry struct { EntryKind string `json:"entry_kind" yaml:"entry_kind"` Height int64 `json:"height" yaml:"height"` Order int64 `json:"order" yaml:"order"` Operation json.RawMessage `json:"operation" yaml:"operation"` }
OperationEntry - an operation entry for logging (ex. BeginBlock, EndBlock, XxxMsg, etc)
func BeginBlockEntry ¶
func BeginBlockEntry(height int64) OperationEntry
BeginBlockEntry - operation entry for begin block
func EndBlockEntry ¶
func EndBlockEntry(height int64) OperationEntry
EndBlockEntry - operation entry for end block
func MsgEntry ¶
func MsgEntry(height, order int64, opMsg simulation.OperationMsg) OperationEntry
MsgEntry - operation entry for standard msg
func NewOperationEntry ¶
func NewOperationEntry(entry string, height, order int64, op json.RawMessage) OperationEntry
NewOperationEntry creates a new OperationEntry instance
func QueuedMsgEntry ¶
func QueuedMsgEntry(height int64, opMsg simulation.OperationMsg) OperationEntry
QueuedMsgEntry creates an operation entry for a given queued message.
func (OperationEntry) MustMarshal ¶
func (oe OperationEntry) MustMarshal() json.RawMessage
MustMarshal marshals the operation entry, panic on error.
type OperationQueue ¶
type OperationQueue map[int][]simulation.Operation
OperationQueue defines an object for a queue of operations
func NewOperationQueue ¶
func NewOperationQueue() OperationQueue
NewOperationQueue creates a new OperationQueue instance.
type Params ¶
type Params struct {
// contains filtered or unexported fields
}
Params define the parameters necessary for running the simulations
func RandomParams ¶
RandomParams returns random simulation parameters
func (Params) BlockSizeTransitionMatrix ¶
func (p Params) BlockSizeTransitionMatrix() simulation.TransitionMatrix
func (Params) EvidenceFraction ¶
func (Params) InitialLivenessWeightings ¶
func (Params) LivenessTransitionMatrix ¶
func (p Params) LivenessTransitionMatrix() simulation.TransitionMatrix
func (Params) PastEvidenceFraction ¶
type RandomAccountFn ¶
RandomAccountFn returns a slice of n random simulation accounts
func WrapRandAccFnForResampling ¶
func WrapRandAccFnForResampling(randFn RandomAccountFn, blockList map[string]bool) RandomAccountFn
type StandardLogWriter ¶
type StandardLogWriter struct {
OpEntries []OperationEntry `json:"op_entries" yaml:"op_entries"`
}
log writter
func (*StandardLogWriter) AddEntry ¶
func (lw *StandardLogWriter) AddEntry(opEntry OperationEntry)
add an entry to the log writter
func (*StandardLogWriter) PrintLogs ¶
func (lw *StandardLogWriter) PrintLogs()
PrintLogs - print the logs to a simulation file