This repository has been archived by the owner on Jun 18, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mine.go
144 lines (121 loc) · 3.32 KB
/
mine.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package OracleMiner
import (
"github.com/FactomProject/factomd/common/primitives/random"
"github.com/pegnet/LXR256"
)
type hashFunction func([]byte) []byte
var lx lxr.LXRHash
func init() {
lx.Init(0x123412341234, 10240000, 256, 5)
}
type Mine struct {
MinerNum int // When running many miners, the number of the miner that is this one.
started bool // We are mining
Dbht int32 // Height that we are mining at
Response chan int // Returns 0 when the MinerNumber stops
Control chan int // sending any int to the Mine will stop mining
OPR []byte // The oracle Record that we were mining
OprHash []byte // The hash of the oracle record
BestDifficulty uint64 // Highest Difference Found
BestNonce []byte // The Nonce that produced the bestDifference
BestHash []byte // The best hash we found (to check the Best Difficulty against)
Hashcnt int // Count of hash rounds performed.
HashFunction hashFunction // The Hash function we will be using to mine
}
func (m *Mine) Init() {
m.BestDifficulty = 0
m.Hashcnt = 0
m.Response = make(chan int, 10)
m.Control = make(chan int, 10)
m.OPR = m.OPR[:0]
m.OprHash = m.OPR[:0]
m.BestNonce = m.OPR[:0]
m.BestHash = m.OPR[:0]
// create an LXRHash function for the Lookup XoR hash.
m.HashFunction = func(src []byte) []byte {
return lx.Hash(src)
}
}
// Start mining on a given OPR
func (m *Mine) Start(opr []byte) {
// Make sure the MinerNumber is stopped.
if m.started {
m.Stop()
m.started = false
}
m.Init()
m.started = true
go m.Mine(opr)
}
func (m *Mine) Stop() {
// Only stop a running MinerNumber
if m.started {
// Signal the mining process to stop
m.Control <- 0
// Wait for it to stop
<-m.Response
// Clear the response channel to indicate the MinerNumber is stopped.
m.started = false
}
}
// Create a nonce of eight bytes of zeros followed by 24 bytes of random values
func GetFirstNonce() []byte {
// Start with 8 bytes of zero
nonce := []byte{0, 0, 0, 0, 0, 0, 0, 0}
// Pick a random number to fill out our nonce (don't collide with other miners if in a pool)
nonce = append(nonce, random.RandByteSliceOfLen(24)...)
return nonce
}
// Mine a given Oracle Price Record (OPR)
func (m *Mine) Mine(opr []byte) {
m.OPR = opr
m.OprHash = m.HashFunction(opr)
m.Hashcnt = 0
// Clear out some variables in case the Mine struct is being reused
m.BestDifficulty = 0
m.BestNonce = []byte{}
m.BestHash = []byte{}
// Put my nonce and Opr together... We hash them both
nonceOpr := GetFirstNonce()
nonceOpr = append(nonceOpr, m.OprHash...)
for {
// The process ends when signaled.
select {
case <-m.Control:
m.Response <- 0
return
default:
}
// Increment my nonce
for i := 0; ; i++ {
nonceOpr[i] += 1
if nonceOpr[i] != 0 {
break
}
}
m.Hashcnt++
try := m.HashFunction(nonceOpr)
d := lxr.Difficulty(try)
if d == 0 {
continue
}
if m.BestDifficulty == 0 || m.BestDifficulty > d {
m.BestDifficulty = d
m.BestNonce = append(m.BestNonce[:0], nonceOpr[:32]...)
m.BestHash = append(m.BestHash[:0], try...)
}
}
}
const (
startofblock = iota
blocktime
minute8
faulting
)
type FactomEvent struct {
Type int
Value int
Msg string
}
func (m *Mine) Events(event chan FactomEvent) {
}