refactor!: extract simulation helpers out of simapp (#13402)
This commit is contained in:
@@ -89,9 +89,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// App is deprecated, use runtime.AppI instead
|
||||
App runtime.AppI
|
||||
|
||||
// DefaultNodeHome default home directories for the application daemon
|
||||
DefaultNodeHome string
|
||||
|
||||
|
||||
@@ -100,9 +100,6 @@ import (
|
||||
const appName = "SimApp"
|
||||
|
||||
var (
|
||||
// App is deprecated, use runtime.AppI instead
|
||||
App runtime.AppI
|
||||
|
||||
// DefaultNodeHome default home directories for the application daemon
|
||||
DefaultNodeHome string
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
)
|
||||
|
||||
// List of available flags for the simulator
|
||||
var (
|
||||
FlagGenesisFileValue string
|
||||
FlagParamsFileValue string
|
||||
FlagExportParamsPathValue string
|
||||
FlagExportParamsHeightValue int
|
||||
FlagExportStatePathValue string
|
||||
FlagExportStatsPathValue string
|
||||
FlagSeedValue int64
|
||||
FlagInitialBlockHeightValue int
|
||||
FlagNumBlocksValue int
|
||||
FlagBlockSizeValue int
|
||||
FlagLeanValue bool
|
||||
FlagCommitValue bool
|
||||
FlagOnOperationValue bool // TODO: Remove in favor of binary search for invariant violation
|
||||
FlagAllInvariantsValue bool
|
||||
FlagDBBackendValue string
|
||||
|
||||
FlagEnabledValue bool
|
||||
FlagVerboseValue bool
|
||||
FlagPeriodValue uint
|
||||
FlagGenesisTimeValue int64
|
||||
)
|
||||
|
||||
// GetSimulatorFlags gets the values of all the available simulation flags
|
||||
func GetSimulatorFlags() {
|
||||
// config fields
|
||||
flag.StringVar(&FlagGenesisFileValue, "Genesis", "", "custom simulation genesis file; cannot be used with params file")
|
||||
flag.StringVar(&FlagParamsFileValue, "Params", "", "custom simulation params file which overrides any random params; cannot be used with genesis")
|
||||
flag.StringVar(&FlagExportParamsPathValue, "ExportParamsPath", "", "custom file path to save the exported params JSON")
|
||||
flag.IntVar(&FlagExportParamsHeightValue, "ExportParamsHeight", 0, "height to which export the randomly generated params")
|
||||
flag.StringVar(&FlagExportStatePathValue, "ExportStatePath", "", "custom file path to save the exported app state JSON")
|
||||
flag.StringVar(&FlagExportStatsPathValue, "ExportStatsPath", "", "custom file path to save the exported simulation statistics JSON")
|
||||
flag.Int64Var(&FlagSeedValue, "Seed", 42, "simulation random seed")
|
||||
flag.IntVar(&FlagInitialBlockHeightValue, "InitialBlockHeight", 1, "initial block to start the simulation")
|
||||
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.StringVar(&FlagDBBackendValue, "DBBackend", "goleveldb", "custom db backend type")
|
||||
|
||||
// simulation flags
|
||||
flag.BoolVar(&FlagEnabledValue, "Enabled", false, "enable the simulation")
|
||||
flag.BoolVar(&FlagVerboseValue, "Verbose", false, "verbose log output")
|
||||
flag.UintVar(&FlagPeriodValue, "Period", 0, "run slow invariants only once every period assertions")
|
||||
flag.Int64Var(&FlagGenesisTimeValue, "GenesisTime", 0, "override genesis UNIX time instead of using a random UNIX time")
|
||||
}
|
||||
|
||||
// NewConfigFromFlags creates a simulation from the retrieved values of the flags.
|
||||
func NewConfigFromFlags() simulation.Config {
|
||||
return simulation.Config{
|
||||
GenesisFile: FlagGenesisFileValue,
|
||||
ParamsFile: FlagParamsFileValue,
|
||||
ExportParamsPath: FlagExportParamsPathValue,
|
||||
ExportParamsHeight: FlagExportParamsHeightValue,
|
||||
ExportStatePath: FlagExportStatePathValue,
|
||||
ExportStatsPath: FlagExportStatsPathValue,
|
||||
Seed: FlagSeedValue,
|
||||
InitialBlockHeight: FlagInitialBlockHeightValue,
|
||||
NumBlocks: FlagNumBlocksValue,
|
||||
BlockSize: FlagBlockSizeValue,
|
||||
Lean: FlagLeanValue,
|
||||
Commit: FlagCommitValue,
|
||||
OnOperation: FlagOnOperationValue,
|
||||
AllInvariants: FlagAllInvariantsValue,
|
||||
DBBackend: FlagDBBackendValue,
|
||||
}
|
||||
}
|
||||
+19
-10
@@ -13,13 +13,18 @@ import (
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
|
||||
)
|
||||
|
||||
// Profile with:
|
||||
// /usr/local/go/bin/go test -benchmem -run=^$ cosmossdk.io/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out
|
||||
func BenchmarkFullAppSimulation(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
config, db, dir, logger, skip, err := SetupSimulation("goleveldb-app-sim", "Simulation")
|
||||
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "goleveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
if err != nil {
|
||||
b.Fatalf("simulation setup failed: %s", err.Error())
|
||||
}
|
||||
@@ -35,7 +40,7 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, appOptions, interBlockCacheOpt())
|
||||
|
||||
@@ -46,14 +51,14 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
if err = CheckExportSimulation(app, config, simParams); err != nil {
|
||||
if err = simtestutil.CheckExportSimulation(app, config, simParams); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -62,13 +67,17 @@ func BenchmarkFullAppSimulation(b *testing.B) {
|
||||
}
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkInvariants(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-invariant-bench", "Simulation")
|
||||
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-invariant-bench", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
if err != nil {
|
||||
b.Fatalf("simulation setup failed: %s", err.Error())
|
||||
}
|
||||
@@ -86,7 +95,7 @@ func BenchmarkInvariants(b *testing.B) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, appOptions, interBlockCacheOpt())
|
||||
|
||||
@@ -97,14 +106,14 @@ func BenchmarkInvariants(b *testing.B) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
if err = CheckExportSimulation(app, config, simParams); err != nil {
|
||||
if err = simtestutil.CheckExportSimulation(app, config, simParams); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -113,7 +122,7 @@ func BenchmarkInvariants(b *testing.B) {
|
||||
}
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
|
||||
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight() + 1})
|
||||
|
||||
+40
-27
@@ -34,13 +34,17 @@ import (
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// SimAppChainID hardcoded chainID for simulation
|
||||
const SimAppChainID = "simulation-app"
|
||||
|
||||
// Get flags every time the simulator is run
|
||||
func init() {
|
||||
GetSimulatorFlags()
|
||||
simcli.GetSimulatorFlags()
|
||||
}
|
||||
|
||||
type StoreKeysPrefixes struct {
|
||||
@@ -62,7 +66,10 @@ func interBlockCacheOpt() func(*baseapp.BaseApp) {
|
||||
}
|
||||
|
||||
func TestFullAppSimulation(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
if skip {
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
@@ -75,7 +82,7 @@ func TestFullAppSimulation(t *testing.T) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt)
|
||||
require.Equal(t, "SimApp", app.Name())
|
||||
@@ -87,24 +94,27 @@ func TestFullAppSimulation(t *testing.T) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = CheckExportSimulation(app, config, simParams)
|
||||
err = simtestutil.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppImportExport(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
if skip {
|
||||
t.Skip("skipping application import/export simulation")
|
||||
}
|
||||
@@ -117,7 +127,7 @@ func TestAppImportExport(t *testing.T) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt)
|
||||
require.Equal(t, "SimApp", app.Name())
|
||||
@@ -129,19 +139,19 @@ func TestAppImportExport(t *testing.T) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = CheckExportSimulation(app, config, simParams)
|
||||
err = simtestutil.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
|
||||
fmt.Printf("exporting genesis...\n")
|
||||
@@ -151,7 +161,7 @@ func TestAppImportExport(t *testing.T) {
|
||||
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
_, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||
newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
defer func() {
|
||||
@@ -212,12 +222,15 @@ func TestAppImportExport(t *testing.T) {
|
||||
require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare")
|
||||
|
||||
fmt.Printf("compared %d different key/value pairs between %s and %s\n", len(failedKVAs), skp.A, skp.B)
|
||||
require.Equal(t, 0, len(failedKVAs), GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
|
||||
require.Equal(t, 0, len(failedKVAs), simtestutil.GetSimulationLog(skp.A.Name(), app.SimulationManager().StoreDecoders, failedKVAs, failedKVBs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppSimulationAfterImport(t *testing.T) {
|
||||
config, db, dir, logger, skip, err := SetupSimulation("leveldb-app-sim", "Simulation")
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
db, dir, logger, skip, err := simtestutil.SetupSimulation(config, "leveldb-app-sim", "Simulation", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
if skip {
|
||||
t.Skip("skipping application simulation after import")
|
||||
}
|
||||
@@ -230,7 +243,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
app := NewSimApp(logger, db, nil, true, appOptions, fauxMerkleModeOpt)
|
||||
require.Equal(t, "SimApp", app.Name())
|
||||
@@ -242,19 +255,19 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
)
|
||||
|
||||
// export state and simParams before the simulation error is checked
|
||||
err = CheckExportSimulation(app, config, simParams)
|
||||
err = simtestutil.CheckExportSimulation(app, config, simParams)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, simErr)
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
|
||||
if stopEarly {
|
||||
@@ -269,7 +282,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||
|
||||
fmt.Printf("importing genesis...\n")
|
||||
|
||||
_, newDB, newDir, _, _, err := SetupSimulation("leveldb-app-sim-2", "Simulation-2")
|
||||
newDB, newDir, _, _, err := simtestutil.SetupSimulation(config, "leveldb-app-sim-2", "Simulation-2", simcli.FlagVerboseValue, simcli.FlagEnabledValue)
|
||||
require.NoError(t, err, "simulation setup failed")
|
||||
|
||||
defer func() {
|
||||
@@ -290,7 +303,7 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||
newApp.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(newApp, newApp.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(newApp, newApp.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
@@ -301,16 +314,16 @@ func TestAppSimulationAfterImport(t *testing.T) {
|
||||
// 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) {
|
||||
if !FlagEnabledValue {
|
||||
if !simcli.FlagEnabledValue {
|
||||
t.Skip("skipping application simulation")
|
||||
}
|
||||
|
||||
config := NewConfigFromFlags()
|
||||
config := simcli.NewConfigFromFlags()
|
||||
config.InitialBlockHeight = 1
|
||||
config.ExportParamsPath = ""
|
||||
config.OnOperation = false
|
||||
config.AllInvariants = false
|
||||
config.ChainID = simtestutil.SimAppChainID
|
||||
config.ChainID = SimAppChainID
|
||||
|
||||
numSeeds := 3
|
||||
numTimesToRunPerSeed := 5
|
||||
@@ -318,14 +331,14 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
|
||||
appOptions := make(simtestutil.AppOptionsMap, 0)
|
||||
appOptions[flags.FlagHome] = DefaultNodeHome
|
||||
appOptions[server.FlagInvCheckPeriod] = FlagPeriodValue
|
||||
appOptions[server.FlagInvCheckPeriod] = simcli.FlagPeriodValue
|
||||
|
||||
for i := 0; i < numSeeds; i++ {
|
||||
config.Seed = rand.Int63()
|
||||
|
||||
for j := 0; j < numTimesToRunPerSeed; j++ {
|
||||
var logger log.Logger
|
||||
if FlagVerboseValue {
|
||||
if simcli.FlagVerboseValue {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
@@ -345,7 +358,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
app.BaseApp,
|
||||
AppStateFn(app.AppCodec(), app.SimulationManager()),
|
||||
simtypes.RandomAccounts, // Replace with own random account function if using keys other than secp256k1
|
||||
SimulationOperations(app, app.AppCodec(), config),
|
||||
simtestutil.SimulationOperations(app, app.AppCodec(), config),
|
||||
ModuleAccountAddrs(),
|
||||
config,
|
||||
app.AppCodec(),
|
||||
@@ -353,7 +366,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
if config.Commit {
|
||||
PrintStats(db)
|
||||
simtestutil.PrintStats(db)
|
||||
}
|
||||
|
||||
appHash := app.LastCommitID().Hash
|
||||
|
||||
+4
-3
@@ -20,6 +20,7 @@ import (
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
simcli "github.com/cosmos/cosmos-sdk/x/simulation/client/cli"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
@@ -29,10 +30,10 @@ import (
|
||||
func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simtypes.AppStateFn {
|
||||
return func(r *rand.Rand, accs []simtypes.Account, config simtypes.Config,
|
||||
) (appState json.RawMessage, simAccs []simtypes.Account, chainID string, genesisTimestamp time.Time) {
|
||||
if FlagGenesisTimeValue == 0 {
|
||||
if simcli.FlagGenesisTimeValue == 0 {
|
||||
genesisTimestamp = simtypes.RandTimestamp(r)
|
||||
} else {
|
||||
genesisTimestamp = time.Unix(FlagGenesisTimeValue, 0)
|
||||
genesisTimestamp = time.Unix(simcli.FlagGenesisTimeValue, 0)
|
||||
}
|
||||
|
||||
chainID = config.ChainID
|
||||
@@ -44,7 +45,7 @@ func AppStateFn(cdc codec.JSONCodec, simManager *module.SimulationManager) simty
|
||||
// override the default chain-id from simapp to set it later to the config
|
||||
genesisDoc, accounts := AppStateFromGenesisFileFn(r, cdc, config.GenesisFile)
|
||||
|
||||
if FlagGenesisTimeValue == 0 {
|
||||
if simcli.FlagGenesisTimeValue == 0 {
|
||||
// use genesis timestamp if no custom timestamp is provided (i.e no random timestamp)
|
||||
genesisTimestamp = genesisDoc.GenesisTime
|
||||
}
|
||||
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
)
|
||||
|
||||
// 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) (simtypes.Config, dbm.DB, string, log.Logger, bool, error) {
|
||||
if !FlagEnabledValue {
|
||||
return simtypes.Config{}, nil, "", nil, true, nil
|
||||
}
|
||||
|
||||
config := NewConfigFromFlags()
|
||||
config.ChainID = simtestutil.SimAppChainID
|
||||
|
||||
var logger log.Logger
|
||||
if FlagVerboseValue {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
}
|
||||
|
||||
dir, err := os.MkdirTemp("", dirPrefix)
|
||||
if err != nil {
|
||||
return simtypes.Config{}, nil, "", nil, false, err
|
||||
}
|
||||
|
||||
db, err := dbm.NewDB(dbName, dbm.BackendType(config.DBBackend), dir)
|
||||
if err != nil {
|
||||
return simtypes.Config{}, nil, "", nil, false, err
|
||||
}
|
||||
|
||||
return config, db, dir, logger, false, nil
|
||||
}
|
||||
|
||||
// SimulationOperations retrieves the simulation params from the provided file path
|
||||
// and returns all the modules weighted operations
|
||||
func SimulationOperations(app runtime.AppI, cdc codec.JSONCodec, config simtypes.Config) []simtypes.WeightedOperation {
|
||||
simState := module.SimulationState{
|
||||
AppParams: make(simtypes.AppParams),
|
||||
Cdc: cdc,
|
||||
}
|
||||
|
||||
if config.ParamsFile != "" {
|
||||
bz, err := os.ReadFile(config.ParamsFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(bz, &simState.AppParams)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
simState.Contents = app.SimulationManager().GetProposalContents(simState)
|
||||
return app.SimulationManager().WeightedOperations(simState)
|
||||
}
|
||||
|
||||
// CheckExportSimulation exports the app state and simulation parameters to JSON
|
||||
// if the export paths are defined.
|
||||
func CheckExportSimulation(
|
||||
app runtime.AppI, config simtypes.Config, params simtypes.Params,
|
||||
) error {
|
||||
if config.ExportStatePath != "" {
|
||||
fmt.Println("exporting app state...")
|
||||
exported, err := app.ExportAppStateAndValidators(false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(config.ExportStatePath, []byte(exported.AppState), 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if config.ExportParamsPath != "" {
|
||||
fmt.Println("exporting simulation params...")
|
||||
paramsBz, err := json.MarshalIndent(params, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.WriteFile(config.ExportParamsPath, paramsBz, 0o600); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintStats prints the corresponding statistics from the app DB.
|
||||
func PrintStats(db dbm.DB) {
|
||||
fmt.Println("\nLevelDB Stats")
|
||||
fmt.Println(db.Stats()["leveldb.stats"])
|
||||
fmt.Println("LevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||
}
|
||||
|
||||
// GetSimulationLog unmarshals the KVPair's Value to the corresponding type based on the
|
||||
// each's module store key and the prefix bytes of the KVPair's key.
|
||||
func GetSimulationLog(storeName string, sdr sdk.StoreDecoderRegistry, kvAs, kvBs []kv.Pair) (log string) {
|
||||
for i := 0; i < len(kvAs); i++ {
|
||||
if len(kvAs[i].Value) == 0 && len(kvBs[i].Value) == 0 {
|
||||
// skip if the value doesn't have any bytes
|
||||
continue
|
||||
}
|
||||
|
||||
decoder, ok := sdr[storeName]
|
||||
if ok {
|
||||
log += decoder(kvAs[i], kvBs[i])
|
||||
} else {
|
||||
log += fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", kvAs[i].Key, kvAs[i].Value, kvBs[i].Key, kvBs[i].Value)
|
||||
}
|
||||
}
|
||||
|
||||
return log
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package simapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/kv"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
)
|
||||
|
||||
func makeCodec(bm module.BasicManager) *codec.LegacyAmino {
|
||||
cdc := codec.NewLegacyAmino()
|
||||
|
||||
bm.RegisterLegacyAminoCodec(cdc)
|
||||
std.RegisterLegacyAminoCodec(cdc)
|
||||
|
||||
return cdc
|
||||
}
|
||||
|
||||
func TestGetSimulationLog(t *testing.T) {
|
||||
cdc := makeCodec(ModuleBasics)
|
||||
|
||||
decoders := make(sdk.StoreDecoderRegistry)
|
||||
decoders[authtypes.StoreKey] = func(kvAs, kvBs kv.Pair) string { return "10" }
|
||||
|
||||
tests := []struct {
|
||||
store string
|
||||
kvPairs []kv.Pair
|
||||
expectedLog string
|
||||
}{
|
||||
{
|
||||
"Empty",
|
||||
[]kv.Pair{{}},
|
||||
"",
|
||||
},
|
||||
{
|
||||
authtypes.StoreKey,
|
||||
[]kv.Pair{{Key: authtypes.GlobalAccountNumberKey, Value: cdc.MustMarshal(uint64(10))}},
|
||||
"10",
|
||||
},
|
||||
{
|
||||
"OtherStore",
|
||||
[]kv.Pair{{Key: []byte("key"), Value: []byte("value")}},
|
||||
fmt.Sprintf("store A %X => %X\nstore B %X => %X\n", []byte("key"), []byte("value"), []byte("key"), []byte("value")),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.store, func(t *testing.T) {
|
||||
require.Equal(t, tt.expectedLog, GetSimulationLog(tt.store, decoders, tt.kvPairs, tt.kvPairs), tt.store)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user