glambeth/zecProxy

fails with multiple mining clients (at least for nheqminer)

Opened this issue · 1 comments

aleqx commented

It doesn't seem to work with multiple miners on different machines. I tried the nheqminer with CPU mining and the flypool pool.

In a normal miner->pool communication, the id field in the packets is incremented with every exchange of packets (excluding pool broadcasts). Your code alters the id field to be equal to the miner's id, essentially keeping it fixed for each miner. You also pass the same job to all miners. There are a number of problems that are happening:

  • apart from the first miner, miners reject the pool's response after subscribing as the id is not equal to 1 (here the id is equal to 5 because it was the 5th connecting client, which the proxy incremented to 5 and then keeps it at 5):
[16:09:18][0x00007f80d8da0700] stratum | Rejected share #5 (unknown)
  • if the sequence of events is launch proxy, launch miner 1, launch miner 2 then miner 2 fails and exits saying it's not authorized (looking at the messages, the pool responds with the same Extranonce1 and Extranonce2_size to the mining.subscribe request of miner 2 ...
    • if I launch miner 2 again, then this time it stays connected and waits for a job, which eventually comes ... but then there is another problem, as below:
  • the same job from the pool is sent to all miners in turn, which seems to create another problem ... miner 1 takes this new job and starts mining it, but miner 2, while taking the new job, it detects that there is no target (miner reports "New job but no server target, assuming powLimit") and then gets stuck trying the same nonce over and over again, and eventually fails and exits:
[15:56:12][0x00007fd7f250a700] miner#1 | Found solution with header hash: 0d3343411e70c95496d2aa3f95fcfa863e53897093c286b73ab4f90ffd4867b2
[15:56:12][0x00007fd7f250a700] stratum | Submitting share #4, nonce 0000000000000000000000000100000000000000000000000000000000000000
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 140565498722824) > this->size() (which is 2758)
Aborted (core dumped)

It seems that your proxy hasn't really been tested with multiple miners, or with different mining software (see my other raised issue about EWBF). It would be nice if you looked into it.

aleqx commented

Looking closer at the code, it seems all this proxy does is relaying all messages back and forth between the pool and miners, and altering the id field to make it unique per miner. It fails to set the id back to the same value issued by the miner (breaking the JSON-RPC protocol). Many (all?) pools also reject multiple authorize requests on the same connections, causing miners to fail.

What's needed is a proper proxy that acts as a single miner to the pool, subscribing itself to the pool and dealing with the subscribe, authorize, set_target methods from the pool, then wait for miners to connect. Upon the latter, it should subscribe, authorize, set_target the miners directly (without relaying anything to the pool). It should also record/queue any job broadcasts from the pool for when miners connect. The only messages relayed between miners and pool should then be the job broadcasts from the pool and job submits from miners, making sure that the id field value of each miner's request is preserved when replying back to the miner.

A state machine is needed to implement the above. It's not a simple hack. You made a good start though.