From 4bcd29761eaf290d25227e416a5533aeb87cb01f Mon Sep 17 00:00:00 2001 From: yihuang Date: Sun, 3 Mar 2024 14:45:59 +0800 Subject: [PATCH] feat: add option to disable block gas meter ref: #19613 block gas meter is not safe when executing transactions in parallel. --- CHANGELOG.md | 4 ++++ baseapp/baseapp.go | 11 +++++++++++ baseapp/noopgasmeter.go | 17 +++++++++++++++++ baseapp/options.go | 10 ++++++++++ 4 files changed, 42 insertions(+) create mode 100644 baseapp/noopgasmeter.go diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f96bc690d5..c44db7e443a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/auth) [#19549](https://github.com/cosmos/cosmos-sdk/pull/19549) Accept custom get signers when injecting `x/auth/tx`. +### Features + +* (baseapp) [#19626](https://github.com/cosmos/cosmos-sdk/pull/19626) Adds `DisableBlockGasMeter` option to `BaseApp`, which removes the block gas meter during transaction execution. + ## [v0.50.4](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.4) - 2023-02-19 ### Features diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index e7c3b5744d9f..d1020e21877d 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -186,6 +186,13 @@ type BaseApp struct { // including the goroutine handling.This is experimental and must be enabled // by developers. optimisticExec *oe.OptimisticExecution + + // disableBlockGasMeter will disable the block gas meter if true, block gas meter is tricky to support + // when executing transactions in parallel. + // when disabled, the block gas meter in context is `nil`. + // + // SAFTY: it's safe to do if validators validates the total gas wanted in the proposal. + disableBlockGasMeter bool } // NewBaseApp returns a reference to an initialized BaseApp. It accepts a @@ -640,6 +647,10 @@ func (app *BaseApp) getState(mode execMode) *state { } func (app *BaseApp) getBlockGasMeter(ctx sdk.Context) storetypes.GasMeter { + if app.disableBlockGasMeter { + return noopGasMeter{} + } + if maxGas := app.GetMaximumBlockGas(ctx); maxGas > 0 { return storetypes.NewGasMeter(maxGas) } diff --git a/baseapp/noopgasmeter.go b/baseapp/noopgasmeter.go new file mode 100644 index 000000000000..c341bcbe7b11 --- /dev/null +++ b/baseapp/noopgasmeter.go @@ -0,0 +1,17 @@ +package baseapp + +import storetypes "cosmossdk.io/store/types" + +type noopGasMeter struct{} + +var _ storetypes.GasMeter = noopGasMeter{} + +func (noopGasMeter) GasConsumed() storetypes.Gas { return 0 } +func (noopGasMeter) GasConsumedToLimit() storetypes.Gas { return 0 } +func (noopGasMeter) GasRemaining() storetypes.Gas { return 0 } +func (noopGasMeter) Limit() storetypes.Gas { return 0 } +func (noopGasMeter) ConsumeGas(storetypes.Gas, string) {} +func (noopGasMeter) RefundGas(storetypes.Gas, string) {} +func (noopGasMeter) IsPastLimit() bool { return false } +func (noopGasMeter) IsOutOfGas() bool { return false } +func (noopGasMeter) String() string { return "noopGasMeter" } diff --git a/baseapp/options.go b/baseapp/options.go index c8cacdd8a4be..08cbf77ee297 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -117,6 +117,11 @@ func SetOptimisticExecution(opts ...func(*oe.OptimisticExecution)) func(*BaseApp } } +// DisableBlockGasMeter disables the block gas meter. +func DisableBlockGasMeter() func(*BaseApp) { + return func(app *BaseApp) { app.SetDisableBlockGasMeter(true) } +} + func (app *BaseApp) SetName(name string) { if app.sealed { panic("SetName() on sealed BaseApp") @@ -362,3 +367,8 @@ func (app *BaseApp) SetStoreMetrics(gatherer metrics.StoreMetrics) { func (app *BaseApp) SetStreamingManager(manager storetypes.StreamingManager) { app.streamingManager = manager } + +// SetDisableBlockGasMeter sets the disableBlockGasMeter flag for the BaseApp. +func (app *BaseApp) SetDisableBlockGasMeter(disableBlockGasMeter bool) { + app.disableBlockGasMeter = disableBlockGasMeter +}