-
Notifications
You must be signed in to change notification settings - Fork 2
/
hashrate.go
74 lines (62 loc) · 2.41 KB
/
hashrate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package difficultymanager
import (
"math/big"
"github.com/bugnanetwork/bugnad/domain/consensus/model"
"github.com/bugnanetwork/bugnad/domain/consensus/model/externalapi"
"github.com/bugnanetwork/bugnad/infrastructure/logger"
"github.com/pkg/errors"
)
func (dm *difficultyManager) EstimateNetworkHashesPerSecond(startHash *externalapi.DomainHash, windowSize int) (uint64, error) {
onEnd := logger.LogAndMeasureExecutionTime(log, "EstimateNetworkHashesPerSecond")
defer onEnd()
stagingArea := model.NewStagingArea()
return dm.estimateNetworkHashesPerSecond(stagingArea, startHash, windowSize)
}
func (dm *difficultyManager) estimateNetworkHashesPerSecond(stagingArea *model.StagingArea,
startHash *externalapi.DomainHash, windowSize int) (uint64, error) {
const minWindowSize = 1000
if windowSize < minWindowSize {
return 0, errors.Errorf("windowSize must be equal to or greater than %d", minWindowSize)
}
blockWindow, windowHashes, err := dm.blockWindow(stagingArea, startHash, windowSize)
if err != nil {
return 0, err
}
// return 0 if no blocks had been mined yet
if len(windowHashes) == 0 {
return 0, nil
}
minWindowTimestamp, maxWindowTimestamp, _ := blockWindow.minMaxTimestamps()
if minWindowTimestamp == maxWindowTimestamp {
return 0, errors.Errorf("min window timestamp is equal to the max window timestamp")
}
firstHash := windowHashes[0]
firstBlockGHOSTDAGData, err := dm.ghostdagStore.Get(dm.databaseContext, stagingArea, firstHash, false)
if err != nil {
return 0, err
}
firstBlockBlueWork := firstBlockGHOSTDAGData.BlueWork()
minWindowBlueWork := firstBlockBlueWork
maxWindowBlueWork := firstBlockBlueWork
for _, hash := range windowHashes[1:] {
blockGHOSTDAGData, err := dm.ghostdagStore.Get(dm.databaseContext, stagingArea, hash, false)
if err != nil {
return 0, err
}
blockBlueWork := blockGHOSTDAGData.BlueWork()
if blockBlueWork.Cmp(minWindowBlueWork) < 0 {
minWindowBlueWork = blockBlueWork
}
if blockBlueWork.Cmp(maxWindowBlueWork) > 0 {
maxWindowBlueWork = blockBlueWork
}
}
windowsDiff := (maxWindowTimestamp - minWindowTimestamp) / 1000 // Divided by 1000 to convert milliseconds to seconds
if windowsDiff == 0 {
return 0, nil
}
nominator := new(big.Int).Sub(maxWindowBlueWork, minWindowBlueWork)
denominator := big.NewInt(windowsDiff)
networkHashesPerSecondBigInt := new(big.Int).Div(nominator, denominator)
return networkHashesPerSecondBigInt.Uint64(), nil
}