-
Notifications
You must be signed in to change notification settings - Fork 16
/
cuckatoo.go
98 lines (90 loc) · 3.6 KB
/
cuckatoo.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Copyright (c) 2017-2020 The qitmeer developers
// license that can be found in the LICENSE file.
// Reference resources of rust bitVector
package pow
import (
"errors"
"fmt"
"github.com/Qitmeer/qng/common/hash"
"github.com/Qitmeer/qng/crypto/cuckoo"
"github.com/Qitmeer/qng/log"
"math/big"
)
type Cuckatoo struct {
Cuckoo
}
const MIN_CUCKATOOEDGEBITS = 29
const MAX_CUCKATOOEDGEBITS = 32
func (this *Cuckatoo) Verify(headerData []byte, blockHash hash.Hash, targetDiffBits uint32) error {
targetDiff := CompactToBig(targetDiffBits)
baseDiff := CompactToBig(this.params.CuckarooMinDifficulty)
h := this.GetSipHash(headerData)
nonces := this.GetCircleNonces()
edgeBits := this.GetEdgeBits()
if edgeBits < MIN_CUCKATOOEDGEBITS {
return fmt.Errorf("edge bits:%d is too short!less than %d", edgeBits, MIN_CUCKATOOEDGEBITS)
}
if edgeBits > MAX_CUCKATOOEDGEBITS {
return fmt.Errorf("edge bits:%d is too large! more than %d", edgeBits, MAX_CUCKATOOEDGEBITS)
}
err := cuckoo.VerifyCuckatoo(h[:], nonces[:], uint(edgeBits))
if err != nil {
log.Debug("Verify Error!", err)
return err
}
//The target difficulty must be more than the min diff.
if targetDiff.Cmp(baseDiff) < 0 {
str := fmt.Sprintf("block target difficulty of %d is "+
"less than min diff :%d", targetDiff, this.params.CuckarooMinDifficulty)
return errors.New(str)
}
if CalcCuckooDiff(this.GraphWeight(), blockHash).Cmp(targetDiff) < 0 {
return errors.New("difficulty is too easy!")
}
return nil
}
func (this *Cuckatoo) GetNextDiffBig(weightedSumDiv *big.Int, oldDiffBig *big.Int, currentPowPercent *big.Int) *big.Int {
oldDiffBig.Lsh(oldDiffBig, 32)
nextDiffBig := oldDiffBig.Div(oldDiffBig, weightedSumDiv)
targetPercent := this.PowPercent()
if targetPercent.Cmp(big.NewInt(0)) <= 0 {
return nextDiffBig
}
currentPowPercent.Mul(currentPowPercent, big.NewInt(100))
nextDiffBig.Mul(nextDiffBig, currentPowPercent)
nextDiffBig.Div(nextDiffBig, targetPercent)
return nextDiffBig
}
func (this *Cuckatoo) GetSafeDiff(cur_reduce_diff uint64) *big.Int {
minDiffBig := CompactToBig(this.params.CuckatooMinDifficulty)
if cur_reduce_diff <= 0 {
return minDiffBig
}
newTarget := &big.Int{}
newTarget = newTarget.SetUint64(cur_reduce_diff)
// Limit new value to the proof of work limit.
if newTarget.Cmp(minDiffBig) < 0 {
newTarget.Set(minDiffBig)
}
return newTarget
}
//calc scale
//the edge_bits is bigger ,then scale is bigger
//Reference resources https://eprint.iacr.org/2014/059.pdf 9. Difficulty control page 6
//while the average number of cycles found increases slowly with size; from 2 at 2^20 to 3 at 2^30
//Less times of hash calculation with the same difficulty
// 24 => 48 25 => 100 26 => 208 27 => 432 28 => 896 29 => 1856 30 => 3840 31 => 7936
//assume init difficulty is 1000
//24 target is 0c49ba5e353f7ced000000000000000000000000000000000000000000000000
//(The meaning of difficulty needs to be found 1000/48 * 50 ≈ 1000 times in edge_bits 24, and the answer may be obtained once.)
// why * 50 , because the when edge_count/nodes = 1/2,to find 42 cycles the probality is 2.2%
//29 target is db22d0e560418937000000000000000000000000000000000000000000000000
//(The difficulty needs to be found 1000/1856 * 50 ≈ 26 times in edge_bits 29, and the answer may be obtained once.)
//so In order to ensure the fairness of different edge indexes, the mining difficulty is different.
func (this *Cuckatoo) GraphWeight() uint64 {
return (2 << (this.GetEdgeBits() - MIN_CUCKAROOEDGEBITS)) * uint64(this.GetEdgeBits())
}
//not support
func (this *Cuckatoo) FindSolver(headerData []byte, blockHash hash.Hash, targetDiffBits uint32) bool {
return false
}