1 from __future__ import division
6 from twisted.internet import defer
9 from p2pool import data as p2pool_data
10 from p2pool.util import jsonrpc, variable
11 from p2pool.bitcoin import getwork
13 def get_username(request):
15 return base64.b64decode(request.getHeader('Authorization').split(' ', 1)[1]).split(':')[0]
20 return request.getClientIP(), request.getHeader('Authorization')
22 class LongPollingWorkerInterface(jsonrpc.Server):
23 def __init__(self, parent):
24 jsonrpc.Server.__init__(self)
27 def rpc_getwork(self, request, data=None):
28 return self.parent.getwork(request, data, long_poll=True)
30 class WorkerInterface(jsonrpc.Server):
31 def __init__(self, compute, response_callback, new_work_event=variable.Event()):
32 jsonrpc.Server.__init__(self)
34 self.compute = compute
35 self.response_callback = response_callback
36 self.new_work_event = new_work_event
38 self.worker_views = {}
40 self.putChild('long-polling', LongPollingWorkerInterface(self))
41 self.putChild('', self)
43 def rpc_getwork(self, request, data=None):
44 return self.getwork(request, data, long_poll=False)
46 @defer.inlineCallbacks
47 def getwork(self, request, data, long_poll):
48 request.setHeader('X-Long-Polling', '/long-polling')
49 request.setHeader('X-Roll-NTime', 'expire=60')
52 defer.returnValue(self.response_callback(getwork.decode_data(data), request))
54 request_id = get_id(request)
57 id = random.randrange(1000, 10000)
58 print 'POLL %i START long_poll=%r user_agent=%r x-work-identifier=%r user=%r' % (id, long_poll, request.getHeader('User-Agent'), request.getHeader('X-Work-Identifier'), get_username(request))
60 if request_id not in self.worker_views:
61 self.worker_views[request_id] = variable.Variable(None)
63 if long_poll and self.worker_views[request_id].value in [None, self.new_work_event.times]:
65 print 'POLL %i WAITING user=%r' % (id, get_username(request))
66 yield self.new_work_event.get_deferred()
68 res, identifier = self.compute(request)
71 self.worker_views[request_id].set(self.new_work_event.times)
74 print 'POLL %i END %s user=%r' % (id, p2pool_data.format_hash(identifier), get_username(request)) # XXX identifier is hack
76 defer.returnValue(res.getwork(identifier=str(identifier)))