-
Notifications
You must be signed in to change notification settings - Fork 48
/
sealer_miner.go
102 lines (90 loc) · 2.5 KB
/
sealer_miner.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
// +build !disable_miner
package cuckoo
import (
"github.com/CortexFoundation/CortexTheseus/core/types"
"github.com/CortexFoundation/CortexTheseus/log"
"math/big"
)
func (cuckoo *Cuckoo) Mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) (err error) {
err = cuckoo.InitOnce()
if err != nil {
log.Error("cuckoo", "init error", "error:", err)
return err
}
var (
header = block.Header()
hash = cuckoo.SealHash(header).Bytes()
target = new(big.Int).Div(maxUint256, header.Difficulty)
result types.BlockSolution
)
var (
attempts = int32(0)
nonce = seed
)
logger := log.New("miner", id)
logger.Trace("Started cuckoo search for new solution", "seed", seed)
search:
for {
select {
case errc := <-cuckoo.exitCh:
errc <- nil
break search
case <-abort:
//Mining terminated, update stats and abort
logger.Trace("Cuckoo solution search aborted", "attempts", nonce-seed)
cuckoo.hashrate.Mark(int64(attempts))
break search
default:
attempts++
if attempts%(1<<15) == 0 {
cuckoo.hashrate.Mark(int64(attempts))
attempts = 0
}
m, err := cuckoo.minerPlugin.Lookup("CuckooFindSolutions")
if err != nil {
return err
}
r, res := m.(func([]byte, uint64) (uint32, [][]uint32))(hash, nonce)
if r == 0 {
nonce++
continue
}
copy(result[:], res[0][0:len(res[0])])
m, err = cuckoo.minerPlugin.Lookup("CuckooVerify_cuckaroo")
if err != nil {
return err
}
ret := m.(func(*byte, uint64, types.BlockSolution, []byte, *big.Int) bool)(&hash[0], nonce, result, cuckoo.Sha3Solution(&result), target)
if ret {
// Correct solution found, create a new header with it
header = types.CopyHeader(header)
header.Nonce = types.EncodeNonce(uint64(nonce))
header.Solution = result
select {
case found <- block.WithSeal(header):
logger.Trace("Cuckoo solution found and reported", "attempts", nonce-seed, "nonce", nonce)
case <-abort:
logger.Trace("Cuckoo solution found but discarded", "attempts", nonce-seed, "nonce", nonce)
}
break search
}
nonce++
}
}
return nil
}
func (cuckoo *Cuckoo) SetThreads(threads int) {
cuckoo.lock.Lock()
defer cuckoo.lock.Unlock()
// If we're running a shared PoW, set the thread count on that instead
if cuckoo.shared != nil {
cuckoo.shared.SetThreads(threads)
return
}
// Update the threads and ping any running seal to pull in any changes
cuckoo.threads = threads
select {
case cuckoo.update <- struct{}{}:
default:
}
}