cmd/geth, eth/gasprice: add configurable threshold to gas price oracle (#22752)

This adds a cmd line parameter `--gpo.ignoreprice`, to make the gas price oracle ignore transactions below the given threshold.
pull/22857/head
Ryan Schneider 4 years ago committed by GitHub
parent 643fd0efc6
commit ca98080798
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      cmd/geth/main.go
  2. 1
      cmd/geth/usage.go
  3. 8
      cmd/utils/flags.go
  4. 14
      eth/ethconfig/config.go
  5. 39
      eth/gasprice/gasprice.go

@ -147,6 +147,7 @@ var (
utils.GpoBlocksFlag, utils.GpoBlocksFlag,
utils.GpoPercentileFlag, utils.GpoPercentileFlag,
utils.GpoMaxGasPriceFlag, utils.GpoMaxGasPriceFlag,
utils.GpoIgnoreGasPriceFlag,
utils.EWASMInterpreterFlag, utils.EWASMInterpreterFlag,
utils.EVMInterpreterFlag, utils.EVMInterpreterFlag,
utils.MinerNotifyFullFlag, utils.MinerNotifyFullFlag,

@ -196,6 +196,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.GpoBlocksFlag, utils.GpoBlocksFlag,
utils.GpoPercentileFlag, utils.GpoPercentileFlag,
utils.GpoMaxGasPriceFlag, utils.GpoMaxGasPriceFlag,
utils.GpoIgnoreGasPriceFlag,
}, },
}, },
{ {

@ -687,6 +687,11 @@ var (
Usage: "Maximum gas price will be recommended by gpo", Usage: "Maximum gas price will be recommended by gpo",
Value: ethconfig.Defaults.GPO.MaxPrice.Int64(), 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(),
}
// Metrics flags // Metrics flags
MetricsEnabledFlag = cli.BoolFlag{ MetricsEnabledFlag = cli.BoolFlag{
@ -1296,6 +1301,9 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) {
if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) { if ctx.GlobalIsSet(GpoMaxGasPriceFlag.Name) {
cfg.MaxPrice = big.NewInt(ctx.GlobalInt64(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) { func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {

@ -41,16 +41,18 @@ import (
// FullNodeGPO contains default gasprice oracle settings for full node. // FullNodeGPO contains default gasprice oracle settings for full node.
var FullNodeGPO = gasprice.Config{ var FullNodeGPO = gasprice.Config{
Blocks: 20, Blocks: 20,
Percentile: 60, Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice, MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
} }
// LightClientGPO contains default gasprice oracle settings for light client. // LightClientGPO contains default gasprice oracle settings for light client.
var LightClientGPO = gasprice.Config{ var LightClientGPO = gasprice.Config{
Blocks: 2, Blocks: 2,
Percentile: 60, Percentile: 60,
MaxPrice: gasprice.DefaultMaxPrice, MaxPrice: gasprice.DefaultMaxPrice,
IgnorePrice: gasprice.DefaultIgnorePrice,
} }
// Defaults contains default settings for use on the Ethereum main net. // Defaults contains default settings for use on the Ethereum main net.

@ -32,12 +32,14 @@ import (
const sampleNumber = 3 // Number of transactions sampled in a block const sampleNumber = 3 // Number of transactions sampled in a block
var DefaultMaxPrice = big.NewInt(500 * params.GWei) var DefaultMaxPrice = big.NewInt(500 * params.GWei)
var DefaultIgnorePrice = big.NewInt(2 * params.Wei)
type Config struct { type Config struct {
Blocks int Blocks int
Percentile int Percentile int
Default *big.Int `toml:",omitempty"` Default *big.Int `toml:",omitempty"`
MaxPrice *big.Int `toml:",omitempty"` MaxPrice *big.Int `toml:",omitempty"`
IgnorePrice *big.Int `toml:",omitempty"`
} }
// OracleBackend includes all necessary background APIs for oracle. // OracleBackend includes all necessary background APIs for oracle.
@ -50,12 +52,13 @@ type OracleBackend interface {
// Oracle recommends gas prices based on the content of recent // Oracle recommends gas prices based on the content of recent
// blocks. Suitable for both light and full clients. // blocks. Suitable for both light and full clients.
type Oracle struct { type Oracle struct {
backend OracleBackend backend OracleBackend
lastHead common.Hash lastHead common.Hash
lastPrice *big.Int lastPrice *big.Int
maxPrice *big.Int maxPrice *big.Int
cacheLock sync.RWMutex ignorePrice *big.Int
fetchLock sync.Mutex cacheLock sync.RWMutex
fetchLock sync.Mutex
checkBlocks int checkBlocks int
percentile int percentile int
@ -83,10 +86,18 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
maxPrice = DefaultMaxPrice maxPrice = DefaultMaxPrice
log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice) 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{ return &Oracle{
backend: backend, backend: backend,
lastPrice: params.Default, lastPrice: params.Default,
maxPrice: maxPrice, maxPrice: maxPrice,
ignorePrice: ignorePrice,
checkBlocks: blocks, checkBlocks: blocks,
percentile: percent, percentile: percent,
} }
@ -123,7 +134,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
txPrices []*big.Int txPrices []*big.Int
) )
for sent < gpo.checkBlocks && number > 0 { 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++ sent++
exp++ exp++
number-- number--
@ -146,7 +157,7 @@ func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
// meaningful returned, try to query more blocks. But the maximum // meaningful returned, try to query more blocks. But the maximum
// is 2*checkBlocks. // is 2*checkBlocks.
if len(res.prices) == 1 && len(txPrices)+1+exp < gpo.checkBlocks*2 && number > 0 { 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++ sent++
exp++ exp++
number-- number--
@ -183,7 +194,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 // 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 // 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. // 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)) block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
if block == nil { if block == nil {
select { select {
@ -199,7 +210,7 @@ func (gpo *Oracle) getBlockPrices(ctx context.Context, signer types.Signer, bloc
var prices []*big.Int var prices []*big.Int
for _, tx := range txs { for _, tx := range txs {
if tx.GasPriceIntCmp(common.Big1) <= 0 { if ignoreUnder != nil && tx.GasPriceIntCmp(ignoreUnder) == -1 {
continue continue
} }
sender, err := types.Sender(signer, tx) sender, err := types.Sender(signer, tx)

Loading…
Cancel
Save