github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/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: 30_000_000, 56 GasPrice: big.NewInt(params.GWei), 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 chain *core.BlockChain 74 pending *pending 75 pendingMu sync.Mutex // Lock protects the pending block 76 } 77 78 // New creates a new miner with provided config. 79 func New(eth Backend, config Config, engine consensus.Engine) *Miner { 80 return &Miner{ 81 config: &config, 82 chainConfig: eth.BlockChain().Config(), 83 engine: engine, 84 txpool: eth.TxPool(), 85 chain: eth.BlockChain(), 86 pending: &pending{}, 87 } 88 } 89 90 // Pending returns the currently pending block and associated receipts, logs 91 // and statedb. The returned values can be nil in case the pending block is 92 // not initialized. 93 func (miner *Miner) Pending() (*types.Block, types.Receipts, *state.StateDB) { 94 pending := miner.getPending() 95 if pending == nil { 96 return nil, nil, nil 97 } 98 return pending.block, pending.receipts, pending.stateDB.Copy() 99 } 100 101 // SetExtra sets the content used to initialize the block extra field. 102 func (miner *Miner) SetExtra(extra []byte) error { 103 if uint64(len(extra)) > params.MaximumExtraDataSize { 104 return fmt.Errorf("extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) 105 } 106 miner.confMu.Lock() 107 miner.config.ExtraData = extra 108 miner.confMu.Unlock() 109 return nil 110 } 111 112 // SetGasCeil sets the gaslimit to strive for when mining blocks post 1559. 113 // For pre-1559 blocks, it sets the ceiling. 114 func (miner *Miner) SetGasCeil(ceil uint64) { 115 miner.confMu.Lock() 116 miner.config.GasCeil = ceil 117 miner.confMu.Unlock() 118 } 119 120 // SetGasTip sets the minimum gas tip for inclusion. 121 func (miner *Miner) SetGasTip(tip *big.Int) error { 122 miner.confMu.Lock() 123 miner.config.GasPrice = tip 124 miner.confMu.Unlock() 125 return nil 126 } 127 128 // BuildPayload builds the payload according to the provided parameters. 129 func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) { 130 return miner.buildPayload(args) 131 } 132 133 // getPending retrieves the pending block based on the current head block. 134 // The result might be nil if pending generation is failed. 135 func (miner *Miner) getPending() *newPayloadResult { 136 header := miner.chain.CurrentHeader() 137 miner.pendingMu.Lock() 138 defer miner.pendingMu.Unlock() 139 if cached := miner.pending.resolve(header.Hash()); cached != nil { 140 return cached 141 } 142 143 var ( 144 timestamp = uint64(time.Now().Unix()) 145 withdrawal types.Withdrawals 146 ) 147 if miner.chainConfig.IsShanghai(new(big.Int).Add(header.Number, big.NewInt(1)), timestamp) { 148 withdrawal = []*types.Withdrawal{} 149 } 150 ret := miner.generateWork(&generateParams{ 151 timestamp: timestamp, 152 forceTime: false, 153 parentHash: header.Hash(), 154 coinbase: miner.config.PendingFeeRecipient, 155 random: common.Hash{}, 156 withdrawals: withdrawal, 157 beaconRoot: nil, 158 noTxs: false, 159 }) 160 if ret.err != nil { 161 return nil 162 } 163 miner.pending.update(header.Hash(), ret) 164 return ret 165 }