github.com/cosmos/cosmos-sdk@v0.50.10/types/module/simulation.go (about) 1 package module 2 3 import ( 4 "encoding/json" 5 "math/rand" 6 "sort" 7 "time" 8 9 sdkmath "cosmossdk.io/math" 10 11 "github.com/cosmos/cosmos-sdk/client" 12 "github.com/cosmos/cosmos-sdk/codec" 13 "github.com/cosmos/cosmos-sdk/types/simulation" 14 ) 15 16 // AppModuleSimulation defines the standard functions that every module should expose 17 // for the SDK blockchain simulator 18 type AppModuleSimulation interface { 19 // randomized genesis states 20 GenerateGenesisState(input *SimulationState) 21 22 // register a func to decode the each module's defined types from their corresponding store key 23 RegisterStoreDecoder(simulation.StoreDecoderRegistry) 24 25 // simulation operations (i.e msgs) with their respective weight 26 WeightedOperations(simState SimulationState) []simulation.WeightedOperation 27 } 28 29 // HasProposalMsgs defines the messages that can be used to simulate governance (v1) proposals 30 type HasProposalMsgs interface { 31 // msg functions used to simulate governance proposals 32 ProposalMsgs(simState SimulationState) []simulation.WeightedProposalMsg 33 } 34 35 // HasProposalContents defines the contents that can be used to simulate legacy governance (v1beta1) proposals 36 type HasProposalContents interface { 37 // content functions used to simulate governance proposals 38 ProposalContents(simState SimulationState) []simulation.WeightedProposalContent //nolint:staticcheck // legacy v1beta1 governance 39 } 40 41 // SimulationManager defines a simulation manager that provides the high level utility 42 // for managing and executing simulation functionalities for a group of modules 43 type SimulationManager struct { 44 Modules []AppModuleSimulation // array of app modules; we use an array for deterministic simulation tests 45 StoreDecoders simulation.StoreDecoderRegistry // functions to decode the key-value pairs from each module's store 46 } 47 48 // NewSimulationManager creates a new SimulationManager object 49 // 50 // CONTRACT: All the modules provided must be also registered on the module Manager 51 func NewSimulationManager(modules ...AppModuleSimulation) *SimulationManager { 52 return &SimulationManager{ 53 Modules: modules, 54 StoreDecoders: make(simulation.StoreDecoderRegistry), 55 } 56 } 57 58 // NewSimulationManagerFromAppModules creates a new SimulationManager object. 59 // 60 // First it sets any SimulationModule provided by overrideModules, and ignores any AppModule 61 // with the same moduleName. 62 // Then it attempts to cast every provided AppModule into an AppModuleSimulation. 63 // If the cast succeeds, its included, otherwise it is excluded. 64 func NewSimulationManagerFromAppModules(modules map[string]interface{}, overrideModules map[string]AppModuleSimulation) *SimulationManager { 65 simModules := []AppModuleSimulation{} 66 appModuleNamesSorted := make([]string, 0, len(modules)) 67 for moduleName := range modules { 68 appModuleNamesSorted = append(appModuleNamesSorted, moduleName) 69 } 70 71 sort.Strings(appModuleNamesSorted) 72 73 for _, moduleName := range appModuleNamesSorted { 74 // for every module, see if we override it. If so, use override. 75 // Else, if we can cast the app module into a simulation module add it. 76 // otherwise no simulation module. 77 if simModule, ok := overrideModules[moduleName]; ok { 78 simModules = append(simModules, simModule) 79 } else { 80 appModule := modules[moduleName] 81 if simModule, ok := appModule.(AppModuleSimulation); ok { 82 simModules = append(simModules, simModule) 83 } 84 // cannot cast, so we continue 85 } 86 } 87 return NewSimulationManager(simModules...) 88 } 89 90 // Deprecated: Use GetProposalMsgs instead. 91 // GetProposalContents returns each module's proposal content generator function 92 // with their default operation weight and key. 93 func (sm *SimulationManager) GetProposalContents(simState SimulationState) []simulation.WeightedProposalContent { 94 wContents := make([]simulation.WeightedProposalContent, 0, len(sm.Modules)) 95 for _, module := range sm.Modules { 96 if module, ok := module.(HasProposalContents); ok { 97 wContents = append(wContents, module.ProposalContents(simState)...) 98 } 99 } 100 101 return wContents 102 } 103 104 // GetProposalMsgs returns each module's proposal msg generator function 105 // with their default operation weight and key. 106 func (sm *SimulationManager) GetProposalMsgs(simState SimulationState) []simulation.WeightedProposalMsg { 107 wContents := make([]simulation.WeightedProposalMsg, 0, len(sm.Modules)) 108 for _, module := range sm.Modules { 109 if module, ok := module.(HasProposalMsgs); ok { 110 wContents = append(wContents, module.ProposalMsgs(simState)...) 111 } 112 } 113 114 return wContents 115 } 116 117 // RegisterStoreDecoders registers each of the modules' store decoders into a map 118 func (sm *SimulationManager) RegisterStoreDecoders() { 119 for _, module := range sm.Modules { 120 module.RegisterStoreDecoder(sm.StoreDecoders) 121 } 122 } 123 124 // GenerateGenesisStates generates a randomized GenesisState for each of the 125 // registered modules 126 func (sm *SimulationManager) GenerateGenesisStates(simState *SimulationState) { 127 for _, module := range sm.Modules { 128 module.GenerateGenesisState(simState) 129 } 130 } 131 132 // WeightedOperations returns all the modules' weighted operations of an application 133 func (sm *SimulationManager) WeightedOperations(simState SimulationState) []simulation.WeightedOperation { 134 wOps := make([]simulation.WeightedOperation, 0, len(sm.Modules)) 135 for _, module := range sm.Modules { 136 wOps = append(wOps, module.WeightedOperations(simState)...) 137 } 138 139 return wOps 140 } 141 142 // SimulationState is the input parameters used on each of the module's randomized 143 // GenesisState generator function 144 type SimulationState struct { 145 AppParams simulation.AppParams 146 Cdc codec.JSONCodec // application codec 147 TxConfig client.TxConfig // Shared TxConfig; this is expensive to create and stateless, so create it once up front. 148 Rand *rand.Rand // random number 149 GenState map[string]json.RawMessage // genesis state 150 Accounts []simulation.Account // simulation accounts 151 InitialStake sdkmath.Int // initial coins per account 152 NumBonded int64 // number of initially bonded accounts 153 BondDenom string // denom to be used as default 154 GenTimestamp time.Time // genesis timestamp 155 UnbondTime time.Duration // staking unbond time stored to use it as the slashing maximum evidence duration 156 LegacyParamChange []simulation.LegacyParamChange // simulated parameter changes from modules 157 //nolint:staticcheck // legacy used for testing 158 LegacyProposalContents []simulation.WeightedProposalContent // proposal content generator functions with their default weight and app sim key 159 ProposalMsgs []simulation.WeightedProposalMsg // proposal msg generator functions with their default weight and app sim key 160 }