changed share creation function to require only transaction hashes instead of full...
authorForrest Voight <forrest@forre.st>
Wed, 3 Oct 2012 20:07:01 +0000 (16:07 -0400)
committerForrest Voight <forrest@forre.st>
Wed, 3 Oct 2012 20:26:20 +0000 (16:26 -0400)
p2pool/data.py
p2pool/work.py

index 6b07096..da1e9eb 100644 (file)
@@ -113,7 +113,7 @@ class Share(object):
     gentx_before_refhash = pack.VarStrType().pack(DONATION_SCRIPT) + pack.IntType(64).pack(0) + pack.VarStrType().pack('\x20' + pack.IntType(256).pack(0))[:2]
     
     @classmethod
-    def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, other_transactions, net):
+    def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, other_transaction_hashes, net):
         previous_share = tracker.items[share_data['previous_share_hash']] if share_data['previous_share_hash'] is not None else None
         
         height, last = tracker.get_height_and_last(share_data['previous_share_hash'])
@@ -169,19 +169,18 @@ class Share(object):
             lock_time=0,
         )
         
-        transactions = [gentx] + list(other_transactions)
-        
-        def get_share(header):
+        def get_share(header, transactions):
+            assert transactions[0] == gentx and [bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)) for tx in transactions[1:]] == other_transaction_hashes
             min_header = dict(header);del min_header['merkle_root']
             hash_link = prefix_to_hash_link(bitcoin_data.tx_type.pack(gentx)[:-32-4], cls.gentx_before_refhash)
-            merkle_link = bitcoin_data.calculate_merkle_link([bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)) for tx in transactions], 0)
+            merkle_link = bitcoin_data.calculate_merkle_link([None] + other_transaction_hashes, 0)
             pow_hash = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(header))
             return cls(net, None, dict(
                 min_header=min_header, share_info=share_info, hash_link=hash_link,
                 ref_merkle_link=dict(branch=[], index=0),
             ), merkle_link=merkle_link, other_txs=transactions[1:] if pow_hash <= header['bits'].target else None)
         
-        return share_info, transactions, get_share
+        return share_info, gentx, other_transaction_hashes, get_share
     
     @classmethod
     def get_ref_hash(cls, net, share_info, ref_merkle_link):
@@ -259,7 +258,7 @@ class Share(object):
             return self.as_share1b()
     
     def check(self, tracker):
-        share_info, [gentx], get_share = self.generate_transaction(tracker, self.share_info['share_data'], self.header['bits'].target, self.share_info['timestamp'], self.share_info['bits'].target, self.common['ref_merkle_link'], [], self.net)
+        share_info, gentx, other_transaction_hashes, get_share = self.generate_transaction(tracker, self.share_info['share_data'], self.header['bits'].target, self.share_info['timestamp'], self.share_info['bits'].target, self.common['ref_merkle_link'], [], self.net) # ok because other_transaction_hashes is only used in get_share
         if share_info != self.share_info:
             raise ValueError('share_info invalid')
         if bitcoin_data.hash256(bitcoin_data.tx_type.pack(gentx)) != self.gentx_hash:
index f06eada..dfdde9e 100644 (file)
@@ -180,8 +180,11 @@ class WorkerBridge(worker_interface.WorkerBridge):
             mm_data = ''
             mm_later = []
         
+        tx_hashes = [bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)) for tx in self.current_work.value['transactions']]
+        tx_map = dict(zip(tx_hashes, self.current_work.value['transactions']))
+        
         if True:
-            share_info, transactions, get_share = p2pool_data.Share.generate_transaction(
+            share_info, gentx, other_transaction_hashes, get_share = p2pool_data.Share.generate_transaction(
                 tracker=self.tracker,
                 share_data=dict(
                     previous_share_hash=self.best_share_var.value,
@@ -204,10 +207,12 @@ class WorkerBridge(worker_interface.WorkerBridge):
                 desired_timestamp=int(time.time() + 0.5),
                 desired_target=desired_share_target,
                 ref_merkle_link=dict(branch=[], index=0),
-                other_transactions=list(self.current_work.value['transactions']),
+                other_transaction_hashes=tx_hashes,
                 net=self.net,
             )
         
+        transactions = [gentx] + [tx_map[tx_hash] for tx_hash in other_transaction_hashes]
+        
         mm_later = [(dict(aux_work, target=aux_work['target'] if aux_work['target'] != 'p2pool' else share_info['bits'].target), index, hashes) for aux_work, index, hashes in mm_later]
         
         if desired_pseudoshare_target is None:
@@ -293,7 +298,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
                     log.err(None, 'Error while processing merged mining POW:')
             
             if pow_hash <= share_info['bits'].target and header_hash not in received_header_hashes:
-                share = get_share(header)
+                share = get_share(header, transactions)
                 
                 print 'GOT SHARE! %s %s prev %s age %.2fs%s' % (
                     request.getUser(),