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.
This commit is contained in:
gary rong
2019-04-23 15:08:51 +08:00
committed by Péter Szilágyi
parent d9403690ec
commit 6269e5574c
11 changed files with 162 additions and 162 deletions

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}