Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(GPO): make default gas tip configurable #1096

Merged
merged 12 commits into from
Dec 10, 2024
7 changes: 7 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,10 @@ var (
Usage: "Number of pending transactions to consider the network congested and suggest a minimum tip cap",
Value: ethconfig.Defaults.GPO.CongestedThreshold,
}
GpoDefaultGasTipCapFlag = cli.Int64Flag{
Name: "gpo.defaultgastipcap",
Usage: "Default minimum gas tip cap (in wei) to be used after Curie fork (EIP-1559) (default: 100)",
}

// Metrics flags
MetricsEnabledFlag = cli.BoolFlag{
Expand Down Expand Up @@ -1450,6 +1454,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
if ctx.GlobalIsSet(GpoCongestionThresholdFlag.Name) {
cfg.CongestedThreshold = ctx.GlobalInt(GpoCongestionThresholdFlag.Name)
}
if ctx.GlobalIsSet(GpoDefaultGasTipCapFlag.Name) {
cfg.DefaultGasTipCap = big.NewInt(ctx.GlobalInt64(GpoDefaultGasTipCapFlag.Name))
}
colinlyguo marked this conversation as resolved.
Show resolved Hide resolved
}

func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
Expand Down
22 changes: 16 additions & 6 deletions eth/gasprice/gasprice.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ var (
DefaultMaxPrice = big.NewInt(500 * params.GWei)
DefaultIgnorePrice = big.NewInt(1 * params.Wei)
DefaultBasePrice = big.NewInt(0)
// DefaultGasTipCap is set to 100 wei instead of 1 wei for the following reasons:
// 1. Very low tip values (e.g. 1 wei) can cause issues because transaction pools often reject replacing transactions
// with the same gas tip cap. This becomes problematic when low tips like 1 wei fail to increase due to rounding
// in some SDK implementations (e.g. 1 wei * 1.5 = 1 wei).
// 2. The cost of a gas tip cap of 100 wei is negligible compared to the base fee in most cases.
DefaultGasTipCap = big.NewInt(100) // Default minimum gas tip cap in wei (used after Curie/EIP-1559).
)

type Config struct {
Expand All @@ -52,6 +58,7 @@ type Config struct {
IgnorePrice *big.Int `toml:",omitempty"`
CongestedThreshold int // Number of pending transactions to consider the network congested and suggest a minimum tip cap.
DefaultBasePrice *big.Int `toml:",omitempty"` // Base price to set when CongestedThreshold is reached before Curie (EIP 1559).
DefaultGasTipCap *big.Int `toml:",omitempty"` // Default minimum gas tip cap to use after Curie (EIP 1559).
}

// OracleBackend includes all necessary background APIs for oracle.
Expand Down Expand Up @@ -82,6 +89,7 @@ type Oracle struct {
maxHeaderHistory, maxBlockHistory int
congestedThreshold int // Number of pending transactions to consider the network congested and suggest a minimum tip cap.
defaultBasePrice *big.Int // Base price to set when CongestedThreshold is reached before Curie (EIP 1559).
defaultGasTipCap *big.Int // Default gas tip cap to suggest after Curie (EIP 1559) when the network is not congested.
historyCache *lru.Cache
}

Expand Down Expand Up @@ -133,6 +141,11 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
defaultBasePrice = DefaultBasePrice
log.Warn("Sanitizing invalid gasprice oracle default base price", "provided", params.DefaultBasePrice, "updated", defaultBasePrice)
}
defaultGasTipCap := params.DefaultGasTipCap
if defaultGasTipCap == nil || defaultGasTipCap.Int64() <= 0 {
defaultGasTipCap = DefaultGasTipCap
log.Warn("Sanitizing invalid gasprice oracle default gas tip cap", "provided", params.DefaultGasTipCap, "updated", DefaultGasTipCap)
}

cache, _ := lru.New(2048)
headEvent := make(chan core.ChainHeadEvent, 1)
Expand All @@ -158,6 +171,7 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
maxBlockHistory: maxBlockHistory,
congestedThreshold: congestedThreshold,
defaultBasePrice: defaultBasePrice,
defaultGasTipCap: defaultGasTipCap,
historyCache: cache,
}
}
Expand Down Expand Up @@ -195,13 +209,9 @@ func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
// high-priced txs are causing the suggested tip cap to be high.
pendingTxCount, _ := oracle.backend.StatsWithMinBaseFee(head.BaseFee)
if pendingTxCount < oracle.congestedThreshold {
// Before Curie (EIP-1559), we need to return the total suggested gas price. After Curie we return 2 wei as the tip cap,
// Before Curie (EIP-1559), we need to return the total suggested gas price. After Curie we return defaultGasTipCap wei as the tip cap,
// as the base fee is set separately or added manually for legacy transactions.
// 1. Set price to at least 1 as otherwise tx with a 0 tip might be filtered out by the default mempool config.
// 2. Since oracle.ignoreprice was set to 2 (DefaultIgnorePrice) before by default, we need to set the price
// to 2 to avoid filtering in oracle.getBlockValues() by nodes that did not yet update to this version.
// In the future we can set the price to 1 wei.
price := big.NewInt(2)
price := oracle.defaultGasTipCap
if !oracle.backend.ChainConfig().IsCurie(head.Number) {
price = oracle.defaultBasePrice
}
Expand Down
2 changes: 1 addition & 1 deletion eth/gasprice/gasprice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func TestSuggestTipCap(t *testing.T) {

func TestSuggestTipCapCongestedThreshold(t *testing.T) {
expectedDefaultBasePricePreCurie := big.NewInt(2000)
expectedDefaultBasePricePostCurie := big.NewInt(1)
expectedDefaultBasePricePostCurie := big.NewInt(100)

config := Config{
Blocks: 3,
Expand Down
2 changes: 1 addition & 1 deletion params/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
const (
VersionMajor = 5 // Major version component of the current release
VersionMinor = 7 // Minor version component of the current release
VersionPatch = 28 // Patch version component of the current release
VersionPatch = 29 // Patch version component of the current release
VersionMeta = "mainnet" // Version metadata to append to the version string
)

Expand Down
Loading