Skip to content

Commit

Permalink
eth/gasprice: add configurable threshold to gas price oracle (ethereu…
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Jun 20, 2024
1 parent 2b365e8 commit f445196
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 20 deletions.
1 change: 1 addition & 0 deletions cmd/XDC/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ var (
//utils.GpoBlocksFlag,
//utils.GpoPercentileFlag,
utils.GpoMaxGasPriceFlag,
utils.GpoIgnoreGasPriceFlag,
//utils.ExtraDataFlag,
configFileFlag,
utils.AnnounceTxsFlag,
Expand Down
1 change: 1 addition & 0 deletions cmd/XDC/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ var AppHelpFlagGroups = []flagGroup{
// utils.GpoBlocksFlag,
// utils.GpoPercentileFlag,
// utils.GpoMaxGasPriceFlag,
// utils.GpoIgnoreGasPriceFlag,
// },
//},
//{
Expand Down
8 changes: 8 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,11 @@ var (
Usage: "Maximum gas price will be recommended by gpo",
Value: ethconfig.Defaults.GPO.MaxPrice.Int64(),
}
GpoIgnoreGasPriceFlag = cli.Int64Flag{
Name: "gpo.ignoreprice",
Usage: "Gas price below which gpo will ignore transactions",
Value: ethconfig.Defaults.GPO.IgnorePrice.Int64(),
}
WhisperEnabledFlag = cli.BoolFlag{
Name: "shh",
Usage: "Enable Whisper",
Expand Down Expand Up @@ -999,6 +1004,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) {
cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(GpoMaxGasPriceFlag.Name))
}
if ctx.GlobalIsSet(GpoIgnoreGasPriceFlag.Name) {
cfg.IgnorePrice = big.NewInt(ctx.GlobalInt64(GpoIgnoreGasPriceFlag.Name))
}
}

func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
Expand Down
14 changes: 8 additions & 6 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,18 @@ import (

// FullNodeGPO contains default gasprice oracle settings for full node.
var FullNodeGPO = gasprice.Config{
Blocks: 20,
Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice,
Blocks: 20,
Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
}

// LightClientGPO contains default gasprice oracle settings for light client.
var LightClientGPO = gasprice.Config{
Blocks: 2,
Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice,
Blocks: 2,
Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
}

// Defaults contains default settings for use on the Ethereum main net.
Expand Down
39 changes: 25 additions & 14 deletions eth/gasprice/gasprice.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ import (
const sampleNumber = 3 // Number of transactions sampled in a block

var DefaultMaxPrice = big.NewInt(500 * params.GWei)
var DefaultIgnorePrice = big.NewInt(2 * params.Wei)

type Config struct {
Blocks int
Percentile int
Default *big.Int `toml:",omitempty"`
MaxPrice *big.Int `toml:",omitempty"`
Blocks int
Percentile int
Default *big.Int `toml:",omitempty"`
MaxPrice *big.Int `toml:",omitempty"`
IgnorePrice *big.Int `toml:",omitempty"`
}

// OracleBackend includes all necessary background APIs for oracle.
Expand All @@ -50,12 +52,13 @@ type OracleBackend interface {
// Oracle recommends gas prices based on the content of recent
// blocks. Suitable for both light and full clients.
type Oracle struct {
backend OracleBackend
lastHead common.Hash
lastPrice *big.Int
maxPrice *big.Int
cacheLock sync.RWMutex
fetchLock sync.Mutex
backend OracleBackend
lastHead common.Hash
lastPrice *big.Int
maxPrice *big.Int
ignorePrice *big.Int
cacheLock sync.RWMutex
fetchLock sync.Mutex

checkBlocks int
percentile int
Expand Down Expand Up @@ -83,10 +86,18 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
maxPrice = DefaultMaxPrice
log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice)
}
ignorePrice := params.IgnorePrice
if ignorePrice == nil || ignorePrice.Int64() <= 0 {
ignorePrice = DefaultIgnorePrice
log.Warn("Sanitizing invalid gasprice oracle ignore price", "provided", params.IgnorePrice, "updated", ignorePrice)
} else if ignorePrice.Int64() > 0 {
log.Info("Gasprice oracle is ignoring threshold set", "threshold", ignorePrice)
}
return &Oracle{
backend: backend,
lastPrice: params.Default,
maxPrice: maxPrice,
ignorePrice: ignorePrice,
checkBlocks: blocks,
percentile: percent,
}
Expand Down Expand Up @@ -122,7 +133,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
txPrices []*big.Int
)
for sent < gpo.checkBlocks && number > 0 {
go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit)
go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, gpo.ignorePrice, result, quit)
sent++
exp++
number--
Expand All @@ -145,7 +156,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
// meaningful returned, try to query more blocks. But the maximum
// is 2*checkBlocks.
if len(res.prices) == 1 && len(txPrices)+1+exp < gpo.checkBlocks*2 && number > 0 {
go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, result, quit)
go gpo.getBlockPrices(ctx, types.MakeSigner(gpo.backend.ChainConfig(), big.NewInt(int64(number))), number, sampleNumber, gpo.ignorePrice, result, quit)
sent++
exp++
number--
Expand Down Expand Up @@ -189,7 +200,7 @@ func (t transactionsByGasPrice) Less(i, j int) bool { return t[i].GasPriceCmp(t[
// and sends it to the result channel. If the block is empty or all transactions
// are sent by the miner itself(it doesn't make any sense to include this kind of
// transaction prices for sampling), nil gasprice is returned.
func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, result chan getBlockPricesResult, quit chan struct{}) {
func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, blockNum uint64, limit int, ignoreUnder *big.Int, result chan getBlockPricesResult, quit chan struct{}) {
block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
if block == nil {
select {
Expand All @@ -205,7 +216,7 @@ func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, bloc

var prices []*big.Int
for _, tx := range txs {
if tx.GasPrice().Cmp(common.Big1) <= 0 {
if ignoreUnder != nil && tx.GasPrice().Cmp(ignoreUnder) == -1 {
continue
}
sender, err := types.Sender(signer, tx)
Expand Down

0 comments on commit f445196

Please sign in to comment.