Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
366 lines (296 sloc) 10.9 KB
-------------------------------------------------------------------------
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
info@nicehash.com