Permalink
Browse files

added miner timestamp rolling check

  • Loading branch information...
forrestv committed Jul 8, 2012
1 parent 1ae84c3 commit fc4ae93a433d125828929afb9f1eeb1e7dd153dc
Showing with 9 additions and 5 deletions.
  1. +9 −5 p2pool/bitcoin/worker_interface.py
@@ -43,7 +43,7 @@ def __init__(self, worker_bridge):
self.work_cache = {}
self.work_cache_times = self.worker_bridge.new_work_event.times
- self.merkle_root_to_handler = expiring_dict.ExpiringDict(300)
+ self.merkle_roots = expiring_dict.ExpiringDict(300)
def attach_to(self, res, get_handler=None):
res.putChild('', _GETableServer(_Provider(self, long_poll=False), get_handler))
@@ -62,10 +62,14 @@ def _getwork(self, request, data, long_poll):
if data is not None:
header = getwork.decode_data(data)
- if header['merkle_root'] not in self.merkle_root_to_handler:
+ if header['merkle_root'] not in self.merkle_roots:
print >>sys.stderr, '''Couldn't link returned work's merkle root with its handler. This should only happen if this process was recently restarted!'''
defer.returnValue(False)
- defer.returnValue(self.merkle_root_to_handler[header['merkle_root']](header, request))
+ handler, orig_timestamp = self.merkle_roots[header['merkle_root']]
+ dt = header['timestamp'] - orig_timestamp
+ if dt < 0 or dt % 12 == 11 or dt >= 600:
+ print >>sys.stderr, '''Miner %s @ %s rolled timestamp improperly! This may be a bug in the miner that is causing you to lose work!''' % (request.getUser(), request.getClientIP())
+ defer.returnValue(handler(header, request))
if p2pool.DEBUG:
id = random.randrange(1000, 10000)
@@ -92,10 +96,10 @@ def _getwork(self, request, data, long_poll):
res, orig_timestamp, handler = self.work_cache.pop(key)
else:
res, handler = self.worker_bridge.get_work(*key)
- assert res.merkle_root not in self.merkle_root_to_handler
+ assert res.merkle_root not in self.merkle_roots
orig_timestamp = res.timestamp
- self.merkle_root_to_handler[res.merkle_root] = handler
+ self.merkle_roots[res.merkle_root] = handler, orig_timestamp
if res.timestamp + 12 < orig_timestamp + 600:
self.work_cache[key] = res.update(timestamp=res.timestamp + 12), orig_timestamp, handler

4 comments on commit fc4ae93

@tucenaber

This comment has been minimized.

Show comment Hide comment
@tucenaber

tucenaber Jul 9, 2012

May I ask what the purpose is of dt % 12 == 11?

May I ask what the purpose is of dt % 12 == 11?

@forrestv

This comment has been minimized.

Show comment Hide comment
@forrestv

forrestv Jul 9, 2012

Owner

The timestamp is incremented by 12 farther below to generate new cached work, and the miner is only allowed to roll it 10 times due to the header being "expire=10". Therefore, we'll only get this condition triggered if a miner rolls its timestamp more than 10 seconds.

Owner

forrestv replied Jul 9, 2012

The timestamp is incremented by 12 farther below to generate new cached work, and the miner is only allowed to roll it 10 times due to the header being "expire=10". Therefore, we'll only get this condition triggered if a miner rolls its timestamp more than 10 seconds.

@tucenaber

This comment has been minimized.

Show comment Hide comment
@tucenaber

tucenaber Jul 11, 2012

I have now seen an example of dt=35 triggering the message (after extending the log message). That seems wierd to me. Wouldn't dt>10 be more appropriate?

On the other hand I don't understand the 12 second increment either.

I have now seen an example of dt=35 triggering the message (after extending the log message). That seems wierd to me. Wouldn't dt>10 be more appropriate?

On the other hand I don't understand the 12 second increment either.

@forrestv

This comment has been minimized.

Show comment Hide comment
@forrestv

forrestv Sep 30, 2012

Owner

This code is gone now, as I was assuming that expire=10 meant that the miner could only roll the work 10 times. Now, P2Pool just rolls the work 120 seconds and hopes the miner doesn't go that far in the 10 seconds it's given by the expire=10 header.

Owner

forrestv replied Sep 30, 2012

This code is gone now, as I was assuming that expire=10 meant that the miner could only roll the work 10 times. Now, P2Pool just rolls the work 120 seconds and hopes the miner doesn't go that far in the 10 seconds it's given by the expire=10 header.

Please sign in to comment.