Parallel miner

This commit is contained in:
Kaspa Profiler 2021-04-13 12:48:22 +03:00 committed by stasatdaglabs
parent bbdf7b246d
commit c46503ea7e

View File

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