Skip to content

Commit

Permalink
Merge PR CosmWasm#215: Update simulation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fedekunze authored and alexanderbez committed Dec 19, 2019
1 parent 10493a8 commit ebfbd95
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 351 deletions.
72 changes: 51 additions & 21 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ func MakeCodec() *codec.Codec {
return cdc.Seal()
}

// Verify app interface at compile time
var _ simapp.App = (*GaiaApp)(nil)

// GaiaApp extended ABCI application
type GaiaApp struct {
*bam.BaseApp
Expand All @@ -97,6 +100,9 @@ type GaiaApp struct {
keys map[string]*sdk.KVStoreKey
tKeys map[string]*sdk.TransientStoreKey

// subspaces
subspaces map[string]params.Subspace

// keepers
accountKeeper auth.AccountKeeper
bankKeeper bank.Keeper
Expand Down Expand Up @@ -142,40 +148,56 @@ func NewGaiaApp(
invCheckPeriod: invCheckPeriod,
keys: keys,
tKeys: tKeys,
subspaces: make(map[string]params.Subspace),
}

// init params keeper and subspaces
app.paramsKeeper = params.NewKeeper(app.cdc, keys[params.StoreKey], tKeys[params.TStoreKey], params.DefaultCodespace)
authSubspace := app.paramsKeeper.Subspace(auth.DefaultParamspace)
bankSubspace := app.paramsKeeper.Subspace(bank.DefaultParamspace)
stakingSubspace := app.paramsKeeper.Subspace(staking.DefaultParamspace)
mintSubspace := app.paramsKeeper.Subspace(mint.DefaultParamspace)
distrSubspace := app.paramsKeeper.Subspace(distr.DefaultParamspace)
slashingSubspace := app.paramsKeeper.Subspace(slashing.DefaultParamspace)
govSubspace := app.paramsKeeper.Subspace(gov.DefaultParamspace).WithKeyTable(gov.ParamKeyTable())
crisisSubspace := app.paramsKeeper.Subspace(crisis.DefaultParamspace)
evidenceSubspace := app.paramsKeeper.Subspace(evidence.DefaultParamspace)
app.subspaces[auth.ModuleName] = app.paramsKeeper.Subspace(auth.DefaultParamspace)
app.subspaces[bank.ModuleName] = app.paramsKeeper.Subspace(bank.DefaultParamspace)
app.subspaces[staking.ModuleName] = app.paramsKeeper.Subspace(staking.DefaultParamspace)
app.subspaces[mint.ModuleName] = app.paramsKeeper.Subspace(mint.DefaultParamspace)
app.subspaces[distr.ModuleName] = app.paramsKeeper.Subspace(distr.DefaultParamspace)
app.subspaces[slashing.ModuleName] = app.paramsKeeper.Subspace(slashing.DefaultParamspace)
app.subspaces[gov.ModuleName] = app.paramsKeeper.Subspace(gov.DefaultParamspace).WithKeyTable(gov.ParamKeyTable())
app.subspaces[crisis.ModuleName] = app.paramsKeeper.Subspace(crisis.DefaultParamspace)
app.subspaces[evidence.ModuleName] = app.paramsKeeper.Subspace(evidence.DefaultParamspace)

// add keepers
app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, auth.ProtoBaseAccount)
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, app.ModuleAccountAddrs())
app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms)
app.accountKeeper = auth.NewAccountKeeper(
app.cdc, keys[auth.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount,
)
app.bankKeeper = bank.NewBaseKeeper(
app.accountKeeper, app.subspaces[bank.ModuleName], bank.DefaultCodespace,
app.ModuleAccountAddrs(),
)
app.supplyKeeper = supply.NewKeeper(
app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms,
)
stakingKeeper := staking.NewKeeper(
app.cdc, keys[staking.StoreKey], app.supplyKeeper, stakingSubspace, staking.DefaultCodespace,
app.cdc, keys[staking.StoreKey], app.supplyKeeper,
app.subspaces[staking.ModuleName], staking.DefaultCodespace,
)
app.mintKeeper = mint.NewKeeper(
app.cdc, keys[mint.StoreKey], app.subspaces[mint.ModuleName], &stakingKeeper,
app.supplyKeeper, auth.FeeCollectorName,
)
app.distrKeeper = distr.NewKeeper(
app.cdc, keys[distr.StoreKey], app.subspaces[distr.ModuleName], &stakingKeeper,
app.supplyKeeper, distr.DefaultCodespace, auth.FeeCollectorName, app.ModuleAccountAddrs(),
)
app.mintKeeper = mint.NewKeeper(app.cdc, keys[mint.StoreKey], mintSubspace, &stakingKeeper, app.supplyKeeper, auth.FeeCollectorName)
app.distrKeeper = distr.NewKeeper(app.cdc, keys[distr.StoreKey], distrSubspace, &stakingKeeper,
app.supplyKeeper, distr.DefaultCodespace, auth.FeeCollectorName, app.ModuleAccountAddrs())
app.slashingKeeper = slashing.NewKeeper(
app.cdc, keys[slashing.StoreKey], &stakingKeeper, slashingSubspace, slashing.DefaultCodespace,
app.cdc, keys[slashing.StoreKey], &stakingKeeper, app.subspaces[slashing.ModuleName], slashing.DefaultCodespace,
)
app.crisisKeeper = crisis.NewKeeper(
app.subspaces[crisis.ModuleName], invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName,
)
app.crisisKeeper = crisis.NewKeeper(crisisSubspace, invCheckPeriod, app.supplyKeeper, auth.FeeCollectorName)
app.upgradeKeeper = upgrade.NewKeeper(keys[upgrade.StoreKey], app.cdc)

// create evidence keeper with evidence router
evidenceKeeper := evidence.NewKeeper(
app.cdc, keys[evidence.StoreKey], evidenceSubspace, evidence.DefaultCodespace,
&stakingKeeper, app.slashingKeeper,
app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName],
evidence.DefaultCodespace, &stakingKeeper, app.slashingKeeper,
)
evidenceRouter := evidence.NewRouter()

