diff --git a/cmd/kaspaminer/mineloop.go b/cmd/kaspaminer/mineloop.go index ebba8a187..47441ac3a 100644 --- a/cmd/kaspaminer/mineloop.go +++ b/cmd/kaspaminer/mineloop.go @@ -2,7 +2,9 @@ package main import ( nativeerrors "errors" + "fmt" "math/rand" + "runtime" "sync/atomic" "time" @@ -38,37 +40,40 @@ func mineLoop(client *minerClient, numberOfBlocks uint64, targetBlocksPerSecond templatesLoop(client, miningAddr, errChan) }) - spawn("blocksLoop", func() { - const windowSize = 10 - hasBlockRateTarget := targetBlocksPerSecond != 0 - var windowTicker, blockTicker *time.Ticker - // We use tickers to limit the block rate: - // 1. windowTicker -> makes sure that the last windowSize blocks take at least windowSize*targetBlocksPerSecond. - // 2. blockTicker -> makes sure that each block takes at least targetBlocksPerSecond/windowSize. - // that way we both allow for fluctuation in block rate but also make sure they're not too big (by an order of magnitude) - if hasBlockRateTarget { - windowRate := time.Duration(float64(time.Second) / (targetBlocksPerSecond / windowSize)) - blockRate := time.Duration(float64(time.Second) / (targetBlocksPerSecond * windowSize)) - log.Infof("Minimum average time per %d blocks: %s, smaller minimum time per block: %s", windowSize, windowRate, blockRate) - windowTicker = time.NewTicker(windowRate) - blockTicker = time.NewTicker(blockRate) - defer windowTicker.Stop() - defer blockTicker.Stop() - } - windowStart := time.Now() - for blockIndex := 1; ; blockIndex++ { - foundBlockChan <- mineNextBlock(mineWhenNotSynced) + for c := 0; c < (runtime.NumCPU()/2)+1; c++ { + c := c + spawn(fmt.Sprintf("blocksLoop %d", c), func() { + const windowSize = 10 + hasBlockRateTarget := targetBlocksPerSecond != 0 + var windowTicker, blockTicker *time.Ticker + // We use tickers to limit the block rate: + // 1. windowTicker -> makes sure that the last windowSize blocks take at least windowSize*targetBlocksPerSecond. + // 2. blockTicker -> makes sure that each block takes at least targetBlocksPerSecond/windowSize. + // that way we both allow for fluctuation in block rate but also make sure they're not too big (by an order of magnitude) if hasBlockRateTarget { - <-blockTicker.C - if (blockIndex % windowSize) == 0 { - tickerStart := time.Now() - <-windowTicker.C - log.Infof("Finished mining %d blocks in: %s. slept for: %s", windowSize, time.Since(windowStart), time.Since(tickerStart)) - windowStart = time.Now() + windowRate := time.Duration(float64(time.Second) / (targetBlocksPerSecond / windowSize)) + blockRate := time.Duration(float64(time.Second) / (targetBlocksPerSecond * windowSize)) + log.Infof("Minimum average time per %d blocks: %s, smaller minimum time per block: %s", windowSize, windowRate, blockRate) + windowTicker = time.NewTicker(windowRate) + blockTicker = time.NewTicker(blockRate) + defer windowTicker.Stop() + defer blockTicker.Stop() + } + windowStart := time.Now() + for blockIndex := 1; ; blockIndex++ { + foundBlockChan <- mineNextBlock(mineWhenNotSynced) + if hasBlockRateTarget { + <-blockTicker.C + if (blockIndex % windowSize) == 0 { + tickerStart := time.Now() + <-windowTicker.C + log.Infof("Finished mining %d blocks in: %s. slept for: %s", windowSize, time.Since(windowStart), time.Since(tickerStart)) + windowStart = time.Now() + } } } - } - }) + }) + } spawn("handleFoundBlock", func() { for i := uint64(0); numberOfBlocks == 0 || i < numberOfBlocks; i++ {