expanded get_shares to include parents
authorforrest <forrest@470744a7-cac9-478e-843e-5ec1b25c69e8>
Thu, 14 Jul 2011 14:27:48 +0000 (14:27 +0000)
committerforrest <forrest@470744a7-cac9-478e-843e-5ec1b25c69e8>
Thu, 14 Jul 2011 14:27:48 +0000 (14:27 +0000)
git-svn-id: svn://forre.st/p2pool@1388 470744a7-cac9-478e-843e-5ec1b25c69e8

p2pool/bitcoin/data.py
p2pool/data.py
p2pool/main.py
p2pool/p2p.py

index f4ec5d4..e93d612 100644 (file)
@@ -444,7 +444,7 @@ class Tracker(object):
             height += height_inc
         for update_hash, height_then in updates:
             self.heights[update_hash] = height - height_then, share_hash
-        assert (height, share_hash) == self.get_height_and_last2(orig), ((height, share_hash), self.get_height_and_last2(orig))
+        #assert (height, share_hash) == self.get_height_and_last2(orig), ((height, share_hash), self.get_height_and_last2(orig))
         return height, share_hash
     
     def get_height_and_last2(self, share_hash):
index bf1295d..b79f4c2 100644 (file)
@@ -235,7 +235,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc
     lookbehind = 200
     chain = list(itertools.islice(tracker.get_chain_to_root(previous_share_hash), lookbehind))
     if len(chain) < lookbehind:
