From 6269e5574c024bb82617b33f673550231b3a3b37 Mon Sep 17 00:00:00 2001 From: gary rong Date: Tue, 23 Apr 2019 15:08:51 +0800 Subject: [PATCH] miner: polish miner configuration (#19480) * cmd, eth, miner: disable advance sealing if user require * cmd, console, miner, les, eth: wrap the miner config * eth: remove todo * cmd, miner: revert noadvance flag The reason for this is: if the transaction execution is even longer than block time, then this kind of transactions is DoS attack. --- cmd/utils/flags.go | 81 ++++++++++++++++++---------------- console/console_test.go | 7 ++- eth/backend.go | 18 ++++---- eth/config.go | 30 +++++-------- eth/gen_config.go | 97 ++++++++++++++++------------------------- les/backend.go | 2 +- miner/miner.go | 18 +++++++- miner/stress_clique.go | 10 +++-- miner/stress_ethash.go | 10 +++-- miner/worker.go | 43 +++++++++--------- miner/worker_test.go | 8 +++- 11 files changed, 162 insertions(+), 162 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 689202c693..513557a034 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -49,6 +49,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics/influxdb" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discv5" @@ -375,27 +376,27 @@ var ( MinerGasTargetFlag = cli.Uint64Flag{ Name: "miner.gastarget", Usage: "Target gas floor for mined blocks", - Value: eth.DefaultConfig.MinerGasFloor, + Value: eth.DefaultConfig.Miner.GasFloor, } MinerLegacyGasTargetFlag = cli.Uint64Flag{ Name: "targetgaslimit", Usage: "Target gas floor for mined blocks (deprecated, use --miner.gastarget)", - Value: eth.DefaultConfig.MinerGasFloor, + Value: eth.DefaultConfig.Miner.GasFloor, } MinerGasLimitFlag = cli.Uint64Flag{ Name: "miner.gaslimit", Usage: "Target gas ceiling for mined blocks", - Value: eth.DefaultConfig.MinerGasCeil, + Value: eth.DefaultConfig.Miner.GasCeil, } MinerGasPriceFlag = BigFlag{ Name: "miner.gasprice", Usage: "Minimum gas price for mining a transaction", - Value: eth.DefaultConfig.MinerGasPrice, + Value: eth.DefaultConfig.Miner.GasPrice, } MinerLegacyGasPriceFlag = BigFlag{ Name: "gasprice", Usage: "Minimum gas price for mining a transaction (deprecated, use --miner.gasprice)", - Value: eth.DefaultConfig.MinerGasPrice, + Value: eth.DefaultConfig.Miner.GasPrice, } MinerEtherbaseFlag = cli.StringFlag{ Name: "miner.etherbase", @@ -418,7 +419,7 @@ var ( MinerRecommitIntervalFlag = cli.DurationFlag{ Name: "miner.recommit", Usage: "Time interval to recreate the block being mined", - Value: eth.DefaultConfig.MinerRecommit, + Value: eth.DefaultConfig.Miner.Recommit, } MinerNoVerfiyFlag = cli.BoolFlag{ Name: "miner.noverify", @@ -1023,7 +1024,7 @@ func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) { if err != nil { Fatalf("Invalid miner etherbase: %v", err) } - cfg.Etherbase = account.Address + cfg.Miner.Etherbase = account.Address } else { Fatalf("No etherbase configured") } @@ -1231,6 +1232,39 @@ func setEthash(ctx *cli.Context, cfg *eth.Config) { } } +func setMiner(ctx *cli.Context, cfg *miner.Config) { + if ctx.GlobalIsSet(MinerNotifyFlag.Name) { + cfg.Notify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",") + } + if ctx.GlobalIsSet(MinerLegacyExtraDataFlag.Name) { + cfg.ExtraData = []byte(ctx.GlobalString(MinerLegacyExtraDataFlag.Name)) + } + if ctx.GlobalIsSet(MinerExtraDataFlag.Name) { + cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name)) + } + if ctx.GlobalIsSet(MinerLegacyGasTargetFlag.Name) { + cfg.GasFloor = ctx.GlobalUint64(MinerLegacyGasTargetFlag.Name) + } + if ctx.GlobalIsSet(MinerGasTargetFlag.Name) { + cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name) + } + if ctx.GlobalIsSet(MinerGasLimitFlag.Name) { + cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name) + } + if ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) { + cfg.GasPrice = GlobalBig(ctx, MinerLegacyGasPriceFlag.Name) + } + if ctx.GlobalIsSet(MinerGasPriceFlag.Name) { + cfg.GasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name) + } + if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) { + cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) + } + if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) { + cfg.Noverify = ctx.Bool(MinerNoVerfiyFlag.Name) + } +} + func setWhitelist(ctx *cli.Context, cfg *eth.Config) { whitelist := ctx.GlobalString(WhitelistFlag.Name) if whitelist == "" { @@ -1323,6 +1357,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.TxPool) setEthash(ctx, cfg) + setMiner(ctx, &cfg.Miner) setWhitelist(ctx, cfg) if ctx.GlobalIsSet(SyncModeFlag.Name) { @@ -1359,39 +1394,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) { cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100 } - if ctx.GlobalIsSet(MinerNotifyFlag.Name) { - cfg.MinerNotify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",") - } if ctx.GlobalIsSet(DocRootFlag.Name) { cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name) } - if ctx.GlobalIsSet(MinerLegacyExtraDataFlag.Name) { - cfg.MinerExtraData = []byte(ctx.GlobalString(MinerLegacyExtraDataFlag.Name)) - } - if ctx.GlobalIsSet(MinerExtraDataFlag.Name) { - cfg.MinerExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name)) - } - if ctx.GlobalIsSet(MinerLegacyGasTargetFlag.Name) { - cfg.MinerGasFloor = ctx.GlobalUint64(MinerLegacyGasTargetFlag.Name) - } - if ctx.GlobalIsSet(MinerGasTargetFlag.Name) { - cfg.MinerGasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name) - } - if ctx.GlobalIsSet(MinerGasLimitFlag.Name) { - cfg.MinerGasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name) - } - if ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) { - cfg.MinerGasPrice = GlobalBig(ctx, MinerLegacyGasPriceFlag.Name) - } - if ctx.GlobalIsSet(MinerGasPriceFlag.Name) { - cfg.MinerGasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name) - } - if ctx.GlobalIsSet(MinerRecommitIntervalFlag.Name) { - cfg.MinerRecommit = ctx.Duration(MinerRecommitIntervalFlag.Name) - } - if ctx.GlobalIsSet(MinerNoVerfiyFlag.Name) { - cfg.MinerNoverify = ctx.Bool(MinerNoVerfiyFlag.Name) - } if ctx.GlobalIsSet(VMEnableDebugFlag.Name) { // TODO(fjl): force-enable this in --dev mode cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) @@ -1449,7 +1454,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address) if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) { - cfg.MinerGasPrice = big.NewInt(1) + cfg.Miner.GasPrice = big.NewInt(1) } } } diff --git a/console/console_test.go b/console/console_test.go index 55d799725a..89dd7cd838 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/internal/jsre" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" ) @@ -96,8 +97,10 @@ func newTester(t *testing.T, confOverride func(*eth.Config)) *tester { t.Fatalf("failed to create node: %v", err) } ethConf := ð.Config{ - Genesis: core.DeveloperGenesisBlock(15, common.Address{}), - Etherbase: common.HexToAddress(testAddress), + Genesis: core.DeveloperGenesisBlock(15, common.Address{}), + Miner: miner.Config{ + Etherbase: common.HexToAddress(testAddress), + }, Ethash: ethash.Config{ PowMode: ethash.ModeTest, }, diff --git a/eth/backend.go b/eth/backend.go index b13cb10289..3363054aa8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -109,9 +109,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { if !config.SyncMode.IsValid() { return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) } - if config.MinerGasPrice == nil || config.MinerGasPrice.Cmp(common.Big0) <= 0 { - log.Warn("Sanitizing invalid miner gas price", "provided", config.MinerGasPrice, "updated", DefaultConfig.MinerGasPrice) - config.MinerGasPrice = new(big.Int).Set(DefaultConfig.MinerGasPrice) + if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 { + log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", DefaultConfig.Miner.GasPrice) + config.Miner.GasPrice = new(big.Int).Set(DefaultConfig.Miner.GasPrice) } if config.NoPruning && config.TrieDirtyCache > 0 { config.TrieCleanCache += config.TrieDirtyCache @@ -135,11 +135,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { chainDb: chainDb, eventMux: ctx.EventMux, accountManager: ctx.AccountManager, - engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.MinerNotify, config.MinerNoverify, chainDb), + engine: CreateConsensusEngine(ctx, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb), shutdownChan: make(chan bool), networkID: config.NetworkId, - gasPrice: config.MinerGasPrice, - etherbase: config.Etherbase, + gasPrice: config.Miner.GasPrice, + etherbase: config.Miner.Etherbase, bloomRequests: make(chan chan *bloombits.Retrieval), bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), } @@ -194,13 +194,13 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { return nil, err } - eth.miner = miner.New(eth, chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil, eth.isLocalBlock) - eth.miner.SetExtra(makeExtraData(config.MinerExtraData)) + eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) + eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) eth.APIBackend = &EthAPIBackend{ctx.ExtRPCEnabled(), eth, nil} gpoParams := config.GPO if gpoParams.Default == nil { - gpoParams.Default = config.MinerGasPrice + gpoParams.Default = config.Miner.GasPrice } eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) diff --git a/eth/config.go b/eth/config.go index d97ae3070d..fbe6597b67 100644 --- a/eth/config.go +++ b/eth/config.go @@ -25,11 +25,11 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/params" ) @@ -49,11 +49,12 @@ var DefaultConfig = Config{ TrieCleanCache: 256, TrieDirtyCache: 256, TrieTimeout: 60 * time.Minute, - MinerGasFloor: 8000000, - MinerGasCeil: 8000000, - MinerGasPrice: big.NewInt(params.GWei), - MinerRecommit: 3 * time.Second, - + Miner: miner.Config{ + GasFloor: 8000000, + GasCeil: 8000000, + GasPrice: big.NewInt(params.GWei), + Recommit: 3 * time.Second, + }, TxPool: core.DefaultTxPoolConfig, GPO: gasprice.Config{ Blocks: 20, @@ -82,7 +83,7 @@ func init() { } } -//go:generate gencodec -type Config -field-override configMarshaling -formats toml -out gen_config.go +//go:generate gencodec -type Config -formats toml -out gen_config.go type Config struct { // The genesis block, which is inserted if the database is empty. @@ -118,15 +119,8 @@ type Config struct { TrieDirtyCache int TrieTimeout time.Duration - // Mining-related options - Etherbase common.Address `toml:",omitempty"` - MinerNotify []string `toml:",omitempty"` - MinerExtraData []byte `toml:",omitempty"` - MinerGasFloor uint64 - MinerGasCeil uint64 - MinerGasPrice *big.Int - MinerRecommit time.Duration - MinerNoverify bool + // Mining options + Miner miner.Config // Ethash options Ethash ethash.Config @@ -155,7 +149,3 @@ type Config struct { // RPCGasCap is the global gas cap for eth-call variants. RPCGasCap *big.Int `toml:",omitempty"` } - -type configMarshaling struct { - MinerExtraData hexutil.Bytes -} diff --git a/eth/gen_config.go b/eth/gen_config.go index 30ff8b6e13..178faf7cb7 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -7,15 +7,13 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/miner" ) -var _ = (*configMarshaling)(nil) - // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { @@ -23,10 +21,12 @@ func (c Config) MarshalTOML() (interface{}, error) { NetworkId uint64 SyncMode downloader.SyncMode NoPruning bool - LightServ int `toml:",omitempty"` - LightBandwidthIn int `toml:",omitempty"` - LightBandwidthOut int `toml:",omitempty"` - LightPeers int `toml:",omitempty"` + NoPrefetch bool + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ int `toml:",omitempty"` + LightBandwidthIn int `toml:",omitempty"` + LightBandwidthOut int `toml:",omitempty"` + LightPeers int `toml:",omitempty"` OnlyAnnounce bool ULC *ULCConfig `toml:",omitempty"` SkipBcVersionCheck bool `toml:"-"` @@ -35,14 +35,7 @@ func (c Config) MarshalTOML() (interface{}, error) { TrieCleanCache int TrieDirtyCache int TrieTimeout time.Duration - Etherbase common.Address `toml:",omitempty"` - MinerNotify []string `toml:",omitempty"` - MinerExtraData hexutil.Bytes `toml:",omitempty"` - MinerGasFloor uint64 - MinerGasCeil uint64 - MinerGasPrice *big.Int - MinerRecommit time.Duration - MinerNoverify bool + Miner miner.Config Ethash ethash.Config TxPool core.TxPoolConfig GPO gasprice.Config @@ -50,12 +43,16 @@ func (c Config) MarshalTOML() (interface{}, error) { DocRoot string `toml:"-"` EWASMInterpreter string EVMInterpreter string + ConstantinopleOverride *big.Int + RPCGasCap *big.Int `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis enc.NetworkId = c.NetworkId enc.SyncMode = c.SyncMode enc.NoPruning = c.NoPruning + enc.NoPrefetch = c.NoPrefetch + enc.Whitelist = c.Whitelist enc.LightServ = c.LightServ enc.LightBandwidthIn = c.LightBandwidthIn enc.LightBandwidthOut = c.LightBandwidthOut @@ -68,22 +65,16 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.TrieCleanCache = c.TrieCleanCache enc.TrieDirtyCache = c.TrieDirtyCache enc.TrieTimeout = c.TrieTimeout - enc.Etherbase = c.Etherbase - enc.MinerNotify = c.MinerNotify - enc.MinerExtraData = c.MinerExtraData - enc.MinerGasFloor = c.MinerGasFloor - enc.MinerGasCeil = c.MinerGasCeil - enc.MinerGasPrice = c.MinerGasPrice - enc.MinerRecommit = c.MinerRecommit - enc.MinerNoverify = c.MinerNoverify + enc.Miner = c.Miner enc.Ethash = c.Ethash enc.TxPool = c.TxPool enc.GPO = c.GPO - enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot enc.EWASMInterpreter = c.EWASMInterpreter enc.EVMInterpreter = c.EVMInterpreter + enc.ConstantinopleOverride = c.ConstantinopleOverride + enc.RPCGasCap = c.RPCGasCap return &enc, nil } @@ -94,10 +85,12 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { NetworkId *uint64 SyncMode *downloader.SyncMode NoPruning *bool - LightServ *int `toml:",omitempty"` - LightBandwidthIn *int `toml:",omitempty"` - LightBandwidthOut *int `toml:",omitempty"` - LightPeers *int `toml:",omitempty"` + NoPrefetch *bool + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ *int `toml:",omitempty"` + LightBandwidthIn *int `toml:",omitempty"` + LightBandwidthOut *int `toml:",omitempty"` + LightPeers *int `toml:",omitempty"` OnlyAnnounce *bool ULC *ULCConfig `toml:",omitempty"` SkipBcVersionCheck *bool `toml:"-"` @@ -106,14 +99,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TrieCleanCache *int TrieDirtyCache *int TrieTimeout *time.Duration - Etherbase *common.Address `toml:",omitempty"` - MinerNotify []string `toml:",omitempty"` - MinerExtraData *hexutil.Bytes `toml:",omitempty"` - MinerGasFloor *uint64 - MinerGasCeil *uint64 - MinerGasPrice *big.Int - MinerRecommit *time.Duration - MinerNoverify *bool + Miner *miner.Config Ethash *ethash.Config TxPool *core.TxPoolConfig GPO *gasprice.Config @@ -121,6 +107,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { DocRoot *string `toml:"-"` EWASMInterpreter *string EVMInterpreter *string + ConstantinopleOverride *big.Int + RPCGasCap *big.Int `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -138,6 +126,12 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.NoPruning != nil { c.NoPruning = *dec.NoPruning } + if dec.NoPrefetch != nil { + c.NoPrefetch = *dec.NoPrefetch + } + if dec.Whitelist != nil { + c.Whitelist = dec.Whitelist + } if dec.LightServ != nil { c.LightServ = *dec.LightServ } @@ -174,29 +168,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.TrieTimeout != nil { c.TrieTimeout = *dec.TrieTimeout } - if dec.Etherbase != nil { - c.Etherbase = *dec.Etherbase - } - if dec.MinerNotify != nil { - c.MinerNotify = dec.MinerNotify - } - if dec.MinerExtraData != nil { - c.MinerExtraData = *dec.MinerExtraData - } - if dec.MinerGasFloor != nil { - c.MinerGasFloor = *dec.MinerGasFloor - } - if dec.MinerGasCeil != nil { - c.MinerGasCeil = *dec.MinerGasCeil - } - if dec.MinerGasPrice != nil { - c.MinerGasPrice = dec.MinerGasPrice - } - if dec.MinerRecommit != nil { - c.MinerRecommit = *dec.MinerRecommit - } - if dec.MinerNoverify != nil { - c.MinerNoverify = *dec.MinerNoverify + if dec.Miner != nil { + c.Miner = *dec.Miner } if dec.Ethash != nil { c.Ethash = *dec.Ethash @@ -219,5 +192,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EVMInterpreter != nil { c.EVMInterpreter = *dec.EVMInterpreter } + if dec.ConstantinopleOverride != nil { + c.ConstantinopleOverride = dec.ConstantinopleOverride + } + if dec.RPCGasCap != nil { + c.RPCGasCap = dec.RPCGasCap + } return nil } diff --git a/les/backend.go b/les/backend.go index a50fe0ced5..80a912816f 100644 --- a/les/backend.go +++ b/les/backend.go @@ -170,7 +170,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) { gpoParams := config.GPO if gpoParams.Default == nil { - gpoParams.Default = config.MinerGasPrice + gpoParams.Default = config.Miner.GasPrice } leth.ApiBackend.gpo = gasprice.NewOracle(leth.ApiBackend, gpoParams) return leth, nil diff --git a/miner/miner.go b/miner/miner.go index 5218c12107..ab97b0c038 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -19,10 +19,12 @@ package miner import ( "fmt" + "math/big" "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -39,6 +41,18 @@ type Backend interface { TxPool() *core.TxPool } +// Config is the configuration parameters of mining. +type Config struct { + Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account) + Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). + ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner + GasFloor uint64 // Target gas floor for mined blocks. + GasCeil uint64 // Target gas ceiling for mined blocks. + GasPrice *big.Int // Minimum gas price for mining a transaction + Recommit time.Duration // The time interval for miner to re-create mining work. + Noverify bool // Disable remote mining solution verification(only useful in ethash). +} + // Miner creates blocks and searches for proof-of-work values. type Miner struct { mux *event.TypeMux @@ -52,13 +66,13 @@ type Miner struct { shouldStart int32 // should start indicates whether we should start after sync } -func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(block *types.Block) bool) *Miner { +func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, isLocalBlock func(block *types.Block) bool) *Miner { miner := &Miner{ eth: eth, mux: mux, engine: engine, exitCh: make(chan struct{}), - worker: newWorker(config, engine, eth, mux, recommit, gasFloor, gasCeil, isLocalBlock), + worker: newWorker(config, chainConfig, engine, eth, mux, isLocalBlock), canStart: 1, } go miner.update() diff --git a/miner/stress_clique.go b/miner/stress_clique.go index 8a355a4dc4..7f5db2e520 100644 --- a/miner/stress_clique.go +++ b/miner/stress_clique.go @@ -199,10 +199,12 @@ func makeSealer(genesis *core.Genesis) (*node.Node, error) { DatabaseHandles: 256, TxPool: core.DefaultTxPoolConfig, GPO: eth.DefaultConfig.GPO, - MinerGasFloor: genesis.GasLimit * 9 / 10, - MinerGasCeil: genesis.GasLimit * 11 / 10, - MinerGasPrice: big.NewInt(1), - MinerRecommit: time.Second, + Miner: Config{ + GasFloor: genesis.GasLimit * 9 / 10, + GasCeil: genesis.GasLimit * 11 / 10, + GasPrice: big.NewInt(1), + Recommit: time.Second, + }, }) }); err != nil { return nil, err diff --git a/miner/stress_ethash.go b/miner/stress_ethash.go index 040af9fba2..7d4a7d24f7 100644 --- a/miner/stress_ethash.go +++ b/miner/stress_ethash.go @@ -179,10 +179,12 @@ func makeMiner(genesis *core.Genesis) (*node.Node, error) { TxPool: core.DefaultTxPoolConfig, GPO: eth.DefaultConfig.GPO, Ethash: eth.DefaultConfig.Ethash, - MinerGasFloor: genesis.GasLimit * 9 / 10, - MinerGasCeil: genesis.GasLimit * 11 / 10, - MinerGasPrice: big.NewInt(1), - MinerRecommit: time.Second, + Miner: Config{ + GasFloor: genesis.GasLimit * 9 / 10, + GasCeil: genesis.GasLimit * 11 / 10, + GasPrice: big.NewInt(1), + Recommit: time.Second, + }, }) }); err != nil { return nil, err diff --git a/miner/worker.go b/miner/worker.go index a9e440aec5..802c7e365e 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -122,13 +122,11 @@ type intervalAdjust struct { // worker is the main object which takes care of submitting new work to consensus engine // and gathering the sealing result. type worker struct { - config *params.ChainConfig - engine consensus.Engine - eth Backend - chain *core.BlockChain - - gasFloor uint64 - gasCeil uint64 + config *Config + chainConfig *params.ChainConfig + engine consensus.Engine + eth Backend + chain *core.BlockChain // Subscriptions mux *event.TypeMux @@ -178,15 +176,14 @@ type worker struct { resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval. } -func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, recommit time.Duration, gasFloor, gasCeil uint64, isLocalBlock func(*types.Block) bool) *worker { +func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, isLocalBlock func(*types.Block) bool) *worker { worker := &worker{ config: config, + chainConfig: chainConfig, engine: engine, eth: eth, mux: mux, chain: eth.BlockChain(), - gasFloor: gasFloor, - gasCeil: gasCeil, isLocalBlock: isLocalBlock, localUncles: make(map[common.Hash]*types.Block), remoteUncles: make(map[common.Hash]*types.Block), @@ -210,6 +207,7 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, worker.chainSideSub = eth.BlockChain().SubscribeChainSideEvent(worker.chainSideCh) // Sanitize recommit interval if the user-specified one is too short. + recommit := worker.config.Recommit if recommit < minRecommitInterval { log.Warn("Sanitizing miner recommit interval", "provided", recommit, "updated", minRecommitInterval) recommit = minRecommitInterval @@ -354,7 +352,7 @@ func (w *worker) newWorkLoop(recommit time.Duration) { case <-timer.C: // If mining is running resubmit a new work cycle periodically to pull in // higher priced transactions. Disable this overhead for pending blocks. - if w.isRunning() && (w.config.Clique == nil || w.config.Clique.Period > 0) { + if w.isRunning() && (w.chainConfig.Clique == nil || w.chainConfig.Clique.Period > 0) { // Short circuit if no new transaction arrives. if atomic.LoadInt32(&w.newTxs) == 0 { timer.Reset(recommit) @@ -468,9 +466,10 @@ func (w *worker) mainLoop() { w.commitTransactions(txset, coinbase, nil) w.updateSnapshot() } else { - // If we're mining, but nothing is being processed, wake on new transactions - if w.config.Clique != nil && w.config.Clique.Period == 0 { - w.commitNewWork(nil, false, time.Now().Unix()) + // If clique is running in dev mode(period is 0), disable + // advance sealing here. + if w.chainConfig.Clique != nil && w.chainConfig.Clique.Period == 0 { + w.commitNewWork(nil, true, time.Now().Unix()) } } atomic.AddInt32(&w.newTxs, int32(len(ev.Txs))) @@ -618,7 +617,7 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error { return err } env := &environment{ - signer: types.NewEIP155Signer(w.config.ChainID), + signer: types.NewEIP155Signer(w.chainConfig.ChainID), state: state, ancestors: mapset.NewSet(), family: mapset.NewSet(), @@ -696,7 +695,7 @@ func (w *worker) updateSnapshot() { func (w *worker) commitTransaction(tx *types.Transaction, coinbase common.Address) ([]*types.Log, error) { snap := w.current.state.Snapshot() - receipt, _, err := core.ApplyTransaction(w.config, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, *w.chain.GetVMConfig()) + receipt, _, err := core.ApplyTransaction(w.chainConfig, w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &w.current.header.GasUsed, *w.chain.GetVMConfig()) if err != nil { w.current.state.RevertToSnapshot(snap) return nil, err @@ -757,8 +756,8 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin from, _ := types.Sender(w.current.signer, tx) // Check whether the tx is replay protected. If we're not in the EIP155 hf // phase, start ignoring the sender until we do. - if tx.Protected() && !w.config.IsEIP155(w.current.header.Number) { - log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", w.config.EIP155Block) + if tx.Protected() && !w.chainConfig.IsEIP155(w.current.header.Number) { + log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", w.chainConfig.EIP155Block) txs.Pop() continue @@ -842,7 +841,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) header := &types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), - GasLimit: core.CalcGasLimit(parent, w.gasFloor, w.gasCeil), + GasLimit: core.CalcGasLimit(parent, w.config.GasFloor, w.config.GasCeil), Extra: w.extra, Time: uint64(timestamp), } @@ -859,12 +858,12 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) return } // If we are care about TheDAO hard-fork check whether to override the extra-data or not - if daoBlock := w.config.DAOForkBlock; daoBlock != nil { + if daoBlock := w.chainConfig.DAOForkBlock; daoBlock != nil { // Check whether the block is among the fork extra-override range limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 { // Depending whether we support or oppose the fork, override differently - if w.config.DAOForkSupport { + if w.chainConfig.DAOForkSupport { header.Extra = common.CopyBytes(params.DAOForkBlockExtra) } else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data @@ -879,7 +878,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) } // Create the current work task and check any fork transitions needed env := w.current - if w.config.DAOForkSupport && w.config.DAOForkBlock != nil && w.config.DAOForkBlock.Cmp(header.Number) == 0 { + if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(env.state) } // Accumulate the uncles for the current block diff --git a/miner/worker_test.go b/miner/worker_test.go index 99a671ae30..7fa9a5f984 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -52,6 +52,12 @@ var ( // Test transactions pendingTxs []*types.Transaction newTxs []*types.Transaction + + testConfig = &Config{ + Recommit: time.Second, + GasFloor: params.GenesisGasLimit, + GasCeil: params.GenesisGasLimit, + } ) func init() { @@ -134,7 +140,7 @@ func (b *testWorkerBackend) PostChainEvents(events []interface{}) { func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, blocks int) (*worker, *testWorkerBackend) { backend := newTestWorkerBackend(t, chainConfig, engine, blocks) backend.txPool.AddLocals(pendingTxs) - w := newWorker(chainConfig, engine, backend, new(event.TypeMux), time.Second, params.GenesisGasLimit, params.GenesisGasLimit, nil) + w := newWorker(testConfig, chainConfig, engine, backend, new(event.TypeMux), nil) w.setEtherbase(testBankAddress) return w, backend }