return ''.join(s[x:x+l][::-1] for x in xrange(0, len(s), l))
class BlockAttempt(object):
- def __init__(self, version, previous_block, merkle_root, timestamp, target):
- assert version == 1
- self.version, self.previous_block, self.merkle_root, self.timestamp, self.target = version, previous_block, merkle_root, timestamp, target
+ def __init__(self, version, previous_block, merkle_root, timestamp, target, target2=None):
+ if target2 is None:
+ target2 = target
+ self.version, self.previous_block, self.merkle_root, self.timestamp, self.target, self.target2 = version, previous_block, merkle_root, timestamp, target, target2
def __hash__(self):
- return hash((self.version, self.previous_block, self.merkle_root, self.timestamp, self.target))
-
- def __repr__(self):
- return '<BlockAttempt %s>' % (' '.join('%s=%r' % (k, v) for k, v in self.__dict__.iteritems()),)
+ return hash((self.version, self.previous_block, self.merkle_root, self.timestamp, self.target, self.target2))
def __eq__(self, other):
if not isinstance(other, BlockAttempt):
def __repr__(self):
return 'BlockAttempt(%s)' % (', '.join('%s=%r' % (k, v) for k, v in self.__dict__.iteritems()),)
- def getwork(self, target=None, _check=3):
- target2 = self.target if target is None else target
- #if target2 >= 2**256//2**32:
- # raise ValueError('target higher than standard maximum')
-
+ def getwork(self, _check=3):
block_data = bitcoin_data.block_header_type.pack(dict(
version=self.version,
previous_block=self.previous_block,
getwork = {
'data': _swap(block_data, 4).encode('hex') + '000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000',
'hash1': '00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000',
- 'target': ('%064x' % (target2,)).decode('hex')[::-1].encode('hex'),
+ 'target': ('%064x' % (self.target2,)).decode('hex')[::-1].encode('hex'),
'midstate': _swap(sha256.process(block_data[:64]), 4).encode('hex'),
}
if _check:
- self2 = self.__class__.from_getwork(getwork, _check=_check - 1, _check_target=target)
+ self2 = self.__class__.from_getwork(getwork, _check=_check - 1)
if self2 != self:
raise ValueError('failed check - input invalid or implementation error')
return getwork
@classmethod
- def from_getwork(cls, getwork, _check=3, _check_target=None):
+ def from_getwork(cls, getwork, _check=3):
attrs = decode_data(getwork['data'])
attrs.pop('nonce')
+ attrs['target2'] = int(getwork['target'].decode('hex')[::-1].encode('hex'), 16)
ba = cls(**attrs)
if _check:
- getwork2 = ba.getwork(_check_target, _check=_check - 1)
+ getwork2 = ba.getwork(_check=_check - 1)
if getwork2 != getwork:
raise ValueError('failed check - input invalid or implementation error')
1305759879,
0x44b9f20000000000000000000000000000000000000000000000,
)
- ba.getwork(2**192*5, 100)
- ba.getwork(1, 100)
- ba.getwork(10, 100)
+ ba.getwork(100)
+ ba = BlockAttempt(
+ 1,
+ 0x148135e10208db85abb62754341a392eab1f186aab077a831cf7,
+ 0x534ea08be1ab529f484369344b6d5423ef5a0767db9b3ebb4e182bbb67962520,
+ 1305759879,
+ 0x44b9f20000000000000000000000000000000000000000000000,
+ 432*2**230,
+ )
+ ba.getwork(100)
+ ba = BlockAttempt(
+ 1,
+ 0x148135e10208db85abb62754341a392eab1f186aab077a831cf7,
+ 0x534ea08be1ab529f484369344b6d5423ef5a0767db9b3ebb4e182bbb67962520,
+ 1305759879,
+ 0x44b9f20000000000000000000000000000000000000000000000,
+ 7*2**240,
+ )
+ ba.getwork(100)
ba.getwork()
ba.getwork(_check=100)
block_target=state['target'],
net=args.net,
)
- print 'Generating!'
+ print 'Generating! Difficulty: %.06f' % (0xffff*2**208/p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target'],)
#print 'Target: %x' % (p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target'],)
#, have', shares.count(my_script) - 2, 'share(s) in the current chain. Fee:', sum(tx.value_in - tx.value_out for tx in extra_txs)/100000000
transactions = [generate_tx] + [tx.tx for tx in extra_txs]
if timestamp2 > timestamp:
print 'Toff', timestamp2 - timestamp
timestamp = timestamp2
- ba = bitcoin.getwork.BlockAttempt(state['version'], state['previous_block'], merkle_root, timestamp, state['target'])
- #print 'SENT', 2**256//p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target']
- target = p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target']
+ target2 = p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target']
if not all_targets:
- target = min(2**256//2**32 - 1, target)
+ target2 = min(2**256//2**32 - 1, target2)
print "TOOK", time.time() - start
times[p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['nonce']] = time.time()
- print "TOOK", time.time() - start
- return ba.getwork(target)
+ #print 'SENT', 2**256//p2pool.coinbase_type.unpack(generate_tx['tx_ins'][0]['script'])['share_data']['target']
+ return bitcoin.getwork.BlockAttempt(state['version'], state['previous_block'], merkle_root, timestamp, state['target'], target2)
my_shares = set()
times = {}
raise Error(-32601, u'Method not found')
method_meth = getattr(self, method_name)
- if hasattr(method_meth, "takes_headers"):
- params = [request.received_headers] + list(params)
+ if hasattr(method_meth, "takes_request"):
+ params = [request] + list(params)
try:
result = yield method_meth(*params)
from p2pool.bitcoin import getwork
from p2pool.util import jsonrpc, deferred_resource
-thoughts = {}
-
-def get_id(request):
- return request.getClientIP(), request.getHeader('Authorization')
class LongPollingWorkerInterface(deferred_resource.DeferredResource):
def __init__(self, work, compute):
self.work = work
self.compute = compute
- self.tricks = {}
@defer.inlineCallbacks
def render_GET(self, request):
- x = random.randrange(100000)
- print "LONGPOLL BEGIN", x
- request.setHeader('X-Long-Polling', '/long-polling')
-
- if request.getClientIP() in self.tricks and False:
- res = self.tricks.pop(request.getClientIP())
- print "trick pt 2", request.getClientIP()
- else:
- res = self.compute((yield self.work.changed.get_deferred()), 'x-all-targets' in map(str.lower, request.received_headers))
- self.tricks[request.getClientIP()] = res
- res = res.copy()
- res['data'] = res['data'][:4] + ''.join(random.choice('0123456789abcdef') for i in xrange(64)) + res['data'][4+64:]
- print "trick pt 1", request.getClientIP()
+ res = self.compute((yield self.work.changed.get_deferred()), request.getHeader('X-All-Targets') is not None)
+ request.setHeader('X-Long-Polling', '/long-polling')
request.setHeader('Content-Type', 'application/json')
request.write(json.dumps({
'jsonrpc': '2.0',
'id': 0,
- 'result': res,
+ 'result': res.getwork(),
'error': None,
}))
- print "LONGPOLL END", x, res
render_POST = render_GET
class RateInterface(deferred_resource.DeferredResource):
request.write(json.dumps(self.get_rate()))
class WorkerInterface(jsonrpc.Server):
- extra_headers = {
- 'X-Long-Polling': '/long-polling',
- }
-
def __init__(self, work, compute, response_callback, get_rate):
jsonrpc.Server.__init__(self)
RateInterface(get_rate))
self.putChild('', self)
- def rpc_getwork(self, headers, data=None):
+ def rpc_getwork(self, request, data=None):
+ request.setHeader('X-Long-Polling', '/long-polling')
+
if data is not None:
return self.response_callback(data)
- return self.compute(self.work.value, 'x-all-targets' in map(str.lower, headers))
- rpc_getwork.takes_headers = True
+ res = self.compute(self.work.value, request.getHeader('X-All-Targets') is not None)
+
+ return res.getwork()
+ rpc_getwork.takes_request = True