Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add simulation tests #2947

Merged
merged 23 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ type App struct {

mm *module.Manager
sm *module.SimulationManager
ModuleBasics module.BasicManager
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
configurator module.Configurator

// sdk keepers
Expand Down Expand Up @@ -737,6 +738,8 @@ func New(
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
)

app.ModuleBasics = newBasicManagerFromManager(app)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved

// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
Expand Down Expand Up @@ -812,6 +815,10 @@ func New(
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
app.mm.RegisterServices(app.configurator)

app.sm = module.NewSimulationManager(simulationModules(app, appCodec, skipGenesisInvariants)...)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved

app.sm.RegisterStoreDecoders()

// initialize stores
app.MountKVStores(keys)
app.MountTransientStores(tKeys)
Expand Down Expand Up @@ -962,7 +969,7 @@ func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig
nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)

// Register legacy and grpc-gateway routes for all modules.
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
app.ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved

// register app's OpenAPI routes.
if apiConfig.Swagger {
Expand Down
1 change: 0 additions & 1 deletion app/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
evmenc "github.com/zeta-chain/ethermint/encoding"
ethermint "github.com/zeta-chain/ethermint/types"
evmtypes "github.com/zeta-chain/ethermint/x/evm/types"

authoritytypes "github.com/zeta-chain/node/x/authority/types"
crosschaintypes "github.com/zeta-chain/node/x/crosschain/types"
emissionstypes "github.com/zeta-chain/node/x/emissions/types"
Expand Down
84 changes: 84 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package app

import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/evidence"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/zeta-chain/ethermint/x/evm"
evmtypes "github.com/zeta-chain/ethermint/x/evm/types"
)

// ModuleBasics defines the module BasicManager that is in charge of setting up basic,
// non-dependant module elements, such as codec registration
// and genesis verification.
func newBasicManagerFromManager(app *App) module.BasicManager {
var moduleBasics []module.AppModuleBasic

Check failure on line 35 in app/modules.go

View workflow job for this annotation

GitHub Actions / lint

Consider pre-allocating `moduleBasics` (prealloc)
for _, m := range app.mm.Modules {
m, ok := m.(module.AppModuleBasic)
if !ok {
fmt.Printf("module %s is not an instance of module.AppModuleBasic\n", m)
continue
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
}
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
if m.Name() == govtypes.ModuleName {
m = gov.NewAppModuleBasic(getGovProposalHandlers())
}

if m.Name() == genutiltypes.ModuleName {
m = genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator)
}

moduleBasics = append(moduleBasics, m)
}
basicManager := module.NewBasicManager(moduleBasics...)
//basicManager.RegisterLegacyAminoCodec(app.cdc)
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
basicManager.RegisterInterfaces(app.interfaceRegistry)

return basicManager
}

func simulationModules(
app *App,
appCodec codec.Codec,
_ bool,
) []module.AppModuleSimulation {
return []module.AppModuleSimulation{
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
//gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)),
slashing.NewAppModule(
appCodec,
app.SlashingKeeper,
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
app.GetSubspace(slashingtypes.ModuleName),
),
params.NewAppModule(app.ParamsKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper, app.GetSubspace(evmtypes.ModuleName)),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
}
}
43 changes: 43 additions & 0 deletions sims.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/make -f
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved

########################################
### Simulations

BINDIR ?= $(GOPATH)/bin
SIMAPP = ./tests/simulation
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved


# Run sim is a cosmos tool which helps us to run multiple simulations in parallel.
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
runsim: $(BINDIR)/runsim
$(BINDIR)/runsim:
@echo "Installing runsim..."
@(cd /tmp && go install github.com/cosmos/tools/cmd/[email protected])
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved


test-sim-nondeterminism:
@echo "Running non-determinism test..."
@go test -mod=readonly $(SIMAPP) -run TestAppStateDeterminism -Enabled=true \
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h


test-sim-fullappsimulation:
@echo "Running TestFullAppSimulation."
@go test -mod=readonly $(SIMAPP) -run TestFullAppSimulation -Enabled=true \
-NumBlocks=100 -BlockSize=200 -Commit=true -Period=0 -v -timeout 24h

test-sim-multi-seed-long: runsim
@echo "Running long multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 500 50 TestFullAppSimulation

test-sim-multi-seed-short: runsim
@echo "Running short multi-seed application simulation. This may take awhile!"
@$(BINDIR)/runsim -Jobs=4 -SimAppPkg=$(SIMAPP) -ExitOnFail 50 10 TestFullAppSimulation
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved



.PHONY: \
test-sim-nondeterminism \
test-sim-fullappsimulation \
test-sim-multi-seed-long \
test-sim-multi-seed-short

75 changes: 75 additions & 0 deletions tests/simulation/sim/sim_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package sim

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

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")

// 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,
}
}
kingpinXD marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading