imp(feemarket): update BaseFee based on GasWanted (#1105)

* add gasWanted transient store keys

* add gasWanted transient store keeper functions

* add gasWanted transient store tracker

* add comment

* remove unncesary comment

* remove unnecesary function

* fix tests

* fix bad comment

* remove unnecesary comment

* update comment

* update changelog

* Update CHANGELOG.md

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* add GasWantedDecorator

* remove unnecesary comments

* gasWanted decorator test

* fix tests

* fix tests and build

* fix lint

* updated end block event

* Update app/ante/fee_market.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* fix undeclared variable

* Update app/ante/fee_market_test.go

* remove unnecesary line

* migrate MinGasMultiplier to FeeMarket module

* set limited gas wanted

* remove old newKeeper param

* update proto comment

* fix test

* update comments

* Update x/feemarket/keeper/abci.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* address comments from review

* tidy

* tests

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
crypto-facs
2022-06-05 09:22:33 +00:00
committed by GitHub
co-authored by Federico Kunze Küllmer
parent 8155e1f319
commit 620f6a6770
46 changed files with 570 additions and 521 deletions
+2 -2
View File
@@ -15,7 +15,7 @@ func InitGenesis(
data types.GenesisState,
) []abci.ValidatorUpdate {
k.SetParams(ctx, data.Params)
k.SetBlockGasUsed(ctx, data.BlockGas)
k.SetBlockGasWanted(ctx, data.BlockGas)
return []abci.ValidatorUpdate{}
}
@@ -24,6 +24,6 @@ func InitGenesis(
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
return &types.GenesisState{
Params: k.GetParams(ctx),
BlockGas: k.GetBlockGasUsed(ctx),
BlockGas: k.GetBlockGasWanted(ctx),
}
}
+13 -5
View File
@@ -34,26 +34,34 @@ func (k *Keeper) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
})
}
// EndBlock update block gas used.
// EndBlock update block gas wanted.
// The EVM end block logic doesn't update the validator set, thus it returns
// an empty slice.
func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) {
if ctx.BlockGasMeter() == nil {
k.Logger(ctx).Error("block gas meter is nil when setting block gas used")
k.Logger(ctx).Error("block gas meter is nil when setting block gas wanted")
return
}
gasWanted := k.GetTransientGasWanted(ctx)
gasUsed := ctx.BlockGasMeter().GasConsumedToLimit()
k.SetBlockGasUsed(ctx, gasUsed)
// to prevent BaseFee manipulation we limit the gasWanted so that
// gasWanted = max(gasWanted * MinGasMultiplier, gasUsed)
// this will be keep BaseFee protected from un-penalized manipulation
// more info here https://github.com/tharsis/ethermint/pull/1105#discussion_r888798925
minGasMultiplier := k.GetParams(ctx).MinGasMultiplier
limitedGasWanted := sdk.NewDec(int64(gasWanted)).Mul(minGasMultiplier)
gasWanted = sdk.MaxDec(limitedGasWanted, sdk.NewDec(int64(gasUsed))).TruncateInt().Uint64()
k.SetBlockGasWanted(ctx, gasWanted)
defer func() {
telemetry.SetGauge(float32(gasUsed), "feemarket", "block_gas")
telemetry.SetGauge(float32(gasWanted), "feemarket", "block_gas")
}()
ctx.EventManager().EmitEvent(sdk.NewEvent(
"block_gas",
sdk.NewAttribute("height", fmt.Sprintf("%d", ctx.BlockHeight())),
sdk.NewAttribute("amount", fmt.Sprintf("%d", ctx.BlockGasMeter().GasConsumedToLimit())),
sdk.NewAttribute("amount", fmt.Sprintf("%d", gasWanted)),
))
}
+11 -20
View File
@@ -2,39 +2,32 @@ package keeper_test
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/abci/types"
)
func (suite *KeeperTestSuite) TestEndBlock() {
testCases := []struct {
name string
NoBaseFee bool
malleate func()
expGasUsed uint64
name string
NoBaseFee bool
malleate func()
expGasWanted uint64
}{
{
"basFee nil",
"baseFee nil",
true,
func() {},
uint64(0),
},
{
"Block gas meter is nil",
false,
func() {},
uint64(0),
},
{
"pass",
false,
func() {
meter := sdk.NewGasMeter(uint64(1000000000))
suite.ctx = suite.ctx.WithBlockGasMeter(meter)
suite.ctx.BlockGasMeter().ConsumeGas(uint64(5000000), "consume gas")
suite.app.FeeMarketKeeper.SetTransientBlockGasWanted(suite.ctx, 5000000)
},
uint64(5000000),
uint64(2500000),
},
}
for _, tc := range testCases {
@@ -45,11 +38,9 @@ func (suite *KeeperTestSuite) TestEndBlock() {
suite.app.FeeMarketKeeper.SetParams(suite.ctx, params)
tc.malleate()
req := abci.RequestEndBlock{Height: 1}
suite.app.FeeMarketKeeper.EndBlock(suite.ctx, req)
gasUsed := suite.app.FeeMarketKeeper.GetBlockGasUsed(suite.ctx)
suite.Require().Equal(tc.expGasUsed, gasUsed, tc.name)
suite.app.FeeMarketKeeper.EndBlock(suite.ctx, types.RequestEndBlock{Height: 1})
gasWanted := suite.app.FeeMarketKeeper.GetBlockGasWanted(suite.ctx)
suite.Require().Equal(tc.expGasWanted, gasWanted, tc.name)
})
}
}
+1 -1
View File
@@ -39,7 +39,7 @@ func (k Keeper) CalculateBaseFee(ctx sdk.Context) *big.Int {
return nil
}
parentGasUsed := k.GetBlockGasUsed(ctx)
parentGasUsed := k.GetBlockGasWanted(ctx)
gasLimit := new(big.Int).SetUint64(math.MaxUint64)
+6 -6
View File
@@ -28,14 +28,14 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
suite.app.FeeMarketKeeper.GetParams(suite.ctx).BaseFee.BigInt(),
},
{
"with BaseFee - parent block used the same gas as its target",
"with BaseFee - parent block wanted the same gas as its target",
false,
func() {
// non initial block
suite.ctx = suite.ctx.WithBlockHeight(1)
// Set gas used
suite.app.FeeMarketKeeper.SetBlockGasUsed(suite.ctx, 100)
suite.app.FeeMarketKeeper.SetBlockGasWanted(suite.ctx, 100)
// Set target/gasLimit through Consensus Param MaxGas
blockParams := abci.BlockParams{
@@ -53,12 +53,12 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
suite.app.FeeMarketKeeper.GetParams(suite.ctx).BaseFee.BigInt(),
},
{
"with BaseFee - parent block used more gas than its target",
"with BaseFee - parent block wanted more gas than its target",
false,
func() {
suite.ctx = suite.ctx.WithBlockHeight(1)
suite.app.FeeMarketKeeper.SetBlockGasUsed(suite.ctx, 200)
suite.app.FeeMarketKeeper.SetBlockGasWanted(suite.ctx, 200)
blockParams := abci.BlockParams{
MaxGas: 100,
@@ -74,12 +74,12 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
big.NewInt(1125000000),
},
{
"with BaseFee - Parent gas used smaller than parent gas target",
"with BaseFee - Parent gas wanted smaller than parent gas target",
false,
func() {
suite.ctx = suite.ctx.WithBlockHeight(1)
suite.app.FeeMarketKeeper.SetBlockGasUsed(suite.ctx, 50)
suite.app.FeeMarketKeeper.SetBlockGasWanted(suite.ctx, 50)
blockParams := abci.BlockParams{
MaxGas: 100,
+1 -1
View File
@@ -38,7 +38,7 @@ func (k Keeper) BaseFee(c context.Context, _ *types.QueryBaseFeeRequest) (*types
// BlockGas implements the Query/BlockGas gRPC method
func (k Keeper) BlockGas(c context.Context, _ *types.QueryBlockGasRequest) (*types.QueryBlockGasResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
gas := k.GetBlockGasUsed(ctx)
gas := k.GetBlockGasWanted(ctx)
return &types.QueryBlockGasResponse{
Gas: int64(gas),
+1 -1
View File
@@ -86,7 +86,7 @@ func (suite *KeeperTestSuite) TestQueryBlockGas() {
},
}
for _, tc := range testCases {
gas := suite.app.FeeMarketKeeper.GetBlockGasUsed(suite.ctx)
gas := suite.app.FeeMarketKeeper.GetBlockGasWanted(suite.ctx)
exp := &types.QueryBlockGasResponse{Gas: int64(gas)}
res, err := suite.queryClient.BlockGas(suite.ctx.Context(), &types.QueryBlockGasRequest{})
+40 -14
View File
@@ -14,14 +14,15 @@ type Keeper struct {
// Protobuf codec
cdc codec.BinaryCodec
// Store key required for the Fee Market Prefix KVStore.
storeKey sdk.StoreKey
storeKey sdk.StoreKey
transientKey sdk.StoreKey
// module specific parameter space that can be configured through governance
paramSpace paramtypes.Subspace
}
// NewKeeper generates new fee market module keeper
func NewKeeper(
cdc codec.BinaryCodec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace,
cdc codec.BinaryCodec, paramSpace paramtypes.Subspace, storeKey, transientKey sdk.StoreKey,
) Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
@@ -29,9 +30,10 @@ func NewKeeper(
}
return Keeper{
cdc: cdc,
storeKey: storeKey,
paramSpace: paramSpace,
cdc: cdc,
storeKey: storeKey,
paramSpace: paramSpace,
transientKey: transientKey,
}
}
@@ -45,10 +47,18 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
// Required by EIP1559 base fee calculation.
// ----------------------------------------------------------------------------
// GetBlockGasUsed returns the last block gas used value from the store.
func (k Keeper) GetBlockGasUsed(ctx sdk.Context) uint64 {
// SetBlockGasWanted sets the block gas wanted to the store.
// CONTRACT: this should be only called during EndBlock.
func (k Keeper) SetBlockGasWanted(ctx sdk.Context, gas uint64) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyPrefixBlockGasUsed)
gasBz := sdk.Uint64ToBigEndian(gas)
store.Set(types.KeyPrefixBlockGasWanted, gasBz)
}
// GetBlockGasWanted returns the last block gas wanted value from the store.
func (k Keeper) GetBlockGasWanted(ctx sdk.Context) uint64 {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyPrefixBlockGasWanted)
if len(bz) == 0 {
return 0
}
@@ -56,10 +66,26 @@ func (k Keeper) GetBlockGasUsed(ctx sdk.Context) uint64 {
return sdk.BigEndianToUint64(bz)
}
// SetBlockGasUsed gets the block gas consumed to the store.
// CONTRACT: this should be only called during EndBlock.
func (k Keeper) SetBlockGasUsed(ctx sdk.Context, gas uint64) {
store := ctx.KVStore(k.storeKey)
gasBz := sdk.Uint64ToBigEndian(gas)
store.Set(types.KeyPrefixBlockGasUsed, gasBz)
// GetTransientGasWanted returns the gas wanted in the current block from transient store.
func (k Keeper) GetTransientGasWanted(ctx sdk.Context) uint64 {
store := ctx.TransientStore(k.transientKey)
bz := store.Get(types.KeyPrefixTransientBlockGasWanted)
if len(bz) == 0 {
return 0
}
return sdk.BigEndianToUint64(bz)
}
// SetTransientBlockGasWanted sets the block gas wanted to the transient store.
func (k Keeper) SetTransientBlockGasWanted(ctx sdk.Context, gasWanted uint64) {
store := ctx.TransientStore(k.transientKey)
gasBz := sdk.Uint64ToBigEndian(gasWanted)
store.Set(types.KeyPrefixTransientBlockGasWanted, gasBz)
}
// AddTransientGasWanted adds the cumulative gas wanted in the transient store
func (k Keeper) AddTransientGasWanted(ctx sdk.Context, gasWanted uint64) (uint64, error) {
result := k.GetTransientGasWanted(ctx) + gasWanted
k.SetTransientBlockGasWanted(ctx, result)
return result, nil
}
+3 -3
View File
@@ -166,7 +166,7 @@ func (suite *KeeperTestSuite) CommitAfter(t time.Duration) {
suite.queryClient = types.NewQueryClient(queryHelper)
}
func (suite *KeeperTestSuite) TestSetGetBlockGasUsed() {
func (suite *KeeperTestSuite) TestSetGetBlockGasWanted() {
testCases := []struct {
name string
malleate func()
@@ -175,7 +175,7 @@ func (suite *KeeperTestSuite) TestSetGetBlockGasUsed() {
{
"with last block given",
func() {
suite.app.FeeMarketKeeper.SetBlockGasUsed(suite.ctx, uint64(1000000))
suite.app.FeeMarketKeeper.SetBlockGasWanted(suite.ctx, uint64(1000000))
},
uint64(1000000),
},
@@ -183,7 +183,7 @@ func (suite *KeeperTestSuite) TestSetGetBlockGasUsed() {
for _, tc := range testCases {
tc.malleate()
gas := suite.app.FeeMarketKeeper.GetBlockGasUsed(suite.ctx)
gas := suite.app.FeeMarketKeeper.GetBlockGasWanted(suite.ctx)
suite.Require().Equal(tc.expGas, gas, tc.name)
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ func TestMigrateStore(t *testing.T) {
paramstore := paramtypes.NewSubspace(
encCfg.Marshaler, encCfg.Amino, feemarketKey, tFeeMarketKey, "feemarket",
)
fmKeeper := feemarketkeeper.NewKeeper(encCfg.Marshaler, feemarketKey, paramstore)
fmKeeper := feemarketkeeper.NewKeeper(encCfg.Marshaler, paramstore, feemarketKey, tFeeMarketKey)
fmKeeper.SetParams(ctx, types.DefaultParams())
require.True(t, paramstore.HasKeyTable())
+8 -2
View File
@@ -9,19 +9,24 @@ import (
)
// MigrateStore adds the MinGasPrice param with a value of 0
// and MinGasMultiplier to 0,5
func MigrateStore(ctx sdk.Context, paramstore *paramtypes.Subspace) error {
if !paramstore.HasKeyTable() {
ps := paramstore.WithKeyTable(types.ParamKeyTable())
paramstore = &ps
}
paramstore.Set(ctx, types.ParamStoreKeyMinGasPrice, sdk.ZeroDec())
// add MinGasPrice
paramstore.Set(ctx, types.ParamStoreKeyMinGasPrice, types.DefaultMinGasPrice)
// add MinGasMultiplier
paramstore.Set(ctx, types.ParamStoreKeyMinGasMultiplier, types.DefaultMinGasMultiplier)
return nil
}
// MigrateJSON accepts exported v0.10 x/feemarket genesis state and migrates it to
// v0.11 x/feemarket genesis state. The migration includes:
// - add MinGasPrice param
// - add MinGasMultiplier param
func MigrateJSON(oldState v010types.GenesisState) types.GenesisState {
return types.GenesisState{
Params: types.Params{
@@ -30,7 +35,8 @@ func MigrateJSON(oldState v010types.GenesisState) types.GenesisState {
ElasticityMultiplier: oldState.Params.ElasticityMultiplier,
EnableHeight: oldState.Params.EnableHeight,
BaseFee: oldState.Params.BaseFee,
MinGasPrice: sdk.ZeroDec(),
MinGasPrice: types.DefaultMinGasPrice,
MinGasMultiplier: types.DefaultMinGasMultiplier,
},
BlockGas: oldState.BlockGas,
}
+18 -3
View File
@@ -15,9 +15,15 @@ import (
"github.com/tharsis/ethermint/app"
v010types "github.com/tharsis/ethermint/x/feemarket/migrations/v010/types"
v011 "github.com/tharsis/ethermint/x/feemarket/migrations/v011"
"github.com/tharsis/ethermint/x/feemarket/types"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
)
func init() {
// modify defaults through global
types.DefaultMinGasPrice = sdk.NewDecWithPrec(25, 3)
}
func TestMigrateStore(t *testing.T) {
encCfg := encoding.MakeConfig(app.ModuleBasics)
feemarketKey := sdk.NewKVStoreKey(feemarkettypes.StoreKey)
@@ -32,6 +38,7 @@ func TestMigrateStore(t *testing.T) {
// check no MinGasPrice param
require.False(t, paramstore.Has(ctx, feemarkettypes.ParamStoreKeyMinGasPrice))
require.False(t, paramstore.Has(ctx, feemarkettypes.ParamStoreKeyMinGasMultiplier))
// Run migrations
err := v011.MigrateStore(ctx, &paramstore)
@@ -39,16 +46,23 @@ func TestMigrateStore(t *testing.T) {
// Make sure the params are set
require.True(t, paramstore.Has(ctx, feemarkettypes.ParamStoreKeyMinGasPrice))
require.True(t, paramstore.Has(ctx, feemarkettypes.ParamStoreKeyMinGasMultiplier))
var minGasPrice sdk.Dec
var (
minGasPrice sdk.Dec
minGasMultiplier sdk.Dec
)
// Make sure the new params are set
require.NotPanics(t, func() {
paramstore.Get(ctx, feemarkettypes.ParamStoreKeyMinGasPrice, &minGasPrice)
paramstore.Get(ctx, feemarkettypes.ParamStoreKeyMinGasMultiplier, &minGasMultiplier)
})
// check the params are updated
require.True(t, minGasPrice.IsZero())
require.Equal(t, types.DefaultMinGasPrice.String(), minGasPrice.String())
require.False(t, minGasPrice.IsZero())
require.Equal(t, types.DefaultMinGasMultiplier.String(), minGasMultiplier.String())
}
func TestMigrateJSON(t *testing.T) {
@@ -69,5 +83,6 @@ func TestMigrateJSON(t *testing.T) {
migratedGenState := v011.MigrateJSON(genState)
require.True(t, migratedGenState.Params.MinGasPrice.IsZero())
require.Equal(t, types.DefaultMinGasPrice, migratedGenState.Params.MinGasPrice)
require.Equal(t, types.DefaultMinGasMultiplier, migratedGenState.Params.MinGasMultiplier)
}
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// RandomizedGenState generates a random GenesisState for nft
func RandomizedGenState(simState *module.SimulationState) {
params := types.NewParams(simState.Rand.Uint32()%2 == 0, simState.Rand.Uint32(), simState.Rand.Uint32(), simState.Rand.Uint64(), simState.Rand.Int63(), sdk.ZeroDec())
params := types.NewParams(simState.Rand.Uint32()%2 == 0, simState.Rand.Uint32(), simState.Rand.Uint32(), simState.Rand.Uint64(), simState.Rand.Int63(), sdk.ZeroDec(), types.DefaultMinGasMultiplier)
blockGas := simState.Rand.Uint64()
feemarketGenesis := types.NewGenesisState(params, blockGas)
+75 -25
View File
@@ -40,6 +40,9 @@ type Params struct {
BaseFee github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,6,opt,name=base_fee,json=baseFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"base_fee"`
// min_gas_price defines the minimum gas price value for cosmos and eth transactions
MinGasPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=min_gas_price,json=minGasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_gas_price"`
// min gas denominator bounds the minimum gasUsed to be charged
// to senders based on GasLimit
MinGasMultiplier github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,8,opt,name=min_gas_multiplier,json=minGasMultiplier,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"min_gas_multiplier"`
}
func (m *Params) Reset() { *m = Params{} }
@@ -112,31 +115,32 @@ func init() {
}
var fileDescriptor_4feb8b20cf98e6e1 = []byte{
// 371 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x4f, 0xeb, 0xda, 0x30,
0x18, 0xc7, 0x9b, 0xdf, 0x1f, 0xff, 0xc4, 0x09, 0x52, 0xdc, 0x28, 0x1b, 0xd4, 0xb2, 0x81, 0xf4,
0xb2, 0x16, 0xf1, 0xbc, 0x8b, 0x93, 0x4d, 0x07, 0x03, 0xe9, 0x71, 0x97, 0x90, 0xd6, 0xc7, 0x36,
0xd8, 0x24, 0x25, 0x89, 0x32, 0xdf, 0xc5, 0x5e, 0x96, 0x47, 0x8f, 0x63, 0x07, 0x19, 0xfa, 0x26,
0x76, 0x1c, 0x56, 0xd7, 0x7a, 0xdd, 0xa9, 0xcd, 0xf3, 0xf9, 0xe4, 0x79, 0x1e, 0xf2, 0xc5, 0x43,
0x30, 0x19, 0x28, 0xce, 0x84, 0x09, 0x57, 0x00, 0x9c, 0xaa, 0x35, 0x98, 0x70, 0x3b, 0xaa, 0x0f,
0x41, 0xa1, 0xa4, 0x91, 0xf6, 0xab, 0xca, 0x0b, 0x6a, 0xb4, 0x1d, 0xbd, 0xee, 0xa7, 0x32, 0x95,
0xa5, 0x12, 0x5e, 0xfe, 0xae, 0xf6, 0xdb, 0x3f, 0x0f, 0xb8, 0xb1, 0xa0, 0x8a, 0x72, 0x6d, 0xbb,
0xb8, 0x23, 0x24, 0x89, 0xa9, 0x06, 0xb2, 0x02, 0x70, 0x90, 0x87, 0xfc, 0x56, 0xd4, 0x16, 0x72,
0x42, 0x35, 0x7c, 0x02, 0xb0, 0x3f, 0xe0, 0x37, 0xff, 0x20, 0x49, 0x32, 0x2a, 0x52, 0x20, 0x4b,
0x10, 0x92, 0x33, 0x41, 0x8d, 0x54, 0xce, 0x83, 0x87, 0xfc, 0x6e, 0xe4, 0xc4, 0x57, 0xfb, 0x63,
0x29, 0x4c, 0x6b, 0x6e, 0x8f, 0xf1, 0x4b, 0xc8, 0xa9, 0x36, 0x2c, 0x61, 0x66, 0x47, 0xf8, 0x26,
0x37, 0xac, 0xc8, 0x19, 0x28, 0xe7, 0xb1, 0xbc, 0xd8, 0xaf, 0xe1, 0xd7, 0x8a, 0xd9, 0xef, 0x70,
0x17, 0x04, 0x8d, 0x73, 0x20, 0x19, 0xb0, 0x34, 0x33, 0xce, 0xb3, 0x87, 0xfc, 0xc7, 0xe8, 0xc5,
0xb5, 0x38, 0x2b, 0x6b, 0xf6, 0x1c, 0xb7, 0xaa, 0xad, 0x1b, 0x1e, 0xf2, 0xdb, 0x93, 0x60, 0x7f,
0x1c, 0x58, 0xbf, 0x8e, 0x83, 0x61, 0xca, 0x4c, 0xb6, 0x89, 0x83, 0x44, 0xf2, 0x30, 0x91, 0x9a,
0x4b, 0x7d, 0xfb, 0xbc, 0xd7, 0xcb, 0x75, 0x68, 0x76, 0x05, 0xe8, 0x60, 0x2e, 0x4c, 0xd4, 0xbc,
0x6d, 0x6d, 0x47, 0xb8, 0xcb, 0x99, 0x20, 0x29, 0xd5, 0xa4, 0x50, 0x2c, 0x01, 0xa7, 0xf9, 0xdf,
0xfd, 0xa6, 0x90, 0x44, 0x1d, 0xce, 0xc4, 0x67, 0xaa, 0x17, 0x97, 0x16, 0x5f, 0x9e, 0x5a, 0x4f,
0xbd, 0xe7, 0xa8, 0xc7, 0x04, 0x33, 0x8c, 0xe6, 0xd5, 0x03, 0x4f, 0x66, 0xfb, 0x93, 0x8b, 0x0e,
0x27, 0x17, 0xfd, 0x3e, 0xb9, 0xe8, 0xc7, 0xd9, 0xb5, 0x0e, 0x67, 0xd7, 0xfa, 0x79, 0x76, 0xad,
0x6f, 0xc1, 0xdd, 0x18, 0x93, 0x51, 0xa5, 0x99, 0x0e, 0xeb, 0xf4, 0xbf, 0xdf, 0xe5, 0x5f, 0x8e,
0x8c, 0x1b, 0x65, 0x96, 0xe3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x5d, 0x33, 0x70, 0x23,
0x02, 0x00, 0x00,
// 391 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x41, 0x6b, 0xdb, 0x30,
0x14, 0xc7, 0xad, 0xa5, 0x4d, 0x5d, 0x75, 0x81, 0x20, 0xba, 0x61, 0x36, 0x70, 0xcd, 0x06, 0xc5,
0x97, 0xd9, 0x94, 0x9e, 0x77, 0xc9, 0xca, 0xd6, 0x0e, 0x06, 0xc1, 0xc7, 0x31, 0x10, 0xb2, 0xf3,
0x62, 0x8b, 0x58, 0x92, 0x91, 0x94, 0xb0, 0x7c, 0x8b, 0x7d, 0xac, 0x1c, 0x73, 0x1a, 0x63, 0x87,
0x30, 0x92, 0x2f, 0x32, 0x62, 0x27, 0x76, 0xae, 0xdb, 0xc9, 0xd6, 0xfb, 0xff, 0xf5, 0x7b, 0x4f,
0xd2, 0x1f, 0xdf, 0x82, 0x2d, 0x40, 0x0b, 0x2e, 0x6d, 0x3c, 0x05, 0x10, 0x4c, 0xcf, 0xc0, 0xc6,
0x8b, 0xbb, 0x6e, 0x11, 0x55, 0x5a, 0x59, 0x45, 0x5e, 0xb6, 0xbe, 0xa8, 0x93, 0x16, 0x77, 0xaf,
0xae, 0x73, 0x95, 0xab, 0xda, 0x12, 0xef, 0xff, 0x1a, 0xf7, 0x9b, 0x9f, 0x3d, 0xdc, 0x1f, 0x33,
0xcd, 0x84, 0x21, 0x3e, 0xbe, 0x92, 0x8a, 0xa6, 0xcc, 0x00, 0x9d, 0x02, 0x78, 0x28, 0x40, 0xa1,
0x9b, 0x5c, 0x4a, 0x35, 0x62, 0x06, 0x3e, 0x02, 0x90, 0xf7, 0xf8, 0xf5, 0x51, 0xa4, 0x59, 0xc1,
0x64, 0x0e, 0x74, 0x02, 0x52, 0x09, 0x2e, 0x99, 0x55, 0xda, 0x7b, 0x16, 0xa0, 0x70, 0x90, 0x78,
0x69, 0xe3, 0xfe, 0x50, 0x1b, 0x1e, 0x3a, 0x9d, 0xdc, 0xe3, 0x17, 0x50, 0x32, 0x63, 0x79, 0xc6,
0xed, 0x92, 0x8a, 0x79, 0x69, 0x79, 0x55, 0x72, 0xd0, 0x5e, 0xaf, 0xde, 0x78, 0xdd, 0x89, 0x5f,
0x5a, 0x8d, 0xbc, 0xc5, 0x03, 0x90, 0x2c, 0x2d, 0x81, 0x16, 0xc0, 0xf3, 0xc2, 0x7a, 0xe7, 0x01,
0x0a, 0x7b, 0xc9, 0xf3, 0xa6, 0xf8, 0x58, 0xd7, 0xc8, 0x13, 0x76, 0xdb, 0xa9, 0xfb, 0x01, 0x0a,
0x2f, 0x47, 0xd1, 0x6a, 0x73, 0xe3, 0xfc, 0xde, 0xdc, 0xdc, 0xe6, 0xdc, 0x16, 0xf3, 0x34, 0xca,
0x94, 0x88, 0x33, 0x65, 0x84, 0x32, 0x87, 0xcf, 0x3b, 0x33, 0x99, 0xc5, 0x76, 0x59, 0x81, 0x89,
0x9e, 0xa4, 0x4d, 0x2e, 0x0e, 0x53, 0x93, 0x04, 0x0f, 0x04, 0x97, 0x34, 0x67, 0x86, 0x56, 0x9a,
0x67, 0xe0, 0x5d, 0xfc, 0x33, 0xef, 0x01, 0xb2, 0xe4, 0x4a, 0x70, 0xf9, 0x89, 0x99, 0xf1, 0x1e,
0x41, 0xbe, 0x61, 0x72, 0x64, 0x9e, 0x9c, 0xda, 0xfd, 0x2f, 0xf0, 0xb0, 0x01, 0x77, 0x37, 0xf4,
0xf9, 0xcc, 0x3d, 0x1b, 0x9e, 0x27, 0x43, 0x2e, 0xb9, 0xe5, 0xac, 0x6c, 0x9f, 0x6f, 0xf4, 0xb8,
0xda, 0xfa, 0x68, 0xbd, 0xf5, 0xd1, 0x9f, 0xad, 0x8f, 0x7e, 0xec, 0x7c, 0x67, 0xbd, 0xf3, 0x9d,
0x5f, 0x3b, 0xdf, 0xf9, 0x1a, 0x9d, 0xf4, 0xb2, 0x05, 0xd3, 0x86, 0x9b, 0xb8, 0xcb, 0xd6, 0xf7,
0x93, 0x74, 0xd5, 0x7d, 0xd3, 0x7e, 0x9d, 0x94, 0xfb, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x83,
0x4b, 0x74, 0x7c, 0x81, 0x02, 0x00, 0x00,
}
func (m *Params) Marshal() (dAtA []byte, err error) {
@@ -159,6 +163,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i
var l int
_ = l
{
size := m.MinGasMultiplier.Size()
i -= size
if _, err := m.MinGasMultiplier.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintFeemarket(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x42
{
size := m.MinGasPrice.Size()
i -= size
@@ -240,6 +254,8 @@ func (m *Params) Size() (n int) {
n += 1 + l + sovFeemarket(uint64(l))
l = m.MinGasPrice.Size()
n += 1 + l + sovFeemarket(uint64(l))
l = m.MinGasMultiplier.Size()
n += 1 + l + sovFeemarket(uint64(l))
return n
}
@@ -423,6 +439,40 @@ func (m *Params) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 8:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MinGasMultiplier", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowFeemarket
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthFeemarket
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthFeemarket
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.MinGasMultiplier.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipFeemarket(dAtA[iNdEx:])
+1 -1
View File
@@ -27,7 +27,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type GenesisState struct {
// params defines all the paramaters of the module.
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
// block gas is the amount of gas used on the last block before the upgrade.
// block gas is the amount of gas wanted on the last block before the upgrade.
// Zero by default.
BlockGas uint64 `protobuf:"varint,3,opt,name=block_gas,json=blockGas,proto3" json:"block_gas,omitempty"`
}
+15 -2
View File
@@ -10,15 +10,28 @@ const (
// RouterKey uses module name for routing
RouterKey = ModuleName
// TransientKey is the key to access the FeeMarket transient store, that is reset
// during the Commit phase.
TransientKey = "transient_" + ModuleName
)
// prefix bytes for the feemarket persistent store
const (
prefixBlockGasUsed = iota + 1
prefixBlockGasWanted = iota + 1
deprecatedPrefixBaseFee // nolint
)
const (
prefixTransientBlockGasUsed = iota + 1
)
// KVStore key prefixes
var (
KeyPrefixBlockGasUsed = []byte{prefixBlockGasUsed}
KeyPrefixBlockGasWanted = []byte{prefixBlockGasWanted}
)
// Transient Store key prefixes
var (
KeyPrefixTransientBlockGasWanted = []byte{prefixTransientBlockGasUsed}
)
+38 -1
View File
@@ -18,6 +18,14 @@ var (
ParamStoreKeyBaseFee = []byte("BaseFee")
ParamStoreKeyEnableHeight = []byte("EnableHeight")
ParamStoreKeyMinGasPrice = []byte("MinGasPrice")
ParamStoreKeyMinGasMultiplier = []byte("MinGasMultiplier")
)
var (
// DefaultMinGasMultiplier is 0.5 or 50%
DefaultMinGasMultiplier = sdk.NewDecWithPrec(50, 2)
// DefaultMinGasPrice is 0 (i.e disabled)
DefaultMinGasPrice = sdk.ZeroDec()
)
// ParamKeyTable returns the parameter key table.
@@ -33,6 +41,7 @@ func NewParams(
baseFee uint64,
enableHeight int64,
minGasPrice sdk.Dec,
minGasPriceMultiplier sdk.Dec,
) Params {
return Params{
NoBaseFee: noBaseFee,
@@ -41,6 +50,7 @@ func NewParams(
BaseFee: sdk.NewIntFromUint64(baseFee),
EnableHeight: enableHeight,
MinGasPrice: minGasPrice,
MinGasMultiplier: minGasPriceMultiplier,
}
}
@@ -52,7 +62,8 @@ func DefaultParams() Params {
ElasticityMultiplier: params.ElasticityMultiplier,
BaseFee: sdk.NewIntFromUint64(params.InitialBaseFee),
EnableHeight: 0,
MinGasPrice: sdk.ZeroDec(),
MinGasPrice: DefaultMinGasPrice,
MinGasMultiplier: DefaultMinGasMultiplier,
}
}
@@ -65,6 +76,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(ParamStoreKeyBaseFee, &p.BaseFee, validateBaseFee),
paramtypes.NewParamSetPair(ParamStoreKeyEnableHeight, &p.EnableHeight, validateEnableHeight),
paramtypes.NewParamSetPair(ParamStoreKeyMinGasPrice, &p.MinGasPrice, validateMinGasPrice),
paramtypes.NewParamSetPair(ParamStoreKeyMinGasMultiplier, &p.MinGasMultiplier, validateMinGasPrice),
}
}
@@ -82,6 +94,10 @@ func (p Params) Validate() error {
return fmt.Errorf("enable height cannot be negative: %d", p.EnableHeight)
}
if err := validateMinGasMultiplier(p.MinGasMultiplier); err != nil {
return err
}
return validateMinGasPrice(p.MinGasPrice)
}
@@ -161,3 +177,24 @@ func validateMinGasPrice(i interface{}) error {
return nil
}
func validateMinGasMultiplier(i interface{}) error {
v, ok := i.(sdk.Dec)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
if v.IsNil() {
return fmt.Errorf("invalid parameter: nil")
}
if v.IsZero() || v.IsNegative() {
return fmt.Errorf("value cannot be zero or negative: %T", i)
}
if v.GT(sdk.OneDec()) {
return fmt.Errorf("value cannot be greater than 1: %T", i)
}
return nil
}
+17 -3
View File
@@ -30,7 +30,7 @@ func (suite *ParamsTestSuite) TestParamsValidate() {
{"default", DefaultParams(), false},
{
"valid",
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), sdk.NewDecWithPrec(20, 4)),
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), sdk.NewDecWithPrec(20, 4), DefaultMinGasMultiplier),
false,
},
{
@@ -40,12 +40,22 @@ func (suite *ParamsTestSuite) TestParamsValidate() {
},
{
"base fee change denominator is 0 ",
NewParams(true, 0, 3, 2000000000, int64(544435345345435345), sdk.NewDecWithPrec(20, 4)),
NewParams(true, 0, 3, 2000000000, int64(544435345345435345), sdk.NewDecWithPrec(20, 4), DefaultMinGasMultiplier),
true,
},
{
"invalid: min gas price negative",
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), sdk.NewDecFromInt(sdk.NewInt(-1))),
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), sdk.NewDecFromInt(sdk.NewInt(-1)), DefaultMinGasMultiplier),
true,
},
{
"invalid: min gas multiplier zero",
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), DefaultMinGasPrice, sdk.ZeroDec()),
true,
},
{
"invalid: min gas multiplier",
NewParams(true, 7, 3, 2000000000, int64(544435345345435345), sdk.NewDecWithPrec(20, 4), sdk.NewDec(2)),
true,
},
}
@@ -76,6 +86,10 @@ func (suite *ParamsTestSuite) TestParamsValidatePriv() {
suite.Require().Error(validateEnableHeight(""))
suite.Require().Error(validateEnableHeight(int64(-544435345345435345)))
suite.Require().NoError(validateEnableHeight(int64(544435345345435345)))
suite.Require().Error(validateMinGasPrice(sdk.Dec{}))
suite.Require().Error(validateMinGasMultiplier(sdk.NewDec(-5)))
suite.Require().Error(validateMinGasMultiplier(sdk.Dec{}))
suite.Require().Error(validateMinGasMultiplier(""))
}
func (suite *ParamsTestSuite) TestParamsValidateMinGasPrice() {