aboutsummaryrefslogtreecommitdiffstats
path: root/eth/backend.go
diff options
context:
space:
mode:
Diffstat (limited to 'eth/backend.go')
-rw-r--r--eth/backend.go76
1 files changed, 58 insertions, 18 deletions
diff --git a/eth/backend.go b/eth/backend.go
index 648175acf..c530d3c7c 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -102,12 +102,18 @@ func (s *Ethereum) AddLesServer(ls LesServer) {
// New creates a new Ethereum object (including the
// initialisation of the common Ethereum object)
func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
+ // Ensure configuration values are compatible and sane
if config.SyncMode == downloader.LightSync {
return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum")
}
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)
+ }
+ // Assemble the Ethereum object
chainDb, err := CreateDB(ctx, config, "chaindata")
if err != nil {
return nil, err
@@ -333,32 +339,66 @@ func (s *Ethereum) SetEtherbase(etherbase common.Address) {
s.miner.SetEtherbase(etherbase)
}
-func (s *Ethereum) StartMining(local bool) error {
- eb, err := s.Etherbase()
- if err != nil {
- log.Error("Cannot start mining without etherbase", "err", err)
- return fmt.Errorf("etherbase missing: %v", err)
+// StartMining starts the miner with the given number of CPU threads. If mining
+// is already running, this method adjust the number of threads allowed to use
+// and updates the minimum price required by the transaction pool.
+func (s *Ethereum) StartMining(threads int) error {
+ // Update the thread count within the consensus engine
+ type threaded interface {
+ SetThreads(threads int)
}
- if clique, ok := s.engine.(*clique.Clique); ok {
- wallet, err := s.accountManager.Find(accounts.Account{Address: eb})
- if wallet == nil || err != nil {
- log.Error("Etherbase account unavailable locally", "err", err)
- return fmt.Errorf("signer missing: %v", err)
+ if th, ok := s.engine.(threaded); ok {
+ log.Info("Updated mining threads", "threads", threads)
+ if threads == 0 {
+ threads = -1 // Disable the miner from within
}
- clique.Authorize(eb, wallet.SignHash)
+ th.SetThreads(threads)
}
- if local {
- // If local (CPU) mining is started, we can disable the transaction rejection
- // mechanism introduced to speed sync times. CPU mining on mainnet is ludicrous
- // so none will ever hit this path, whereas marking sync done on CPU mining
- // will ensure that private networks work in single miner mode too.
+ // If the miner was not running, initialize it
+ if !s.IsMining() {
+ // Propagate the initial price point to the transaction pool
+ s.lock.RLock()
+ price := s.gasPrice
+ s.lock.RUnlock()
+ s.txPool.SetGasPrice(price)
+
+ // Configure the local mining addess
+ eb, err := s.Etherbase()
+ if err != nil {
+ log.Error("Cannot start mining without etherbase", "err", err)
+ return fmt.Errorf("etherbase missing: %v", err)
+ }
+ if clique, ok := s.engine.(*clique.Clique); ok {
+ wallet, err := s.accountManager.Find(accounts.Account{Address: eb})
+ if wallet == nil || err != nil {
+ log.Error("Etherbase account unavailable locally", "err", err)
+ return fmt.Errorf("signer missing: %v", err)
+ }
+ clique.Authorize(eb, wallet.SignHash)
+ }
+ // If mining is started, we can disable the transaction rejection mechanism
+ // introduced to speed sync times.
atomic.StoreUint32(&s.protocolManager.acceptTxs, 1)
+
+ go s.miner.Start(eb)
}
- go s.miner.Start(eb)
return nil
}
-func (s *Ethereum) StopMining() { s.miner.Stop() }
+// StopMining terminates the miner, both at the consensus engine level as well as
+// at the block creation level.
+func (s *Ethereum) StopMining() {
+ // Update the thread count within the consensus engine
+ type threaded interface {
+ SetThreads(threads int)
+ }
+ if th, ok := s.engine.(threaded); ok {
+ th.SetThreads(-1)
+ }
+ // Stop the block creating itself
+ s.miner.Stop()
+}
+
func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
func (s *Ethereum) Miner() *miner.Miner { return s.miner }