diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index aa5b2d8a02..d284e7b00b 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -555,11 +555,18 @@ func (ethash *Ethash) Threads() int { // SetThreads updates the number of mining threads currently enabled. Calling // this method does not start mining, only sets the thread count. If zero is -// specified, the miner will use all cores of the machine. +// specified, the miner will use all cores of the machine. Setting a thread +// count below zero is allowed and will cause the miner to idle, without any +// work being done. func (ethash *Ethash) SetThreads(threads int) { ethash.lock.Lock() defer ethash.lock.Unlock() + // If we're running a shared PoW, set the thread count on that instead + if ethash.shared != nil { + ethash.shared.SetThreads(threads) + return + } // Update the threads and ping any running seal to pull in any changes ethash.threads = threads select { diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go index 9a000ed316..784e8f6491 100644 --- a/consensus/ethash/sealer.go +++ b/consensus/ethash/sealer.go @@ -61,6 +61,9 @@ func (ethash *Ethash) Seal(chain consensus.ChainReader, block *types.Block, stop if threads == 0 { threads = runtime.NumCPU() } + if threads < 0 { + threads = 0 // Allows disabling local mining without extra logic around local/remote + } var pend sync.WaitGroup for i := 0; i < threads; i++ { pend.Add(1) diff --git a/eth/api.go b/eth/api.go index 041ccd397e..9470705159 100644 --- a/eth/api.go +++ b/eth/api.go @@ -139,16 +139,17 @@ func NewPrivateMinerAPI(e *Ethereum) *PrivateMinerAPI { // threads allowed to use. func (api *PrivateMinerAPI) Start(threads *int) error { // Set the number of threads if the seal engine supports it - if threads != nil { - type threaded interface { - SetThreads(threads int) - } - if th, ok := api.e.engine.(threaded); ok { - log.Info("Updated mining threads", "threads", *threads) - th.SetThreads(*threads) - } else { - log.Warn("Current seal engine isn't threaded") - } + if threads == nil { + threads = new(int) + } else if *threads == 0 { + *threads = -1 // Disable the miner from within + } + type threaded interface { + SetThreads(threads int) + } + if th, ok := api.e.engine.(threaded); ok { + log.Info("Updated mining threads", "threads", *threads) + th.SetThreads(*threads) } // Start the miner and return if !api.e.IsMining() { @@ -159,6 +160,12 @@ func (api *PrivateMinerAPI) Start(threads *int) error { // Stop the miner func (api *PrivateMinerAPI) Stop() bool { + type threaded interface { + SetThreads(threads int) + } + if th, ok := api.e.engine.(threaded); ok { + th.SetThreads(-1) + } api.e.StopMining() return true } diff --git a/eth/backend.go b/eth/backend.go index f241d5f34f..df5460201f 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -240,8 +240,10 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - return ethash.New(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk, + engine := ethash.New(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk, config.EthashDatasetDir, config.EthashDatasetsInMem, config.EthashDatasetsOnDisk) + engine.SetThreads(-1) // Disable CPU mining + return engine } }