From: Forrest Voight Date: Sun, 29 Jan 2012 03:21:19 +0000 (-0500) Subject: removed PassthruType and moved hashing functions from util.pack to bitcoin.data X-Git-Tag: 0.8.3~38 X-Git-Url: https://git.novaco.in/?p=p2pool.git;a=commitdiff_plain;h=c501411a570e672fd0bb2ffccd2b5935dec29049 removed PassthruType and moved hashing functions from util.pack to bitcoin.data --- diff --git a/p2pool/bitcoin/data.py b/p2pool/bitcoin/data.py index 921dd72..7d14079 100644 --- a/p2pool/bitcoin/data.py +++ b/p2pool/bitcoin/data.py @@ -5,6 +5,12 @@ import hashlib 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 @@ -137,7 +143,7 @@ def merkle_hash(hashes): 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] @@ -149,7 +155,7 @@ def calculate_merkle_branch(hashes, index): 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)], ) @@ -166,10 +172,10 @@ def calculate_merkle_branch(hashes, index): 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) @@ -189,13 +195,11 @@ human_address_type = ChecksummedType(pack.ComposedType([ ('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)) @@ -206,7 +210,7 @@ def address_to_pubkey_hash(address, net): # 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' diff --git a/p2pool/bitcoin/networks.py b/p2pool/bitcoin/networks.py index 52b1a87..e059daa 100644 --- a/p2pool/bitcoin/networks.py +++ b/p2pool/bitcoin/networks.py @@ -1,7 +1,7 @@ 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'), @@ -12,7 +12,7 @@ BitcoinMainnet = math.Object( '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( @@ -24,7 +24,7 @@ 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', ) @@ -37,7 +37,7 @@ NamecoinMainnet = math.Object( '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( @@ -49,7 +49,7 @@ 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', ) @@ -62,7 +62,7 @@ LitecoinMainnet = math.Object( '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( @@ -74,6 +74,6 @@ 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', ) diff --git a/p2pool/bitcoin/p2p.py b/p2pool/bitcoin/p2p.py index 36c15e9..09a80f1 100644 --- a/p2pool/bitcoin/p2p.py +++ b/p2pool/bitcoin/p2p.py @@ -213,13 +213,13 @@ class Protocol(BaseProtocol): ('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']) @@ -229,7 +229,7 @@ class Protocol(BaseProtocol): 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([]) @@ -277,7 +277,7 @@ class HeaderWrapper(object): @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 diff --git a/p2pool/data.py b/p2pool/data.py index 1c41329..ca67ff5 100644 --- a/p2pool/data.py +++ b/p2pool/data.py @@ -81,7 +81,7 @@ class Share(object): 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') @@ -115,10 +115,10 @@ class Share(object): 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 @@ -142,7 +142,7 @@ class Share(object): 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): @@ -260,7 +260,7 @@ def generate_transaction(tracker, share_data, block_target, desired_timestamp, n 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, ) diff --git a/p2pool/main.py b/p2pool/main.py index 2bddd4f..19d797f 100644 --- a/p2pool/main.py +++ b/p2pool/main.py @@ -475,7 +475,7 @@ def main(args, net, datadir_path): 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' % ( @@ -502,7 +502,7 @@ def main(args, net, datadir_path): 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: @@ -513,9 +513,9 @@ def main(args, net, datadir_path): 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:') @@ -527,8 +527,8 @@ def main(args, net, datadir_path): 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=[], diff --git a/p2pool/test/bitcoin/test_data.py b/p2pool/test/bitcoin/test_data.py index c98a7ca..756e0fe 100644 --- a/p2pool/test/bitcoin/test_data.py +++ b/p2pool/test/bitcoin/test_data.py @@ -6,17 +6,17 @@ from p2pool.util import pack 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, @@ -28,7 +28,7 @@ class Test(unittest.TestCase): 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')) diff --git a/p2pool/util/pack.py b/p2pool/util/pack.py index bed3c3b..4380907 100644 --- a/p2pool/util/pack.py +++ b/p2pool/util/pack.py @@ -1,5 +1,4 @@ import binascii -import hashlib import struct import p2pool @@ -80,17 +79,6 @@ class Type(object): 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 @@ -133,13 +121,6 @@ class VarStrType(Type): 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