From 022d46e3b195e0cd799208816745c88c88911d6b Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Fri, 12 Aug 2022 15:03:43 -0500 Subject: [PATCH 1/6] Propert check interface & manager definition --- simulation/internal/pubsub/manager.go | 48 +++++++++++++++++++++++++++ simulation/simtypes/manager.go | 8 ++++- simulation/simtypes/propertycheck.go | 20 +++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 simulation/internal/pubsub/manager.go create mode 100644 simulation/simtypes/propertycheck.go diff --git a/simulation/internal/pubsub/manager.go b/simulation/internal/pubsub/manager.go new file mode 100644 index 00000000000..5a2aa0a187a --- /dev/null +++ b/simulation/internal/pubsub/manager.go @@ -0,0 +1,48 @@ +package pubsub + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "go.uber.org/multierr" + + "github.com/osmosis-labs/osmosis/v10/simulation/simtypes" +) + +var _ simtypes.PubSubManager = &Manager{} + +type Manager struct { + sim *simtypes.SimCtx + subscriptions map[string][]callbackfnWithMetadata +} + +type callbackfnWithMetadata struct { + subscriberName string + callback simtypes.SimCallbackFn +} + +func NewPubSubManager(sim *simtypes.SimCtx) Manager { + return Manager{sim: sim, subscriptions: map[string][]callbackfnWithMetadata{}} +} + +func (m *Manager) Subscribe(key string, subName string, callback simtypes.SimCallbackFn) { + subscriptions, ok := m.subscriptions[key] + callbackStruct := callbackfnWithMetadata{subscriberName: subName, callback: callback} + if ok { + subscriptions = append(subscriptions, callbackStruct) + } else { + subscriptions = []callbackfnWithMetadata{callbackStruct} + } + m.subscriptions[key] = subscriptions +} + +func (m *Manager) Publish(ctx sdk.Context, key string, value interface{}) error { + subscriptions, ok := m.subscriptions[key] + if !ok { + return nil + } + var result error + for _, s := range subscriptions { + err := s.callback(m.sim, ctx, value) + result = multierr.Append(result, err) + } + return result +} diff --git a/simulation/simtypes/manager.go b/simulation/simtypes/manager.go index b617064a600..275143e782e 100644 --- a/simulation/simtypes/manager.go +++ b/simulation/simtypes/manager.go @@ -20,7 +20,6 @@ type AppModuleSimulation interface { module.AppModule Actions() []Action - // PropertyTests() } type AppModuleSimulationGenesis interface { @@ -29,8 +28,15 @@ type AppModuleSimulationGenesis interface { SimulatorGenesisState(*module.SimulationState, *SimCtx) } +type AppModuleSimulationPropertyCheck interface { + module.AppModule + + PropertyChecks() []PropertyCheck +} + type SimulatorManagerI interface { Actions() []ActionsWithMetadata + PropertyCheck() []PropertyCheck } type ActionsWithMetadata struct { diff --git a/simulation/simtypes/propertycheck.go b/simulation/simtypes/propertycheck.go new file mode 100644 index 00000000000..7521c48ed8c --- /dev/null +++ b/simulation/simtypes/propertycheck.go @@ -0,0 +1,20 @@ +package simtypes + +import sdk "github.com/cosmos/cosmos-sdk/types" + +type SimCallbackFn func(sim *SimCtx, ctx sdk.Context, value interface{}) error + +type PubSubManager interface { + Subscribe(key string, subName string, callback SimCallbackFn) + Publish(ctx sdk.Context, key string, value interface{}) error +} + +type PropertyCheck interface { + // A property check listens for signals on the listed channels, that the simulator can emit. + // Known channel types right now: + // * Post-Action execute + // * Pre-Action execute + // * Block end (can make listener execute every Nth block end) + SubscriptionKeys() []string + Check(sim *SimCtx, ctx sdk.Context, key string, value interface{}) error +} From a368d8748a1b7dd4be863a490481119977ae6ae6 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 3 Sep 2022 17:45:50 +0200 Subject: [PATCH 2/6] driveby gamm move actions to file --- x/gamm/module.go | 12 +----------- x/gamm/simulation/sim_setup.go | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 11 deletions(-) create mode 100644 x/gamm/simulation/sim_setup.go diff --git a/x/gamm/module.go b/x/gamm/module.go index b8fb3bbfe30..b171b186b8f 100644 --- a/x/gamm/module.go +++ b/x/gamm/module.go @@ -177,15 +177,5 @@ func (am AppModule) SimulatorGenesisState(simState *module.SimulationState, s *s } func (am AppModule) Actions() []simtypes.Action { - return []simtypes.Action{ - simtypes.NewMsgBasedAction("MsgJoinPool", am.keeper, simulation.RandomJoinPoolMsg).WithFrequency(simtypes.Frequent), - simtypes.NewMsgBasedAction("MsgExitPool", am.keeper, simulation.RandomExitPoolMsg), - simtypes.NewMsgBasedAction("CreateUniV2Msg", am.keeper, simulation.RandomCreateUniV2Msg).WithFrequency(simtypes.Frequent), - simtypes.NewMsgBasedAction("SwapExactAmountIn", am.keeper, simulation.RandomSwapExactAmountIn), - simtypes.NewMsgBasedAction("SwapExactAmountOut", am.keeper, simulation.RandomSwapExactAmountOut), - simtypes.NewMsgBasedAction("JoinSwapExternAmountIn", am.keeper, simulation.RandomJoinSwapExternAmountIn), - simtypes.NewMsgBasedAction("JoinSwapShareAmountOut", am.keeper, simulation.RandomJoinSwapShareAmountOut), - simtypes.NewMsgBasedAction("ExitSwapExternAmountOut", am.keeper, simulation.RandomExitSwapExternAmountOut), - simtypes.NewMsgBasedAction("ExitSwapShareAmountIn", am.keeper, simulation.RandomExitSwapShareAmountIn), - } + return simulation.DefaultActions(am.keeper) } diff --git a/x/gamm/simulation/sim_setup.go b/x/gamm/simulation/sim_setup.go new file mode 100644 index 00000000000..635975e7ae1 --- /dev/null +++ b/x/gamm/simulation/sim_setup.go @@ -0,0 +1,20 @@ +package gammsimulation + +import ( + "github.com/osmosis-labs/osmosis/v11/simulation/simtypes" + "github.com/osmosis-labs/osmosis/v11/x/gamm/keeper" +) + +func DefaultActions(keeper keeper.Keeper) []simtypes.Action { + return []simtypes.Action{ + simtypes.NewMsgBasedAction("MsgJoinPool", keeper, RandomJoinPoolMsg).WithFrequency(simtypes.Frequent), + simtypes.NewMsgBasedAction("MsgExitPool", keeper, RandomExitPoolMsg), + simtypes.NewMsgBasedAction("CreateUniV2Msg", keeper, RandomCreateUniV2Msg).WithFrequency(simtypes.Frequent), + simtypes.NewMsgBasedAction("SwapExactAmountIn", keeper, RandomSwapExactAmountIn), + simtypes.NewMsgBasedAction("SwapExactAmountOut", keeper, RandomSwapExactAmountOut), + simtypes.NewMsgBasedAction("JoinSwapExternAmountIn", keeper, RandomJoinSwapExternAmountIn), + simtypes.NewMsgBasedAction("JoinSwapShareAmountOut", keeper, RandomJoinSwapShareAmountOut), + simtypes.NewMsgBasedAction("ExitSwapExternAmountOut", keeper, RandomExitSwapExternAmountOut), + simtypes.NewMsgBasedAction("ExitSwapShareAmountIn", keeper, RandomExitSwapShareAmountIn), + } +} From 06d1d2b018cc2e9fc0d782b9ce4f8e6c2c260a2b Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 3 Sep 2022 18:16:27 +0200 Subject: [PATCH 3/6] Start cleaning up more of the initialization code --- .gitignore | 2 +- simulation/executor/legacyconfig.go | 82 ++++++++++++++++++--------- simulation/executor/simulate.go | 28 ++++----- simulation/executor/simulate_dev.go | 22 +++---- simulation/executor/types.go | 2 +- simulation/internal/pubsub/manager.go | 11 ++-- simulation/simtypes/propertycheck.go | 2 +- tests/simulator/sim_test.go | 11 ++-- tests/simulator/state.go | 2 +- 9 files changed, 93 insertions(+), 69 deletions(-) diff --git a/.gitignore b/.gitignore index c7abd84e00f..713ac5a1033 100644 --- a/.gitignore +++ b/.gitignore @@ -229,4 +229,4 @@ Cargo.lock # Ignores beaker state .beaker blocks.db -**/blocks.db +**/blocks.db* diff --git a/simulation/executor/legacyconfig.go b/simulation/executor/legacyconfig.go index d6730bb6a0a..6d3e5757c57 100644 --- a/simulation/executor/legacyconfig.go +++ b/simulation/executor/legacyconfig.go @@ -57,7 +57,6 @@ func GetSimulatorFlags() { flag.IntVar(&FlagNumBlocksValue, "NumBlocks", 500, "number of new blocks to simulate from the initial block height") flag.IntVar(&FlagBlockSizeValue, "BlockSize", 200, "operations per block") flag.BoolVar(&FlagLeanValue, "Lean", false, "lean simulation log output") - flag.BoolVar(&FlagCommitValue, "Commit", false, "have the simulation commit") flag.BoolVar(&FlagOnOperationValue, "SimulateEveryOperation", false, "run slow invariants every operation") flag.BoolVar(&FlagAllInvariantsValue, "PrintAllInvariants", false, "print all invariants if a broken invariant is found") flag.BoolVar(&FlagWriteStatsToDB, "WriteStatsToDB", false, "write stats to a local sqlite3 database") @@ -72,24 +71,42 @@ func GetSimulatorFlags() { // NewConfigFromFlags creates a simulation from the retrieved values of the flags. func NewConfigFromFlags() Config { return Config{ - GenesisFile: FlagGenesisFileValue, - ParamsFile: FlagParamsFileValue, + InitializationConfig: NewInitializationConfigFromFlags(), + ExportConfig: NewExportConfigFromFlags(), + ExecutionDbConfig: NewExecutionDbConfigFromFlags(), + Seed: FlagSeedValue, + NumBlocks: FlagNumBlocksValue, + BlockSize: FlagBlockSizeValue, + Lean: FlagLeanValue, + OnOperation: FlagOnOperationValue, + AllInvariants: FlagAllInvariantsValue, + } +} + +func NewExportConfigFromFlags() ExportConfig { + return ExportConfig{ ExportParamsPath: FlagExportParamsPathValue, ExportParamsHeight: FlagExportParamsHeightValue, ExportStatePath: FlagExportStatePathValue, ExportStatsPath: FlagExportStatsPathValue, - Seed: FlagSeedValue, - InitialBlockHeight: FlagInitialBlockHeightValue, - NumBlocks: FlagNumBlocksValue, - BlockSize: FlagBlockSizeValue, - Lean: FlagLeanValue, - Commit: FlagCommitValue, - OnOperation: FlagOnOperationValue, - AllInvariants: FlagAllInvariantsValue, WriteStatsToDB: FlagWriteStatsToDB, } } +func NewInitializationConfigFromFlags() InitializationConfig { + return InitializationConfig{ + GenesisFile: FlagGenesisFileValue, + ParamsFile: FlagParamsFileValue, + InitialBlockHeight: FlagInitialBlockHeightValue, + } +} + +func NewExecutionDbConfigFromFlags() ExecutionDbConfig { + return ExecutionDbConfig{ + UseMerkleTree: true, + } +} + // 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. @@ -99,7 +116,7 @@ func SetupSimulation(dirPrefix, dbName string) (Config, dbm.DB, string, log.Logg } config := NewConfigFromFlags() - config.ChainID = helpers.SimAppChainID + config.InitializationConfig.ChainID = helpers.SimAppChainID var logger log.Logger if FlagVerboseValue { @@ -129,24 +146,37 @@ func PrintStats(db dbm.DB) { } type Config 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 + InitializationConfig InitializationConfig + ExportConfig ExportConfig + ExecutionDbConfig ExecutionDbConfig - ExportParamsPath string // custom file path to save the exported params JSON - ExportParamsHeight int // height to which export the randomly generated params - ExportStatePath string // custom file path to save the exported app state JSON - ExportStatsPath string // custom file path to save the exported simulation statistics JSON + 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 +} - Seed int64 // simulation random seed +// Config for how to initialize the simulator state +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 - NumBlocks int // number of new blocks to simulate from the initial block height - BlockSize int // operations per block ChainID string // chain-id used on the simulation +} - Lean bool // lean simulation log output - Commit bool // have the simulation commit +type ExportConfig struct { + ExportParamsPath string // custom file path to save the exported params JSON + ExportParamsHeight int // height to which export the randomly generated params + ExportStatePath string // custom file path to save the exported app state JSON + ExportStatsPath string // custom file path to save the exported simulation statistics JSON + WriteStatsToDB bool +} - OnOperation bool // run slow invariants every operation - AllInvariants bool // print all failed invariants if a broken invariant is found - WriteStatsToDB bool +type ExecutionDbConfig struct { + UseMerkleTree bool // Use merkle tree underneath, vs using a "fake" merkle tree } diff --git a/simulation/executor/simulate.go b/simulation/executor/simulate.go index 1a5704c1b25..45c3f35b7cf 100644 --- a/simulation/executor/simulate.go +++ b/simulation/executor/simulate.go @@ -70,7 +70,7 @@ func SimulateFromSeed( // Set up sql table var db *sql.DB - if config.WriteStatsToDB { + if config.ExportConfig.WriteStatsToDB { db, err = sql.Open("sqlite3", "./blocks.db") if err != nil { tb.Fatal(err) @@ -122,9 +122,9 @@ func SimulateFromSeed( }() } - stopEarly = simState.SimulateAllBlocks(w, simCtx, blockSimulator, config) + stopEarly = simState.SimulateAllBlocks(w, simCtx, blockSimulator) - simState.eventStats.exportEvents(config.ExportStatsPath, w) + simState.eventStats.exportEvents(config.ExportConfig.ExportStatsPath, w) return stopEarly, nil } @@ -157,11 +157,11 @@ func cursedInitializationLogic( genesisTimestamp.UTC().Format(time.UnixDate), genesisTimestamp.Unix(), ) - simCtx := simtypes.NewSimCtx(r, app, accs, config.ChainID) + simCtx := simtypes.NewSimCtx(r, app, accs, config.InitializationConfig.ChainID) initialHeader := tmproto.Header{ - ChainID: config.ChainID, - Height: int64(config.InitialBlockHeight), + ChainID: config.InitializationConfig.ChainID, + Height: int64(config.InitializationConfig.InitialBlockHeight), Time: genesisTimestamp, ProposerAddress: validators.randomProposer(r).Address(), AppHash: res.AppHash, @@ -170,7 +170,7 @@ func cursedInitializationLogic( // must set version in order to generate hashes initialHeader.Version.Block = 11 - simState := newSimulatorState(simParams, initialHeader, tb, w, validators).WithLogParam(config.Lean) + simState := newSimulatorState(simParams, initialHeader, tb, w, validators, *config) // TODO: If simulation has a param export path configured, export params here. @@ -187,7 +187,7 @@ func initChain( config *Config, ) (mockValidators, time.Time, []simulation.Account, abci.ResponseInitChain) { // TODO: Cleanup the whole config dependency with appStateFn - appState, accounts, chainID, genesisTimestamp := appStateFn(r, accounts, *config) + appState, accounts, chainID, genesisTimestamp := appStateFn(r, accounts, config.InitializationConfig) consensusParams := randomConsensusParams(r, appState, app.AppCodec()) req := abci.RequestInitChain{ AppStateBytes: appState, @@ -201,9 +201,9 @@ func initChain( validators := newMockValidators(r, res.Validators, params) // update config - config.ChainID = chainID - if config.InitialBlockHeight == 0 { - config.InitialBlockHeight = 1 + config.InitializationConfig.ChainID = chainID + if config.InitializationConfig.InitialBlockHeight == 0 { + config.InitializationConfig.InitialBlockHeight = 1 } return validators, genesisTimestamp, accounts, res @@ -285,7 +285,7 @@ func (simState *simState) logActionResult( header tmproto.Header, actionIndex int, config Config, blocksize int, opMsg simulation.OperationMsg, resultData []byte, db *sql.DB, actionErr error) { opMsg.LogEvent(simState.eventStats.Tally) - if config.WriteStatsToDB { + if config.ExportConfig.WriteStatsToDB { appHash := fmt.Sprintf("%X", simState.header.AppHash) resData := fmt.Sprintf("%X", resultData) sts := "INSERT INTO blocks(height,module,name,comment,passed, gasWanted, gasUsed, msg, resData, appHash) VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);" @@ -295,7 +295,7 @@ func (simState *simState) logActionResult( } } - if !simState.leanLogs || opMsg.OK { + if !simState.config.Lean || opMsg.OK { simState.logWriter.AddEntry(MsgEntry(header.Height, int64(actionIndex), opMsg)) } @@ -327,7 +327,7 @@ func (simState *simState) runQueuedOperations(simCtx *simtypes.SimCtx, ctx sdk.C opMsg, _, err := queuedOp[i](r, simCtx.BaseApp(), ctx, simCtx.Accounts, simCtx.ChainID()) opMsg.LogEvent(simState.eventStats.Tally) - if !simState.leanLogs || opMsg.OK { + if !simState.config.Lean || opMsg.OK { simState.logWriter.AddEntry((QueuedMsgEntry(int64(height), opMsg))) } diff --git a/simulation/executor/simulate_dev.go b/simulation/executor/simulate_dev.go index d6d94602b9c..d617fe46d46 100644 --- a/simulation/executor/simulate_dev.go +++ b/simulation/executor/simulate_dev.go @@ -41,7 +41,6 @@ type simState struct { pastTimes []time.Time pastVoteInfos [][]abci.VoteInfo - leanLogs bool logWriter LogWriter w io.Writer @@ -51,9 +50,11 @@ type simState struct { // Its fine to keep some basic aggregate statistics, but not where it should end. eventStats EventStats opCount int + + config Config } -func newSimulatorState(simParams Params, initialHeader tmproto.Header, tb testing.TB, w io.Writer, validators mockValidators) *simState { +func newSimulatorState(simParams Params, initialHeader tmproto.Header, tb testing.TB, w io.Writer, validators mockValidators, config Config) *simState { return &simState{ simParams: simParams, header: initialHeader, @@ -67,29 +68,24 @@ func newSimulatorState(simParams Params, initialHeader tmproto.Header, tb testin w: w, eventStats: NewEventStats(), opCount: 0, + config: config, } } -func (simState *simState) WithLogParam(leanLogs bool) *simState { - simState.leanLogs = leanLogs - return simState -} - func (simState *simState) SimulateAllBlocks( w io.Writer, simCtx *simtypes.SimCtx, - blockSimulator blockSimFn, - config Config) (stopEarly bool) { + blockSimulator blockSimFn) (stopEarly bool) { stopEarly = false - for height := config.InitialBlockHeight; height < config.NumBlocks+config.InitialBlockHeight && !stopEarly; height++ { + initialHeight := simState.config.InitializationConfig.InitialBlockHeight + numBlocks := simState.config.NumBlocks + for height := initialHeight; height < numBlocks+initialHeight && !stopEarly; height++ { stopEarly = simState.SimulateBlock(simCtx, blockSimulator) if stopEarly { break } - if config.Commit { - simCtx.BaseApp().Commit() - } + simCtx.BaseApp().Commit() } if !stopEarly { diff --git a/simulation/executor/types.go b/simulation/executor/types.go index 700ff3e6e83..5b5ac83965e 100644 --- a/simulation/executor/types.go +++ b/simulation/executor/types.go @@ -9,7 +9,7 @@ import ( ) // AppStateFn returns the app state json bytes and the genesis accounts -type AppStateFn func(r *rand.Rand, accs []simtypes.Account, config Config) ( +type AppStateFn func(r *rand.Rand, accs []simtypes.Account, config InitializationConfig) ( appState json.RawMessage, accounts []simtypes.Account, chainId string, genesisTimestamp time.Time, ) diff --git a/simulation/internal/pubsub/manager.go b/simulation/internal/pubsub/manager.go index 5a2aa0a187a..9b604176327 100644 --- a/simulation/internal/pubsub/manager.go +++ b/simulation/internal/pubsub/manager.go @@ -4,13 +4,12 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "go.uber.org/multierr" - "github.com/osmosis-labs/osmosis/v10/simulation/simtypes" + "github.com/osmosis-labs/osmosis/v11/simulation/simtypes" ) var _ simtypes.PubSubManager = &Manager{} type Manager struct { - sim *simtypes.SimCtx subscriptions map[string][]callbackfnWithMetadata } @@ -19,8 +18,8 @@ type callbackfnWithMetadata struct { callback simtypes.SimCallbackFn } -func NewPubSubManager(sim *simtypes.SimCtx) Manager { - return Manager{sim: sim, subscriptions: map[string][]callbackfnWithMetadata{}} +func NewPubSubManager() Manager { + return Manager{subscriptions: map[string][]callbackfnWithMetadata{}} } func (m *Manager) Subscribe(key string, subName string, callback simtypes.SimCallbackFn) { @@ -34,14 +33,14 @@ func (m *Manager) Subscribe(key string, subName string, callback simtypes.SimCal m.subscriptions[key] = subscriptions } -func (m *Manager) Publish(ctx sdk.Context, key string, value interface{}) error { +func (m *Manager) Publish(sim *simtypes.SimCtx, ctx sdk.Context, key string, value interface{}) error { subscriptions, ok := m.subscriptions[key] if !ok { return nil } var result error for _, s := range subscriptions { - err := s.callback(m.sim, ctx, value) + err := s.callback(sim, ctx, value) result = multierr.Append(result, err) } return result diff --git a/simulation/simtypes/propertycheck.go b/simulation/simtypes/propertycheck.go index 7521c48ed8c..96ac68151ab 100644 --- a/simulation/simtypes/propertycheck.go +++ b/simulation/simtypes/propertycheck.go @@ -6,7 +6,7 @@ type SimCallbackFn func(sim *SimCtx, ctx sdk.Context, value interface{}) error type PubSubManager interface { Subscribe(key string, subName string, callback SimCallbackFn) - Publish(ctx sdk.Context, key string, value interface{}) error + Publish(sim *SimCtx, ctx sdk.Context, key string, value interface{}) error } type PropertyCheck interface { diff --git a/tests/simulator/sim_test.go b/tests/simulator/sim_test.go index 8a57a743107..43b8b69d049 100644 --- a/tests/simulator/sim_test.go +++ b/tests/simulator/sim_test.go @@ -57,7 +57,7 @@ func fullAppSimulation(tb testing.TB, is_testing bool) { logger = simlogger.NewSimLogger(logger) // This file is needed to provide the correct path // to reflect.wasm test file needed for wasmd simulation testing. - config.ParamsFile = "params.json" + config.InitializationConfig.ParamsFile = "params.json" defer func() { db.Close() @@ -109,7 +109,7 @@ func fullAppSimulation(tb testing.TB, is_testing bool) { tb.Fatal(simErr) } - if config.Commit { + if config.ExecutionDbConfig.UseMerkleTree { osmosim.PrintStats(db) } } @@ -128,17 +128,16 @@ func TestAppStateDeterminism(t *testing.T) { // } config := osmosim.NewConfigFromFlags() - config.ExportParamsPath = "" + config.ExportConfig.ExportParamsPath = "" config.NumBlocks = 50 config.BlockSize = 5 config.OnOperation = false config.AllInvariants = false - config.ChainID = helpers.SimAppChainID - config.Commit = true + config.InitializationConfig.ChainID = helpers.SimAppChainID // This file is needed to provide the correct path // to reflect.wasm test file needed for wasmd simulation testing. - config.ParamsFile = "params.json" + config.InitializationConfig.ParamsFile = "params.json" numSeeds := 3 numTimesToRunPerSeed := 5 diff --git a/tests/simulator/state.go b/tests/simulator/state.go index 97578f3a5c3..c743382cf50 100644 --- a/tests/simulator/state.go +++ b/tests/simulator/state.go @@ -25,7 +25,7 @@ import ( // It panics if the user provides files for both of them. // If a file is not given for the genesis or the sim params, it creates a randomized one. func AppStateFn(cdc codec.JSONCodec, simManager *osmosimtypes.Manager) osmosim.AppStateFn { - return func(r *rand.Rand, accs []simtypes.Account, config osmosim.Config, + return func(r *rand.Rand, accs []simtypes.Account, config osmosim.InitializationConfig, ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { if osmosim.FlagGenesisTimeValue == 0 { genesisTimestamp = simtypes.RandTimestamp(r) From afd317f8dab64f368419babe6933a51f4cd639bd Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 3 Sep 2022 18:22:47 +0200 Subject: [PATCH 4/6] Remove enocding config param to app --- app/app.go | 2 +- app/config.go | 6 ++---- app/test_helpers.go | 5 ++--- cmd/osmosisd/cmd/root.go | 5 ++--- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/app.go b/app/app.go index 9a7072acf3f..feecec7763f 100644 --- a/app/app.go +++ b/app/app.go @@ -152,12 +152,12 @@ func NewOsmosisApp( skipUpgradeHeights map[int64]bool, homePath string, invCheckPeriod uint, - encodingConfig appparams.EncodingConfig, appOpts servertypes.AppOptions, wasmEnabledProposals []wasm.ProposalType, wasmOpts []wasm.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *OsmosisApp { + encodingConfig := appparams.MakeEncodingConfig() appCodec := encodingConfig.Marshaler cdc := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry diff --git a/app/config.go b/app/config.go index f83aa341cc3..6d271c9b836 100644 --- a/app/config.go +++ b/app/config.go @@ -4,7 +4,6 @@ import ( "fmt" "time" - "github.com/osmosis-labs/osmosis/v11/app/params" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" @@ -30,7 +29,7 @@ func DefaultConfig() network.Config { LegacyAmino: encCfg.Amino, InterfaceRegistry: encCfg.InterfaceRegistry, AccountRetriever: authtypes.AccountRetriever{}, - AppConstructor: NewAppConstructor(encCfg), + AppConstructor: NewAppConstructor(), GenesisState: ModuleBasics.DefaultGenesis(encCfg.Marshaler), TimeoutCommit: 1 * time.Second / 2, ChainID: "osmosis-code-test", @@ -48,11 +47,10 @@ func DefaultConfig() network.Config { } // NewAppConstructor returns a new Osmosis app given encoding type configs. -func NewAppConstructor(encodingCfg params.EncodingConfig) network.AppConstructor { +func NewAppConstructor() network.AppConstructor { return func(val network.Validator) servertypes.Application { return NewOsmosisApp( val.Ctx.Logger, dbm.NewMemDB(), nil, true, make(map[int64]bool), val.Ctx.Config.RootDir, 0, - encodingCfg, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts, diff --git a/app/test_helpers.go b/app/test_helpers.go index a85c4c008ca..4e5ba6fb7cd 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -13,7 +13,6 @@ import ( ) var defaultGenesisBz []byte -var defaultEncodingConfig = MakeEncodingConfig() func getDefaultGenesisStateBytes() []byte { if len(defaultGenesisBz) == 0 { @@ -30,7 +29,7 @@ func getDefaultGenesisStateBytes() []byte { // Setup initializes a new OsmosisApp. func Setup(isCheckTx bool) *OsmosisApp { db := dbm.NewMemDB() - app := NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, defaultEncodingConfig, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) + app := NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) if !isCheckTx { stateBytes := getDefaultGenesisStateBytes() @@ -54,7 +53,7 @@ func SetupTestingAppWithLevelDb(isCheckTx bool) (app *OsmosisApp, cleanupFn func if err != nil { panic(err) } - app = NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, MakeEncodingConfig(), simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) + app = NewOsmosisApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 5, simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) if !isCheckTx { genesisState := NewDefaultGenesisState() stateBytes, err := json.MarshalIndent(genesisState, "", " ") diff --git a/cmd/osmosisd/cmd/root.go b/cmd/osmosisd/cmd/root.go index ad303ba8b84..9647963cdaf 100644 --- a/cmd/osmosisd/cmd/root.go +++ b/cmd/osmosisd/cmd/root.go @@ -274,7 +274,6 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts serverty logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), - osmosis.MakeEncodingConfig(), // Ideally, we would reuse the one created by NewRootCmd. appOpts, osmosis.GetWasmEnabledProposals(), wasmOpts, @@ -300,13 +299,13 @@ func createOsmosisAppAndExport( encCfg.Marshaler = codec.NewProtoCodec(encCfg.InterfaceRegistry) var app *osmosis.OsmosisApp if height != -1 { - app = osmosis.NewOsmosisApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), encCfg, appOpts, osmosis.GetWasmEnabledProposals(), osmosis.EmptyWasmOpts) + app = osmosis.NewOsmosisApp(logger, db, traceStore, false, map[int64]bool{}, "", uint(1), appOpts, osmosis.GetWasmEnabledProposals(), osmosis.EmptyWasmOpts) if err := app.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { - app = osmosis.NewOsmosisApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), encCfg, appOpts, osmosis.GetWasmEnabledProposals(), osmosis.EmptyWasmOpts) + app = osmosis.NewOsmosisApp(logger, db, traceStore, true, map[int64]bool{}, "", uint(1), appOpts, osmosis.GetWasmEnabledProposals(), osmosis.EmptyWasmOpts) } return app.ExportAppStateAndValidators(forZeroHeight, jailWhiteList) From 387e7ae4ec811c6ec5192ede755bb8e87c0362b5 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 3 Sep 2022 19:26:44 +0200 Subject: [PATCH 5/6] Simplify more of the setup logic --- app/app.go | 3 +- app/modules.go | 2 +- simulation/executor/legacyconfig.go | 19 +++++++++ simulation/executor/simulate.go | 54 +++++++++++------------- simulation/executor/types.go | 10 +++-- simulation/simtypes/app.go | 3 ++ tests/simulator/osmosis_helper.go | 36 ++++++++++++++++ tests/simulator/sim_test.go | 65 +++++------------------------ tests/simulator/state.go | 5 ++- 9 files changed, 104 insertions(+), 93 deletions(-) create mode 100644 tests/simulator/osmosis_helper.go diff --git a/app/app.go b/app/app.go index feecec7763f..00c3f93f0e1 100644 --- a/app/app.go +++ b/app/app.go @@ -40,7 +40,6 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/osmosis-labs/osmosis/v11/app/keepers" - appparams "github.com/osmosis-labs/osmosis/v11/app/params" "github.com/osmosis-labs/osmosis/v11/app/upgrades" v10 "github.com/osmosis-labs/osmosis/v11/app/upgrades/v10" v11 "github.com/osmosis-labs/osmosis/v11/app/upgrades/v11" @@ -157,7 +156,7 @@ func NewOsmosisApp( wasmOpts []wasm.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *OsmosisApp { - encodingConfig := appparams.MakeEncodingConfig() + encodingConfig := MakeEncodingConfig() appCodec := encodingConfig.Marshaler cdc := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry diff --git a/app/modules.go b/app/modules.go index bc8372290bf..2e1333f8f88 100644 --- a/app/modules.go +++ b/app/modules.go @@ -229,7 +229,7 @@ func createSimulationManager( } // ModuleAccountAddrs returns all the app's module account addresses. -func (app *OsmosisApp) ModuleAccountAddrs() map[string]bool { +func ModuleAccountAddrs() map[string]bool { modAccAddrs := make(map[string]bool) for acc := range maccPerms { modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true diff --git a/simulation/executor/legacyconfig.go b/simulation/executor/legacyconfig.go index 6d3e5757c57..73c970ec243 100644 --- a/simulation/executor/legacyconfig.go +++ b/simulation/executor/legacyconfig.go @@ -5,7 +5,9 @@ import ( "fmt" "io/ioutil" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp/helpers" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" @@ -145,6 +147,23 @@ func PrintStats(db dbm.DB) { fmt.Println("LevelDB cached block size", db.Stats()["leveldb.cachedblock"]) } +func baseappOptionsFromConfig(config Config) []func(*baseapp.BaseApp) { + // fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of + // an IAVLStore for faster simulation speed. + fauxMerkleModeOpt := func(bapp *baseapp.BaseApp) { + if config.ExecutionDbConfig.UseMerkleTree { + bapp.SetFauxMerkleMode() + } + } + return []func(*baseapp.BaseApp){interBlockCacheOpt(), fauxMerkleModeOpt} +} + +// interBlockCacheOpt returns a BaseApp option function that sets the persistent +// inter-block write-through cache. +func interBlockCacheOpt() func(*baseapp.BaseApp) { + return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) +} + type Config struct { InitializationConfig InitializationConfig ExportConfig ExportConfig diff --git a/simulation/executor/simulate.go b/simulation/executor/simulate.go index 45c3f35b7cf..64b702cf2cf 100644 --- a/simulation/executor/simulate.go +++ b/simulation/executor/simulate.go @@ -7,12 +7,15 @@ import ( "math/rand" "os" "os/signal" + "path/filepath" "runtime" "runtime/debug" "syscall" "testing" "time" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + _ "github.com/mattn/go-sqlite3" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -25,28 +28,6 @@ import ( const AverageBlockTime = 6 * time.Second -// SimulateFromSeedLegacy tests an application by running the provided -// operations, testing the provided invariants, but using the provided config.Seed. -// TODO: Restore SimulateFromSeedLegacy by adding a wrapper that can take in -// func SimulateFromSeedLegacy( -// tb testing.TB, -// w io.Writer, -// app *baseapp.BaseApp, -// appStateFn simulation.AppStateFn, -// randAccFn simulation.RandomAccountFn, -// ops legacysimexec.WeightedOperations, -// blockedAddrs map[string]bool, -// config simulation.Config, -// cdc codec.JSONCodec, -// ) (stopEarly bool, exportedParams Params, err error) { -// actions := simtypes.ActionsFromWeightedOperations(ops) -// initFns := simtypes.InitFunctions{ -// RandomAccountFn: simtypes.WrapRandAccFnForResampling(randAccFn, blockedAddrs), -// AppInitialStateFn: appStateFn, -// } -// return SimulateFromSeed(tb, w, app, initFns, actions, config, cdc) -// } - // SimulateFromSeed tests an application by running the provided // operations, testing the provided invariants, but using the provided config.Seed. // TODO: Inputs should be: @@ -60,15 +41,19 @@ const AverageBlockTime = 6 * time.Second func SimulateFromSeed( tb testing.TB, w io.Writer, - app simtypes.App, + appCreator simtypes.AppCreator, initFunctions InitFunctions, - actions []simtypes.ActionsWithMetadata, config Config, -) (stopEarly bool, err error) { +) (lastCommitId storetypes.CommitID, stopEarly bool, err error) { // in case we have to end early, don't os.Exit so that we can run cleanup code. // TODO: Understand exit pattern, this is so screwed up. Then delete ^ + legacyInvariantPeriod := uint(10) // TODO: Make a better answer of what to do here, at minimum put into config + app := appCreator(simulationHomeDir(), legacyInvariantPeriod, baseappOptionsFromConfig(config)...) + actions := app.SimulationManager().Actions(config.Seed, app.AppCodec()) + // Set up sql table + // TODO: Move all SQL stuff to its own file/package, should not be here. var db *sql.DB if config.ExportConfig.WriteStatsToDB { db, err = sql.Open("sqlite3", "./blocks.db") @@ -90,7 +75,7 @@ func SimulateFromSeed( // Encapsulate the bizarre initialization logic that must be cleaned. simCtx, simState, simParams, err := cursedInitializationLogic(tb, w, app, initFunctions, &config) if err != nil { - return true, err + return storetypes.CommitID{}, true, err } // Setup code to catch SIGTERM's @@ -125,7 +110,16 @@ func SimulateFromSeed( stopEarly = simState.SimulateAllBlocks(w, simCtx, blockSimulator) simState.eventStats.exportEvents(config.ExportConfig.ExportStatsPath, w) - return stopEarly, nil + return storetypes.CommitID{}, stopEarly, nil +} + +func simulationHomeDir() string { + userHomeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + + return filepath.Join(userHomeDir, ".osmosis_simulation") } // The goal of this function is to group the extremely badly abstracted genesis logic, @@ -150,7 +144,8 @@ func cursedInitializationLogic( return nil, nil, simParams, fmt.Errorf("must have greater than zero genesis accounts") } - validators, genesisTimestamp, accs, res := initChain(r, simParams, accs, app, initFunctions.AppInitialStateFn, config) + validators, genesisTimestamp, accs, res := initChain( + app.SimulationManager(), r, simParams, accs, app, initFunctions.AppInitialStateFn, config) fmt.Printf( "Starting the simulation from time %v (unixtime %v)\n", @@ -179,6 +174,7 @@ func cursedInitializationLogic( // initialize the chain for the simulation func initChain( + simManager *simtypes.Manager, r *rand.Rand, params Params, accounts []simulation.Account, @@ -187,7 +183,7 @@ func initChain( config *Config, ) (mockValidators, time.Time, []simulation.Account, abci.ResponseInitChain) { // TODO: Cleanup the whole config dependency with appStateFn - appState, accounts, chainID, genesisTimestamp := appStateFn(r, accounts, config.InitializationConfig) + appState, accounts, chainID, genesisTimestamp := appStateFn(simManager, r, accounts, config.InitializationConfig) consensusParams := randomConsensusParams(r, appState, app.AppCodec()) req := abci.RequestInitChain{ AppStateBytes: appState, diff --git a/simulation/executor/types.go b/simulation/executor/types.go index 5b5ac83965e..da4b168a270 100644 --- a/simulation/executor/types.go +++ b/simulation/executor/types.go @@ -5,13 +5,15 @@ import ( "math/rand" "time" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + legacysim "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/osmosis-labs/osmosis/v11/simulation/simtypes" ) // AppStateFn returns the app state json bytes and the genesis accounts -type AppStateFn func(r *rand.Rand, accs []simtypes.Account, config InitializationConfig) ( - appState json.RawMessage, accounts []simtypes.Account, chainId string, genesisTimestamp time.Time, +type AppStateFn func(simManager *simtypes.Manager, r *rand.Rand, accs []legacysim.Account, config InitializationConfig) ( + appState json.RawMessage, accounts []legacysim.Account, chainId string, genesisTimestamp time.Time, ) // RandomAccountFn returns a slice of n random simulation accounts -type RandomAccountFn func(r *rand.Rand, n int) []simtypes.Account +type RandomAccountFn func(r *rand.Rand, n int) []legacysim.Account diff --git a/simulation/simtypes/app.go b/simulation/simtypes/app.go index 852bddc5644..c3f2b6ee3aa 100644 --- a/simulation/simtypes/app.go +++ b/simulation/simtypes/app.go @@ -7,11 +7,14 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) +type AppCreator = func(homepath string, legacyInvariantPeriod uint, baseappOptions ...func(*baseapp.BaseApp)) App + type App interface { GetBaseApp() *baseapp.BaseApp AppCodec() codec.Codec GetAccountKeeper() AccountKeeper GetBankKeeper() BankKeeper + SimulationManager() *Manager } type AccountKeeper interface { diff --git a/tests/simulator/osmosis_helper.go b/tests/simulator/osmosis_helper.go new file mode 100644 index 00000000000..2aa86e108c7 --- /dev/null +++ b/tests/simulator/osmosis_helper.go @@ -0,0 +1,36 @@ +package simapp + +import ( + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/baseapp" + db "github.com/tendermint/tm-db" + + "github.com/osmosis-labs/osmosis/v11/app" + "github.com/osmosis-labs/osmosis/v11/simulation/simtypes" +) + +func OsmosisAppCreator(logger log.Logger, db db.DB) simtypes.AppCreator { + return func(homepath string, legacyInvariantPeriod uint, baseappOptions ...func(*baseapp.BaseApp)) simtypes.App { + return app.NewOsmosisApp( + logger, + db, + nil, + true, // load latest + map[int64]bool{}, + homepath, + legacyInvariantPeriod, + emptyAppOptions{}, + app.GetWasmEnabledProposals(), + app.EmptyWasmOpts, + baseappOptions...) + } +} + +// EmptyAppOptions is a stub implementing AppOptions +type emptyAppOptions struct{} + +// Get implements AppOptions +func (ao emptyAppOptions) Get(o string) interface{} { + return nil +} diff --git a/tests/simulator/sim_test.go b/tests/simulator/sim_test.go index 43b8b69d049..80079a9b853 100644 --- a/tests/simulator/sim_test.go +++ b/tests/simulator/sim_test.go @@ -12,9 +12,7 @@ import ( "github.com/osmosis-labs/osmosis/v11/app" - "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp/helpers" - "github.com/cosmos/cosmos-sdk/store" "github.com/cosmos/cosmos-sdk/types/simulation" osmosim "github.com/osmosis-labs/osmosis/v11/simulation/executor" @@ -58,6 +56,7 @@ func fullAppSimulation(tb testing.TB, is_testing bool) { // This file is needed to provide the correct path // to reflect.wasm test file needed for wasmd simulation testing. config.InitializationConfig.ParamsFile = "params.json" + config.ExecutionDbConfig.UseMerkleTree = false defer func() { db.Close() @@ -67,41 +66,17 @@ func fullAppSimulation(tb testing.TB, is_testing bool) { } }() - // fauxMerkleModeOpt returns a BaseApp option to use a dbStoreAdapter instead of - // an IAVLStore for faster simulation speed. - fauxMerkleModeOpt := func(bapp *baseapp.BaseApp) { - if is_testing { - bapp.SetFauxMerkleMode() - } - } - - osmosis := app.NewOsmosisApp( - logger, - db, - nil, - true, // load latest - map[int64]bool{}, - app.DefaultNodeHome, - osmosim.FlagPeriodValue, - app.MakeEncodingConfig(), - osmosim.EmptyAppOptions{}, - app.GetWasmEnabledProposals(), - app.EmptyWasmOpts, - interBlockCacheOpt(), - fauxMerkleModeOpt) - initFns := osmosim.InitFunctions{ - RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, osmosis.ModuleAccountAddrs()), - AppInitialStateFn: AppStateFn(osmosis.AppCodec(), osmosis.SimulationManager()), + RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, app.ModuleAccountAddrs()), + AppInitialStateFn: AppStateFn(), } // Run randomized simulation: - _, simErr := osmosim.SimulateFromSeed( + _, _, simErr := osmosim.SimulateFromSeed( tb, os.Stdout, - osmosis, + OsmosisAppCreator(logger, db), initFns, - osmosis.SimulationManager().Actions(config.Seed, osmosis.AppCodec()), // Run all registered operations config, ) @@ -114,12 +89,6 @@ func fullAppSimulation(tb testing.TB, is_testing bool) { } } -// interBlockCacheOpt returns a BaseApp option function that sets the persistent -// inter-block write-through cache. -func interBlockCacheOpt() func(*baseapp.BaseApp) { - return baseapp.SetInterBlockCache(store.NewCommitKVStoreCacheManager()) -} - // TODO: Make another test for the fuzzer itself, which just has noOp txs // and doesn't depend on the application. func TestAppStateDeterminism(t *testing.T) { @@ -156,19 +125,6 @@ func TestAppStateDeterminism(t *testing.T) { // } db := dbm.NewMemDB() - osmosis := app.NewOsmosisApp( - logger, - db, - nil, - true, - map[int64]bool{}, - app.DefaultNodeHome, - osmosim.FlagPeriodValue, - app.MakeEncodingConfig(), - osmosim.EmptyAppOptions{}, - app.GetWasmEnabledProposals(), - app.EmptyWasmOpts, - interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", @@ -176,23 +132,22 @@ func TestAppStateDeterminism(t *testing.T) { ) initFns := osmosim.InitFunctions{ - RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, osmosis.ModuleAccountAddrs()), - AppInitialStateFn: AppStateFn(osmosis.AppCodec(), osmosis.SimulationManager()), + RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, app.ModuleAccountAddrs()), + AppInitialStateFn: AppStateFn(), } // Run randomized simulation: - _, simErr := osmosim.SimulateFromSeed( + lastCommitId, _, simErr := osmosim.SimulateFromSeed( t, os.Stdout, - osmosis, + OsmosisAppCreator(logger, db), initFns, - osmosis.SimulationManager().Actions(config.Seed, osmosis.AppCodec()), // Run all registered operations config, ) require.NoError(t, simErr) - appHash := osmosis.LastCommitID().Hash + appHash := lastCommitId.Hash appHashList[j] = fmt.Sprintf("%X", appHash) if j != 0 { diff --git a/tests/simulator/state.go b/tests/simulator/state.go index c743382cf50..6426e858013 100644 --- a/tests/simulator/state.go +++ b/tests/simulator/state.go @@ -24,8 +24,9 @@ import ( // AppStateFn returns the initial application state using a genesis or the simulation parameters. // It panics if the user provides files for both of them. // If a file is not given for the genesis or the sim params, it creates a randomized one. -func AppStateFn(cdc codec.JSONCodec, simManager *osmosimtypes.Manager) osmosim.AppStateFn { - return func(r *rand.Rand, accs []simtypes.Account, config osmosim.InitializationConfig, +func AppStateFn() osmosim.AppStateFn { + cdc := app.MakeEncodingConfig().Marshaler + return func(simManager *osmosimtypes.Manager, r *rand.Rand, accs []simtypes.Account, config osmosim.InitializationConfig, ) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) { if osmosim.FlagGenesisTimeValue == 0 { genesisTimestamp = simtypes.RandTimestamp(r) From ae661335976e0045eb1fccf2b664453e3802162d Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 3 Sep 2022 19:36:23 +0200 Subject: [PATCH 6/6] More simulator instantiation cleanup --- simulation/executor/init_functions.go | 2 ++ simulation/executor/legacyconfig.go | 22 ++++++++++----- tests/simulator/osmosis_helper.go | 8 ++++++ tests/simulator/sim_test.go | 40 ++++----------------------- 4 files changed, 31 insertions(+), 41 deletions(-) diff --git a/simulation/executor/init_functions.go b/simulation/executor/init_functions.go index 446b1f5a1b2..12c46cb777d 100644 --- a/simulation/executor/init_functions.go +++ b/simulation/executor/init_functions.go @@ -1,5 +1,7 @@ package simulation +// TODO: Move this entire file to simtypes + import ( "math/rand" diff --git a/simulation/executor/legacyconfig.go b/simulation/executor/legacyconfig.go index 73c970ec243..c018dea5362 100644 --- a/simulation/executor/legacyconfig.go +++ b/simulation/executor/legacyconfig.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "io/ioutil" + "os" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/simapp/helpers" @@ -11,6 +12,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" + + "github.com/osmosis-labs/osmosis/v11/simulation/simtypes/simlogger" ) // List of available flags for the simulator @@ -112,32 +115,37 @@ func NewExecutionDbConfigFromFlags() ExecutionDbConfig { // 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. -func SetupSimulation(dirPrefix, dbName string) (Config, dbm.DB, string, log.Logger, bool, error) { +func SetupSimulation(dirPrefix, dbName string) (cfg Config, db dbm.DB, logger log.Logger, cleanup func(), err error) { if !FlagEnabledValue { - return Config{}, nil, "", nil, true, nil + return Config{}, nil, nil, func() {}, nil } config := NewConfigFromFlags() config.InitializationConfig.ChainID = helpers.SimAppChainID - var logger log.Logger if FlagVerboseValue { logger = log.TestingLogger() } else { logger = log.NewNopLogger() } + logger = simlogger.NewSimLogger(logger) dir, err := ioutil.TempDir("", dirPrefix) if err != nil { - return Config{}, nil, "", nil, false, err + return Config{}, nil, nil, func() {}, err } - db, err := sdk.NewLevelDB(dbName, dir) + db, err = sdk.NewLevelDB(dbName, dir) if err != nil { - return Config{}, nil, "", nil, false, err + return Config{}, nil, nil, func() {}, err + } + + cleanup = func() { + db.Close() + err = os.RemoveAll(dir) } - return config, db, dir, logger, false, nil + return config, db, logger, cleanup, nil } // PrintStats prints the corresponding statistics from the app DB. diff --git a/tests/simulator/osmosis_helper.go b/tests/simulator/osmosis_helper.go index 2aa86e108c7..4cce842110a 100644 --- a/tests/simulator/osmosis_helper.go +++ b/tests/simulator/osmosis_helper.go @@ -4,8 +4,11 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/types/simulation" db "github.com/tendermint/tm-db" + simexec "github.com/osmosis-labs/osmosis/v11/simulation/executor" + "github.com/osmosis-labs/osmosis/v11/app" "github.com/osmosis-labs/osmosis/v11/simulation/simtypes" ) @@ -27,6 +30,11 @@ func OsmosisAppCreator(logger log.Logger, db db.DB) simtypes.AppCreator { } } +var OsmosisInitFns = simexec.InitFunctions{ + RandomAccountFn: simexec.WrapRandAccFnForResampling(simulation.RandomAccounts, app.ModuleAccountAddrs()), + AppInitialStateFn: AppStateFn(), +} + // EmptyAppOptions is a stub implementing AppOptions type emptyAppOptions struct{} diff --git a/tests/simulator/sim_test.go b/tests/simulator/sim_test.go index 80079a9b853..b8a3905ff02 100644 --- a/tests/simulator/sim_test.go +++ b/tests/simulator/sim_test.go @@ -10,10 +10,7 @@ import ( "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" - "github.com/osmosis-labs/osmosis/v11/app" - "github.com/cosmos/cosmos-sdk/simapp/helpers" - "github.com/cosmos/cosmos-sdk/types/simulation" osmosim "github.com/osmosis-labs/osmosis/v11/simulation/executor" "github.com/osmosis-labs/osmosis/v11/simulation/simtypes/simlogger" @@ -48,35 +45,22 @@ func TestFullAppSimulation(t *testing.T) { } func fullAppSimulation(tb testing.TB, is_testing bool) { - config, db, dir, logger, _, err := osmosim.SetupSimulation("goleveldb-app-sim", "Simulation") + config, db, logger, cleanup, err := osmosim.SetupSimulation("goleveldb-app-sim", "Simulation") if err != nil { tb.Fatalf("simulation setup failed: %s", err.Error()) } - logger = simlogger.NewSimLogger(logger) + defer cleanup() // This file is needed to provide the correct path // to reflect.wasm test file needed for wasmd simulation testing. config.InitializationConfig.ParamsFile = "params.json" - config.ExecutionDbConfig.UseMerkleTree = false - - defer func() { - db.Close() - err = os.RemoveAll(dir) - if err != nil { - tb.Fatal(err) - } - }() - - initFns := osmosim.InitFunctions{ - RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, app.ModuleAccountAddrs()), - AppInitialStateFn: AppStateFn(), - } + config.ExecutionDbConfig.UseMerkleTree = !is_testing // Run randomized simulation: _, _, simErr := osmosim.SimulateFromSeed( tb, os.Stdout, OsmosisAppCreator(logger, db), - initFns, + OsmosisInitFns, config, ) @@ -116,14 +100,7 @@ func TestAppStateDeterminism(t *testing.T) { config.Seed = rand.Int63() for j := 0; j < numTimesToRunPerSeed; j++ { - var logger log.Logger - logger = simlogger.NewSimLogger(log.TestingLogger()) - // if osmosim.FlagVerboseValue { - // logger = log.TestingLogger() - // } else { - // logger = log.NewNopLogger() - // } - + logger := simlogger.NewSimLogger(log.TestingLogger()) db := dbm.NewMemDB() fmt.Printf( @@ -131,17 +108,12 @@ func TestAppStateDeterminism(t *testing.T) { config.Seed, i+1, numSeeds, j+1, numTimesToRunPerSeed, ) - initFns := osmosim.InitFunctions{ - RandomAccountFn: osmosim.WrapRandAccFnForResampling(simulation.RandomAccounts, app.ModuleAccountAddrs()), - AppInitialStateFn: AppStateFn(), - } - // Run randomized simulation: lastCommitId, _, simErr := osmosim.SimulateFromSeed( t, os.Stdout, OsmosisAppCreator(logger, db), - initFns, + OsmosisInitFns, config, )