-        target2 = bitcoin_data.FloatingIntegerType().truncate_to(2**256//2**24 - 1)
+        target2 = bitcoin_data.FloatingIntegerType().truncate_to(2**256//2**20 - 1)
     else:
         attempts = sum(bitcoin_data.target_to_average_attempts(share.target2) for share in chain[:-1])
         time = chain[0].timestamp - chain[-1].timestamp
@@ -244,7 +244,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc
         attempts_per_second = attempts//time
         pre_target = 2**256//(net.SHARE_PERIOD*attempts_per_second) - 1
         pre_target2 = math.clip(pre_target, (previous_share2.target2*9//10, previous_share2.target2*11//10))
-        pre_target3 = math.clip(pre_target2, (0, 2**256//2**24 - 1))
+        pre_target3 = math.clip(pre_target2, (0, 2**256//2**20 - 1))
         target2 = bitcoin_data.FloatingIntegerType().truncate_to(pre_target3)
         print attempts_per_second//1000, 'KHASH'
         #print 'TARGET', 2**256//target2, 2**256/pre_target
@@ -339,7 +339,7 @@ class OkayTracker(bitcoin_data.Tracker):
         for head in self.heads:
             head_height, last = self.get_height_and_last(head)
             
-            for share in itertools.islice(self.get_chain_known(head), None if last is None else head_height - self.net.CHAIN_LENGTH):
+            for share in itertools.islice(self.get_chain_known(head), None if last is None else max(0, head_height - self.net.CHAIN_LENGTH)):
                 if self.attempt_verify(share):
                     break
             else:
@@ -370,11 +370,12 @@ class OkayTracker(bitcoin_data.Tracker):
             attempts = 0
             max_height = 0
             # XXX should only look past a certain share, not at recent ones
-            share2_hash = self.verified.get_nth_parent(share_hash, self.net.CHAIN_LENGTH//2)
+            share2_hash = self.verified.get_nth_parent_hash(share_hash, self.net.CHAIN_LENGTH//2) if last is not None else share_hash
             for share in itertools.islice(self.verified.get_chain_known(share2_hash), self.net.CHAIN_LENGTH):
                 max_height = max(max_height, ht.get_min_height(share.header['previous_block']))
                 attempts += bitcoin_data.target_to_average_attempts(share.target2)
                 this_score = attempts//(ht.get_highest_height() - max_height + 1)
+                #this_score = -(ht.get_highest_height() - max_height + 1)//attempts
                 if this_score > score2:
                     score2 = this_score
             res = (min(head_height, self.net.CHAIN_LENGTH), score2)
@@ -397,7 +398,7 @@ class Mainnet(bitcoin_data.Mainnet):
 
 class Testnet(bitcoin_data.Testnet):
     SHARE_PERIOD = 5 # seconds
-    CHAIN_LENGTH = 24*60*60//5 # shares
+    CHAIN_LENGTH = 60*60//5 # shares
     SPREAD = 3 # blocks
     SCRIPT = '410403ad3dee8ab3d8a9ce5dd2abfbe7364ccd9413df1d279bf1a207849310465b0956e5904b1155ecd17574778f9949589ebfd4fb33ce837c241474a225cf08d85dac'.decode('hex')
     IDENTIFIER = '1ae3479e4eb6700a'.decode('hex')
index 56e764d..e6e098d 100644 (file)
@@ -203,7 +203,9 @@ def main(args):
         def set_real_work():
             work, height = yield getwork(bitcoind)
             best, desired = tracker.think(ht)
-            # XXX desired?
+            for peer2, share_hash in desired:
+                print 'Requesting parent share %x' % (share_hash,)
+                peer2.send_getshares(hashes=[share_hash], parents=2000)
             current_work.set(dict(
                 version=work.version,
                 previous_block=work.previous_block,
@@ -239,9 +241,9 @@ def main(args):
             
             tracker.add(share)
             best, desired = tracker.think(ht)
-            for peer2, share_hash in desired:
-                print 'Requesting parent share %x' % (share_hash,)
-                peer2.send_getshares(hashes=[share_hash])
+            #for peer2, share_hash in desired:
+            #    print 'Requesting parent share %x' % (share_hash,)
+            #    peer2.send_getshares(hashes=[share_hash], parents=2000)
             
             if share.gentx is not None:
                 if share.hash <= share.header['target']:
@@ -267,9 +269,10 @@ def main(args):
                 print 'Got share hash, already have, ignoring. Hash: %x' % (share_hash,)
             else:
                 print 'Got share hash, requesting! Hash: %x' % (share_hash,)
-                peer.send_getshares(hashes=[share_hash])
+                peer.send_getshares(hashes=[share_hash], parents=0)
         
         def p2p_get_to_best(chain_id_data, have, peer):
+            # XXX
             chain = get_chain(chain_id_data)
             if chain.highest.value is None:
                 return
@@ -285,10 +288,11 @@ def main(args):
                     continue
                 peer.send_share(chain.share2s[share_hash].share, full=True) # doesn't have to be full ... but does that still guarantee ordering?
         
-        def p2p_get_shares(share_hashes, peer):
+        def p2p_get_shares(share_hashes, parents, peer):
+            parents = min(parents, 100//len(share_hashes))
             for share_hash in share_hashes:
-                if share_hash in tracker.shares:
-                    peer.send_share(tracker.shares[share_hash], full=True)
+                for share in itertools.islice(tracker.get_chain_known(share_hash), parents + 1):
+                    peer.send_share(share, full=True)
         
         print 'Joining p2pool network using TCP port %i...' % (args.p2pool_port,)
         
index 212e4c3..877b4de 100644 (file)
@@ -183,9 +183,10 @@ class Protocol(bitcoin_p2p.BaseProtocol):
     
     message_getshares = bitcoin_data.ComposedType([
         ('hashes', bitcoin_data.ListType(bitcoin_data.HashType())),
+        ('parents', bitcoin_data.VarIntType()),
     ])
-    def handle_getshares(self, hashes):
-        self.node.handle_get_shares(hashes, self)
+    def handle_getshares(self, hashes, parents):
+        self.node.handle_get_shares(hashes, parents, self)
     
     message_share0s = bitcoin_data.ComposedType([
         ('hashes', bitcoin_data.ListType(bitcoin_data.HashType())),
@@ -409,8 +410,8 @@ class Node(object):
     def handle_get_to_best(self, have, peer):
         print 'handle_get_to_best', (have, peer)
     
-    def handle_get_shares(self, hashes, peer):
-        print 'handle_get_shares', (hashes, peer)
+    def handle_get_shares(self, hashes, parents, peer):
+        print 'handle_get_shares', (hashes, parents, peer)
 
 if __name__ == '__main__':
     p = random.randrange(2**15, 2**16)