workaround for stupid miners
authorForrest Voight <forrest@forre.st>
Wed, 27 Jul 2011 02:45:34 +0000 (22:45 -0400)
committerForrest Voight <forrest@forre.st>
Wed, 27 Jul 2011 02:45:34 +0000 (22:45 -0400)
p2pool/worker_interface.py

index 85688f9..ac7c06a 100644 (file)
@@ -1,11 +1,16 @@
 from __future__ import division
 
 import json
+import random
 
 from twisted.internet import defer
 
 from p2pool.util import jsonrpc, deferred_resource
 
+def get_id(request):
+    return request.getClientIP(), request.getHeader('Authorization'), request.getHeader('User-Agent')
+
+last_cache_invalidation = {}
 
 class LongPollingWorkerInterface(deferred_resource.DeferredResource):
     def __init__(self, work, compute):
@@ -14,7 +19,33 @@ class LongPollingWorkerInterface(deferred_resource.DeferredResource):
     
     @defer.inlineCallbacks
     def render_GET(self, request):
-        res = self.compute((yield self.work.changed.get_deferred()), request.getHeader('X-All-Targets') is not None)
+        id = random.randrange(10000)
+        print "LONG POLL", id
+        
+        request_id = get_id(request)
+        
+        work = self.work.value
+        thought_work = last_cache_invalidation.get(request_id, None)
+        
+        #if thought_work is not None and work != thought_work and work['previous_block'] == thought_work['previous_block']:
+        #    # clients won't believe the update
+        #    work = work.copy()
+        #    work['previous_block'] = random.randrange(2**256)
+        
+        if work == thought_work:
+            work = yield self.work.changed.get_deferred()
+        else:
+            print "shortcut worked!"
+        
+        thought_work = last_cache_invalidation.get(request_id, None)
+        if thought_work is not None and work != thought_work and work['previous_block'] == thought_work['previous_block']:
+            # clients won't believe the update
+            work = work.copy()
+            work['previous_block'] = random.randrange(2**256)
+        
+        res = self.compute(work, request.getHeader('X-All-Targets') is not None)
+        
+        last_cache_invalidation[request_id] = work
         
         request.setHeader('X-Long-Polling', '/long-polling')
         request.setHeader('Content-Type', 'application/json')
@@ -24,6 +55,8 @@ class LongPollingWorkerInterface(deferred_resource.DeferredResource):
             'result': res.getwork(),
             'error': None,
         }))
+        
+        print "END POLL %i %x" % (id, work['best_share_hash'] % 2**32 if work['best_share_hash'] is not None else 0)
     render_POST = render_GET
 
 class RateInterface(deferred_resource.DeferredResource):
@@ -55,7 +88,19 @@ class WorkerInterface(jsonrpc.Server):
         if data is not None:
             return self.response_callback(data)
         
-        res = self.compute(self.work.value, request.getHeader('X-All-Targets') is not None)
+        request_id = get_id(request)
+        
+        work = self.work.value
+        thought_work = last_cache_invalidation.get(request_id, None)
+        
+        if thought_work is not None and work != thought_work and work['previous_block'] == thought_work['previous_block']:
+            # clients won't believe the update
+            work = work.copy()
+            work['previous_block'] = random.randrange(2**256)
+        
+        res = self.compute(work, request.getHeader('X-All-Targets') is not None)
+        
+        last_cache_invalidation[request_id] = work
         
         return res.getwork()
     rpc_getwork.takes_request = True