From a8c47e00a1fd506138354f3adca7cfce25d0a61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Kunze=20K=C3=BCllmer?= <31522760+fedekunze@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:55:35 +0100 Subject: [PATCH 1/3] imp(types): set custom GasConfig on Context for GasKVStore --- types/context.go | 104 +++++++++++++++++++++++++----------------- types/context_test.go | 9 +++- 2 files changed, 70 insertions(+), 43 deletions(-) diff --git a/types/context.go b/types/context.go index fddee22f950f..1469135f3e22 100644 --- a/types/context.go +++ b/types/context.go @@ -23,43 +23,47 @@ but please do not over-use it. We try to keep all data structured and standard additions here would be better just to add to the Context struct */ type Context struct { - baseCtx context.Context - ms MultiStore - header tmproto.Header - headerHash tmbytes.HexBytes - chainID string - txBytes []byte - logger log.Logger - voteInfo []abci.VoteInfo - gasMeter GasMeter - blockGasMeter GasMeter - checkTx bool - recheckTx bool // if recheckTx == true, then checkTx must also be true - minGasPrice DecCoins - consParams *tmproto.ConsensusParams - eventManager *EventManager - priority int64 // The tx priority, only relevant in CheckTx + baseCtx context.Context + ms MultiStore + header tmproto.Header + headerHash tmbytes.HexBytes + chainID string + txBytes []byte + logger log.Logger + voteInfo []abci.VoteInfo + gasMeter GasMeter + blockGasMeter GasMeter + checkTx bool + recheckTx bool // if recheckTx == true, then checkTx must also be true + minGasPrice DecCoins + consParams *tmproto.ConsensusParams + eventManager *EventManager + priority int64 // The tx priority, only relevant in CheckTx + kvGasConfig storetypes.GasConfig + transientKVGasConfig storetypes.GasConfig } // Proposed rename, not done to avoid API breakage type Request = Context // Read-only accessors -func (c Context) Context() context.Context { return c.baseCtx } -func (c Context) MultiStore() MultiStore { return c.ms } -func (c Context) BlockHeight() int64 { return c.header.Height } -func (c Context) BlockTime() time.Time { return c.header.Time } -func (c Context) ChainID() string { return c.chainID } -func (c Context) TxBytes() []byte { return c.txBytes } -func (c Context) Logger() log.Logger { return c.logger } -func (c Context) VoteInfos() []abci.VoteInfo { return c.voteInfo } -func (c Context) GasMeter() GasMeter { return c.gasMeter } -func (c Context) BlockGasMeter() GasMeter { return c.blockGasMeter } -func (c Context) IsCheckTx() bool { return c.checkTx } -func (c Context) IsReCheckTx() bool { return c.recheckTx } -func (c Context) MinGasPrices() DecCoins { return c.minGasPrice } -func (c Context) EventManager() *EventManager { return c.eventManager } -func (c Context) Priority() int64 { return c.priority } +func (c Context) Context() context.Context { return c.baseCtx } +func (c Context) MultiStore() MultiStore { return c.ms } +func (c Context) BlockHeight() int64 { return c.header.Height } +func (c Context) BlockTime() time.Time { return c.header.Time } +func (c Context) ChainID() string { return c.chainID } +func (c Context) TxBytes() []byte { return c.txBytes } +func (c Context) Logger() log.Logger { return c.logger } +func (c Context) VoteInfos() []abci.VoteInfo { return c.voteInfo } +func (c Context) GasMeter() GasMeter { return c.gasMeter } +func (c Context) BlockGasMeter() GasMeter { return c.blockGasMeter } +func (c Context) IsCheckTx() bool { return c.checkTx } +func (c Context) IsReCheckTx() bool { return c.recheckTx } +func (c Context) MinGasPrices() DecCoins { return c.minGasPrice } +func (c Context) EventManager() *EventManager { return c.eventManager } +func (c Context) Priority() int64 { return c.priority } +func (c Context) KVGasConfig() storetypes.GasConfig { return c.kvGasConfig } +func (c Context) TransientKVGasConfig() storetypes.GasConfig { return c.transientKVGasConfig } // clone the header before returning func (c Context) BlockHeader() tmproto.Header { @@ -95,15 +99,17 @@ func NewContext(ms MultiStore, header tmproto.Header, isCheckTx bool, logger log // https://github.com/gogo/protobuf/issues/519 header.Time = header.Time.UTC() return Context{ - baseCtx: context.Background(), - ms: ms, - header: header, - chainID: header.ChainID, - checkTx: isCheckTx, - logger: logger, - gasMeter: storetypes.NewInfiniteGasMeter(), - minGasPrice: DecCoins{}, - eventManager: NewEventManager(), + baseCtx: context.Background(), + ms: ms, + header: header, + chainID: header.ChainID, + checkTx: isCheckTx, + logger: logger, + gasMeter: storetypes.NewInfiniteGasMeter(), + minGasPrice: DecCoins{}, + eventManager: NewEventManager(), + kvGasConfig: storetypes.KVGasConfig(), + transientKVGasConfig: storetypes.TransientGasConfig(), } } @@ -194,6 +200,20 @@ func (c Context) WithBlockGasMeter(meter GasMeter) Context { return c } +// WithKVGasConfig returns a Context with an updated gas configuration for +// the KVStore +func (c Context) WithKVGasConfig(gasConfig storetypes.GasConfig) Context { + c.kvGasConfig = gasConfig + return c +} + +// WithTransientKVGasConfig returns a Context with an updated gas configuration for +// the transient KVStore +func (c Context) WithTransientKVGasConfig(gasConfig storetypes.GasConfig) Context { + c.transientKVGasConfig = gasConfig + return c +} + // WithIsCheckTx enables or disables CheckTx value for verifying transactions and returns an updated Context func (c Context) WithIsCheckTx(isCheckTx bool) Context { c.checkTx = isCheckTx @@ -258,12 +278,12 @@ func (c Context) Value(key interface{}) interface{} { // KVStore fetches a KVStore from the MultiStore. func (c Context) KVStore(key storetypes.StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), storetypes.KVGasConfig()) + return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), c.kvGasConfig) } // TransientStore fetches a TransientStore from the MultiStore. func (c Context) TransientStore(key storetypes.StoreKey) KVStore { - return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), storetypes.TransientGasConfig()) + return gaskv.NewStore(c.MultiStore().GetKVStore(key), c.GasMeter(), c.transientKVGasConfig) } // CacheContext returns a new Context with the multi-store cached and a new diff --git a/types/context_test.go b/types/context_test.go index fb16c3db49d0..6608681a39d8 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -11,6 +11,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/mock" "github.com/cosmos/cosmos-sdk/types" @@ -92,6 +93,7 @@ func (s *contextTestSuite) TestContextWithCustom() { blockGasMeter := types.NewGasMeter(20000) minGasPrices := types.DecCoins{types.NewInt64DecCoin("feetoken", 1)} headerHash := []byte("headerHash") + zeroGasCfg := storetypes.GasConfig{} ctx = types.NewContext(nil, header, ischeck, logger) s.Require().Equal(header, ctx.BlockHeader()) @@ -104,7 +106,10 @@ func (s *contextTestSuite) TestContextWithCustom() { WithGasMeter(meter). WithMinGasPrices(minGasPrices). WithBlockGasMeter(blockGasMeter). - WithHeaderHash(headerHash) + WithHeaderHash(headerHash). + WithKVGasConfig(zeroGasCfg). + WithTransientKVGasConfig(zeroGasCfg) + s.Require().Equal(height, ctx.BlockHeight()) s.Require().Equal(chainid, ctx.ChainID()) s.Require().Equal(ischeck, ctx.IsCheckTx()) @@ -116,6 +121,8 @@ func (s *contextTestSuite) TestContextWithCustom() { s.Require().Equal(blockGasMeter, ctx.BlockGasMeter()) s.Require().Equal(headerHash, ctx.HeaderHash().Bytes()) s.Require().False(ctx.WithIsCheckTx(false).IsCheckTx()) + s.Require().Equal(zeroGasCfg, ctx.KVGasConfig()) + s.Require().Equal(zeroGasCfg, ctx.TransientKVGasConfig()) // test IsReCheckTx s.Require().False(ctx.IsReCheckTx()) From 5c64fc8cad25ccdd06f57d602109fba38f85eacd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Kunze=20K=C3=BCllmer?= <31522760+fedekunze@users.noreply.github.com> Date: Thu, 10 Nov 2022 17:00:37 +0100 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e98de25afdf5..6ed369e4ccbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Improvements +* [#13826](https://github.com/cosmos/cosmos-sdk/pull/13826) Support custom `GasConfig` configuration for applications. * [#13619](https://github.com/cosmos/cosmos-sdk/pull/13619) Add new function called LogDeferred to report errors in defers. Use the function in x/bank files. * (tools) [#13603](https://github.com/cosmos/cosmos-sdk/pull/13603) Rename cosmovisor package name to `cosmossdk.io/tools/cosmovisor`. The new tool directory contains Cosmos SDK tools. * (deps) [#13397](https://github.com/cosmos/cosmos-sdk/pull/13397) Bump Go version minimum requirement to `1.19`. From bdc23d3dad95b22dadf9b3a120514085dfebc331 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Thu, 10 Nov 2022 19:50:47 +0100 Subject: [PATCH 3/3] updates --- x/gov/keeper/msg_server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/gov/keeper/msg_server.go b/x/gov/keeper/msg_server.go index 5a6eb89efcc3..d0213cbe7016 100644 --- a/x/gov/keeper/msg_server.go +++ b/x/gov/keeper/msg_server.go @@ -8,7 +8,6 @@ import ( "cosmossdk.io/errors" "github.com/armon/go-metrics" - storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -53,7 +52,7 @@ func (k msgServer) SubmitProposal(goCtx context.Context, msg *v1.MsgSubmitPropos // ref: https://github.com/cosmos/cosmos-sdk/issues/9683 ctx.GasMeter().ConsumeGas( - 3*storetypes.KVGasConfig().WriteCostPerByte*uint64(len(bytes)), + 3*ctx.KVGasConfig().WriteCostPerByte*uint64(len(bytes)), "submit proposal", )