from p2pool.util import bases, math, pack
from . import base58
+def hash256(data):
+ return pack.IntType(256).unpack(hashlib.sha256(hashlib.sha256(data).digest()).digest())
+
+def hash160(data):
+ return pack.IntType(160).unpack(hashlib.new('ripemd160', hashlib.sha256(data).digest()).digest())
+
class ChecksummedType(pack.Type):
def __init__(self, inner):
self.inner = inner
return 0
hash_list = list(hashes)
while len(hash_list) > 1:
- hash_list = [merkle_record_type.hash256(dict(left=left, right=left if right is None else right))
+ hash_list = [hash256(merkle_record_type.pack(dict(left=left, right=left if right is None else right)))
for left, right in zip(hash_list[::2], hash_list[1::2] + [None])]
return hash_list[0]
while len(hash_list) > 1:
hash_list = [
(
- merkle_record_type.hash256(dict(left=left, right=right)),
+ hash256(merkle_record_type.pack(dict(left=left, right=right))),
left_f or right_f,
(left_l if left_f else right_l) + [dict(side=1, hash=right) if left_f else dict(side=0, hash=left)],
)
return res
def check_merkle_branch(tip_hash, index, merkle_branch):
- return reduce(lambda c, (i, h): merkle_record_type.hash256(
+ return reduce(lambda c, (i, h): hash256(merkle_record_type.pack(
dict(left=h, right=c) if 2**i & index else
dict(left=c, right=h)
- ), enumerate(merkle_branch), tip_hash)
+ )), enumerate(merkle_branch), tip_hash)
def target_to_average_attempts(target):
return 2**256//(target + 1)
('pubkey_hash', pack.IntType(160)),
]))
-pubkey_type = pack.PassthruType()
-
def pubkey_hash_to_address(pubkey_hash, net):
return base58.encode(human_address_type.pack(dict(version=net.ADDRESS_VERSION, pubkey_hash=pubkey_hash)))
def pubkey_to_address(pubkey, net):
- return pubkey_hash_to_address(pubkey_type.hash160(pubkey), net)
+ return pubkey_hash_to_address(hash160(pubkey), net)
def address_to_pubkey_hash(address, net):
x = human_address_type.unpack(base58.decode(address))
# transactions
def pubkey_to_script2(pubkey):
- return ('\x41' + pubkey_type.pack(pubkey)) + '\xac'
+ return ('\x41' + pubkey) + '\xac'
def pubkey_hash_to_script2(pubkey_hash):
return '\x76\xa9' + ('\x14' + pack.IntType(160).pack(pubkey_hash)) + '\x88\xac'
from twisted.internet import defer
from . import data
-from p2pool.util import math
+from p2pool.util import math, pack
BitcoinMainnet = math.Object(
P2P_PREFIX='f9beb4d9'.decode('hex'),
'bitcoinaddress' in (yield bitcoind.rpc_help()) and
not (yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.hash256,
+ POW_FUNC=data.hash256,
SYMBOL='BTC',
)
BitcoinTestnet = math.Object(
'bitcoinaddress' in (yield bitcoind.rpc_help()) and
(yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.hash256,
+ POW_FUNC=data.hash256,
SYMBOL='tBTC',
)
'namecoinaddress' in (yield bitcoind.rpc_help()) and
not (yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.hash256,
+ POW_FUNC=data.hash256,
SYMBOL='NMC',
)
NamecoinTestnet = math.Object(
'namecoinaddress' in (yield bitcoind.rpc_help()) and
(yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.hash256,
+ POW_FUNC=data.hash256,
SYMBOL='tNMC',
)
'litecoinaddress' in (yield bitcoind.rpc_help()) and
not (yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.scrypt,
+ POW_FUNC=lambda data: pack.IntType(256).unpack(__import__('ltc_scrypt').getPoWHash(data)),
SYMBOL='LTC',
)
LitecoinTestnet = math.Object(
'litecoinaddress' in (yield bitcoind.rpc_help()) and
(yield bitcoind.rpc_getinfo())['testnet']
)),
- POW_FUNC=data.block_header_type.scrypt,
+ POW_FUNC=lambda data: pack.IntType(256).unpack(__import__('ltc_scrypt').getPoWHash(data)),
SYMBOL='tLTC',
)
('tx', bitcoin_data.tx_type),
])
def handle_tx(self, tx):
- self.get_tx.got_response(bitcoin_data.tx_type.hash256(tx), tx)
+ self.get_tx.got_response(bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)), tx)
message_block = pack.ComposedType([
('block', bitcoin_data.block_type),
])
def handle_block(self, block):
- block_hash = bitcoin_data.block_header_type.hash256(block['header'])
+ block_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(block['header']))
self.get_block.got_response(block_hash, block)
self.get_block_header.got_response(block_hash, block['header'])
def handle_headers(self, headers):
for header in headers:
header = header['header']
- self.get_block_header.got_response(bitcoin_data.block_header_type.hash256(header), header)
+ self.get_block_header.got_response(bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)), header)
self.factory.new_headers.happened([header['header'] for header in headers])
message_ping = pack.ComposedType([])
@classmethod
def from_header(cls, header):
- return cls(bitcoin_data.block_header_type.hash256(header), header['previous_block'])
+ return cls(bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)), header['previous_block'])
def __init__(self, hash, previous_hash):
self.hash, self.previous_hash = hash, previous_hash
if merkle_branch is None and other_txs is None:
raise ValueError('need either merkle_branch or other_txs')
if other_txs is not None:
- new_merkle_branch = bitcoin_data.calculate_merkle_branch([0] + map(bitcoin_data.tx_type.hash256, other_txs), 0)
+ new_merkle_branch = bitcoin_data.calculate_merkle_branch([0] + [bitcoin_data.hash256(bitcoin_data.tx_type.pack(x)) for x in other_txs], 0)
if merkle_branch is not None:
if merke_branch != new_merkle_branch:
raise ValueError('invalid merkle_branch and other_txs')
if len(self.share_data['coinbase']) > 100:
raise ValueError('''coinbase too large! %i bytes''' % (len(self.share_data['coinbase']),))
- self.pow_hash = net.PARENT.POW_FUNC(header)
- self.header_hash = bitcoin_data.block_header_type.hash256(header)
+ self.pow_hash = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(header))
+ self.header_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header))
- self.hash = share1a_type.hash256(self.as_share1a())
+ self.hash = bitcoin_data.hash256(share1a_type.pack(self.as_share1a()))
if self.pow_hash > self.target:
print 'hash %x' % self.pow_hash
if share_info != self.share_info:
raise ValueError('share difficulty invalid')
- if bitcoin_data.check_merkle_branch(bitcoin_data.tx_type.hash256(gentx), 0, self.merkle_branch) != self.header['merkle_root']:
+ if bitcoin_data.check_merkle_branch(bitcoin_data.hash256(bitcoin_data.tx_type.pack(gentx)), 0, self.merkle_branch) != self.header['merkle_root']:
raise ValueError('''gentx doesn't match header via merkle_branch''')
def as_share(self):
sequence=None,
script=share_data['coinbase'].ljust(2, '\x00'),
)],
- tx_outs=[dict(value=0, script='\x20' + pack.IntType(256).pack(share_info_type.hash256(share_info)))] + [dict(value=amounts[script], script=script) for script in dests if amounts[script]],
+ tx_outs=[dict(value=0, script='\x20' + pack.IntType(256).pack(bitcoin_data.hash256(share_info_type.pack(share_info))))] + [dict(value=amounts[script], script=script) for script in dests if amounts[script]],
lock_time=0,
)
target = max(target, current_work.value['aux_work']['target'])
transactions = [generate_tx] + list(current_work2.value['transactions'])
- merkle_root = bitcoin_data.merkle_hash(map(bitcoin_data.tx_type.hash256, transactions))
+ merkle_root = bitcoin_data.merkle_hash([bitcoin_data.hash256(bitcoin_data.tx_type.pack(x)) for x in transactions])
self.merkle_root_to_transactions[merkle_root] = share_info, transactions, time.time(), current_work.value['aux_work'], target
print 'New work for worker! Difficulty: %.06f Share difficulty: %.06f Payout if block: %.6f %s Total block value: %.6f %s including %i transactions' % (
return False
share_info, transactions, getwork_time, aux_work, target = self.merkle_root_to_transactions[header['merkle_root']]
- pow_hash = net.PARENT.POW_FUNC(header)
+ pow_hash = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(header))
on_time = current_work.value['best_share_hash'] == share_info['share_data']['previous_share_hash']
try:
print >>sys.stderr, 'No bitcoind connection when block submittal attempted! Erp!'
if pow_hash <= header['bits'].target:
print
- print 'GOT BLOCK FROM MINER! Passing to bitcoind! bitcoin: %x' % (bitcoin_data.block_header_type.hash256(header),)
+ print 'GOT BLOCK FROM MINER! Passing to bitcoind! bitcoin: %x' % (bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)),)
print
- recent_blocks.append({ 'ts': time.time(), 'hash': '%x' % (bitcoin_data.block_header_type.hash256(header),) })
+ recent_blocks.append({ 'ts': time.time(), 'hash': '%x' % (bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)),) })
except:
log.err(None, 'Error while processing potential block:')
bitcoin_data.aux_pow_type.pack(dict(
merkle_tx=dict(
tx=transactions[0],
- block_hash=bitcoin_data.block_header_type.hash256(header),
- merkle_branch=bitcoin_data.calculate_merkle_branch(map(bitcoin_data.tx_type.hash256, transactions), 0),
+ block_hash=bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)),
+ merkle_branch=bitcoin_data.calculate_merkle_branch([bitcoin_data.hash256(bitcoin_data.tx_type.pack(x)) for x in transactions], 0),
index=0,
),
merkle_branch=[],
class Test(unittest.TestCase):
def test_header_hash(self):
- assert data.block_header_type.hash256(dict(
+ assert data.hash256(data.block_header_type.pack(dict(
version=1,
previous_block=0x000000000000038a2a86b72387f93c51298298a732079b3b686df3603d2f6282,
merkle_root=0x37a43a3b812e4eb665975f46393b4360008824aab180f27d642de8c28073bc44,
timestamp=1323752685,
bits=data.FloatingInteger(437159528),
nonce=3658685446,
- )) == 0x000000000000003aaaf7638f9f9c0d0c60e8b0eb817dcdb55fd2b1964efc5175
+ ))) == 0x000000000000003aaaf7638f9f9c0d0c60e8b0eb817dcdb55fd2b1964efc5175
def test_tx_hash(self):
- assert data.tx_type.hash256(dict(
+ assert data.hash256(data.tx_type.pack(dict(
version=1,
tx_ins=[dict(
previous_output=None,
script=data.pubkey_hash_to_script2(pack.IntType(160).unpack('ca975b00a8c203b8692f5a18d92dc5c2d2ebc57b'.decode('hex'))),
)],
lock_time=0,
- )) == 0xb53802b2333e828d6532059f46ecf6b313a42d79f97925e457fbbfda45367e5c
+ ))) == 0xb53802b2333e828d6532059f46ecf6b313a42d79f97925e457fbbfda45367e5c
def test_address_to_pubkey_hash(self):
assert data.address_to_pubkey_hash('1KUCp7YP5FP8ViRxhfszSUJCTAajK6viGy', networks.BitcoinMainnet) == pack.IntType(160).unpack('ca975b00a8c203b8692f5a18d92dc5c2d2ebc57b'.decode('hex'))
import binascii
-import hashlib
import struct
import p2pool
raise AssertionError((self._unpack(data), obj))
return data
-
-
- def hash160(self, obj):
- return IntType(160).unpack(hashlib.new('ripemd160', hashlib.sha256(self.pack(obj)).digest()).digest())
-
- def hash256(self, obj):
- return IntType(256).unpack(hashlib.sha256(hashlib.sha256(self.pack(obj)).digest()).digest())
-
- def scrypt(self, obj):
- import ltc_scrypt
- return IntType(256).unpack(ltc_scrypt.getPoWHash(self.pack(obj)))
class VarIntType(Type):
# redundancy doesn't matter here because bitcoin and p2pool both reencode before hashing
def write(self, file, item):
return self._inner_size.write(file, len(item)), item
-class PassthruType(Type):
- def read(self, file):
- return read(file, size(file))
-
- def write(self, file, item):
- return file, item
-
class EnumType(Type):
def __init__(self, inner, values):
self.inner = inner