Skip to content

Commit

Permalink
Update gas price checks in transaction pool to use base fees
Browse files Browse the repository at this point in the history
  • Loading branch information
HerbertJordan committed Nov 15, 2024
1 parent bbfd2b9 commit 5680656
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 63 deletions.
11 changes: 5 additions & 6 deletions ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
cc "github.com/Fantom-foundation/Carmen/go/common"
"github.com/Fantom-foundation/Carmen/go/common/immutable"
"github.com/Fantom-foundation/go-opera/gossip/evmstore"
"github.com/Fantom-foundation/go-opera/gossip/gasprice/gaspricelimits"
bip39 "github.com/tyler-smith/go-bip39"

"github.com/Fantom-foundation/go-opera/evmcore"
Expand Down Expand Up @@ -82,14 +83,12 @@ func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI {

// GasPrice returns a suggestion for a gas price for legacy transactions.
func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) {
// TODO: look into tip suggestion
// Right now, we are not suggesting any tips since those have no real
// effect on the Sonic network. So the suggested gas price is a slightly
// increased base fee to provide a buffer for short-term price fluctuations.
price := s.b.CurrentBlock().Header().BaseFee
price = gaspricelimits.GetSuggestedGasPriceForNewTransactions(price)
return (*hexutil.Big)(price), nil
/*
tipcap := s.b.SuggestGasTipCap(ctx, gasprice.AsDefaultCertainty)
tipcap.Add(tipcap, s.b.MinGasPrice())
return (*hexutil.Big)(tipcap), nil
*/
}

// MaxPriorityFeePerGas returns a suggestion for a gas tip cap for dynamic fee transactions.
Expand Down
4 changes: 2 additions & 2 deletions eventcheck/epochcheck/epoch_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/Fantom-foundation/lachesis-base/inter/idx"
"github.com/ethereum/go-ethereum/core/types"

