cmd, les, eth, eth/gasprice: using new gas price oracle (#13853)
* cmd, les, eth, eth/gasprice: using new gas price oracle * eth/gasprice: renamed source file * eth/gasprice: added security checks for gpo params * eth/gasprice: fixed naming issues * eth/gasprice: max limit, maxEmpty
This commit is contained in:
		
				
					committed by
					
						
						Péter Szilágyi
					
				
			
			
				
	
			
			
			
						parent
						
							0ec1104ba9
						
					
				
				
					commit
					9aca9e6deb
				
			@@ -147,12 +147,8 @@ func init() {
 | 
				
			|||||||
		utils.FakePoWFlag,
 | 
							utils.FakePoWFlag,
 | 
				
			||||||
		utils.NoCompactionFlag,
 | 
							utils.NoCompactionFlag,
 | 
				
			||||||
		utils.SolcPathFlag,
 | 
							utils.SolcPathFlag,
 | 
				
			||||||
		utils.GpoMinGasPriceFlag,
 | 
							utils.GpoBlocksFlag,
 | 
				
			||||||
		utils.GpoMaxGasPriceFlag,
 | 
							utils.GpoPercentileFlag,
 | 
				
			||||||
		utils.GpoFullBlockRatioFlag,
 | 
					 | 
				
			||||||
		utils.GpobaseStepDownFlag,
 | 
					 | 
				
			||||||
		utils.GpobaseStepUpFlag,
 | 
					 | 
				
			||||||
		utils.GpobaseCorrectionFactorFlag,
 | 
					 | 
				
			||||||
		utils.ExtraDataFlag,
 | 
							utils.ExtraDataFlag,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	app.Flags = append(app.Flags, debug.Flags...)
 | 
						app.Flags = append(app.Flags, debug.Flags...)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,12 +151,8 @@ var AppHelpFlagGroups = []flagGroup{
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		Name: "GAS PRICE ORACLE",
 | 
							Name: "GAS PRICE ORACLE",
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			utils.GpoMinGasPriceFlag,
 | 
								utils.GpoBlocksFlag,
 | 
				
			||||||
			utils.GpoMaxGasPriceFlag,
 | 
								utils.GpoPercentileFlag,
 | 
				
			||||||
			utils.GpoFullBlockRatioFlag,
 | 
					 | 
				
			||||||
			utils.GpobaseStepDownFlag,
 | 
					 | 
				
			||||||
			utils.GpobaseStepUpFlag,
 | 
					 | 
				
			||||||
			utils.GpobaseCorrectionFactorFlag,
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -409,35 +409,15 @@ var (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Gas price oracle settings
 | 
						// Gas price oracle settings
 | 
				
			||||||
	GpoMinGasPriceFlag = BigFlag{
 | 
						GpoBlocksFlag = cli.IntFlag{
 | 
				
			||||||
		Name:  "gpomin",
 | 
							Name:  "gpoblocks",
 | 
				
			||||||
		Usage: "Minimum suggested gas price",
 | 
							Usage: "Number of recent blocks to check for gas prices",
 | 
				
			||||||
		Value: big.NewInt(20 * params.Shannon),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	GpoMaxGasPriceFlag = BigFlag{
 | 
					 | 
				
			||||||
		Name:  "gpomax",
 | 
					 | 
				
			||||||
		Usage: "Maximum suggested gas price",
 | 
					 | 
				
			||||||
		Value: big.NewInt(500 * params.Shannon),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	GpoFullBlockRatioFlag = cli.IntFlag{
 | 
					 | 
				
			||||||
		Name:  "gpofull",
 | 
					 | 
				
			||||||
		Usage: "Full block threshold for gas price calculation (%)",
 | 
					 | 
				
			||||||
		Value: 80,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	GpobaseStepDownFlag = cli.IntFlag{
 | 
					 | 
				
			||||||
		Name:  "gpobasedown",
 | 
					 | 
				
			||||||
		Usage: "Suggested gas price base step down ratio (1/1000)",
 | 
					 | 
				
			||||||
		Value: 10,
 | 
							Value: 10,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	GpobaseStepUpFlag = cli.IntFlag{
 | 
						GpoPercentileFlag = cli.IntFlag{
 | 
				
			||||||
		Name:  "gpobaseup",
 | 
							Name:  "gpopercentile",
 | 
				
			||||||
		Usage: "Suggested gas price base step up ratio (1/1000)",
 | 
							Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
 | 
				
			||||||
		Value: 100,
 | 
							Value: 50,
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	GpobaseCorrectionFactorFlag = cli.IntFlag{
 | 
					 | 
				
			||||||
		Name:  "gpobasecf",
 | 
					 | 
				
			||||||
		Usage: "Suggested gas price base correction factor (%)",
 | 
					 | 
				
			||||||
		Value: 110,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -798,12 +778,8 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
 | 
				
			|||||||
		ExtraData:               MakeMinerExtra(extra, ctx),
 | 
							ExtraData:               MakeMinerExtra(extra, ctx),
 | 
				
			||||||
		DocRoot:                 ctx.GlobalString(DocRootFlag.Name),
 | 
							DocRoot:                 ctx.GlobalString(DocRootFlag.Name),
 | 
				
			||||||
		GasPrice:                GlobalBig(ctx, GasPriceFlag.Name),
 | 
							GasPrice:                GlobalBig(ctx, GasPriceFlag.Name),
 | 
				
			||||||
		GpoMinGasPrice:          GlobalBig(ctx, GpoMinGasPriceFlag.Name),
 | 
							GpoBlocks:               ctx.GlobalInt(GpoBlocksFlag.Name),
 | 
				
			||||||
		GpoMaxGasPrice:          GlobalBig(ctx, GpoMaxGasPriceFlag.Name),
 | 
							GpoPercentile:           ctx.GlobalInt(GpoPercentileFlag.Name),
 | 
				
			||||||
		GpoFullBlockRatio:       ctx.GlobalInt(GpoFullBlockRatioFlag.Name),
 | 
					 | 
				
			||||||
		GpobaseStepDown:         ctx.GlobalInt(GpobaseStepDownFlag.Name),
 | 
					 | 
				
			||||||
		GpobaseStepUp:           ctx.GlobalInt(GpobaseStepUpFlag.Name),
 | 
					 | 
				
			||||||
		GpobaseCorrectionFactor: ctx.GlobalInt(GpobaseCorrectionFactorFlag.Name),
 | 
					 | 
				
			||||||
		SolcPath:                ctx.GlobalString(SolcPathFlag.Name),
 | 
							SolcPath:                ctx.GlobalString(SolcPathFlag.Name),
 | 
				
			||||||
		EthashCacheDir:          MakeEthashCacheDir(ctx),
 | 
							EthashCacheDir:          MakeEthashCacheDir(ctx),
 | 
				
			||||||
		EthashCachesInMem:       ctx.GlobalInt(EthashCachesInMemoryFlag.Name),
 | 
							EthashCachesInMem:       ctx.GlobalInt(EthashCachesInMemoryFlag.Name),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ import (
 | 
				
			|||||||
// EthApiBackend implements ethapi.Backend for full nodes
 | 
					// EthApiBackend implements ethapi.Backend for full nodes
 | 
				
			||||||
type EthApiBackend struct {
 | 
					type EthApiBackend struct {
 | 
				
			||||||
	eth *Ethereum
 | 
						eth *Ethereum
 | 
				
			||||||
	gpo *gasprice.GasPriceOracle
 | 
						gpo *gasprice.Oracle
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *EthApiBackend) ChainConfig() *params.ChainConfig {
 | 
					func (b *EthApiBackend) ChainConfig() *params.ChainConfig {
 | 
				
			||||||
@@ -186,7 +186,7 @@ func (b *EthApiBackend) ProtocolVersion() int {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *EthApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
 | 
					func (b *EthApiBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
 | 
				
			||||||
	return b.gpo.SuggestPrice(), nil
 | 
						return b.gpo.SuggestPrice(ctx)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *EthApiBackend) ChainDb() ethdb.Database {
 | 
					func (b *EthApiBackend) ChainDb() ethdb.Database {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,12 +84,8 @@ type Config struct {
 | 
				
			|||||||
	MinerThreads int
 | 
						MinerThreads int
 | 
				
			||||||
	SolcPath     string
 | 
						SolcPath     string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GpoMinGasPrice          *big.Int
 | 
						GpoBlocks     int
 | 
				
			||||||
	GpoMaxGasPrice          *big.Int
 | 
						GpoPercentile int
 | 
				
			||||||
	GpoFullBlockRatio       int
 | 
					 | 
				
			||||||
	GpobaseStepDown         int
 | 
					 | 
				
			||||||
	GpobaseStepUp           int
 | 
					 | 
				
			||||||
	GpobaseCorrectionFactor int
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EnablePreimageRecording bool
 | 
						EnablePreimageRecording bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -211,16 +207,13 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
 | 
				
			|||||||
	eth.miner.SetGasPrice(config.GasPrice)
 | 
						eth.miner.SetGasPrice(config.GasPrice)
 | 
				
			||||||
	eth.miner.SetExtra(config.ExtraData)
 | 
						eth.miner.SetExtra(config.ExtraData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gpoParams := &gasprice.GpoParams{
 | 
						eth.ApiBackend = &EthApiBackend{eth, nil}
 | 
				
			||||||
		GpoMinGasPrice:          config.GpoMinGasPrice,
 | 
						gpoParams := gasprice.Config{
 | 
				
			||||||
		GpoMaxGasPrice:          config.GpoMaxGasPrice,
 | 
							Blocks:     config.GpoBlocks,
 | 
				
			||||||
		GpoFullBlockRatio:       config.GpoFullBlockRatio,
 | 
							Percentile: config.GpoPercentile,
 | 
				
			||||||
		GpobaseStepDown:         config.GpobaseStepDown,
 | 
							Default:    config.GasPrice,
 | 
				
			||||||
		GpobaseStepUp:           config.GpobaseStepUp,
 | 
					 | 
				
			||||||
		GpobaseCorrectionFactor: config.GpobaseCorrectionFactor,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	gpo := gasprice.NewGasPriceOracle(eth.blockchain, chainDb, eth.eventMux, gpoParams)
 | 
						eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
 | 
				
			||||||
	eth.ApiBackend = &EthApiBackend{eth, gpo}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return eth, nil
 | 
						return eth, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
// Copyright 2015 The go-ethereum Authors
 | 
					// Copyright 2016 The go-ethereum Authors
 | 
				
			||||||
// This file is part of the go-ethereum library.
 | 
					// This file is part of the go-ethereum library.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
 | 
					// The go-ethereum library is free software: you can redistribute it and/or modify
 | 
				
			||||||
@@ -17,212 +17,158 @@
 | 
				
			|||||||
package gasprice
 | 
					package gasprice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
	"math/big"
 | 
						"math/big"
 | 
				
			||||||
	"math/rand"
 | 
						"sort"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/core"
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/core/types"
 | 
						"github.com/ethereum/go-ethereum/internal/ethapi"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/ethdb"
 | 
						"github.com/ethereum/go-ethereum/params"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/event"
 | 
						"github.com/ethereum/go-ethereum/rpc"
 | 
				
			||||||
	"github.com/ethereum/go-ethereum/log"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					var maxPrice = big.NewInt(500 * params.Shannon)
 | 
				
			||||||
	gpoProcessPastBlocks = 100
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// for testing
 | 
					type Config struct {
 | 
				
			||||||
	gpoDefaultBaseCorrectionFactor = 110
 | 
						Blocks     int
 | 
				
			||||||
	gpoDefaultMinGasPrice          = 10000000000000
 | 
						Percentile int
 | 
				
			||||||
)
 | 
						Default    *big.Int
 | 
				
			||||||
 | 
					 | 
				
			||||||
type blockPriceInfo struct {
 | 
					 | 
				
			||||||
	baseGasPrice *big.Int
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type GpoParams struct {
 | 
					// Oracle recommends gas prices based on the content of recent
 | 
				
			||||||
	GpoMinGasPrice          *big.Int
 | 
					// blocks. Suitable for both light and full clients.
 | 
				
			||||||
	GpoMaxGasPrice          *big.Int
 | 
					type Oracle struct {
 | 
				
			||||||
	GpoFullBlockRatio       int
 | 
						backend   ethapi.Backend
 | 
				
			||||||
	GpobaseStepDown         int
 | 
						lastHead  common.Hash
 | 
				
			||||||
	GpobaseStepUp           int
 | 
						lastPrice *big.Int
 | 
				
			||||||
	GpobaseCorrectionFactor int
 | 
						cacheLock sync.RWMutex
 | 
				
			||||||
 | 
						fetchLock sync.Mutex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						checkBlocks, maxEmpty, maxBlocks int
 | 
				
			||||||
 | 
						percentile                       int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GasPriceOracle recommends gas prices based on the content of recent
 | 
					// NewOracle returns a new oracle.
 | 
				
			||||||
// blocks.
 | 
					func NewOracle(backend ethapi.Backend, params Config) *Oracle {
 | 
				
			||||||
type GasPriceOracle struct {
 | 
						blocks := params.Blocks
 | 
				
			||||||
	chain         *core.BlockChain
 | 
						if blocks < 1 {
 | 
				
			||||||
	db            ethdb.Database
 | 
							blocks = 1
 | 
				
			||||||
	evmux         *event.TypeMux
 | 
					 | 
				
			||||||
	params        *GpoParams
 | 
					 | 
				
			||||||
	initOnce      sync.Once
 | 
					 | 
				
			||||||
	minPrice      *big.Int
 | 
					 | 
				
			||||||
	lastBaseMutex sync.Mutex
 | 
					 | 
				
			||||||
	lastBase      *big.Int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// state of listenLoop
 | 
					 | 
				
			||||||
	blocks                        map[uint64]*blockPriceInfo
 | 
					 | 
				
			||||||
	firstProcessed, lastProcessed uint64
 | 
					 | 
				
			||||||
	minBase                       *big.Int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewGasPriceOracle returns a new oracle.
 | 
					 | 
				
			||||||
func NewGasPriceOracle(chain *core.BlockChain, db ethdb.Database, evmux *event.TypeMux, params *GpoParams) *GasPriceOracle {
 | 
					 | 
				
			||||||
	minprice := params.GpoMinGasPrice
 | 
					 | 
				
			||||||
	if minprice == nil {
 | 
					 | 
				
			||||||
		minprice = big.NewInt(gpoDefaultMinGasPrice)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	minbase := new(big.Int).Mul(minprice, big.NewInt(100))
 | 
						percent := params.Percentile
 | 
				
			||||||
	if params.GpobaseCorrectionFactor > 0 {
 | 
						if percent < 0 {
 | 
				
			||||||
		minbase = minbase.Div(minbase, big.NewInt(int64(params.GpobaseCorrectionFactor)))
 | 
							percent = 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &GasPriceOracle{
 | 
						if percent > 100 {
 | 
				
			||||||
		chain:    chain,
 | 
							percent = 100
 | 
				
			||||||
		db:       db,
 | 
					 | 
				
			||||||
		evmux:    evmux,
 | 
					 | 
				
			||||||
		params:   params,
 | 
					 | 
				
			||||||
		blocks:   make(map[uint64]*blockPriceInfo),
 | 
					 | 
				
			||||||
		minBase:  minbase,
 | 
					 | 
				
			||||||
		minPrice: minprice,
 | 
					 | 
				
			||||||
		lastBase: minprice,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
						return &Oracle{
 | 
				
			||||||
 | 
							backend:     backend,
 | 
				
			||||||
func (gpo *GasPriceOracle) init() {
 | 
							lastPrice:   params.Default,
 | 
				
			||||||
	gpo.initOnce.Do(func() {
 | 
							checkBlocks: blocks,
 | 
				
			||||||
		gpo.processPastBlocks()
 | 
							maxEmpty:    blocks / 2,
 | 
				
			||||||
		go gpo.listenLoop()
 | 
							maxBlocks:   blocks * 5,
 | 
				
			||||||
	})
 | 
							percentile:  percent,
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (self *GasPriceOracle) processPastBlocks() {
 | 
					 | 
				
			||||||
	last := int64(-1)
 | 
					 | 
				
			||||||
	cblock := self.chain.CurrentBlock()
 | 
					 | 
				
			||||||
	if cblock != nil {
 | 
					 | 
				
			||||||
		last = int64(cblock.NumberU64())
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	first := int64(0)
 | 
					 | 
				
			||||||
	if last > gpoProcessPastBlocks {
 | 
					 | 
				
			||||||
		first = last - gpoProcessPastBlocks
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	self.firstProcessed = uint64(first)
 | 
					 | 
				
			||||||
	for i := first; i <= last; i++ {
 | 
					 | 
				
			||||||
		block := self.chain.GetBlockByNumber(uint64(i))
 | 
					 | 
				
			||||||
		if block != nil {
 | 
					 | 
				
			||||||
			self.processBlock(block)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (self *GasPriceOracle) listenLoop() {
 | 
					 | 
				
			||||||
	events := self.evmux.Subscribe(core.ChainEvent{}, core.ChainSplitEvent{})
 | 
					 | 
				
			||||||
	defer events.Unsubscribe()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for event := range events.Chan() {
 | 
					 | 
				
			||||||
		switch event := event.Data.(type) {
 | 
					 | 
				
			||||||
		case core.ChainEvent:
 | 
					 | 
				
			||||||
			self.processBlock(event.Block)
 | 
					 | 
				
			||||||
		case core.ChainSplitEvent:
 | 
					 | 
				
			||||||
			self.processBlock(event.Block)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (self *GasPriceOracle) processBlock(block *types.Block) {
 | 
					 | 
				
			||||||
	i := block.NumberU64()
 | 
					 | 
				
			||||||
	if i > self.lastProcessed {
 | 
					 | 
				
			||||||
		self.lastProcessed = i
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	lastBase := self.minPrice
 | 
					 | 
				
			||||||
	bpl := self.blocks[i-1]
 | 
					 | 
				
			||||||
	if bpl != nil {
 | 
					 | 
				
			||||||
		lastBase = bpl.baseGasPrice
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if lastBase == nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var corr int
 | 
					 | 
				
			||||||
	lp := self.lowestPrice(block)
 | 
					 | 
				
			||||||
	if lp == nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if lastBase.Cmp(lp) < 0 {
 | 
					 | 
				
			||||||
		corr = self.params.GpobaseStepUp
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		corr = -self.params.GpobaseStepDown
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	crand := int64(corr * (900 + rand.Intn(201)))
 | 
					 | 
				
			||||||
	newBase := new(big.Int).Mul(lastBase, big.NewInt(1000000+crand))
 | 
					 | 
				
			||||||
	newBase.Div(newBase, big.NewInt(1000000))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if newBase.Cmp(self.minBase) < 0 {
 | 
					 | 
				
			||||||
		newBase = self.minBase
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bpi := self.blocks[i]
 | 
					 | 
				
			||||||
	if bpi == nil {
 | 
					 | 
				
			||||||
		bpi = &blockPriceInfo{}
 | 
					 | 
				
			||||||
		self.blocks[i] = bpi
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	bpi.baseGasPrice = newBase
 | 
					 | 
				
			||||||
	self.lastBaseMutex.Lock()
 | 
					 | 
				
			||||||
	self.lastBase = newBase
 | 
					 | 
				
			||||||
	self.lastBaseMutex.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log.Trace("Processed block, base price updated", "number", i, "base", newBase)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// returns the lowers possible price with which a tx was or could have been included
 | 
					 | 
				
			||||||
func (self *GasPriceOracle) lowestPrice(block *types.Block) *big.Int {
 | 
					 | 
				
			||||||
	gasUsed := big.NewInt(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	receipts := core.GetBlockReceipts(self.db, block.Hash(), block.NumberU64())
 | 
					 | 
				
			||||||
	if len(receipts) > 0 {
 | 
					 | 
				
			||||||
		if cgu := receipts[len(receipts)-1].CumulativeGasUsed; cgu != nil {
 | 
					 | 
				
			||||||
			gasUsed = receipts[len(receipts)-1].CumulativeGasUsed
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if new(big.Int).Mul(gasUsed, big.NewInt(100)).Cmp(new(big.Int).Mul(block.GasLimit(),
 | 
					 | 
				
			||||||
		big.NewInt(int64(self.params.GpoFullBlockRatio)))) < 0 {
 | 
					 | 
				
			||||||
		// block is not full, could have posted a tx with MinGasPrice
 | 
					 | 
				
			||||||
		return big.NewInt(0)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	txs := block.Transactions()
 | 
					 | 
				
			||||||
	if len(txs) == 0 {
 | 
					 | 
				
			||||||
		return big.NewInt(0)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// block is full, find smallest gasPrice
 | 
					 | 
				
			||||||
	minPrice := txs[0].GasPrice()
 | 
					 | 
				
			||||||
	for i := 1; i < len(txs); i++ {
 | 
					 | 
				
			||||||
		price := txs[i].GasPrice()
 | 
					 | 
				
			||||||
		if price.Cmp(minPrice) < 0 {
 | 
					 | 
				
			||||||
			minPrice = price
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return minPrice
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SuggestPrice returns the recommended gas price.
 | 
					// SuggestPrice returns the recommended gas price.
 | 
				
			||||||
func (self *GasPriceOracle) SuggestPrice() *big.Int {
 | 
					func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
 | 
				
			||||||
	self.init()
 | 
						gpo.cacheLock.RLock()
 | 
				
			||||||
	self.lastBaseMutex.Lock()
 | 
						lastHead := gpo.lastHead
 | 
				
			||||||
	price := new(big.Int).Set(self.lastBase)
 | 
						lastPrice := gpo.lastPrice
 | 
				
			||||||
	self.lastBaseMutex.Unlock()
 | 
						gpo.cacheLock.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	price.Mul(price, big.NewInt(int64(self.params.GpobaseCorrectionFactor)))
 | 
						head, _ := gpo.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
 | 
				
			||||||
	price.Div(price, big.NewInt(100))
 | 
						headHash := head.Hash()
 | 
				
			||||||
	if price.Cmp(self.minPrice) < 0 {
 | 
						if headHash == lastHead {
 | 
				
			||||||
		price.Set(self.minPrice)
 | 
							return lastPrice, nil
 | 
				
			||||||
	} else if self.params.GpoMaxGasPrice != nil && price.Cmp(self.params.GpoMaxGasPrice) > 0 {
 | 
					 | 
				
			||||||
		price.Set(self.params.GpoMaxGasPrice)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return price
 | 
					
 | 
				
			||||||
 | 
						gpo.fetchLock.Lock()
 | 
				
			||||||
 | 
						defer gpo.fetchLock.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// try checking the cache again, maybe the last fetch fetched what we need
 | 
				
			||||||
 | 
						gpo.cacheLock.RLock()
 | 
				
			||||||
 | 
						lastHead = gpo.lastHead
 | 
				
			||||||
 | 
						lastPrice = gpo.lastPrice
 | 
				
			||||||
 | 
						gpo.cacheLock.RUnlock()
 | 
				
			||||||
 | 
						if headHash == lastHead {
 | 
				
			||||||
 | 
							return lastPrice, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						blockNum := head.Number.Uint64()
 | 
				
			||||||
 | 
						ch := make(chan getBlockPricesResult, gpo.checkBlocks)
 | 
				
			||||||
 | 
						sent := 0
 | 
				
			||||||
 | 
						exp := 0
 | 
				
			||||||
 | 
						var txPrices []*big.Int
 | 
				
			||||||
 | 
						for sent < gpo.checkBlocks && blockNum > 0 {
 | 
				
			||||||
 | 
							go gpo.getBlockPrices(ctx, blockNum, ch)
 | 
				
			||||||
 | 
							sent++
 | 
				
			||||||
 | 
							exp++
 | 
				
			||||||
 | 
							blockNum--
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						maxEmpty := gpo.maxEmpty
 | 
				
			||||||
 | 
						for exp > 0 {
 | 
				
			||||||
 | 
							res := <-ch
 | 
				
			||||||
 | 
							if res.err != nil {
 | 
				
			||||||
 | 
								return lastPrice, res.err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							exp--
 | 
				
			||||||
 | 
							if len(res.prices) > 0 {
 | 
				
			||||||
 | 
								txPrices = append(txPrices, res.prices...)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if maxEmpty > 0 {
 | 
				
			||||||
 | 
								maxEmpty--
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if blockNum > 0 && sent < gpo.maxBlocks {
 | 
				
			||||||
 | 
								go gpo.getBlockPrices(ctx, blockNum, ch)
 | 
				
			||||||
 | 
								sent++
 | 
				
			||||||
 | 
								exp++
 | 
				
			||||||
 | 
								blockNum--
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						price := lastPrice
 | 
				
			||||||
 | 
						if len(txPrices) > 0 {
 | 
				
			||||||
 | 
							sort.Sort(bigIntArray(txPrices))
 | 
				
			||||||
 | 
							price = txPrices[(len(txPrices)-1)*gpo.percentile/100]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if price.Cmp(maxPrice) > 0 {
 | 
				
			||||||
 | 
							price = new(big.Int).Set(maxPrice)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gpo.cacheLock.Lock()
 | 
				
			||||||
 | 
						gpo.lastHead = headHash
 | 
				
			||||||
 | 
						gpo.lastPrice = price
 | 
				
			||||||
 | 
						gpo.cacheLock.Unlock()
 | 
				
			||||||
 | 
						return price, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type getBlockPricesResult struct {
 | 
				
			||||||
 | 
						prices []*big.Int
 | 
				
			||||||
 | 
						err    error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getLowestPrice calculates the lowest transaction gas price in a given block
 | 
				
			||||||
 | 
					// and sends it to the result channel. If the block is empty, price is nil.
 | 
				
			||||||
 | 
					func (gpo *Oracle) getBlockPrices(ctx context.Context, blockNum uint64, ch chan getBlockPricesResult) {
 | 
				
			||||||
 | 
						block, err := gpo.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
 | 
				
			||||||
 | 
						if block == nil {
 | 
				
			||||||
 | 
							ch <- getBlockPricesResult{nil, err}
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						txs := block.Transactions()
 | 
				
			||||||
 | 
						prices := make([]*big.Int, len(txs))
 | 
				
			||||||
 | 
						for i, tx := range txs {
 | 
				
			||||||
 | 
							prices[i] = tx.GasPrice()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ch <- getBlockPricesResult{prices, nil}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type bigIntArray []*big.Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s bigIntArray) Len() int           { return len(s) }
 | 
				
			||||||
 | 
					func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
 | 
				
			||||||
 | 
					func (s bigIntArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,160 +0,0 @@
 | 
				
			|||||||
// Copyright 2016 The go-ethereum Authors
 | 
					 | 
				
			||||||
// This file is part of the go-ethereum library.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
// it under the terms of the GNU Lesser General Public License as published by
 | 
					 | 
				
			||||||
// the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
// (at your option) any later version.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// The go-ethereum library is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
					 | 
				
			||||||
// GNU Lesser General Public License for more details.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// You should have received a copy of the GNU Lesser General Public License
 | 
					 | 
				
			||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package gasprice
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"math/big"
 | 
					 | 
				
			||||||
	"sort"
 | 
					 | 
				
			||||||
	"sync"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/ethereum/go-ethereum/common"
 | 
					 | 
				
			||||||
	"github.com/ethereum/go-ethereum/internal/ethapi"
 | 
					 | 
				
			||||||
	"github.com/ethereum/go-ethereum/rpc"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	LpoAvgCount     = 5
 | 
					 | 
				
			||||||
	LpoMinCount     = 3
 | 
					 | 
				
			||||||
	LpoMaxBlocks    = 20
 | 
					 | 
				
			||||||
	LpoSelect       = 50
 | 
					 | 
				
			||||||
	LpoDefaultPrice = 20000000000
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// LightPriceOracle recommends gas prices based on the content of recent
 | 
					 | 
				
			||||||
// blocks. Suitable for both light and full clients.
 | 
					 | 
				
			||||||
type LightPriceOracle struct {
 | 
					 | 
				
			||||||
	backend   ethapi.Backend
 | 
					 | 
				
			||||||
	lastHead  common.Hash
 | 
					 | 
				
			||||||
	lastPrice *big.Int
 | 
					 | 
				
			||||||
	cacheLock sync.RWMutex
 | 
					 | 
				
			||||||
	fetchLock sync.Mutex
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewLightPriceOracle returns a new oracle.
 | 
					 | 
				
			||||||
func NewLightPriceOracle(backend ethapi.Backend) *LightPriceOracle {
 | 
					 | 
				
			||||||
	return &LightPriceOracle{
 | 
					 | 
				
			||||||
		backend:   backend,
 | 
					 | 
				
			||||||
		lastPrice: big.NewInt(LpoDefaultPrice),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SuggestPrice returns the recommended gas price.
 | 
					 | 
				
			||||||
func (self *LightPriceOracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
 | 
					 | 
				
			||||||
	self.cacheLock.RLock()
 | 
					 | 
				
			||||||
	lastHead := self.lastHead
 | 
					 | 
				
			||||||
	lastPrice := self.lastPrice
 | 
					 | 
				
			||||||
	self.cacheLock.RUnlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	head, _ := self.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
 | 
					 | 
				
			||||||
	headHash := head.Hash()
 | 
					 | 
				
			||||||
	if headHash == lastHead {
 | 
					 | 
				
			||||||
		return lastPrice, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	self.fetchLock.Lock()
 | 
					 | 
				
			||||||
	defer self.fetchLock.Unlock()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// try checking the cache again, maybe the last fetch fetched what we need
 | 
					 | 
				
			||||||
	self.cacheLock.RLock()
 | 
					 | 
				
			||||||
	lastHead = self.lastHead
 | 
					 | 
				
			||||||
	lastPrice = self.lastPrice
 | 
					 | 
				
			||||||
	self.cacheLock.RUnlock()
 | 
					 | 
				
			||||||
	if headHash == lastHead {
 | 
					 | 
				
			||||||
		return lastPrice, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	blockNum := head.Number.Uint64()
 | 
					 | 
				
			||||||
	chn := make(chan lpResult, LpoMaxBlocks)
 | 
					 | 
				
			||||||
	sent := 0
 | 
					 | 
				
			||||||
	exp := 0
 | 
					 | 
				
			||||||
	var lps bigIntArray
 | 
					 | 
				
			||||||
	for sent < LpoAvgCount && blockNum > 0 {
 | 
					 | 
				
			||||||
		go self.getLowestPrice(ctx, blockNum, chn)
 | 
					 | 
				
			||||||
		sent++
 | 
					 | 
				
			||||||
		exp++
 | 
					 | 
				
			||||||
		blockNum--
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	maxEmpty := LpoAvgCount - LpoMinCount
 | 
					 | 
				
			||||||
	for exp > 0 {
 | 
					 | 
				
			||||||
		res := <-chn
 | 
					 | 
				
			||||||
		if res.err != nil {
 | 
					 | 
				
			||||||
			return nil, res.err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		exp--
 | 
					 | 
				
			||||||
		if res.price != nil {
 | 
					 | 
				
			||||||
			lps = append(lps, res.price)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			if maxEmpty > 0 {
 | 
					 | 
				
			||||||
				maxEmpty--
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				if blockNum > 0 && sent < LpoMaxBlocks {
 | 
					 | 
				
			||||||
					go self.getLowestPrice(ctx, blockNum, chn)
 | 
					 | 
				
			||||||
					sent++
 | 
					 | 
				
			||||||
					exp++
 | 
					 | 
				
			||||||
					blockNum--
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	price := lastPrice
 | 
					 | 
				
			||||||
	if len(lps) > 0 {
 | 
					 | 
				
			||||||
		sort.Sort(lps)
 | 
					 | 
				
			||||||
		price = lps[(len(lps)-1)*LpoSelect/100]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	self.cacheLock.Lock()
 | 
					 | 
				
			||||||
	self.lastHead = headHash
 | 
					 | 
				
			||||||
	self.lastPrice = price
 | 
					 | 
				
			||||||
	self.cacheLock.Unlock()
 | 
					 | 
				
			||||||
	return price, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type lpResult struct {
 | 
					 | 
				
			||||||
	price *big.Int
 | 
					 | 
				
			||||||
	err   error
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getLowestPrice calculates the lowest transaction gas price in a given block
 | 
					 | 
				
			||||||
// and sends it to the result channel. If the block is empty, price is nil.
 | 
					 | 
				
			||||||
func (self *LightPriceOracle) getLowestPrice(ctx context.Context, blockNum uint64, chn chan lpResult) {
 | 
					 | 
				
			||||||
	block, err := self.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
 | 
					 | 
				
			||||||
	if block == nil {
 | 
					 | 
				
			||||||
		chn <- lpResult{nil, err}
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	txs := block.Transactions()
 | 
					 | 
				
			||||||
	if len(txs) == 0 {
 | 
					 | 
				
			||||||
		chn <- lpResult{nil, nil}
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// find smallest gasPrice
 | 
					 | 
				
			||||||
	minPrice := txs[0].GasPrice()
 | 
					 | 
				
			||||||
	for i := 1; i < len(txs); i++ {
 | 
					 | 
				
			||||||
		price := txs[i].GasPrice()
 | 
					 | 
				
			||||||
		if price.Cmp(minPrice) < 0 {
 | 
					 | 
				
			||||||
			minPrice = price
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	chn <- lpResult{minPrice, nil}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type bigIntArray []*big.Int
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s bigIntArray) Len() int           { return len(s) }
 | 
					 | 
				
			||||||
func (s bigIntArray) Less(i, j int) bool { return s[i].Cmp(s[j]) < 0 }
 | 
					 | 
				
			||||||
func (s bigIntArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 | 
					 | 
				
			||||||
@@ -38,7 +38,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type LesApiBackend struct {
 | 
					type LesApiBackend struct {
 | 
				
			||||||
	eth *LightEthereum
 | 
						eth *LightEthereum
 | 
				
			||||||
	gpo *gasprice.LightPriceOracle
 | 
						gpo *gasprice.Oracle
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *LesApiBackend) ChainConfig() *params.ChainConfig {
 | 
					func (b *LesApiBackend) ChainConfig() *params.ChainConfig {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -111,7 +111,12 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
 | 
				
			|||||||
	relay.reqDist = eth.protocolManager.reqDist
 | 
						relay.reqDist = eth.protocolManager.reqDist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eth.ApiBackend = &LesApiBackend{eth, nil}
 | 
						eth.ApiBackend = &LesApiBackend{eth, nil}
 | 
				
			||||||
	eth.ApiBackend.gpo = gasprice.NewLightPriceOracle(eth.ApiBackend)
 | 
						gpoParams := gasprice.Config{
 | 
				
			||||||
 | 
							Blocks:     config.GpoBlocks,
 | 
				
			||||||
 | 
							Percentile: config.GpoPercentile,
 | 
				
			||||||
 | 
							Default:    config.GasPrice,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
 | 
				
			||||||
	return eth, nil
 | 
						return eth, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -173,12 +173,8 @@ func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) {
 | 
				
			|||||||
			DatabaseCache:      config.EthereumDatabaseCache,
 | 
								DatabaseCache:      config.EthereumDatabaseCache,
 | 
				
			||||||
			NetworkId:          config.EthereumNetworkID,
 | 
								NetworkId:          config.EthereumNetworkID,
 | 
				
			||||||
			GasPrice:           new(big.Int).SetUint64(20 * params.Shannon),
 | 
								GasPrice:           new(big.Int).SetUint64(20 * params.Shannon),
 | 
				
			||||||
			GpoMinGasPrice:          new(big.Int).SetUint64(50 * params.Shannon),
 | 
								GpoBlocks:          5,
 | 
				
			||||||
			GpoMaxGasPrice:          new(big.Int).SetUint64(500 * params.Shannon),
 | 
								GpoPercentile:      50,
 | 
				
			||||||
			GpoFullBlockRatio:       80,
 | 
					 | 
				
			||||||
			GpobaseStepDown:         10,
 | 
					 | 
				
			||||||
			GpobaseStepUp:           100,
 | 
					 | 
				
			||||||
			GpobaseCorrectionFactor: 110,
 | 
					 | 
				
			||||||
			EthashCacheDir:     "ethash",
 | 
								EthashCacheDir:     "ethash",
 | 
				
			||||||
			EthashCachesInMem:  2,
 | 
								EthashCachesInMem:  2,
 | 
				
			||||||
			EthashCachesOnDisk: 3,
 | 
								EthashCachesOnDisk: 3,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user