Skip to content

Commit

Permalink
feat(types): set custom GasConfig on Context for GasKVStore (#13826)
Browse files Browse the repository at this point in the history
  • Loading branch information
fedekunze authored Nov 10, 2022
1 parent d32d896 commit f001b46
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
104 changes: 62 additions & 42 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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(),
}
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion types/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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())
Expand All @@ -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())
Expand All @@ -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())
Expand Down
3 changes: 1 addition & 2 deletions x/gov/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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",
)

Expand Down

0 comments on commit f001b46

Please sign in to comment.