pooler / cpuminer

CPU miner for Litecoin and Bitcoin
https://bitcointalk.org/index.php?topic=55038.0
Other
2.77k stars 1.21k forks source link

Stratum support #24

Closed tjconcept closed 11 years ago

pooler commented 11 years ago

I started working on this a few days ago.

tjconcept commented 11 years ago

Wow, sounds awesome :+1:

dwearden commented 11 years ago

This would be useful. The new altcoins can often be cpu mined at first launch while the difficulty is low, but when the difficulty is low, pooled mining needs to be stratum because the blocks are found so quickly. If you need someone to test this on CentOS or Ubuntu, let me know. Otherwise, I'm not sure how helpful I would be.

pooler commented 11 years ago

Stratum support added in commit ee7b535.

Maeyanie commented 11 years ago

The X-Stratum header parsing seems to not quite work. It seems to detect the header okay, but doesn't redo the request, and fails with a "JSON decode failed(1): '[' or '{' expected near 'Stratum'" error.

Connecting with stratum+tcp:// works, though, it has some trouble with the target. The problem seems to be because my pool sends the mining.set_difficulty command after the initial params, and cpuminer only updates the target when parsing a params command (util.c:1050). So from connect until the first new block arrives the target is wrong, and most shares fail with: [2013-06-09 20:05:37] DEBUG: hash <= target Hash: 00003b6659ca71960c6a9a361ac518cf2bf02d57e2a3108bb3f7e1fe063eda81 Target: 0000ffff00000000000000000000000000000000000000000000000000000000 [2013-06-09 20:05:37] thread 0: 7752 hashes, 6.57 khash/s [2013-06-09 20:05:37] accepted: 0/12 (0.00%), 12.75 khash/s (booooo) [2013-06-09 20:05:37] DEBUG: reject reason: Hash above target

Changing stratum_set_difficulty() to set sctx->job.diff in addition to next_diff seems to work, though I'm guessing that has some race condition you were trying to avoid with the two-step thing.

Increasing the default timeout from 120s was also helpful, as my system isn't fast enough to reliably crunch a share in that time, and it kept reconnecting. :smile:

Testing with the Coinotron.com pool.

pooler commented 11 years ago

@Maeyanie The first issue you mention is due to the fact that minerd was expecting a valid JSON response, but only got a page saying "Stratum" because Coinotron doesn't support getwork anymore. I have pushed 4aa1c37 to fix this.

Second issue: This looks like a bug in the pool's implementation of Stratum. According to the specifications (see here and here), miners should only begin enforcing the new difficulty on the next job received. I have talked to the operator of Coinotron and he said he's going to fix this soon.

Third Issue: This is more delicate. The specifications state that mining.notify messages should be sent by the server at regular intervals, but do not set an upper limit to the time a miner can go without fresh work. That said, all the pools I had tested send at least a notification every minute, which makes sense, because this way new transactions can get included in the next block. This is why if minerd doesn't receive any communication from the pool for two minutes it considers the connection dead and tries to reconnect. I think cgminer does the same. I've discussed this with Coinotron, and it turned out the frequency at which they send out notifications is not fixed, but depends on the speed of each miner. Because they did not put an upper limit to the notification interval and they use a fixed high difficulty, slow miners can well go 120 seconds without any communication with the server. Unfortunately right now Coinotron is suffering from a DDoS attack and is busy trying to mitigate it, so we have agreed to discuss this again in 1-2 days. In theory the timeout could be customized via a command-line option, but I prefer to avoid implementing this if possible, because updating the job less frequently than every two minutes is not good for the network.

Maeyanie commented 11 years ago

Ah, figures I happen to test it on a broken pool. :wink: It did seem to work fine both with your miner before Stratum, and with cgminer, though. Maybe I was just testing with a different coin type.

Besides, I guess testing with slightly-bad input is the best way to find potential problems anyhow. :smile:

It does seem fairly safe to increase the timeout, though, since I noticed you use TCP keepalives to detect if the connection dies.