-
Notifications
You must be signed in to change notification settings - Fork 42
/
EthereumStratum_NiceHash_v1.0.0.txt
365 lines (296 loc) · 10.9 KB
/
EthereumStratum_NiceHash_v1.0.0.txt
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
-------------------------------------------------------------------------
NiceHash presents
=========================================================================
Ethereum stratum mining protocol v1.0.0
=========================================================================
revision of this document: R2
I. Introduction
II. Concept
III. Specifications (RFC)
IV. Real world scenario
V. Planned improvements
VI. Contact
I. Introduction
---------------
Ethereum does not have official stratum protocol. It supports only
GetWork, which is very resource hoggy as miners need to constantly
poll pool to obtain possible new work. GetWork thus affects performance
of miners and pools. Due to demand for more professional Ethereum
mining, several versions of "stratum" for Ethereum emerged. These
"stratums" utilize GetWork on server side (pool side) to obtain work,
which would be fine, if careful considerations and precautions were
taken when creating such protocols. But this was not done. Issues of
these protocols are following:
1. No unique data per miner/worker. Extranonce is ignored (but still
sent). Each miner gets seedhash (which is always the same for every
30k blocks) and headerhash (which changes every block). Then miner uses
these two values and own nonces to generate hashes. Miners may be
doing duplicate work (if they choose same nonces).
2. Difficulty redundancy. Difficulty is sent in mining.notify message
as a third parameter named target. This is not needed, because miners
can calculate target hash on their own out of provided difficulty.
3. Overall data redundancy. There are several fields that are not needed
to be sent over network. Firstly; if extranonce is not used, it does not
have to be sent. Secondly; seedhash changes every 30k blocks - there is
no need to send it with every mining.notify. Thirdly; as already pointed
out in 2 - target in mining.notify is redundant as set_difficulty is
being used. Fourthly; mining.submit actually only needs to send nonce.
Pool needs to verify nonce for validity and will calculate hash and
mixhash. Bandwidth usage can be easily reduced by 50% or more if removing
all mentioned redundancies.
4. There are some inconsistencies compared to original slush's stratum
specifications. One of them are ids. Ids should increase so that the pool
can keep track of data being received. Another thing are HEX marks '0x'
starting with each string field. This is, again, redundant and we will
save some bandwidth if not using them.
5. No specifications, only projects with implemented solutions. This
usually lead to several similar versions of protocol; exactly what
happened.
Our goal is to make a solid, non-redundant, bullet-proof stratum mining
protocol for Ethereum that does not have issues pointed out above.
II. Concept
-----------
Ethereum's GetWork gives us 3 values:
{ ... "result":[
"0x645cf20198c2f3861e947d4f67e3ab63b7b2e24dcc9095bd9123e7b33371f6cc",
"0xabad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
"0x0000000394427b08175efa9a9eb59b9123e2969bf19bf272b20787ed022fbe6c"
]}
First value is headerhash, second value is seedhash and third value is
target. Seedhash is used to identify DAG file, headerhash and 64 bit
nonce value chosen by our miner give us hash, which, if below provided
target, yield block/share.
Since nonce is 64 bit (8 bytes) wide and considering very bad possible
scenario, that Ethereum does not find a block in 5 minutes time, 8 bytes
of nonce can support miner with speed of up to:
(2^64 / 300) / 1G ~ 61,489,147 GH/s
This is a very big number so we can easily consider taking some bytes off
for our stratum protocol.
---------------------------------------
| Bytes | Max supported hashing speed |
| 8 | ~61,489,147.000 GH/s |
| 7 | ~240,192.000 GH/s |
| 6 | ~938.000 GH/s |
| 5 | ~3.665 GH/s |
| 4 | ~0.014 GH/s |
---------------------------------------
Having only 4 bytes for nonce is not an option, since we already have
miners capable of reaching 14 MH/s and more. Nonce width of 5 bytes
allows max speed of 3.665 GH/s which shall be enough for quite some time,
even if ASICs arrive.
The miner needs to get seedhash, headerhash, difficulty and part of
nonce (called extranonce) from pool. Miner chooses on it's own second
part of the nonce (called minernonce). Extranonce glued with minernonce
gives us 64 bit Ethereum nonce.
III. Specifications (RFC)
-------------------------
Handshake happens after TCP connection is established from miner to the
pool. Miner sends data first:
{
"id": 1,
"method": "mining.subscribe",
"params": [
"MinerName/1.0.0", "EthereumStratum/1.0.0"
]
}\n
First parameter is miner name and version (as with standard stratum
protocol). Second parameter must be "EthereumStratum/Version" where
Version is version of EthereumStratum miner is using according to this
document's version. If pool does not support this version, it may
terminate the connection or respond back with error.
Note that miner iterates ids and can start with any number. Each message
from miner to the pool needs to have unique id for miner to properly read
responses as pool may not process miner's messages in FIFO manner.
Server replies back:
{
"id": 1,
"result": [
[
"mining.notify",
"ae6812eb4cd7735a302a8a9dd95cf71f",
"EthereumStratum/1.0.0"
],
"080c"
],
"error": null
}\n
Response is almost the same as with standard stratum protocol with
following differences; Third parameter of first parameter of result array
is "EthereumStratum/Version"; If pool does not report this parameter or
version is different than supported by miner, miner can expect
compatibility issues and should terminate connection. Second parameter
of result array is extranonce (in HEX) set by pool. There is no third
parameter, because there is no extranonce2 (as with standard stratum).
Extranonce may be max 3 bytes in size.
Miner shall authorize during initial handshake; this is done the same way
as in standard stratum protocol and will not be explained here in
details.
Before first job (work) is provided, pool MUST set difficulty by sending:
{
"id": null,
"method": "mining.set_difficulty",
"params": [
0.5
]
}\n
First item of params array is difficulty in double data type. Conversion
between difficulty and target is done the same way as with Bitcoin;
difficulty of 1 is transformed to target being in HEX:
00000000ffff0000000000000000000000000000000000000000000000000000
If pool does not set difficulty before first job, then miner can assume
difficulty 1 was being set.
When difficulty is changed, miner starts using new difficulty for every
NEXT job that arrives.
If miner has subscribed to extranonce notifications (detailed explanations
is here: https://www.nicehash.com/?p=software#devs), then pool may change
miner's extranonce by sending:
{
"id": null,
"method": "mining.set_extranonce",
"params": [
"af4c"
]
}\n
New extranonce is valid for all NEXT jobs sent by the pool.
Pool informs miners about job (work) by sending:
{
"id": null,
"method": "mining.notify",
"params": [
"bf0488aa",
"abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
"645cf20198c2f3861e947d4f67e3ab63b7b2e24dcc9095bd9123e7b33371f6cc",
true
]
}\n
First parameter of params array is job ID (must be HEX number of any
size). Second parameter is seedhash. Seedhash is sent with every job to
support possible multipools, which may switch between coins quickly.
Third parameter is headerhash. Last parameter is boolean cleanjobs.
If set to true, then miner needs to clear queue of jobs and immediatelly
start working on new provided job, because all old jobs shares will
result with stale share error.
Miner uses seedhash to identify DAG, then tries to find share below
target (which is created out of provided difficulty) with headerhash,
extranonce and own minernonce.
When share below target is found, miner submits it to the pool:
{
"id": 244,
"method": "mining.submit",
"params": [
"username",
"bf0488aa",
"6a909d9bbc0f"
]
}\n
Second parameter of params array is job ID, third parameter is
minernonce. Note in above example that minernonce is 6 bytes, because
provided extranonce was 2 bytes. If pool provides 3 bytes extranonce,
then minernonce must be 5 bytes.
For every work submit, pool needs to respond back with standard stratum
response:
{
"id": 244,
"result": true,
"error": null
}\n
Or if share was not accepted (standard stratum response):
{
"id": 244,
"result": false,
"error": [
-1,
"Job not found",
NULL
]
}\n
IV. Real world scenario
-----------------------
Miner connects to the pool and sends:
{
"id": 1,
"method": "mining.subscribe",
"params": [
"EthereumMiner/1.0.0", "EthereumStratum/1.0.0"
]
}\n
Pool responds:
{
"id": 1,
"result": [
[
"mining.notify",
"ae6812eb4cd7735a302a8a9dd95cf71f",
"EthereumStratum/1.0.0"
],
"a2eea0"
],
"error": null
}\n
Miner then authorize:
{
"id": 2,
"method": "mining.authorize",
"params": [
"test",
"password"
]
}\n
And pool confirms:
{
"id": 2,
"result": true,
"error": null
}\n
Pool sends difficulty:
{
"id": null,
"method": "mining.set_difficulty",
"params": [
1.0
]
}\n
And job:
{
"id": null,
"method": "mining.notify",
"params": [
"bf0488aa",
"abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c",
"fc12eb20c58158071c956316cdcd12a22dd8bf126ac4aee559f0ffe4df11f279",
true
]
}\n
After a while, miner finds share and submits it:
{
"id": 3,
"method": "mining.submit",
"params": [
"test",
"bf0488aa",
"cfae7df760"
]
}\n
Response from the pool:
{
"id": 3,
"result": true,
"error": null
}\n
The share was valid considering data:
seedhash=abad8f99f3918bf903c6a909d9bbc0fdfa5a2f4b9cb1196175ec825c6610126c
headerhash=fc12eb20c58158071c956316cdcd12a22dd8bf126ac4aee559f0ffe4df11f279
nonce=a2eea0cfae7df760
Result is share with difficulty of 1.863 which is above 1.0.
V. Planned improvements
-----------------------
Ethereum has RPC method eth_getBlockByNumber which can return some data about
next block that is yet to be mined. Among data is next block number (block
height). This number could be used instead of seedhash; every miner would then
calculate seedhash on it's own thus bandwidth usage would be reduced even more.
There are plans to make eth_getBlockTemplate method. When this is made, this
stratum protocol may get very similar to standard stratum.
VI. Contact
-----------
www.nicehash.com