Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

BaseFee based on GasWanted #1105

Merged
merged 35 commits into from
Jun 5, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
07d345f
add gasWanted transient store keys
crypto-facs Jun 1, 2022
4100800
add gasWanted transient store keeper functions
crypto-facs Jun 1, 2022
a74bd63
add gasWanted transient store tracker
crypto-facs Jun 1, 2022
838e3f8
add comment
crypto-facs Jun 1, 2022
abe329a
remove unncesary comment
crypto-facs Jun 1, 2022
fed33d4
remove unnecesary function
crypto-facs Jun 1, 2022
2263d53
fix tests
crypto-facs Jun 1, 2022
ca2eff2
fix bad comment
crypto-facs Jun 1, 2022
2fb3287
remove unnecesary comment
crypto-facs Jun 1, 2022
85b304a
update comment
crypto-facs Jun 1, 2022
3003e29
update changelog
crypto-facs Jun 1, 2022
0adb53e
Update CHANGELOG.md
crypto-facs Jun 2, 2022
eb09409
add GasWantedDecorator
crypto-facs Jun 2, 2022
b5b8e85
remove unnecesary comments
crypto-facs Jun 2, 2022
440a9fc
gasWanted decorator test
crypto-facs Jun 2, 2022
d0c44d3
fix tests
crypto-facs Jun 2, 2022
7238beb
fix tests and build
crypto-facs Jun 2, 2022
af97be4
fix lint
crypto-facs Jun 2, 2022
b1021d1
updated end block event
crypto-facs Jun 2, 2022
e48bca5
Merge branch 'main' into gas-wanted-feemarket
crypto-facs Jun 3, 2022
2f9ff64
Update app/ante/fee_market.go
crypto-facs Jun 3, 2022
a71d7d6
fix undeclared variable
crypto-facs Jun 3, 2022
6b7190e
Update app/ante/fee_market_test.go
fedekunze Jun 3, 2022
44eea13
remove unnecesary line
crypto-facs Jun 3, 2022
0600a66
migrate MinGasMultiplier to FeeMarket module
crypto-facs Jun 3, 2022
0b129bb
set limited gas wanted
crypto-facs Jun 3, 2022
f900de9
remove old newKeeper param
crypto-facs Jun 3, 2022
85f41e2
update proto comment
crypto-facs Jun 3, 2022
0e54db8
fix test
crypto-facs Jun 3, 2022
51a8b40
update comments
crypto-facs Jun 3, 2022
8264bbf
Update x/feemarket/keeper/abci.go
crypto-facs Jun 4, 2022
eb82517
address comments from review
fedekunze Jun 5, 2022
63efb44
tidy
fedekunze Jun 5, 2022
9814c7c
tests
fedekunze Jun 5, 2022
240ac4c
Merge branch 'main' into gas-wanted-feemarket
fedekunze Jun 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### State Machine Breaking
- (feemarket) [tharsis#1105](https://github.com/tharsis/ethermint/pull/1105) BaseFee calculation based on GasWanted instead of GasUsed.
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved

### API Breaking

- (feemarket) [tharsis#1104](https://github.com/tharsis/ethermint/pull/1104) Enforce a minimum gas price for Cosmos and EVM transactions through the `MinGasPrice` parameter.
Expand Down
15 changes: 14 additions & 1 deletion app/ante/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,19 @@ func (avd EthAccountVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx
// gas consumption.
type EthGasConsumeDecorator struct {
evmKeeper EVMKeeper
feeMaker FeeMarketKeeper
maxGasWanted uint64
}

// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
func NewEthGasConsumeDecorator(
evmKeeper EVMKeeper,
feeMarket FeeMarketKeeper,
maxGasWanted uint64,
) EthGasConsumeDecorator {
return EthGasConsumeDecorator{
evmKeeper,
feeMarket,
maxGasWanted,
}
}
Expand Down Expand Up @@ -232,6 +235,14 @@ func (egcd EthGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
ctx = ctx.WithGasMeter(ethermint.NewInfiniteGasMeterWithLimit(gasWanted))
ctx.GasMeter().ConsumeGas(gasConsumed, "copy gas consumed")

// Add total gasWanted to cumulative in block transientStore for BaseFee calculation
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
if london {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
_, err = egcd.feeMaker.AddTransientGasWanted(ctx, gasWanted)
if err != nil {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
return ctx, sdkerrors.Wrapf(err, "failed to add gas wanted to transient store")
}
}

// we know that we have enough gas on the pool to cover the intrinsic gas
return next(ctx, tx, simulate)
}
Expand Down Expand Up @@ -473,11 +484,13 @@ func (vbd EthValidateBasicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simu
// by setting the gas meter to infinite
type EthSetupContextDecorator struct {
evmKeeper EVMKeeper
feeMarket FeeMarketKeeper
}

func NewEthSetUpContextDecorator(evmKeeper EVMKeeper) EthSetupContextDecorator {
func NewEthSetUpContextDecorator(evmKeeper EVMKeeper, feeMarket FeeMarketKeeper) EthSetupContextDecorator {
return EthSetupContextDecorator{
evmKeeper: evmKeeper,
feeMarket: feeMarket,
}
}

Expand Down
8 changes: 4 additions & 4 deletions app/ante/handler_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ func (options HandlerOptions) Validate() error {

func newEthAnteHandler(options HandlerOptions) sdk.AnteHandler {
return sdk.ChainAnteDecorators(
NewEthSetUpContextDecorator(options.EvmKeeper), // outermost AnteDecorator. SetUpContext must be called first
NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
NewEthMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), // Check eth effective gas price against the global MinGasPrice
NewEthSetUpContextDecorator(options.EvmKeeper, options.FeeMarketKeeper), // outermost AnteDecorator. SetUpContext must be called first
NewEthMempoolFeeDecorator(options.EvmKeeper), // Check eth effective gas price against minimal-gas-prices
NewEthMinGasPriceDecorator(options.FeeMarketKeeper, options.EvmKeeper), // Check eth effective gas price against the global MinGasPrice
NewEthValidateBasicDecorator(options.EvmKeeper),
NewEthSigVerificationDecorator(options.EvmKeeper),
NewEthAccountVerificationDecorator(options.AccountKeeper, options.EvmKeeper),
NewEthGasConsumeDecorator(options.EvmKeeper, options.MaxTxGasWanted),
NewEthGasConsumeDecorator(options.EvmKeeper, options.FeeMarketKeeper, options.MaxTxGasWanted),
NewCanTransferDecorator(options.EvmKeeper),
NewEthIncrementSenderSequenceDecorator(options.AccountKeeper), // innermost AnteDecorator.
NewEthEmitEventDecorator(options.EvmKeeper), // emit eth tx hash and index at the very last ante handler.
Expand Down
1 change: 1 addition & 0 deletions app/ante/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ type protoTxProvider interface {
// FeeMarketKeeper defines the expected keeper interface used on the AnteHandler
type FeeMarketKeeper interface {
GetParams(ctx sdk.Context) (params feemarkettypes.Params)
AddTransientGasWanted(ctx sdk.Context, gasWanted uint64) (uint64, error)
}
4 changes: 2 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func NewEthermintApp(
)

// Add the EVM transient store key
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)

app := &EthermintApp{
Expand Down Expand Up @@ -344,7 +344,7 @@ func NewEthermintApp(

// Create Ethermint keepers
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
appCodec, keys[feemarkettypes.StoreKey], app.GetSubspace(feemarkettypes.ModuleName),
appCodec, app.GetSubspace(feemarkettypes.ModuleName), keys[feemarkettypes.StoreKey], tkeys[feemarkettypes.TransientKey],
)

app.EvmKeeper = evmkeeper.NewKeeper(
Expand Down
2 changes: 1 addition & 1 deletion x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func (k *Keeper) GetBalance(ctx sdk.Context, addr common.Address) *big.Int {
return coin.Amount.BigInt()
}

// BaseFee returns current base fee, return values:
// GetBaseFee returns current base fee, return values:
// - `nil`: london hardfork not enabled.
// - `0`: london hardfork enabled but feemarket is not enabled.
// - `n`: both london hardfork and feemarket are enabled.
Expand Down
1 change: 1 addition & 0 deletions x/evm/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type StakingKeeper interface {
type FeeMarketKeeper interface {
GetBaseFee(ctx sdk.Context) *big.Int
GetParams(ctx sdk.Context) feemarkettypes.Params
AddTransientGasWanted(ctx sdk.Context, gasWanted uint64) (uint64, error)
}

// Event Hooks
Expand Down
4 changes: 2 additions & 2 deletions x/feemarket/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}
}
Expand All @@ -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),
}
}
6 changes: 3 additions & 3 deletions x/feemarket/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ 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) {
Expand All @@ -38,9 +38,9 @@ func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) {
return
}

gasUsed := ctx.BlockGasMeter().GasConsumedToLimit()
gasWanted := k.GetTransientGasWanted(ctx)

k.SetBlockGasUsed(ctx, gasUsed)
k.SetBlockGasWanted(ctx, gasWanted)

ctx.EventManager().EmitEvent(sdk.NewEvent(
"block_gas",
Expand Down
2 changes: 1 addition & 1 deletion x/feemarket/keeper/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (suite *KeeperTestSuite) TestEndBlock() {

req := abci.RequestEndBlock{Height: 1}
suite.app.FeeMarketKeeper.EndBlock(suite.ctx, req)
gasUsed := suite.app.FeeMarketKeeper.GetBlockGasUsed(suite.ctx)
gasUsed := suite.app.FeeMarketKeeper.GetBlockGasWanted(suite.ctx)
suite.Require().Equal(tc.expGasUsed, gasUsed, tc.name)
})
}
Expand Down
2 changes: 1 addition & 1 deletion x/feemarket/keeper/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (k Keeper) CalculateBaseFee(ctx sdk.Context) *big.Int {
return nil
}

parentGasUsed := k.GetBlockGasUsed(ctx)
parentGasUsed := k.GetBlockGasWanted(ctx)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved

gasLimit := new(big.Int).SetUint64(math.MaxUint64)

Expand Down
6 changes: 3 additions & 3 deletions x/feemarket/keeper/eip1559_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
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{
Expand All @@ -58,7 +58,7 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
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,
Expand All @@ -79,7 +79,7 @@ func (suite *KeeperTestSuite) TestCalculateBaseFee() {
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,
Expand Down
2 changes: 1 addition & 1 deletion x/feemarket/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion x/feemarket/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{})
Expand Down
54 changes: 40 additions & 14 deletions x/feemarket/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,26 @@ 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() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}

return Keeper{
cdc: cdc,
storeKey: storeKey,
paramSpace: paramSpace,
cdc: cdc,
storeKey: storeKey,
paramSpace: paramSpace,
transientKey: transientKey,
}
}

Expand All @@ -45,21 +47,45 @@ 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)
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.KeyPrefixBlockGasUsed)
bz := store.Get(types.KeyPrefixBlockGasWanted)
if len(bz) == 0 {
return 0
}

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
}
6 changes: 3 additions & 3 deletions x/feemarket/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -175,15 +175,15 @@ 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),
},
}
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)
}
}
Expand Down
17 changes: 15 additions & 2 deletions x/feemarket/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,28 @@ const (

// RouterKey uses module name for routing
RouterKey = ModuleName

// TransientKey is the key to access the EVM 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}
)