From 89950ec3f0b3a697a65d49861ad97731b7133bab Mon Sep 17 00:00:00 2001 From: keruch Date: Fri, 22 Nov 2024 18:47:52 +0100 Subject: [PATCH] feat: simulation tests --- app/app.go | 8 ++- app/keepers/modules.go | 10 ++++ ibctesting/genesis_bridge_test.go | 4 +- simulation/simulation_test.go | 94 ++++++++++++++++++++++++++++--- 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/app/app.go b/app/app.go index 34bfac3e2..4eb0d6251 100644 --- a/app/app.go +++ b/app/app.go @@ -113,6 +113,8 @@ type App struct { mm *module.Manager // module configurator configurator module.Configurator + // simulation manager + sm *module.SimulationManager } // New returns a reference to an initialized blockchain app @@ -195,6 +197,10 @@ func New( app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) app.mm.RegisterServices(app.configurator) + /**** Simulations ****/ + app.sm = module.NewSimulationManager(app.SetupSimulationModules(appCodec)...) + app.sm.RegisterStoreDecoders() + // initialize stores app.MountKVStores(keepers.KVStoreKeys) app.MountTransientStores(app.GetTransientStoreKey()) @@ -358,7 +364,7 @@ func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) { // SimulationManager implements the SimulationApp interface func (app *App) SimulationManager() *module.SimulationManager { - return nil + return app.sm } // GetTxConfig implements ibctesting.TestingApp diff --git a/app/keepers/modules.go b/app/keepers/modules.go index 6e4aa0f15..cc99514d9 100644 --- a/app/keepers/modules.go +++ b/app/keepers/modules.go @@ -228,6 +228,16 @@ func (a *AppKeepers) SetupModules( } } +func (a *AppKeepers) SetupSimulationModules(appCodec codec.Codec) []module.AppModuleSimulation { + return []module.AppModuleSimulation{ + rollappmodule.NewAppModule(appCodec, a.RollappKeeper, a.AccountKeeper, a.BankKeeper), + sequencermodule.NewAppModule(appCodec, a.SequencerKeeper, a.AccountKeeper, a.BankKeeper), + eibcmodule.NewAppModule(appCodec, a.EIBCKeeper, a.AccountKeeper, a.BankKeeper), + dymnsmodule.NewAppModule(appCodec, a.DymNSKeeper), + //sponsorship.NewAppModule(a.SponsorshipKeeper), + } +} + // ModuleAccountAddrs returns all the app's module account addresses. func (*AppKeepers) ModuleAccountAddrs() map[string]bool { modAccAddrs := make(map[string]bool) diff --git a/ibctesting/genesis_bridge_test.go b/ibctesting/genesis_bridge_test.go index f288c1d7d..c14b1b169 100644 --- a/ibctesting/genesis_bridge_test.go +++ b/ibctesting/genesis_bridge_test.go @@ -9,15 +9,17 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" + "github.com/dymensionxyz/dymension/v3/testutil/sample" irotypes "github.com/dymensionxyz/dymension/v3/x/iro/types" "github.com/dymensionxyz/dymension/v3/x/rollapp/genesisbridge" rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + "github.com/dymensionxyz/dymension/v3/app/apptesting" appparams "github.com/dymensionxyz/dymension/v3/app/params" - "github.com/stretchr/testify/suite" "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types" diff --git a/simulation/simulation_test.go b/simulation/simulation_test.go index 829713040..3c9a564d4 100644 --- a/simulation/simulation_test.go +++ b/simulation/simulation_test.go @@ -4,18 +4,97 @@ import ( "os" "testing" - simapp "github.com/cosmos/cosmos-sdk/testutil/sims" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" simulationtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/cosmos/cosmos-sdk/x/simulation" simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli" - "github.com/dymensionxyz/dymension/v3/app" + "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/testing/simapp" "github.com/stretchr/testify/require" + + "github.com/dymensionxyz/dymension/v3/app" ) func init() { simcli.GetSimulatorFlags() } +const SimulationAppChainID = "dymension_100-1" + +/* +To execute a completely pseudo-random simulation: + + $ go test . \ + -run=TestFullAppSimulation \ + -Enabled=true \ + -NumBlocks=100 \ + -BlockSize=200 \ + -Commit=true \ + -Seed=99 \ + -Period=5 \ + -v -timeout 24h +*/ + +func TestFullAppSimulation(t *testing.T) { + config := simcli.NewConfigFromFlags() + config.ChainID = SimulationAppChainID + + db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue) + if skip { + t.Skip("skipping application simulation") + } + require.NoError(t, err, "simulation setup failed") + + defer func() { + require.NoError(t, db.Close()) + require.NoError(t, os.RemoveAll(dir)) + }() + + appOptions := make(simtestutil.AppOptionsMap, 0) + appOptions[flags.FlagHome] = app.DefaultNodeHome + appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue + + encoding := app.MakeEncodingConfig() + + dymdApp := app.New( + logger, + db, + nil, + true, + map[int64]bool{}, + app.DefaultNodeHome, + 0, + encoding, + simapp.EmptyAppOptions{}, + baseapp.SetChainID(SimulationAppChainID), + ) + require.Equal(t, "dymension", dymdApp.Name()) + + // run randomized simulation + _, simParams, simErr := simulation.SimulateFromSeed( + t, + os.Stdout, + dymdApp.BaseApp, + simtestutil.AppStateFn(dymdApp.AppCodec(), dymdApp.SimulationManager(), app.NewDefaultGenesisState(dymdApp.AppCodec())), + simulationtypes.RandomAccounts, + simtestutil.SimulationOperations(dymdApp, dymdApp.AppCodec(), config), + dymdApp.ModuleAccountAddrs(), + config, + dymdApp.AppCodec(), + ) + + // export state and simParams before the simulation error is checked + err = simtestutil.CheckExportSimulation(dymdApp, config, simParams) + require.NoError(t, err) + require.NoError(t, simErr) + + if config.Commit { + simtestutil.PrintStats(db) + } +} + // BenchmarkSimulation run the chain simulation // Running using starport command: // `starport chain simulate -v --numBlocks 200 --blockSize 50` @@ -27,7 +106,7 @@ func BenchmarkSimulation(b *testing.B) { config := simcli.NewConfigFromFlags() config.ChainID = "simulation-app" - db, dir, logger, _, err := simapp.SetupSimulation(config, "goleveldb-app-sim", "Simulation", simcli.FlagEnabledValue, simcli.FlagEnabledValue) + db, dir, logger, _, err := simtestutil.SetupSimulation(config, "goleveldb-app-sim", "Simulation", simcli.FlagEnabledValue, simcli.FlagEnabledValue) require.NoError(b, err, "simulation setup failed") b.Cleanup(func() { @@ -49,6 +128,7 @@ func BenchmarkSimulation(b *testing.B) { 0, encoding, simapp.EmptyAppOptions{}, + baseapp.SetChainID(SimulationAppChainID), ) // Run randomized simulations @@ -56,20 +136,20 @@ func BenchmarkSimulation(b *testing.B) { b, os.Stdout, dymdApp.BaseApp, - simapp.AppStateFn(dymdApp.AppCodec(), dymdApp.SimulationManager(), app.NewDefaultGenesisState(dymdApp.AppCodec())), + simtestutil.AppStateFn(dymdApp.AppCodec(), dymdApp.SimulationManager(), app.NewDefaultGenesisState(dymdApp.AppCodec())), simulationtypes.RandomAccounts, - simapp.SimulationOperations(dymdApp, dymdApp.AppCodec(), config), + simtestutil.SimulationOperations(dymdApp, dymdApp.AppCodec(), config), dymdApp.ModuleAccountAddrs(), config, dymdApp.AppCodec(), ) // export state and simParams before the simulation error is checked - err = simapp.CheckExportSimulation(dymdApp, config, simParams) + err = simtestutil.CheckExportSimulation(dymdApp, config, simParams) require.NoError(b, err) require.NoError(b, simErr) if config.Commit { - simapp.PrintStats(db) + simtestutil.PrintStats(db) } }