rpc, feemarket: store base fee in event (#673)
* store base fee in event * update changelog
This commit is contained in:
parent
b1b12945c0
commit
cd3b0be5ed
@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* (rpc, evm) [tharsis#673](https://github.com/tharsis/ethermint/pull/673) Use tendermint events to store fee market basefee.
|
||||||
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
* (rpc) [tharsis#624](https://github.com/tharsis/ethermint/pull/624) Implement new JSON-RPC endpoints from latest geth version
|
||||||
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
* (evm) [tharsis#662](https://github.com/tharsis/ethermint/pull/662) Disable basefee for non london blocks
|
||||||
|
|
||||||
|
@ -826,22 +826,24 @@ func (e *EVMBackend) BaseFee(height int64) (*big.Int, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := e.queryClient.FeeMarket.BaseFee(types.ContextWithHeight(height), &feemarkettypes.QueryBaseFeeRequest{})
|
blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.BaseFee != nil {
|
baseFee := types.BaseFeeFromEvents(blockRes.EndBlockEvents)
|
||||||
|
if baseFee != nil {
|
||||||
|
return baseFee, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we cannot find in events, we tried to get it from the state.
|
||||||
|
// It will return feemarket.baseFee if london is activated but feemarket is not enable
|
||||||
|
res, err := e.queryClient.FeeMarket.BaseFee(types.ContextWithHeight(height), &feemarkettypes.QueryBaseFeeRequest{})
|
||||||
|
if err == nil && res.BaseFee != nil {
|
||||||
return res.BaseFee.BigInt(), nil
|
return res.BaseFee.BigInt(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
resParams, err := e.queryClient.FeeMarket.Params(types.ContextWithHeight(height), &feemarkettypes.QueryParamsRequest{})
|
return nil, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
baseFee := big.NewInt(resParams.Params.InitialBaseFee)
|
|
||||||
return baseFee, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFilteredBlocks returns the block height list match the given bloom filters.
|
// GetFilteredBlocks returns the block height list match the given bloom filters.
|
||||||
|
@ -3,7 +3,6 @@ package filters
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -18,7 +17,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/eth/filters"
|
"github.com/ethereum/go-ethereum/eth/filters"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
||||||
@ -239,9 +237,6 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
|
|||||||
return rpc.ID(fmt.Sprintf("error creating block filter: %s", err.Error()))
|
return rpc.ID(fmt.Sprintf("error creating block filter: %s", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use events to get the base fee amount
|
|
||||||
baseFee := big.NewInt(params.InitialBaseFee)
|
|
||||||
|
|
||||||
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
|
api.filters[headerSub.ID()] = &filter{typ: filters.BlocksSubscription, deadline: time.NewTimer(deadline), hashes: []common.Hash{}, s: headerSub}
|
||||||
|
|
||||||
go func(headersCh <-chan coretypes.ResultEvent, errCh <-chan error) {
|
go func(headersCh <-chan coretypes.ResultEvent, errCh <-chan error) {
|
||||||
@ -263,6 +258,8 @@ func (api *PublicFilterAPI) NewBlockFilter() rpc.ID {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseFee := types.BaseFeeFromEvents(data.ResultEndBlock.Events)
|
||||||
|
|
||||||
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||||
api.filtersMu.Lock()
|
api.filtersMu.Lock()
|
||||||
if f, found := api.filters[headerSub.ID()]; found {
|
if f, found := api.filters[headerSub.ID()]; found {
|
||||||
@ -296,9 +293,6 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
|
|||||||
return &rpc.Subscription{}, err
|
return &rpc.Subscription{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use events to get the base fee amount
|
|
||||||
baseFee := big.NewInt(params.InitialBaseFee)
|
|
||||||
|
|
||||||
go func(headersCh <-chan coretypes.ResultEvent) {
|
go func(headersCh <-chan coretypes.ResultEvent) {
|
||||||
defer cancelSubs()
|
defer cancelSubs()
|
||||||
|
|
||||||
@ -316,6 +310,8 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
baseFee := types.BaseFeeFromEvents(data.ResultEndBlock.Events)
|
||||||
|
|
||||||
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
header := types.EthHeaderFromTendermint(data.Header, baseFee)
|
||||||
err = notifier.Notify(rpcSub.ID, header)
|
err = notifier.Notify(rpcSub.ID, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
@ -244,3 +248,24 @@ func NewRPCTransaction(
|
|||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BaseFeeFromEvents parses the feemarket basefee from cosmos events
|
||||||
|
func BaseFeeFromEvents(events []abci.Event) *big.Int {
|
||||||
|
for _, event := range events {
|
||||||
|
if event.Type != feemarkettypes.EventTypeFeeMarket {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, attr := range event.Attributes {
|
||||||
|
if bytes.Equal(attr.Key, []byte(feemarkettypes.AttributeKeyBaseFee)) {
|
||||||
|
result, success := new(big.Int).SetString(string(attr.Value), 10)
|
||||||
|
if success {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
"github.com/tharsis/ethermint/x/feemarket/types"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
@ -13,13 +14,22 @@ import (
|
|||||||
// an empty slice.
|
// an empty slice.
|
||||||
func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) {
|
func (k *Keeper) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) {
|
||||||
baseFee := k.CalculateBaseFee(ctx)
|
baseFee := k.CalculateBaseFee(ctx)
|
||||||
|
|
||||||
|
// return immediately if base fee is nil
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// only set base fee if the NoBaseFee param is false
|
|
||||||
k.SetBaseFee(ctx, baseFee)
|
k.SetBaseFee(ctx, baseFee)
|
||||||
|
|
||||||
|
// Store current base fee in event
|
||||||
|
ctx.EventManager().EmitEvents(sdk.Events{
|
||||||
|
sdk.NewEvent(
|
||||||
|
types.EventTypeFeeMarket,
|
||||||
|
sdk.NewAttribute(types.AttributeKeyBaseFee, baseFee.String()),
|
||||||
|
),
|
||||||
|
})
|
||||||
|
|
||||||
if ctx.BlockGasMeter() == nil {
|
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 used")
|
||||||
return
|
return
|
||||||
|
@ -10,20 +10,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// CalculateBaseFee calculates the base fee for the current block. This is only calculated once per
|
// CalculateBaseFee calculates the base fee for the current block. This is only calculated once per
|
||||||
// block during EndBlock. If the NoBaseFee parameter is enabled, this function returns nil.
|
// block during EndBlock. If the NoBaseFee parameter is enabled or below activation height, this function returns nil.
|
||||||
// NOTE: This code is inspired from the go-ethereum EIP1559 implementation and adapted to Cosmos SDK-based
|
// NOTE: This code is inspired from the go-ethereum EIP1559 implementation and adapted to Cosmos SDK-based
|
||||||
// chains. For the canonical code refer to: https://github.com/ethereum/go-ethereum/blob/master/consensus/misc/eip1559.go
|
// chains. For the canonical code refer to: https://github.com/ethereum/go-ethereum/blob/master/consensus/misc/eip1559.go
|
||||||
func (k Keeper) CalculateBaseFee(ctx sdk.Context) *big.Int {
|
func (k Keeper) CalculateBaseFee(ctx sdk.Context) *big.Int {
|
||||||
params := k.GetParams(ctx)
|
params := k.GetParams(ctx)
|
||||||
|
|
||||||
if params.NoBaseFee {
|
// Ignore the calculation if not enable
|
||||||
|
if !params.IsBaseFeeEnabled(ctx.BlockHeight()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
consParams := ctx.ConsensusParams()
|
consParams := ctx.ConsensusParams()
|
||||||
|
|
||||||
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
|
||||||
if ctx.BlockHeight() <= params.EnableHeight {
|
if ctx.BlockHeight() == params.EnableHeight {
|
||||||
return new(big.Int).SetInt64(params.InitialBaseFee)
|
return new(big.Int).SetInt64(params.InitialBaseFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ func (k Keeper) SetBlockGasUsed(ctx sdk.Context, gas uint64) {
|
|||||||
// Required by EIP1559 base fee calculation.
|
// Required by EIP1559 base fee calculation.
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// GetBlockGasUsed returns the last block gas used value from the store.
|
// GetLastBaseFee returns the last base fee value from the store.
|
||||||
func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
|
func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
bz := store.Get(types.KeyPrefixBaseFee)
|
bz := store.Get(types.KeyPrefixBaseFee)
|
||||||
@ -82,7 +82,7 @@ func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
|
|||||||
return new(big.Int).SetBytes(bz)
|
return new(big.Int).SetBytes(bz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBlockGasUsed gets the current block gas consumed to the store.
|
// SetBaseFee set the last base fee value to the store.
|
||||||
// CONTRACT: this should be only called during EndBlock.
|
// CONTRACT: this should be only called during EndBlock.
|
||||||
func (k Keeper) SetBaseFee(ctx sdk.Context, baseFee *big.Int) {
|
func (k Keeper) SetBaseFee(ctx sdk.Context, baseFee *big.Int) {
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
|
8
x/feemarket/types/events.go
Normal file
8
x/feemarket/types/events.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
// feemarket module events
|
||||||
|
const (
|
||||||
|
EventTypeFeeMarket = "fee_market"
|
||||||
|
|
||||||
|
AttributeKeyBaseFee = "base_fee"
|
||||||
|
)
|
@ -80,6 +80,10 @@ func (p Params) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Params) IsBaseFeeEnabled(height int64) bool {
|
||||||
|
return !p.NoBaseFee && height >= p.EnableHeight
|
||||||
|
}
|
||||||
|
|
||||||
func validateBool(i interface{}) error {
|
func validateBool(i interface{}) error {
|
||||||
_, ok := i.(bool)
|
_, ok := i.(bool)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
Loading…
Reference in New Issue
Block a user