From 1c08b354030e3cec25dab34f6510650550bc3fb3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 14 Nov 2018 16:00:15 +0100 Subject: [PATCH 1/2] Initial pass --- PENDING.md | 1 + cmd/gaia/app/app.go | 2 ++ cmd/gaia/app/invariants.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 cmd/gaia/app/invariants.go diff --git a/PENDING.md b/PENDING.md index 5480b778017b..b2c315675654 100644 --- a/PENDING.md +++ b/PENDING.md @@ -31,6 +31,7 @@ FEATURES * Gaia * [x/gov] [#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Implemented querier for getting governance parameters. + * [app] \#2663 - Runtime-assertable invariants * SDK * [simulator] \#2682 MsgEditValidator now looks at the validator's max rate, thus it now succeeds a significant portion of the time diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 918bfc67d114..8642da3eeead 100644 --- a/cmd/gaia/app/app.go +++ b/cmd/gaia/app/app.go @@ -210,6 +210,8 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R tags := gov.EndBlocker(ctx, app.govKeeper) validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + app.assertRuntimeInvariants() + return abci.ResponseEndBlock{ ValidatorUpdates: validatorUpdates, Tags: tags, diff --git a/cmd/gaia/app/invariants.go b/cmd/gaia/app/invariants.go new file mode 100644 index 000000000000..774212e9bd38 --- /dev/null +++ b/cmd/gaia/app/invariants.go @@ -0,0 +1,32 @@ +package app + +import ( + "fmt" + + banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" + distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation" + govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation" + stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" +) + +func (app *GaiaApp) runtimeInvariants() []simulation.Invariant { + return []simulation.Invariant{ + banksim.NonnegativeBalanceInvariant(app.accountKeeper), + govsim.AllInvariants(), + distrsim.AllInvariants(app.distrKeeper, app.stakeKeeper), + stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, + app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper), + slashingsim.AllInvariants(), + } +} + +func (app *GaiaApp) assertRuntimeInvariants() { + invariants := app.runtimeInvariants() + for _, inv := range invariants { + if err := inv(app.BaseApp); err != nil { + panic(fmt.Errorf("invariant broken: %s", err)) + } + } +} From 492e9f0313d1b3abb338e8750b97bed95932ba96 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 14 Nov 2018 16:43:05 +0100 Subject: [PATCH 2/2] Minor cleanup --- cmd/gaia/app/invariants.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/gaia/app/invariants.go b/cmd/gaia/app/invariants.go index 774212e9bd38..67ec1c71414a 100644 --- a/cmd/gaia/app/invariants.go +++ b/cmd/gaia/app/invariants.go @@ -2,31 +2,33 @@ package app import ( "fmt" + "time" banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation" - govsim "github.com/cosmos/cosmos-sdk/x/gov/simulation" "github.com/cosmos/cosmos-sdk/x/mock/simulation" - slashingsim "github.com/cosmos/cosmos-sdk/x/slashing/simulation" stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" ) func (app *GaiaApp) runtimeInvariants() []simulation.Invariant { return []simulation.Invariant{ banksim.NonnegativeBalanceInvariant(app.accountKeeper), - govsim.AllInvariants(), - distrsim.AllInvariants(app.distrKeeper, app.stakeKeeper), - stakesim.AllInvariants(app.bankKeeper, app.stakeKeeper, + distrsim.ValAccumInvariants(app.distrKeeper, app.stakeKeeper), + stakesim.SupplyInvariants(app.bankKeeper, app.stakeKeeper, app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper), - slashingsim.AllInvariants(), + stakesim.PositivePowerInvariant(app.stakeKeeper), } } func (app *GaiaApp) assertRuntimeInvariants() { invariants := app.runtimeInvariants() + start := time.Now() for _, inv := range invariants { if err := inv(app.BaseApp); err != nil { panic(fmt.Errorf("invariant broken: %s", err)) } } + end := time.Now() + diff := end.Sub(start) + app.BaseApp.Logger.With("module", "invariants").Info("Asserted all invariants", "duration", diff) }