-
Notifications
You must be signed in to change notification settings - Fork 3
/
cuckoo.go
108 lines (91 loc) · 2.83 KB
/
cuckoo.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
99
100
101
102
103
104
105
106
107
108
// Copyright (c) 2020-2021 The bitcoinpay developers
// license that can be found in the LICENSE file.
// Reference resources of rust bitVector
package pow
import (
"encoding/binary"
"encoding/hex"
"github.com/btceasypay/bitcoinpay/common/hash"
"github.com/btceasypay/bitcoinpay/core/json"
"github.com/btceasypay/bitcoinpay/crypto/cuckoo"
"math/big"
)
type Cuckoo struct {
Pow
}
const (
PROOF_DATA_EDGE_BITS_START = 0
PROOF_DATA_EDGE_BITS_END = 1
PROOF_DATA_CIRCLE_NONCE_END = 169
)
func (this *Cuckoo) GetPowResult() json.PowResult {
return json.PowResult{
PowName: PowMapString[this.GetPowType()].(string),
PowType: uint8(this.GetPowType()),
Nonce: this.GetNonce(),
ProofData: &json.ProofData{
EdgeBits: int(this.ProofData[PROOF_DATA_EDGE_BITS_START:PROOF_DATA_EDGE_BITS_END][0]),
CircleNonces: hex.EncodeToString(this.ProofData[PROOF_DATA_EDGE_BITS_END:PROOF_DATA_CIRCLE_NONCE_END]),
},
}
}
// set edge bits
func (this *Cuckoo) SetEdgeBits(edge_bits uint8) {
copy(this.ProofData[PROOF_DATA_EDGE_BITS_START:PROOF_DATA_EDGE_BITS_END], []byte{edge_bits})
}
// get edge bits
func (this *Cuckoo) GetEdgeBits() uint8 {
return uint8(this.ProofData[PROOF_DATA_EDGE_BITS_START:PROOF_DATA_EDGE_BITS_END][0])
}
// set edge circles
func (this *Cuckoo) SetCircleEdges(edges []uint32) {
for i := 0; i < len(edges); i++ {
b := make([]byte, 4)
binary.LittleEndian.PutUint32(b, edges[i])
copy(this.ProofData[(i*4)+PROOF_DATA_EDGE_BITS_END:(i*4)+PROOF_DATA_EDGE_BITS_END+4], b)
}
}
func (this *Cuckoo) GetCircleNonces() (nonces [cuckoo.ProofSize]uint32) {
arr := ConvertBytesToUint32Array(this.ProofData[PROOF_DATA_EDGE_BITS_END:PROOF_DATA_CIRCLE_NONCE_END])
copy(nonces[:cuckoo.ProofSize], arr[:cuckoo.ProofSize])
return
}
func ConvertBytesToUint32Array(data []byte) []uint32 {
nonces := make([]uint32, 0)
j := 0
l := len(data)
for i := 0; i < l; i += 4 {
nonceBytes := data[i : i+4]
nonces = append(nonces, binary.LittleEndian.Uint32(nonceBytes))
j++
}
return nonces
}
//get sip hash
//first header data 113 bytes hash
func (this *Cuckoo) GetSipHash(headerData []byte) hash.Hash {
return hash.HashH(headerData[:len(headerData)-PROOF_DATA_CIRCLE_NONCE_END])
}
//cuckoo pow proof data
func (this *Cuckoo) Bytes() PowBytes {
r := make(PowBytes, 0)
//write nonce 4 bytes
n := make([]byte, 4)
binary.LittleEndian.PutUint32(n, this.Nonce)
r = append(r, n...)
//write pow type 1 byte
r = append(r, []byte{byte(this.PowType)}...)
//write ProofData 169 bytes
r = append(r, this.ProofData[:]...)
return PowBytes(r)
}
// compare the target
// wether target match the target diff
func (this *Cuckoo) CompareDiff(newTarget *big.Int, target *big.Int) bool {
return newTarget.Cmp(target) >= 0
}
// pow proof data
func (this *Cuckoo) BlockData() PowBytes {
return this.Bytes()
}
func (this *Cuckoo) GraphWeight() uint64 { return 0 }