-
Notifications
You must be signed in to change notification settings - Fork 7
/
cpu.go
52 lines (41 loc) · 1.08 KB
/
cpu.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
package nanopow
import (
"encoding/binary"
"golang.org/x/crypto/blake2b"
"math"
"runtime"
)
type cpuWorker struct {
thread uint64
}
func NewWorkerCPU() (*cpuWorker, error) {
return NewWorkerCPUThread(uint64(runtime.NumCPU()))
}
func NewWorkerCPUThread(threads uint64) (*cpuWorker, error) {
return &cpuWorker{thread: threads}, nil
}
func (w *cpuWorker) GenerateWork(ctx *Context, root []byte, difficulty uint64) (err error) {
for i := uint64(0); i < w.thread; i++ {
go w.generateWork(ctx, root, difficulty, math.MaxUint32 + ((math.MaxUint32 / w.thread) * i))
}
return nil
}
func (w *cpuWorker) generateWork(ctx *Context, root []byte, difficulty uint64, result uint64) (err error) {
h, _ := blake2b.New(8, nil)
nonce := make([]byte, 40)
copy(nonce[8:], root)
for ; ; result++ {
select {
default:
binary.LittleEndian.PutUint64(nonce[:8], result) // Using `binary.Write(h, ...) is worse
h.Write(nonce)
if binary.LittleEndian.Uint64(h.Sum(nil)) >= difficulty {
ctx.workerResult(result)
return nil
}
h.Reset()
case <-ctx.workerStop():
return nil
}
}
}