-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathwork.go
103 lines (86 loc) · 2.26 KB
/
work.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
package stratum
import (
"encoding/binary"
"fmt"
"math"
"strings"
"unsafe"
log "github.com/sirupsen/logrus"
)
type Work struct {
Data WorkData
Target uint64 `json:"target"`
JobID string `json:"job_id"`
NoncePtr *uint32
Difficulty float64 `json:"difficulty"`
XNonce2 string
Size int
}
func NewWork() *Work {
work := &Work{}
work.Data = make([]byte, 96)
work.Target = 0
work.NoncePtr = (*uint32)(unsafe.Pointer(&work.Data[39]))
return work
}
type WorkData []byte
func ParseWorkFromResponse(r *Response) (*Work, error) {
result := r.Result
if job, ok := result["job"]; !ok {
return nil, fmt.Errorf("No job found")
} else {
return ParseWork(job.(map[string]interface{}))
}
}
func ParseWork(args map[string]interface{}) (*Work, error) {
jobId := args["job_id"].(string)
hexBlob := args["blob"].(string)
log.Debugf("job_id: %v", jobId)
log.Debugf("hexblob: %v", hexBlob)
blobLen := len(hexBlob)
log.Debugf("blobLen: %v", blobLen)
if blobLen%2 != 0 || ((blobLen/2) < 40 && blobLen != 0) || (blobLen/2) > 128 {
return nil, fmt.Errorf("JSON invalid blob length")
}
if blobLen == 0 {
return nil, fmt.Errorf("Blob length was 0?")
}
// TODO: Should there be a lock here?
blob, err := HexToBin(hexBlob, blobLen)
if err != nil {
return nil, err
}
log.Debugf("blob bytes=%v", BinToStr(blob))
targetStr := args["target"].(string)
log.Debugf("targetStr: %v", targetStr)
b, err := HexToBin(targetStr, 8)
target := uint64(binary.LittleEndian.Uint32(b))
target64 := math.MaxUint64 / (uint64(0xFFFFFFFF) / target)
target = target64
log.Debugf("target: %X", target)
difficulty := float64(0xFFFFFFFFFFFFFFFF) / float64(target64)
log.Debugf("Pool set difficulty: %.2f", difficulty)
work := NewWork()
copy(work.Data, blob)
// XXX: Do we need to do this?
for i := len(blob); i < len(work.Data); i++ {
work.Data[i] = '\x00'
}
work.Size = blobLen / 2
work.JobID = jobId
work.Target = target
work.Difficulty = difficulty
return work, nil
}
func WorkCopy(dest *Work, src *Work) {
copy(dest.Data, src.Data)
dest.Size = src.Size
dest.Difficulty = src.Difficulty
dest.Target = src.Target
if strings.Compare(src.JobID, "") != 0 {
dest.JobID = src.JobID
}
if strings.Compare(src.XNonce2, "") != 0 {
dest.XNonce2 = src.XNonce2
}
}