github.com/theQRL/go-zond@v0.2.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 Zond block creation and mining. 18 package miner 19 20 import ( 21 "fmt" 22 "math/big" 23 "sync" 24 "time" 25 26 "github.com/theQRL/go-zond/common" 27 "github.com/theQRL/go-zond/common/hexutil" 28 "github.com/theQRL/go-zond/consensus" 29 "github.com/theQRL/go-zond/core" 30 "github.com/theQRL/go-zond/core/state" 31 "github.com/theQRL/go-zond/core/txpool" 32 "github.com/theQRL/go-zond/core/types" 33 "github.com/theQRL/go-zond/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 PendingFeeRecipient common.Address `toml:"-"` // Address for pending block rewards. 46 ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner 47 GasCeil uint64 // Target gas ceiling for mined blocks. 48 GasPrice *big.Int // Minimum gas price for mining a transaction 49 Recommit time.Duration // The time interval for miner to re-create mining work. 50 } 51 52 // DefaultConfig contains default settings for miner. 53 var DefaultConfig = Config{ 54 GasCeil: params.MaxGasLimit, 55 GasPrice: big.NewInt(params.GWei), 56 57 // The default recommit time is chosen as two seconds since 58 // consensus-layer usually will wait a half slot of time(30s) 59 // for payload generation. It should be enough for Gzond to 60 // run 3 rounds. 61 Recommit: 10 * time.Second, 62 } 63 64 // Miner is the main object which takes care of submitting new work to consensus 65 // engine and gathering the sealing result. 66 type Miner struct { 67 confMu sync.RWMutex // The lock used to protect the config fields: GasCeil, GasTip and Extradata 68 config *Config 69 chainConfig *params.ChainConfig 70 engine consensus.Engine 71 txpool *txpool.TxPool 72 chain *core.BlockChain 73 pending *pending 74 pendingMu sync.Mutex // Lock protects the pending block 75 } 76 77 // New creates a new miner with provided config. 78 func New(zond Backend, config Config, engine consensus.Engine) *Miner { 79 return &Miner{ 80 config: &config, 81 chainConfig: zond.BlockChain().Config(), 82 engine: engine, 83 txpool: zond.TxPool(), 84 chain: zond.BlockChain(), 85 pending: &pending{}, 86 } 87 } 88 89 // Pending returns the currently pending block and associated receipts, logs 90 // and statedb. The returned values can be nil in case the pending block is 91 // not initialized. 92 func (miner *Miner) Pending() (*types.Block, types.Receipts, *state.StateDB) { 93 pending := miner.getPending() 94 if pending == nil { 95 return nil, nil, nil 96 } 97 return pending.block, pending.receipts, pending.stateDB.Copy() 98 } 99 100 // SetExtra sets the content used to initialize the block extra field. 101 func (miner *Miner) SetExtra(extra []byte) error { 102 if uint64(len(extra)) > params.MaximumExtraDataSize { 103 return fmt.Errorf("extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) 104 } 105 miner.confMu.Lock() 106 miner.config.ExtraData = extra 107 miner.confMu.Unlock() 108 return nil 109 } 110 111 // SetGasCeil sets the gaslimit to strive for when mining blocks post 1559. 112 // For pre-1559 blocks, it sets the ceiling. 113 func (miner *Miner) SetGasCeil(ceil uint64) { 114 miner.confMu.Lock() 115 miner.config.GasCeil = ceil 116 miner.confMu.Unlock() 117 } 118 119 // SetGasTip sets the minimum gas tip for inclusion. 120 func (miner *Miner) SetGasTip(tip *big.Int) error { 121 miner.confMu.Lock() 122 miner.config.GasPrice = tip 123 miner.confMu.Unlock() 124 return nil 125 } 126 127 // BuildPayload builds the payload according to the provided parameters. 128 func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) { 129 return miner.buildPayload(args) 130 } 131 132 // getPending retrieves the pending block based on the current head block. 133 // The result might be nil if pending generation is failed. 134 func (miner *Miner) getPending() *newPayloadResult { 135 header := miner.chain.CurrentHeader() 136 miner.pendingMu.Lock() 137 defer miner.pendingMu.Unlock() 138 if cached := miner.pending.resolve(header.Hash()); cached != nil { 139 return cached 140 } 141 142 ret := miner.generateWork(&generateParams{ 143 timestamp: uint64(time.Now().Unix()), 144 forceTime: false, 145 parentHash: header.Hash(), 146 coinbase: miner.config.PendingFeeRecipient, 147 random: common.Hash{}, 148 withdrawals: []*types.Withdrawal{}, 149 noTxs: false, 150 }) 151 if ret.err != nil { 152 return nil 153 } 154 miner.pending.update(header.Hash(), ret) 155 return ret 156 }