changed merkle functions to accept hashes instead txs
authorForrest Voight <forrest@forre.st>
Tue, 13 Dec 2011 06:11:56 +0000 (01:11 -0500)
committerForrest Voight <forrest@forre.st>
Tue, 13 Dec 2011 06:11:56 +0000 (01:11 -0500)
p2pool/bitcoin/data.py
p2pool/data.py
p2pool/main.py
p2pool/test/bitcoin/test_data.py

index 051e331..ad090f2 100644 (file)
@@ -471,19 +471,19 @@ merkle_record_type = ComposedType([
     ('right', HashType()),
 ])
 
-def merkle_hash(tx_list):
-    if not tx_list:
+def merkle_hash(hashes):
+    if not hashes:
         return 0
-    hash_list = map(tx_type.hash256, tx_list)
+    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))
             for left, right in zip(hash_list[::2], hash_list[1::2] + [None])]
     return hash_list[0]
 
-def calculate_merkle_branch(txs, index):
+def calculate_merkle_branch(hashes, index):
     # XXX optimize this
     
-    hash_list = [(tx_type.hash256(tx), i == index, []) for i, tx in enumerate(txs)]
+    hash_list = [(h, i == index, []) for i, h in enumerate(hashes)]
     
     while len(hash_list) > 1:
         hash_list = [
@@ -499,16 +499,16 @@ def calculate_merkle_branch(txs, index):
     res = [x['hash'] for x in hash_list[0][2]]
     
     assert hash_list[0][1]
-    assert check_merkle_branch(txs[index], index, res) == hash_list[0][0]
+    assert check_merkle_branch(hashes[index], index, res) == hash_list[0][0]
     assert index == sum(k*2**i for i, k in enumerate([1-x['side'] for x in hash_list[0][2]]))
     
     return res
 
-def check_merkle_branch(tx, index, merkle_branch):
+def check_merkle_branch(tip_hash, index, merkle_branch):
     return reduce(lambda c, (i, h): merkle_record_type.hash256(
         dict(left=h, right=c) if 2**i & index else
         dict(left=c, right=h)
-    ), enumerate(merkle_branch), tx_type.hash256(tx))
+    ), enumerate(merkle_branch), tip_hash)
 
 def target_to_average_attempts(target):
     return 2**256//(target + 1)
index 25a3d88..a42b97e 100644 (file)
@@ -82,7 +82,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([dict(version=0, tx_ins=[], tx_outs=[], lock_time=0)] + other_txs, 0)
+            new_merkle_branch = bitcoin_data.calculate_merkle_branch([0] + map(bitcoin_data.tx_type.hash256, other_txs), 0)
             if merkle_branch is not None:
                 if merke_branch != new_merkle_branch:
                     raise ValueError('invalid merkle_branch and other_txs')
@@ -145,7 +145,7 @@ class Share(object):
         if share_info != self.share_info:
             raise ValueError('share difficulty invalid')
         
-        if bitcoin_data.check_merkle_branch(gentx, 0, self.merkle_branch) != self.header['merkle_root']:
+        if bitcoin_data.check_merkle_branch(bitcoin_data.tx_type.hash256(gentx), 0, self.merkle_branch) != self.header['merkle_root']:
             raise ValueError('''gentx doesn't match header via merkle_branch''')
     
     def as_share(self):
index 38521d6..4fd2188 100644 (file)
@@ -457,7 +457,7 @@ def main(args, net, datadir_path):
             )
             
             transactions = [generate_tx] + list(current_work2.value['transactions'])
-            merkle_root = bitcoin_data.merkle_hash(transactions)
+            merkle_root = bitcoin_data.merkle_hash(map(bitcoin_data.tx_type.hash256, transactions))
             merkle_root_to_transactions[merkle_root] = share_info, transactions, time.time()
             
             return bitcoin_getwork.BlockAttempt(state['version'], state['previous_block'], merkle_root, current_work2.value['time'], state['target'], share_info['target']), state['best_share_hash']
