simulation

package
v3.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2024 License: Apache-2.0 Imports: 28 Imported by: 0

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

Switch to `simapp/` directory:

$ cd simapp/

To execute a completely pseudo-random simulation:

 $ go test -mod=readonly . \
	-tags='sims' \
	-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 . \
	-tags='sims' \
 	-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 . \
	-tags='sims' \
	-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 . \
	-tags='sims' \
 	-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 . \
	-tags='sims' \
 	-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 set both module parameters and simulation parameters. See sim_test.go for the full set of parameters that can be provided.

Index

Constants

View Source
const (
	BeginBlockEntryKind = "begin_block"
	EndBlockEntryKind   = "end_block"
	MsgEntryKind        = "msg"
	QueuedMsgEntryKind  = "queued_msg"
)

entry kinds for use within OperationEntry

View Source
const AverageBlockTime = 6 * time.Second
View Source
const (
	TruncatedSize = 20
)

TODO: move this somewhere else

Variables

This section is empty.

Functions

func CreateTransitionMatrix

func CreateTransitionMatrix(weights [][]int) (simulation.TransitionMatrix, error)

CreateTransitionMatrix creates a transition matrix from the provided weights. TODO: Provide example usage

func GenAndDeliverTx

func GenAndDeliverTx(txCtx OperationInput, fees sdk.Coins) (simtypes.OperationMsg, []simtypes.FutureOperation, error)

GenAndDeliverTx generates a transactions and delivers it.

func GenAndDeliverTxWithRandFees

func GenAndDeliverTxWithRandFees(txCtx OperationInput) (simtypes.OperationMsg, []simtypes.FutureOperation, error)

GenAndDeliverTxWithRandFees generates a transaction with a random fee and delivers it.

func GetMemberOfInitialState

func GetMemberOfInitialState(r *rand.Rand, weights []int) int

GetMemberOfInitialState takes an initial array of weights, of size n. It returns a weighted random number in [0,n).

func NewSimLegacyParamChange

func NewSimLegacyParamChange(subspace, key string, simVal simulation.SimValFn) simulation.LegacyParamChange

NewSimLegacyParamChange creates a new LegacyParamChange instance

func NewWeightedProposalContent

func NewWeightedProposalContent(appParamsKey string, defaultWeight int, contentSimulatorFn simulation.ContentSimulatorFn) simulation.WeightedProposalContent

func NewWeightedProposalMsg

func NewWeightedProposalMsg(appParamsKey string, defaultWeight int, msgSimulatorFn simulation.MsgSimulatorFn) simulation.WeightedProposalMsg

func RandomRequestFinalizeBlock

func RandomRequestFinalizeBlock(
	r *rand.Rand,
	params Params,
	validators mockValidators,
	pastTimes []time.Time,
	pastVoteInfos [][]abci.VoteInfo,
	event func(route, op, evResult string),
	blockHeight int64,
	time time.Time,
	proposer []byte,
) *abci.FinalizeBlockRequest

RandomRequestFinalizeBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction

func SumTruncated

func SumTruncated(bz []byte) []byte

SumTruncated returns the first 20 bytes of SHA256 of the bz.

Types

type AccountKeeper

type AccountKeeper interface {
	GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
}

AccountKeeper defines the expected account keeper used for simulations (noalias)

type BankKeeper

type BankKeeper interface {
	SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins
}

BankKeeper defines the expected interface needed to retrieve account balances.

type ByteSource

type ByteSource struct {
	// contains filtered or unexported fields
}

ByteSource offers deterministic pseudo-random numbers for math.Rand with fuzzer support. The 'seed' data is read in big endian to uint64. When exhausted, it falls back to a standard random number generator initialized with a specific 'seed' value.

func NewByteSource

func NewByteSource(fuzzSeed []byte, seed int64) *ByteSource

NewByteSource creates a new ByteSource with a specified byte slice and seed. This gives a fixed sequence of pseudo-random numbers. Initially, it utilizes the byte slice. Once that's exhausted, it continues generating numbers using the provided seed.

func (*ByteSource) Int63

func (s *ByteSource) Int63() int64

func (*ByteSource) Seed

func (s *ByteSource) Seed(seed int64)

func (*ByteSource) Uint64

func (s *ByteSource) Uint64() uint64

type DummyLogWriter

type DummyLogWriter struct{}

dummy log writer

func (*DummyLogWriter) AddEntry

func (lw *DummyLogWriter) AddEntry(_ OperationEntry)

do nothing

func (*DummyLogWriter) PrintLogs

func (lw *DummyLogWriter) PrintLogs()

do nothing

type EventStats

type EventStats map[string]map[string]map[string]int

EventStats defines an object that keeps a tally of each event that has occurred during a simulation.

func NewEventStats

func NewEventStats() EventStats

NewEventStats creates a new empty EventStats object

func (EventStats) ExportJSON

func (es EventStats) ExportJSON(path string)

ExportJSON saves the event stats as a JSON file on a given path

func (EventStats) Print

func (es EventStats) Print(w io.Writer)

Print the event stats in JSON format.

func (EventStats) Tally

func (es EventStats) Tally(moduleName, op, evResult string)

Tally increases the count of a simulation event.

type LegacyParamChange

type LegacyParamChange struct {
	// contains filtered or unexported fields
}

LegacyParamChange defines the object used for simulating parameter change proposals

func (LegacyParamChange) ComposedKey

func (spc LegacyParamChange) ComposedKey() string

ComposedKey creates a new composed key for the legacy param change proposal

func (LegacyParamChange) Key

func (spc LegacyParamChange) Key() string

func (LegacyParamChange) SimValue

func (spc LegacyParamChange) SimValue() simulation.SimValFn

func (LegacyParamChange) Subspace

func (spc LegacyParamChange) Subspace() string

type LogWriter

type LogWriter interface {
	AddEntry(OperationEntry)
	PrintLogs()
}

log writer

func NewLogWriter

func NewLogWriter(testingmode bool) LogWriter

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"`
	BlockTime int64           `json:"block_time" yaml:"block_time"`
}

OperationEntry - an operation entry for logging (ex. BeginBlock, EndBlock, XxxMsg, etc)

func BeginBlockEntry

func BeginBlockEntry(blockTime time.Time, height int64) OperationEntry

BeginBlockEntry - operation entry for begin block

func EndBlockEntry

func EndBlockEntry(blockTime time.Time, height int64) OperationEntry

EndBlockEntry - operation entry for end block

func MsgEntry

func MsgEntry(blockTime time.Time, height, order int64, opMsg simulation.OperationMsg) OperationEntry

MsgEntry - operation entry for standard msg

func NewOperationEntry

func NewOperationEntry(entry string, blockTime time.Time, height, order int64, op json.RawMessage) OperationEntry

NewOperationEntry creates a new OperationEntry instance

func QueuedMsgEntry

