-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmining_subscribe.go
144 lines (114 loc) · 2.9 KB
/
mining_subscribe.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 Stratum
import (
"errors"
"math"
)
type SubscribeParams struct {
UserAgent string
ExtraNonce1 *ID
}
func (p *SubscribeParams) Read(r *request) error {
l := len(r.params)
if l == 0 || l > 2 {
return errors.New("Invalid parameter length; must be 1 or 2")
}
var ok bool
p.UserAgent, ok = r.params[0].(string)
if !ok {
return errors.New("invalid user agent format")
}
if l == 1 {
p.ExtraNonce1 = nil
return nil
}
idstr, ok := r.params[1].(string)
if !ok {
return errors.New("invalid session id format")
}
id, err := decodeID(idstr)
if err != nil {
return err
}
p.ExtraNonce1 = &id
return nil
}
func SubscribeRequest(id MessageID, r SubscribeParams) request {
if r.ExtraNonce1 == nil {
return Request(id, MiningSubscribe, []interface{}{r.UserAgent})
}
return Request(id, MiningSubscribe, []interface{}{r.UserAgent, encodeID(*r.ExtraNonce1)})
}
// A Subscription is a 2-element json array containing a method
// and a session id.
type Subscription struct {
Method Method
SessionID ID
}
type SubscribeResult struct {
Subscriptions []Subscription
ExtraNonce1 ID
ExtraNonce2Size uint32
}
func (p *SubscribeResult) Read(r *response) error {
result, ok := r.result.([]interface{})
if !ok {
return errors.New("Invalid result type; should be array")
}
l := len(result)
if l != 3 {
return errors.New("Invalid parameter length; must be 3")
}
subscriptions, ok := result[0].([][]string)
if !ok {
return errors.New("Invalid subscriptions format")
}
idstr, ok := result[1].(string)
if !ok {
return errors.New("Invalid session id")
}
extraNonce2Size, ok := result[2].(uint64)
if !ok {
return errors.New("Invalid ExtraNonces2_size")
}
if extraNonce2Size > math.MaxUint32 {
return errors.New("ExtraNonce2_size too big.")
}
p.ExtraNonce2Size = uint32(extraNonce2Size)
var err error
p.Subscriptions = make([]Subscription, len(subscriptions))
for i := 0; i < len(subscriptions); i++ {
if len(subscriptions[i]) != 2 {
return errors.New("Invalid subscriptions format")
}
p.Subscriptions[i].Method, err = DecodeMethod(subscriptions[i][0])
if err != nil {
return err
}
p.Subscriptions[i].SessionID, err = decodeID(subscriptions[i][1])
if err != nil {
return err
}
}
p.ExtraNonce1, err = decodeID(idstr)
if err != nil {
return errors.New("Invalid session id")
}
return nil
}
func SubscribeResponse(m MessageID, r SubscribeResult) response {
subscriptions := make([][]string, len(r.Subscriptions))
for i := 0; i < len(r.Subscriptions); i++ {
subscriptions[i] = make([]string, 2)
method, err := EncodeMethod(r.Subscriptions[i].Method)
if err != nil {
return Response(nil, nil)
}
subscriptions[i][0] = method
subscriptions[i][1] = encodeID(r.Subscriptions[i].SessionID)
}
result := make([]interface{}, 3)
result[0] = subscriptions
result[1] = encodeID(r.ExtraNonce1)
result[2] = r.ExtraNonce2Size
return Response(m, result)
}