@@ -495,7 +495,7 @@ def main(args, net, datadir_path):
                             merkle_tx=dict(
                                 tx=transactions[0],
                                 block_hash=hash_,
-                                merkle_branch=[x['hash'] for x in p2pool_data.calculate_merkle_branch(transactions, 0)],
+                                merkle_branch=[x['hash'] for x in p2pool_data.calculate_merkle_branch(map(bitcoin_data.tx_type.hash256, transactions), 0)],
                                 index=0,
                             ),
                             merkle_branch=[],
index 8064d01..6b690b2 100644 (file)
@@ -32,7 +32,36 @@ class Test(unittest.TestCase):
     def test_address_to_pubkey_hash(self):
         assert data.address_to_pubkey_hash('1KUCp7YP5FP8ViRxhfszSUJCTAajK6viGy', networks.BitcoinMainnet) == data.ShortHashType().unpack('ca975b00a8c203b8692f5a18d92dc5c2d2ebc57b'.decode('hex'))
     
-    # merkle_hash should accept hashes, not txs
-    #def test_merkle_hash(self):
-    #    x = [0xb53802b2333e828d6532059f46ecf6b313a42d79f97925e457fbbfda45367e5c, 0x326dfe222def9cf571af37a511ccda282d83bedcc01dabf8aa2340d342398cf0, 0x5d2e0541c0f735bac85fa84bfd3367100a3907b939a0c13e558d28c6ffd1aea4, 0x8443faf58aa0079760750afe7f08b759091118046fe42794d3aca2aa0ff69da2, 0x4d8d1c65ede6c8eab843212e05c7b380acb82914eef7c7376a214a109dc91b9d, 0x1d750bc0fa276f89db7e6ed16eb1cf26986795121f67c03712210143b0cb0125, 0x5179349931d714d3102dfc004400f52ef1fed3b116280187ca85d1d638a80176, 0xa8b3f6d2d566a9239c9ad9ae2ed5178dee4a11560a8dd1d9b608fd6bf8c1e75, 0xab4d07cd97f9c0c4129cff332873a44efdcd33bdbfc7574fe094df1d379e772f, 0xf54a7514b1de8b5d9c2a114d95fba1e694b6e3e4a771fda3f0333515477d685b, 0x894e972d8a2fc6c486da33469b14137a7f89004ae07b95e63923a3032df32089, 0x86cdde1704f53fce33ab2d4f5bc40c029782011866d0e07316d695c41e32b1a0, 0xf7cf4eae5e497be8215778204a86f1db790d9c27fe6a5b9f745df5f3862f8a85, 0x2e72f7ddf157d64f538ec72562a820e90150e8c54afc4d55e0d6e3dbd8ca50a, 0x9f27471dfbc6ce3cbfcf1c8b25d44b8d1b9d89ea5255e9d6109e0f9fd662f75c, 0x995f4c9f78c5b75a0c19f0a32387e9fa75adaa3d62fba041790e06e02ae9d86d, 0xb11ec2ad2049aa32b4760d458ee9effddf7100d73c4752ea497e54e2c58ba727, 0xa439f288fbc5a3b08e5ffd2c4e2d87c19ac2d5e4dfc19fabfa33c7416819e1ec, 0x3aa33f886f1357b4bbe81784ec1cf05873b7c5930ab912ee684cc6e4f06e4c34, 0xcab9a1213037922d94b6dcd9c567aa132f16360e213c202ee59f16dde3642ac7, 0xa2d7a3d2715eb6b094946c6e3e46a88acfb37068546cabe40dbf6cd01a625640, 0x3d02764f24816aaa441a8d472f58e0f8314a70d5b44f8a6f88cc8c7af373b24e, 0xcc5adf077c969ebd78acebc3eb4416474aff61a828368113d27f72ad823214d0, 0xf2d8049d1971f02575eb37d3a732d46927b6be59a18f1bd0c7f8ed123e8a58a, 0x94ffe8d46a1accd797351894f1774995ed7df3982c9a5222765f44d9c3151dbb, 0x82268fa74a878636261815d4b8b1b01298a8bffc87336c0d6f13ef6f0373f1f0, 0x73f441f8763dd1869fe5c2e9d298b88dc62dc8c75af709fccb3622a4c69e2d55, 0xeb78fc63d4ebcdd27ed618fd5025dc61de6575f39b2d98e3be3eb482b210c0a0, 0x13375a426de15631af9afdf00c490e87cc5aab823c327b9856004d0b198d72db, 0x67d76a64fa9b6c5d39fde87356282ef507b3dec1eead4b54e739c74e02e81db4]
-    #    assert data.merkle_hash(x) == 0x37a43a3b812e4eb665975f46393b4360008824aab180f27d642de8c28073bc44
+    def test_merkle_hash(self):
+        assert data.merkle_hash([
+            0xb53802b2333e828d6532059f46ecf6b313a42d79f97925e457fbbfda45367e5c,
+            0x326dfe222def9cf571af37a511ccda282d83bedcc01dabf8aa2340d342398cf0,
+            0x5d2e0541c0f735bac85fa84bfd3367100a3907b939a0c13e558d28c6ffd1aea4,
+            0x8443faf58aa0079760750afe7f08b759091118046fe42794d3aca2aa0ff69da2,
+            0x4d8d1c65ede6c8eab843212e05c7b380acb82914eef7c7376a214a109dc91b9d,
+            0x1d750bc0fa276f89db7e6ed16eb1cf26986795121f67c03712210143b0cb0125,
+            0x5179349931d714d3102dfc004400f52ef1fed3b116280187ca85d1d638a80176,
+            0xa8b3f6d2d566a9239c9ad9ae2ed5178dee4a11560a8dd1d9b608fd6bf8c1e75,
+            0xab4d07cd97f9c0c4129cff332873a44efdcd33bdbfc7574fe094df1d379e772f,
+            0xf54a7514b1de8b5d9c2a114d95fba1e694b6e3e4a771fda3f0333515477d685b,
+            0x894e972d8a2fc6c486da33469b14137a7f89004ae07b95e63923a3032df32089,
+            0x86cdde1704f53fce33ab2d4f5bc40c029782011866d0e07316d695c41e32b1a0,
+            0xf7cf4eae5e497be8215778204a86f1db790d9c27fe6a5b9f745df5f3862f8a85, 
+            0x2e72f7ddf157d64f538ec72562a820e90150e8c54afc4d55e0d6e3dbd8ca50a,
+            0x9f27471dfbc6ce3cbfcf1c8b25d44b8d1b9d89ea5255e9d6109e0f9fd662f75c, 
+            0x995f4c9f78c5b75a0c19f0a32387e9fa75adaa3d62fba041790e06e02ae9d86d, 
+            0xb11ec2ad2049aa32b4760d458ee9effddf7100d73c4752ea497e54e2c58ba727, 
+            0xa439f288fbc5a3b08e5ffd2c4e2d87c19ac2d5e4dfc19fabfa33c7416819e1ec, 
+            0x3aa33f886f1357b4bbe81784ec1cf05873b7c5930ab912ee684cc6e4f06e4c34, 
+            0xcab9a1213037922d94b6dcd9c567aa132f16360e213c202ee59f16dde3642ac7,
+            0xa2d7a3d2715eb6b094946c6e3e46a88acfb37068546cabe40dbf6cd01a625640,
+            0x3d02764f24816aaa441a8d472f58e0f8314a70d5b44f8a6f88cc8c7af373b24e,
+            0xcc5adf077c969ebd78acebc3eb4416474aff61a828368113d27f72ad823214d0,
+            0xf2d8049d1971f02575eb37d3a732d46927b6be59a18f1bd0c7f8ed123e8a58a,
+            0x94ffe8d46a1accd797351894f1774995ed7df3982c9a5222765f44d9c3151dbb,
+            0x82268fa74a878636261815d4b8b1b01298a8bffc87336c0d6f13ef6f0373f1f0,
+            0x73f441f8763dd1869fe5c2e9d298b88dc62dc8c75af709fccb3622a4c69e2d55,
+            0xeb78fc63d4ebcdd27ed618fd5025dc61de6575f39b2d98e3be3eb482b210c0a0,
+            0x13375a426de15631af9afdf00c490e87cc5aab823c327b9856004d0b198d72db,
+            0x67d76a64fa9b6c5d39fde87356282ef507b3dec1eead4b54e739c74e02e81db4,
+        ]) == 0x37a43a3b812e4eb665975f46393b4360008824aab180f27d642de8c28073bc44