cleaned up share creation
authorForrest Voight <forrest@forre.st>
Wed, 3 Oct 2012 05:41:43 +0000 (01:41 -0400)
committerForrest Voight <forrest@forre.st>
Wed, 3 Oct 2012 18:26:55 +0000 (14:26 -0400)
p2pool/data.py
p2pool/main.py
p2pool/work.py

index a114462..6b07096 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, net):
+    def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, other_transactions, 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'])
@@ -155,7 +155,7 @@ class Share(object):
             )) if previous_share is not None else desired_timestamp,
         )
         
-        return share_info, dict(
+        gentx = dict(
             version=1,
             tx_ins=[dict(
                 previous_output=None,
@@ -168,6 +168,20 @@ class Share(object):
             )],
             lock_time=0,
         )
+        
+        transactions = [gentx] + list(other_transactions)
+        
+        def get_share(header):
+            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)
+            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
     
     @classmethod
     def get_ref_hash(cls, net, share_info, ref_merkle_link):
@@ -245,7 +259,7 @@ class Share(object):
             return self.as_share1b()
     
     def check(self, tracker):
-        share_info, gentx = 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], 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)
         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 b22ffaf..be8f921 100644 (file)
@@ -50,7 +50,6 @@ def getwork(bitcoind, use_getblocktemplate=False):
         version=work['version'],
         previous_block=int(work['previousblockhash'], 16),
         transactions=map(bitcoin_data.tx_type.unpack, packed_transactions),
-        merkle_link=bitcoin_data.calculate_merkle_link([None] + map(bitcoin_data.hash256, packed_transactions), 0),
         subsidy=work['coinbasevalue'],
         time=work['time'] if 'time' in work else work['curtime'],
         bits=bitcoin_data.FloatingIntegerType().unpack(work['bits'].decode('hex')[::-1]) if isinstance(work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']),
index eea799c..f06eada 100644 (file)
@@ -181,7 +181,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
             mm_later = []
         
         if True:
-            share_info, generate_tx = p2pool_data.Share.generate_transaction(
+            share_info, transactions, get_share = p2pool_data.Share.generate_transaction(
                 tracker=self.tracker,
                 share_data=dict(
                     previous_share_hash=self.best_share_var.value,
@@ -204,6 +204,7 @@ 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']),
                 net=self.net,
             )
         
@@ -222,13 +223,9 @@ class WorkerBridge(worker_interface.WorkerBridge):
             target = max(target, aux_work['target'])
         target = math.clip(target, self.net.PARENT.SANE_TARGET_RANGE)
         
-        transactions = [generate_tx] + list(self.current_work.value['transactions'])
-        packed_generate_tx = bitcoin_data.tx_type.pack(generate_tx)
-        merkle_root = bitcoin_data.check_merkle_link(bitcoin_data.hash256(packed_generate_tx), self.current_work.value['merkle_link'])
-        
         getwork_time = time.time()
         lp_count = self.new_work_event.times
-        merkle_link = self.current_work.value['merkle_link']
+        merkle_link = bitcoin_data.calculate_merkle_link([bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)) for tx in transactions], 0)
         
         print 'New work for worker! Difficulty: %.06f Share difficulty: %.06f Total block value: %.6f %s including %i transactions' % (
             bitcoin_data.target_to_difficulty(target),
@@ -237,12 +234,10 @@ class WorkerBridge(worker_interface.WorkerBridge):
             len(self.current_work.value['transactions']),
         )
         
-        bits = self.current_work.value['bits']
-        previous_block = self.current_work.value['previous_block']
         ba = bitcoin_getwork.BlockAttempt(
             version=min(self.current_work.value['version'], 2),
             previous_block=self.current_work.value['previous_block'],
-            merkle_root=merkle_root,
+            merkle_root=bitcoin_data.check_merkle_link(bitcoin_data.hash256(bitcoin_data.tx_type.pack(transactions[0])), merkle_link),
             timestamp=self.current_work.value['time'],
             bits=self.current_work.value['bits'],
             share_target=target,
@@ -264,9 +259,9 @@ class WorkerBridge(worker_interface.WorkerBridge):
                 log.err(None, 'Error while processing potential block:')
             
             user, _, _, _ = self.get_user_details(request)
-            assert header['merkle_root'] == merkle_root
-            assert header['previous_block'] == previous_block
-            assert header['bits'] == bits
+            assert header['previous_block'] == ba.previous_block
+            assert header['merkle_root'] == ba.merkle_root
+            assert header['bits'] == ba.bits
             
             on_time = self.new_work_event.times == lp_count
             
@@ -298,12 +293,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:
-                min_header = dict(header);del min_header['merkle_root']
-                hash_link = p2pool_data.prefix_to_hash_link(packed_generate_tx[:-32-4], p2pool_data.Share.gentx_before_refhash)
-                share = p2pool_data.Share(self.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)
+                share = get_share(header)
                 
                 print 'GOT SHARE! %s %s prev %s age %.2fs%s' % (
                     request.getUser(),