"github.com/Fantom-foundation/go-opera/gossip/gasprice"
"github.com/Fantom-foundation/go-opera/gossip/gasprice/gaspricelimits"
"github.com/Fantom-foundation/go-opera/inter"
"github.com/Fantom-foundation/go-opera/opera"
)
Expand Down Expand Up @@ -98,7 +98,7 @@ func CheckTxs(
if rules.Upgrades.Sonic {
maxType = 3
}
limit := gasprice.GetMinimumFeeCapForEventEmitter(baseFee)
limit := gaspricelimits.GetMinimumFeeCapForEventEmitter(baseFee)
for _, tx := range txs {
if tx.Type() > maxType {
return ErrUnsupportedTxType
Expand Down
17 changes: 12 additions & 5 deletions evmcore/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"

"github.com/Fantom-foundation/go-opera/gossip/gasprice/gaspricelimits"
"github.com/Fantom-foundation/go-opera/utils"
"github.com/Fantom-foundation/go-opera/utils/signers/gsignercache"
"github.com/Fantom-foundation/go-opera/utils/txtime"
Expand Down Expand Up @@ -156,8 +157,7 @@ type StateReader interface {
CurrentBlock() *EvmBlock
GetBlock(hash common.Hash, number uint64) *EvmBlock
GetTxPoolStateDB() (TxPoolStateDB, error)
MinGasPrice() *big.Int
EffectiveMinTip() *big.Int
GetCurrentBaseFee() *big.Int
MaxGasLimit() uint64
SubscribeNewBlock(ch chan<- ChainHeadNotify) notify.Subscription
Config() *params.ChainConfig
Expand Down Expand Up @@ -705,8 +705,15 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
log.Trace("Rejecting underpriced tx: pool.gasPrice", "pool.gasPrice", pool.gasPrice, "tx.GasTipCap", tx.GasTipCap())
return ErrUnderpriced
}
// Ensure Opera-specific hard bounds
if baseFee := pool.chain.GetCurrentBaseFee(); baseFee != nil {
limit := gaspricelimits.GetMinimumFeeCapForTransactionPool(baseFee)
if tx.GasFeeCapIntCmp(limit) < 0 {
log.Trace("Rejecting underpriced tx: minimumBaseFee", "minimumBaseFee", baseFee, "limit", limit, "tx.GasFeeCap", tx.GasFeeCap())
return ErrUnderpriced
}
}
/*
// Ensure Opera-specific hard bounds
if recommendedGasTip, minPrice := pool.chain.EffectiveMinTip(), pool.chain.MinGasPrice(); recommendedGasTip != nil && minPrice != nil {
if tx.GasTipCapIntCmp(recommendedGasTip) < 0 {
log.Trace("Rejecting underpriced tx: recommendedGasTip", "recommendedGasTip", recommendedGasTip, "tx.GasTipCap", tx.GasTipCap())
Expand Down Expand Up @@ -1285,9 +1292,9 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
// because of another transaction (e.g. higher gas price).
if reset != nil {
pool.demoteUnexecutables()
if pool.chain.MinGasPrice() != nil {
if baseFee := pool.chain.GetCurrentBaseFee(); baseFee != nil {
// Opera-specific base fee
pool.priced.SetBaseFee(pool.chain.MinGasPrice())
pool.priced.SetBaseFee(baseFee)
} else {
// for tests only
if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
Expand Down
5 changes: 1 addition & 4 deletions evmcore/tx_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ func (bc *testBlockChain) CurrentBlock() *EvmBlock {
}
}

func (bc *testBlockChain) MinGasPrice() *big.Int {
return common.Big0
}
func (bc *testBlockChain) EffectiveMinTip() *big.Int {
func (bc *testBlockChain) GetCurrentBaseFee() *big.Int {
return nil
}
func (bc *testBlockChain) MaxGasLimit() uint64 {
Expand Down
4 changes: 3 additions & 1 deletion gossip/ethapi_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/Fantom-foundation/go-opera/ethapi"
"github.com/Fantom-foundation/go-opera/evmcore"
"github.com/Fantom-foundation/go-opera/gossip/evmstore"
"github.com/Fantom-foundation/go-opera/gossip/gasprice/gaspricelimits"
"github.com/Fantom-foundation/go-opera/inter"
"github.com/Fantom-foundation/go-opera/inter/iblockproc"
"github.com/Fantom-foundation/go-opera/inter/state"
Expand Down Expand Up @@ -481,7 +482,8 @@ func (b *EthAPIBackend) CurrentEpoch(ctx context.Context) idx.Epoch {
}

func (b *EthAPIBackend) MinGasPrice() *big.Int {
return b.state.MinGasPrice()
current := b.state.GetCurrentBaseFee()
return gaspricelimits.GetSuggestedGasPriceForNewTransactions(current)
}
func (b *EthAPIBackend) MaxGasLimit() uint64 {
return b.state.MaxGasLimit()
Expand Down
18 changes: 4 additions & 14 deletions gossip/evm_state_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,10 @@ type EvmStateReader struct {
gpo *gasprice.Oracle
}

// MinGasPrice returns current hard lower bound for gas price
func (r *EvmStateReader) MinGasPrice() *big.Int {
return r.store.GetRules().Economy.MinGasPrice
}

// EffectiveMinTip returns current soft lower bound for gas tip
func (r *EvmStateReader) EffectiveMinTip() *big.Int {
min := r.MinGasPrice()
est := r.gpo.EffectiveMinGasPrice()
est.Sub(est, min)
if est.Sign() < 0 {
return new(big.Int)
}
return est
// GetCurrentBaseFee returns the base fee charged in the most recent block.
func (r *EvmStateReader) GetCurrentBaseFee() *big.Int {
res := r.store.GetBlock(r.store.GetLatestBlockIndex()).BaseFee
return new(big.Int).Set(res)
}

func (r *EvmStateReader) MaxGasLimit() uint64 {
Expand Down
31 changes: 0 additions & 31 deletions gossip/gasprice/base_fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,37 +97,6 @@ func getBaseFeeForNextBlock(parent *evmcore.EvmHeader, rules opera.EconomyRules)
return newPrice
}

// GetSuggestedGasPriceForNewTransactions a gas price that should be suggested
// to users for new transactions based on the current base fee. This function
// returns a value that is 10% higher than the base fee to provide a buffer
// for the price to increase before the transaction is included in a block.
func GetSuggestedGasPriceForNewTransactions(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 10)
}

// GetMinimumFeeCapForTransactionPool returns the gas price the transaction pool
// should check for when accepting new transactions. This function returns a
// value that is 5% higher than the base fee to provide a buffer for the price
// to increase before the transaction is included in a block.
func GetMinimumFeeCapForTransactionPool(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 5)
}

// GetMinimumFeeCapForEventEmitter returns the gas price the event emitter should
// check for when including transactions in a block. This function returns a
// value that is 2% higher than the base fee to provide a buffer for the price
// to increase before the transaction is included in a block.
func GetMinimumFeeCapForEventEmitter(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 2)
}

func addPercentage(a *big.Int, percentage int) *big.Int {
if a == nil {
return big.NewInt(0)
}
return div(mul(a, big.NewInt(int64(percentage+100))), big.NewInt(100))
}

// approximateExponential approximates f * e ** (n/d) using
// Taylor expansion at n=0.
//
Expand Down
37 changes: 37 additions & 0 deletions gossip/gasprice/gaspricelimits/gas_price_limits.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package gaspricelimits

import "math/big"

// GetSuggestedGasPriceForNewTransactions a gas price that should be suggested
// to users for new transactions based on the current base fee. This function
// returns a value that is 10% higher than the base fee to provide a buffer
// for the price to increase before the transaction is included in a block.
func GetSuggestedGasPriceForNewTransactions(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 10)
}

// GetMinimumFeeCapForTransactionPool returns the gas price the transaction pool
// should check for when accepting new transactions. This function returns a
// value that is 5% higher than the base fee to provide a buffer for the price
// to increase before the transaction is included in a block.
func GetMinimumFeeCapForTransactionPool(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 5)
}

// GetMinimumFeeCapForEventEmitter returns the gas price the event emitter should
// check for when including transactions in a block. This function returns a
// value that is 2% higher than the base fee to provide a buffer for the price
// to increase before the transaction is included in a block.
func GetMinimumFeeCapForEventEmitter(baseFee *big.Int) *big.Int {
return addPercentage(baseFee, 2)
}

func addPercentage(a *big.Int, percentage int) *big.Int {
if a == nil {
return big.NewInt(0)
}
res := new(big.Int).Set(a)
res.Mul(res, big.NewInt(int64(percentage+100)))
res.Div(res, big.NewInt(100))
return res
}

0 comments on commit 5680656

Please sign in to comment.