Ori Newman 02d5fb29cf
Fix notifyVirtualSelectedParentBlueScoreChanged to show the selected tip blue score instead of the virtual's (#1309)
* Fix notifyVirtualSelectedParentBlueScoreChanged to show the selected tip blue score instead of the virtual's

* Fix ShouldMine() to fetch selected tip header
2020-12-29 12:07:05 +02:00

84 lines
2.6 KiB
Go

package flowcontext
import "github.com/kaspanet/kaspad/util/mstime"
const (
syncRateWindowInMilliSeconds = 60_000
syncRateMaxDeviation = 0.05
maxSelectedParentTimeDiffToAllowMiningInMilliSeconds = 300_000
)
func (f *FlowContext) updateRecentBlockAddedTimesWithLastBlock() {
f.recentBlockAddedTimesMutex.Lock()
defer f.recentBlockAddedTimesMutex.Unlock()
f.removeOldBlockTimes()
f.recentBlockAddedTimes = append(f.recentBlockAddedTimes, mstime.Now().UnixMilliseconds())
}
// removeOldBlockTimes removes from recentBlockAddedTimes block times
// older than syncRateWindowInMilliSeconds.
// This function is not safe for concurrent use.
func (f *FlowContext) removeOldBlockTimes() {
now := mstime.Now().UnixMilliseconds()
mostRecentBlockToKeep := 0
for i, blockAddedTime := range f.recentBlockAddedTimes {
if now-syncRateWindowInMilliSeconds < blockAddedTime {
mostRecentBlockToKeep = i
break
}
}
f.recentBlockAddedTimes = f.recentBlockAddedTimes[mostRecentBlockToKeep:]
}
func (f *FlowContext) isSyncRateBelowMinimum() bool {
f.recentBlockAddedTimesMutex.Lock()
defer f.recentBlockAddedTimesMutex.Unlock()
f.removeOldBlockTimes()
now := mstime.Now().UnixMilliseconds()
timeSinceStart := now - f.timeStarted
if timeSinceStart <= syncRateWindowInMilliSeconds {
return false
}
expectedBlocks := float64(syncRateWindowInMilliSeconds) / float64(f.cfg.NetParams().TargetTimePerBlock.Milliseconds())
return 1-float64(len(f.recentBlockAddedTimes))/expectedBlocks > syncRateMaxDeviation
}
// ShouldMine returns whether it's ok to use block template from this node
// for mining purposes.
func (f *FlowContext) ShouldMine() (bool, error) {
if f.isSyncRateBelowMinimum() {
log.Debugf("The sync rate is below the minimum, so ShouldMine returns true")
return true, nil
}
if f.IsIBDRunning() {
log.Debugf("IBD is running, so ShouldMine returns false")
return false, nil
}
virtualSelectedParent, err := f.domain.Consensus().GetVirtualSelectedParent()
if err != nil {
return false, err
}
virtualSelectedParentHeader, err := f.domain.Consensus().GetBlockHeader(virtualSelectedParent)
if err != nil {
return false, err
}
now := mstime.Now().UnixMilliseconds()
if now-virtualSelectedParentHeader.TimeInMilliseconds < maxSelectedParentTimeDiffToAllowMiningInMilliSeconds {
log.Debugf("The selected tip timestamp is recent (%d), so ShouldMine returns true",
virtualSelectedParentHeader.TimeInMilliseconds)
return true, nil
}
log.Debugf("The selected tip timestamp is old (%d), so ShouldMine returns false",
virtualSelectedParentHeader.TimeInMilliseconds)
return false, nil
}