github.com/ethereum/go-ethereum@v1.16.1/miner/miner.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package miner implements Ethereum block creation and mining. 18 package miner 19 20 import ( 21 "fmt" 22 "math/big" 23 "sync" 24 "time" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/common/hexutil" 28 "github.com/ethereum/go-ethereum/consensus" 29 "github.com/ethereum/go-ethereum/core" 30 "github.com/ethereum/go-ethereum/core/state" 31 "github.com/ethereum/go-ethereum/core/txpool" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/params" 34 ) 35 36 // Backend wraps all methods required for mining. Only full node is capable 37 // to offer all the functions here. 38 type Backend interface { 39 BlockChain() *core.BlockChain 40 TxPool() *txpool.TxPool 41 } 42 43 // Config is the configuration parameters of mining. 44 type Config struct { 45 Etherbase common.Address `toml:"-"` // Deprecated 46 PendingFeeRecipient common.Address `toml:"-"` // Address for pending block rewards. 47 ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner 48 GasCeil uint64 // Target gas ceiling for mined blocks. 49 GasPrice *big.Int // Minimum gas price for mining a transaction 50 Recommit time.Duration // The time interval for miner to re-create mining work. 51 } 52 53 // DefaultConfig contains default settings for miner. 54 var DefaultConfig = Config{ 55 GasCeil: 45_000_000, 56 GasPrice: big.NewInt(params.GWei / 1000), 57 58 // The default recommit time is chosen as two seconds since 59 // consensus-layer usually will wait a half slot of time(6s) 60 // for payload generation. It should be enough for Geth to 61 // run 3 rounds. 62 Recommit: 2 * time.Second, 63 } 64 65 // Miner is the main object which takes care of submitting new work to consensus 66 // engine and gathering the sealing result. 67 type Miner struct { 68 confMu sync.RWMutex // The lock used to protect the config fields: GasCeil, GasTip and Extradata 69 config *Config 70 chainConfig *params.ChainConfig 71 engine consensus.Engine 72 txpool *txpool.TxPool 73 prio []common.Address // A list of senders to prioritize 74 chain *core.BlockChain 75 pending *pending 76 pendingMu sync.Mutex // Lock protects the pending block 77 } 78 79 // New creates a new miner with provided config. 80 func New(eth Backend, config Config, engine consensus.Engine) *Miner { 81 return &Miner{ 82 config: &config, 83 chainConfig: eth.BlockChain().Config(), 84 engine: engine, 85 txpool: eth.TxPool(), 86 chain: eth.BlockChain(), 87 pending: &pending{}, 88 } 89 } 90 91 // Pending returns the currently pending block and associated receipts, logs 92 // and statedb. The returned values can be nil in case the pending block is 93 // not initialized. 94 func (miner *Miner) Pending() (*types.Block, types.Receipts, *state.StateDB) { 95 pending := miner.getPending() 96 if pending == nil { 97 return nil, nil, nil 98 } 99 return pending.block, pending.receipts, pending.stateDB.Copy() 100 } 101 102 // SetExtra sets the content used to initialize the block extra field. 103 func (miner *Miner) SetExtra(extra []byte) error { 104 if uint64(len(extra)) > params.MaximumExtraDataSize { 105 return fmt.Errorf("extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) 106 } 107 miner.confMu.Lock() 108 miner.config.ExtraData = extra 109 miner.confMu.Unlock() 110 return nil 111 } 112 113 // SetPrioAddresses sets a list of addresses to prioritize for transaction inclusion. 114 func (miner *Miner) SetPrioAddresses(prio []common.Address) { 115 miner.confMu.Lock() 116 miner.prio = prio 117 miner.confMu.Unlock() 118 } 119 120 // SetGasCeil sets the gaslimit to strive for when mining blocks post 1559. 121 // For pre-1559 blocks, it sets the ceiling. 122 func (miner *Miner) SetGasCeil(ceil uint64) { 123 miner.confMu.Lock() 124 miner.config.GasCeil = ceil 125 miner.confMu.Unlock() 126 } 127 128 // SetGasTip sets the minimum gas tip for inclusion. 129 func (miner *Miner) SetGasTip(tip *big.Int) error { 130 miner.confMu.Lock() 131 miner.config.GasPrice = tip 132 miner.confMu.Unlock() 133 return nil 134 } 135 136 // BuildPayload builds the payload according to the provided parameters. 137 func (miner *Miner) BuildPayload(args *BuildPayloadArgs, witness bool) (*Payload, error) { 138 return miner.buildPayload(args, witness) 139 } 140 141 // getPending retrieves the pending block based on the current head block. 142 // The result might be nil if pending generation is failed. 143 func (miner *Miner) getPending() *newPayloadResult { 144 header := miner.chain.CurrentHeader() 145 miner.pendingMu.Lock() 146 defer miner.pendingMu.Unlock() 147 if cached := miner.pending.resolve(header.Hash()); cached != nil { 148 return cached 149 } 150 151 var ( 152 timestamp = uint64(time.Now().Unix()) 153 withdrawal types.Withdrawals 154 ) 155 if miner.chainConfig.IsShanghai(new(big.Int).Add(header.Number, big.NewInt(1)), timestamp) { 156 withdrawal = []*types.Withdrawal{} 157 } 158 ret := miner.generateWork(&generateParams{ 159 timestamp: timestamp, 160 forceTime: false, 161 parentHash: header.Hash(), 162 coinbase: miner.config.PendingFeeRecipient, 163 random: common.Hash{}, 164 withdrawals: withdrawal, 165 beaconRoot: nil, 166 noTxs: false, 167 }, false) // we will never make a witness for a pending block 168 if ret.err != nil { 169 return nil 170 } 171 miner.pending.update(header.Hash(), ret) 172 return ret 173 }