From cf6b7ef6d85781100e254cb535724c085ef74df9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 15 Nov 2018 22:21:42 +0100 Subject: [PATCH] Test runtime-assertable invariants every block (#2807) * Initial pass * Minor cleanup --- PENDING.md | 1 + cmd/gaia/app/app.go | 2 ++ cmd/gaia/app/invariants.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 cmd/gaia/app/invariants.go diff --git a/PENDING.md b/PENDING.md index 357d1c8b0b79..ba90d3ac8fd5 100644 --- a/PENDING.md +++ b/PENDING.md @@ -34,6 +34,7 @@ FEATURES * [app] \#2791 Support export at a specific height, with `gaiad export --height=HEIGHT`. * [x/gov] [#2479](https://github.com/cosmos/cosmos-sdk/issues/2479) Implemented querier for getting governance parameters. + * [app] \#2663 - Runtime-assertable invariants * [app] \#2791 Support export at a specific height, with `gaiad export --height=HEIGHT`. * SDK diff --git a/cmd/gaia/app/app.go b/cmd/gaia/app/app.go index 25265a3611f2..fb8455b5aea8 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..67ec1c71414a --- /dev/null +++ b/cmd/gaia/app/invariants.go @@ -0,0 +1,34 @@ +package app + +import ( + "fmt" + "time" + + banksim "github.com/cosmos/cosmos-sdk/x/bank/simulation" + distrsim "github.com/cosmos/cosmos-sdk/x/distribution/simulation" + "github.com/cosmos/cosmos-sdk/x/mock/simulation" + stakesim "github.com/cosmos/cosmos-sdk/x/stake/simulation" +) + +func (app *GaiaApp) runtimeInvariants() []simulation.Invariant { + return []simulation.Invariant{ + banksim.NonnegativeBalanceInvariant(app.accountKeeper), + distrsim.ValAccumInvariants(app.distrKeeper, app.stakeKeeper), + stakesim.SupplyInvariants(app.bankKeeper, app.stakeKeeper, + app.feeCollectionKeeper, app.distrKeeper, app.accountKeeper), + 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) +}