2 Representation of a getwork request/reply
5 from __future__ import division
7 from . import data as bitcoin_data
13 return ''.join(s[x:x+4][::-1] for x in xrange(0, len(s), 4))
15 class BlockAttempt(object):
16 def __init__(self, version, previous_block, merkle_root, timestamp, bits, share_target):
17 self.version, self.previous_block, self.merkle_root, self.timestamp, self.bits, self.share_target = version, previous_block, merkle_root, timestamp, bits, share_target
20 return hash((self.version, self.previous_block, self.merkle_root, self.timestamp, self.bits, self.share_target))
22 def __eq__(self, other):
23 if not isinstance(other, BlockAttempt):
24 raise ValueError('comparisons only valid with other BlockAttempts')
25 return self.__dict__ == other.__dict__
27 def __ne__(self, other):
28 return not (self == other)
31 return 'BlockAttempt(%s)' % (', '.join('%s=%r' % (k, v) for k, v in self.__dict__.iteritems()),)
33 def getwork(self, _check=False, **extra):
34 if 'data' in extra or 'hash1' in extra or 'target' in extra or 'midstate' in extra:
37 block_data = bitcoin_data.block_header_type.pack(dict(
39 previous_block=self.previous_block,
40 merkle_root=self.merkle_root,
41 timestamp=self.timestamp,
47 'data': _swap4(block_data).encode('hex') + '000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000',
48 'hash1': '00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000010000',
49 'target': bitcoin_data.IntType(256).pack(self.share_target).encode('hex'),
50 'midstate': _swap4(sha256.process(block_data[:64])).encode('hex'),
54 self_check = self.__class__.from_getwork(getwork, _check=False)
55 if self_check != self:
56 raise AssertionError('failed check - input invalid or implementation error')
58 getwork = dict(getwork)
64 def from_getwork(cls, getwork, _check=True):
65 attrs = decode_data(getwork['data'])
68 version=attrs['version'],
69 previous_block=attrs['previous_block'],
70 merkle_root=attrs['merkle_root'],
71 timestamp=attrs['timestamp'],
73 share_target=bitcoin_data.IntType(256).unpack(getwork['target'].decode('hex')),
78 del extra['data'], extra['hash1'], extra['target']
79 extra.pop('midstate', None)
80 getwork_check = ba.getwork(_check=False, **extra)
81 if getwork_check != getwork and dict((k, v) for k, v in getwork_check.iteritems() if k != 'midstate') != getwork:
82 raise AssertionError('failed check - input invalid or implementation error')
86 def update(self, **kwargs):
87 d = self.__dict__.copy()
89 return self.__class__(**d)
91 def decode_data(data):
92 return bitcoin_data.block_header_type.unpack(_swap4(data.decode('hex'))[:80])