github.com/cosmos/cosmos-sdk@v0.50.10/docs/docs/build/building-modules/14-simulator.md (about)

     1  ---
     2  sidebar_position: 1
     3  ---
     4  
     5  # Module Simulation
     6  
     7  :::note Pre-requisite Readings
     8  
     9  * [Cosmos Blockchain Simulator](../../learn/advanced/12-simulation.md)
    10  :::
    11  
    12  ## Synopsis
    13  
    14  This document details how to define each module simulation functions to be
    15  integrated with the application `SimulationManager`.
    16    
    17  * [Simulation package](#simulation-package)
    18      * [Store decoders](#store-decoders)
    19      * [Randomized genesis](#randomized-genesis)
    20      * [Random weighted operations](#random-weighted-operations)
    21      * [Random proposal contents](#random-proposal-contents)
    22  * [Registering simulation functions](#registering-simulation-functions)
    23  * [App Simulator manager](#app-simulator-manager)
    24  
    25  ## Simulation package
    26  
    27  Every module that implements the Cosmos SDK simulator needs to have a `x/<module>/simulation`
    28  package which contains the primary functions required by the fuzz tests: store
    29  decoders, randomized genesis state and parameters, weighted operations and proposal
    30  contents.
    31  
    32  ### Store decoders
    33  
    34  Registering the store decoders is required for the `AppImportExport`. This allows
    35  for the key-value pairs from the stores to be decoded (_i.e_ unmarshalled)
    36  to their corresponding types. In particular, it matches the key to a concrete type
    37  and then unmarshals the value from the `KVPair` to the type provided.
    38  
    39  You can use the example [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/distribution/simulation/decoder.go) from the distribution module to implement your store decoders.
    40  
    41  ### Randomized genesis
    42  
    43  The simulator tests different scenarios and values for genesis parameters
    44  in order to fully test the edge cases of specific modules. The `simulator` package from each module must expose a `RandomizedGenState` function to generate the initial random `GenesisState` from a given seed.
    45  
    46  Once the module genesis parameter are generated randomly (or with the key and
    47  values defined in a `params` file), they are marshaled to JSON format and added
    48  to the app genesis JSON to use it on the simulations.
    49  
    50  You can check an example on how to create the randomized genesis [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/genesis.go).
    51  
    52  ### Randomized parameter changes
    53  
    54  The simulator is able to test parameter changes at random. The simulator package from each module must contain a `RandomizedParams` func that will simulate parameter changes of the module throughout the simulations lifespan.
    55  
    56  You can see how an example of what is needed to fully test parameter changes [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/params.go)
    57  
    58  ### Random weighted operations
    59  
    60  Operations are one of the crucial parts of the Cosmos SDK simulation. They are the transactions
    61  (`Msg`) that are simulated with random field values. The sender of the operation
    62  is also assigned randomly.
    63  
    64  Operations on the simulation are simulated using the full [transaction cycle](../../learn/advanced/01-transactions.md) of a
    65  `ABCI` application that exposes the `BaseApp`.
    66  
    67  Shown below is how weights are set:
    68  
    69  ```go reference
    70  https://github.com/cosmos/cosmos-sdk/blob/release/v0.50.x/x/staking/simulation/operations.go#L19-L86
    71  ```
    72  
    73  As you can see, the weights are predefined in this case. Options exist to override this behavior with different weights. One option is to use `*rand.Rand` to define a random weight for the operation, or you can inject your own predefined weights.
    74  
    75  Here is how one can override the above package `simappparams`.
    76  
    77  ```go reference
    78  https://github.com/cosmos/cosmos-sdk/blob/release/v0.50.x/Makefile#L293-L299
    79  ```
    80  
    81  For the last test a tool called [runsim](https://github.com/cosmos/tools/tree/master/cmd/runsim) is used, this is used to parallelize go test instances, provide info to Github and slack integrations to provide information to your team on how the simulations are running.  
    82  
    83  ### Random proposal contents
    84  
    85  Randomized governance proposals are also supported on the Cosmos SDK simulator. Each
    86  module must define the governance proposal `Content`s that they expose and register
    87  them to be used on the parameters.
    88  
    89  ## Registering simulation functions
    90  
    91  Now that all the required functions are defined, we need to integrate them into the module pattern within the `module.go`:
    92  
    93  ```go reference
    94  https://github.com/cosmos/cosmos-sdk/blob/release/v0.50.x/x/distribution/module.go#L180-L203
    95  ```
    96  
    97  ## App Simulator manager
    98  
    99  The following step is setting up the `SimulatorManager` at the app level. This
   100  is required for the simulation test files on the next step.
   101  
   102  ```go
   103  type CustomApp struct {
   104    ...
   105    sm *module.SimulationManager
   106  }
   107  ```
   108  
   109  Then at the instantiation of the application, we create the `SimulationManager`
   110  instance in the same way we create the `ModuleManager` but this time we only pass
   111  the modules that implement the simulation functions from the `AppModuleSimulation`
   112  interface described above.
   113  
   114  ```go
   115  func NewCustomApp(...) {
   116    // create the simulation manager and define the order of the modules for deterministic simulations
   117    app.sm = module.NewSimulationManager(
   118      auth.NewAppModule(app.accountKeeper),
   119      bank.NewAppModule(app.bankKeeper, app.accountKeeper),
   120      supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
   121      gov.NewAppModule(app.govKeeper, app.accountKeeper, app.supplyKeeper),
   122      mint.NewAppModule(app.mintKeeper),
   123      distr.NewAppModule(app.distrKeeper, app.accountKeeper, app.supplyKeeper, app.stakingKeeper),
   124      staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.supplyKeeper),
   125      slashing.NewAppModule(app.slashingKeeper, app.accountKeeper, app.stakingKeeper),
   126    )
   127  
   128    // register the store decoders for simulation tests
   129    app.sm.RegisterStoreDecoders()
   130    ...
   131  }
   132  ```