Expand All @@ -191,7 +213,7 @@ func NewGaiaApp(
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper)).
AddRoute(upgrade.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.upgradeKeeper))
app.govKeeper = gov.NewKeeper(
app.cdc, keys[gov.StoreKey], govSubspace,
app.cdc, keys[gov.StoreKey], app.subspaces[gov.ModuleName],
app.supplyKeeper, &stakingKeeper, gov.DefaultCodespace, govRouter,
)

Expand Down Expand Up @@ -272,6 +294,9 @@ func NewGaiaApp(
return app
}

// Name returns the name of the App
func (app *GaiaApp) Name() string { return app.BaseApp.Name() }

// BeginBlocker application updates every begin block
func (app *GaiaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.mm.BeginBlock(ctx, req)
Expand Down Expand Up @@ -310,6 +335,11 @@ func (app *GaiaApp) Codec() *codec.Codec {
return app.cdc
}

// SimulationManager implements the SimulationApp interface
func (app *GaiaApp) SimulationManager() *module.SimulationManager {
return app.sm
}

// GetMaccPerms returns a mapping of the application's module account permissions.
func GetMaccPerms() map[string][]string {
modAccPerms := make(map[string][]string)
Expand Down
2 changes: 1 addition & 1 deletion app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestBlackListedAddrs(t *testing.T) {

func setGenesis(gapp *GaiaApp) error {
genesisState := simapp.NewDefaultGenesisState()
stateBytes, err := codec.MarshalJSONIndent(gapp.cdc, genesisState)
stateBytes, err := codec.MarshalJSONIndent(gapp.Codec(), genesisState)
if err != nil {
return err
}
Expand Down
107 changes: 107 additions & 0 deletions app/sim_bench_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package app

import (
"fmt"
"os"
"testing"

"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/x/simulation"
abci "github.com/tendermint/tendermint/abci/types"
)

// Profile with:
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/simapp -bench ^BenchmarkFullAppSimulation$ -Commit=true -cpuprofile cpu.out
func BenchmarkFullAppSimulation(b *testing.B) {
config, db, dir, logger, _, err := simapp.SetupSimulation("goleveldb-app-sim", "Simulation")
if err != nil {
b.Fatalf("simulation setup failed: %s", err.Error())
}

defer func() {
db.Close()
err = os.RemoveAll(dir)
if err != nil {
b.Fatal(err)
}
}()

app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt())

// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
b, os.Stdout, app.BaseApp, simapp.AppStateFn(app.Codec(), app.SimulationManager()),
simapp.SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)

// export state and simParams before the simulation error is checked
if err = simapp.CheckExportSimulation(app, config, simParams); err != nil {
b.Fatal(err)
}

if simErr != nil {
b.Fatal(simErr)
}

if config.Commit {
simapp.PrintStats(db)
}
}

func BenchmarkInvariants(b *testing.B) {
config, db, dir, logger, _, err := simapp.SetupSimulation("leveldb-app-invariant-bench", "Simulation")
if err != nil {
b.Fatalf("simulation setup failed: %s", err.Error())
}

config.AllInvariants = false

defer func() {
db.Close()
err = os.RemoveAll(dir)
if err != nil {
b.Fatal(err)
}
}()

app := NewGaiaApp(logger, db, nil, true, simapp.FlagPeriodValue, interBlockCacheOpt())

// run randomized simulation
_, simParams, simErr := simulation.SimulateFromSeed(
b, os.Stdout, app.BaseApp, simapp.AppStateFn(app.Codec(), app.SimulationManager()),
simapp.SimulationOperations(app, app.Codec(), config),
app.ModuleAccountAddrs(), config,
)

// export state and simParams before the simulation error is checked
if err = simapp.CheckExportSimulation(app, config, simParams); err != nil {
b.Fatal(err)
}

if simErr != nil {
b.Fatal(simErr)
}

if config.Commit {
simapp.PrintStats(db)
}

ctx := app.NewContext(true, abci.Header{Height: app.LastBlockHeight() + 1})

// 3. Benchmark each invariant separately
//
// NOTE: We use the crisis keeper as it has all the invariants registered with
// their respective metadata which makes it useful for testing/benchmarking.
for _, cr := range app.crisisKeeper.Routes() {
cr := cr
b.Run(fmt.Sprintf("%s/%s", cr.ModuleName, cr.Route), func(b *testing.B) {
if res, stop := cr.Invar(ctx); stop {
b.Fatalf(
"broken invariant at block %d of %d\n%s",
ctx.BlockHeight()-1, config.NumBlocks, res,
)
}
})
}
}
Loading

0 comments on commit ebfbd95

Please sign in to comment.