func QueuedMsgEntry(blockTime time.Time, 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 OperationInput

type OperationInput struct {
	R               *rand.Rand
	App             *baseapp.BaseApp
	TxGen           client.TxConfig
	Cdc             *codec.ProtoCodec
	Msg             sdk.Msg
	CoinsSpentInMsg sdk.Coins
	Context         sdk.Context
	SimAccount      simtypes.Account
	AccountKeeper   AccountKeeper
	Bankkeeper      BankKeeper
	ModuleName      string
}

OperationInput is a struct that holds all the needed values to generate a tx and deliver it

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

func RandomParams(r *rand.Rand) Params

RandomParams returns random simulation parameters

func SimulateFromSeed

func SimulateFromSeed(
	tb testing.TB,
	logger log.Logger,
	w io.Writer,
	app *baseapp.BaseApp,
	appStateFn simulation.AppStateFn,
	randAccFn simulation.RandomAccountFn,
	ops WeightedOperations,
	blockedAddrs map[string]bool,
	config simulation.Config,
	cdc codec.JSONCodec,
	addressCodec address.Codec,
) (exportedParams Params, err error)

SimulateFromSeed tests an application by running the provided operations, testing the provided invariants, but using the provided config.Seed.

func SimulateFromSeedX

func SimulateFromSeedX(
	tb testing.TB,
	logger log.Logger,
	w io.Writer,
	app *baseapp.BaseApp,
	appStateFn simulation.AppStateFn,
	randAccFn simulation.RandomAccountFn,
	ops WeightedOperations,
	blockedAddrs map[string]bool,
	config simulation.Config,
	cdc codec.JSONCodec,
	addressCodec address.Codec,
	logWriter LogWriter,
) (exportedParams Params, err error)

SimulateFromSeedX tests an application by running the provided operations, testing the provided invariants, but using the provided config.Seed.

func (Params) BlockSizeTransitionMatrix

func (p Params) BlockSizeTransitionMatrix() simulation.TransitionMatrix

func (Params) EvidenceFraction

func (p Params) EvidenceFraction() float64

func (Params) InitialLivenessWeightings

func (p Params) InitialLivenessWeightings() []int

func (Params) LivenessTransitionMatrix

func (p Params) LivenessTransitionMatrix() simulation.TransitionMatrix

func (Params) NumKeys

func (p Params) NumKeys() int

func (Params) PastEvidenceFraction

func (p Params) PastEvidenceFraction() float64

type StandardLogWriter

type StandardLogWriter struct {
	Seed int64

	OpEntries []OperationEntry `json:"op_entries" yaml:"op_entries"`
	// contains filtered or unexported fields
}

log writer

func (*StandardLogWriter) AddEntry

func (lw *StandardLogWriter) AddEntry(opEntry OperationEntry)

add an entry to the log writer

func (*StandardLogWriter) PrintLogs

func (lw *StandardLogWriter) PrintLogs()

PrintLogs - print the logs to a simulation file

type TransitionMatrix

type TransitionMatrix struct {
	// contains filtered or unexported fields
}

TransitionMatrix is _almost_ a left stochastic matrix. It is technically not one due to not normalizing the column values. In the future, if we want to find the steady state distribution, it will be quite easy to normalize these values to get a stochastic matrix. Floats aren't currently used as the default due to non-determinism across architectures

func (TransitionMatrix) NextState

func (t TransitionMatrix) NextState(r *rand.Rand, i int) int

NextState returns the next state randomly chosen using r, and the weightings provided in the transition matrix.

type WeightedOperation

type WeightedOperation struct {
	// contains filtered or unexported fields
}

WeightedOperation is an operation with associated weight. This is used to bias the selection operation within the simulator.

func NewWeightedOperation

func NewWeightedOperation(weight int, op simulation.Operation) WeightedOperation

NewWeightedOperation creates a new WeightedOperation instance

func (WeightedOperation) Op

func (WeightedOperation) Weight

func (w WeightedOperation) Weight() int

type WeightedOperations

type WeightedOperations []simulation.WeightedOperation

WeightedOperations is the group of all weighted operations to simulate.

type WeightedProposalContent

type WeightedProposalContent struct {
	// contains filtered or unexported fields
}

WeightedProposalContent defines a common struct for proposal content defined by external modules (i.e outside gov)

func (WeightedProposalContent) AppParamsKey

func (w WeightedProposalContent) AppParamsKey() string

func (WeightedProposalContent) ContentSimulatorFn

func (w WeightedProposalContent) ContentSimulatorFn() simulation.ContentSimulatorFn

func (WeightedProposalContent) DefaultWeight

func (w WeightedProposalContent) DefaultWeight() int

type WeightedProposalMsg

type WeightedProposalMsg struct {
	// contains filtered or unexported fields
}

WeightedProposalMsg defines a common struct for proposal msgs defined by external modules (i.e outside gov)

func (WeightedProposalMsg) AppParamsKey

func (w WeightedProposalMsg) AppParamsKey() string

func (WeightedProposalMsg) DefaultWeight

func (w WeightedProposalMsg) DefaultWeight() int

func (WeightedProposalMsg) MsgSimulatorFn

func (w WeightedProposalMsg) MsgSimulatorFn() simulation.MsgSimulatorFn

Directories

Path Synopsis
client
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL