Module Simulation
Synopsis
This document guides developers on integrating their custom modules with the Cosmos SDK Simulations
.
Simulations are useful for testing edge cases in module implementations.
- Simulation Package
- Simulation App Module
- SimsX
- Store decoders
- Randomized genesis
- Random weighted operations
- App Simulator manager
- Running Simulations
Simulation Package
The Cosmos SDK suggests organizing your simulation related code in a x/<module>/simulation
package.
Simulation App Module
To integrate with the Cosmos SDK SimulationManager
, app modules must implement the AppModuleSimulation
interface.
loading...
See an example implementation of these methods from x/distribution
here.
SimsX
Cosmos SDK v0.53.0 introduced a new package, simsx
, providing improved DevX for writing simulation code.
It exposes the following extension interfaces that modules may implement to integrate with the new simsx
runner.
loading...
These methods allow constructing randomized messages and/or proposal messages.
Note that modules should not implement both HasWeightedOperationsX
and HasWeightedOperationsXWithProposals
.
See the runner code here for details
If the module does not have message handlers or governance proposal handlers, these interface methods do not need to be implemented.
Example Implementations
Store decoders
Registering the store decoders is required for the AppImportExport
simulation. This allows
for the key-value pairs from the stores to be decoded to their corresponding types.
In particular, it matches the key to a concrete type and then unmarshalls the value from the KVPair
to the type provided.
Modules using collections can use the NewStoreDecoderFuncFromCollectionsSchema
function that builds the decoder for you:
loading...
Modules not using collections must manually build the store decoder. See the implementation here from the distribution module for an example.
Randomized genesis
The simulator tests different scenarios and values for genesis parameters.
App modules must implement a GenerateGenesisState
method to generate the initial random GenesisState
from a given seed.
loading...
See an example from x/auth
here.
Once the module's genesis parameters are generated randomly (or with the key and
values defined in a params
file), they are marshaled to JSON format and added
to the app genesis JSON for the simulation.
Random weighted operations
Operations are one of the crucial parts of the Cosmos SDK simulation. They are the transactions
(Msg
) that are simulated with random field values. The sender of the operation
is also assigned randomly.
Operations on the simulation are simulated using the full transaction cycle of a
ABCI
application that exposes the BaseApp
.
Using Simsx
Simsx introduces the ability to define a MsgFactory
for each of a module's messages.
These factories are registered in WeightedOperationsX
and/or ProposalMsgsX
.
loading...
Note that the name passed in to weights.Get
must match the name of the operation set in the WeightedOperations
.
For example, if the module contains an operation op_weight_msg_set_withdraw_address
, the name passed to weights.Get
should be msg_set_withdraw_address
.
See the x/distribution
for an example of implementing message factories here
App Simulator manager
The following step is setting up the SimulatorManager
at the app level. This
is required for the simulation test files in the next step.
type CoolApp struct {
...
sm *module.SimulationManager
}
Within the constructor of the application, construct the simulation manager using the modules from ModuleManager
and call the RegisterStoreDecoders
method.
loading...
Note that you may override some modules.
This is useful if the existing module configuration in the ModuleManager
should be different in the SimulationManager
.
Finally, the application should expose the SimulationManager
via the following method defined in the Runtime
interface:
// SimulationManager implements the SimulationApp interface
func (app *SimApp) SimulationManager() *module.SimulationManager {
return app.sm
}
Running Simulations
To run the simulation, use the simsx
runner.
Call the following function from the simsx
package to begin simulating with a default seed:
loading...
If a custom seed is desired, tests should use RunWithSeed
:
loading...
These functions should be called in tests (i.e., app_test.go, app_sim_test.go, etc.)
Example:
loading...