Skip to content

Commit

Permalink
added miner timestamp rolling check
Browse files Browse the repository at this point in the history
  • Loading branch information
forrestv committed Jul 9, 2012
1 parent 1ae84c3 commit fc4ae93
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions p2pool/bitcoin/worker_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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)
Expand All @@ -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
Expand Down

4 comments on commit fc4ae93

@tucenaber
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@forrestv
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.