compensate for old shares being forgotton in stale calculations
authorForrest Voight <forrest@forre.st>
Mon, 15 Aug 2011 06:01:26 +0000 (02:01 -0400)
committerForrest Voight <forrest@forre.st>
Mon, 15 Aug 2011 06:01:26 +0000 (02:01 -0400)
p2pool/bitcoin/data.py
p2pool/main.py

index e87f2eb..e520c19 100644 (file)
@@ -736,6 +736,14 @@ class Tracker(object):
     
     def get_highest_height(self):
         return max(self.get_height_and_last(head)[0] for head in self.heads) if self.heads else 0
+    
+    def is_child_of(self, share_hash, possible_child_hash):
+        height, last = self.get_height_and_last(share_hash)
+        child_height, child_last = self.get_height_and_last(possible_child_hash)
+        if child_last != last:
+            return None # not connected, so can't be determined
+        height_up = child_height - height
+        return height_up >= 0 and self.get_nth_parent_hash(possible_child_hash, height_up) == share_hash
 
 class FakeShare(object):
     def __init__(self, **kwargs):
index 1c41f93..a03c568 100644 (file)
@@ -343,12 +343,17 @@ def main(args):
         run_identifier = struct.pack('<Q', random.randrange(2**64))
         
         share_counter = skiplists.CountsSkipList(tracker, run_identifier)
+        removed_unstales = set()
         def get_share_counts():
             height, last = tracker.get_height_and_last(current_work.value['best_share_hash'])
-            matching_in_chain = share_counter(current_work.value['best_share_hash'], height)
+            matching_in_chain = share_counter(current_work.value['best_share_hash'], height) | removed_unstales
             shares_in_chain = my_shares & matching_in_chain
             stale_shares = my_shares - matching_in_chain
             return len(shares_in_chain) + len(stale_shares), len(stale_shares)
+        @tracker.verified.removed.watch
+        def _(share):
+            if share.hash in my_shares and tracker.is_child_of(share.hash, current_work.value['best_share_hash']):
+                removed_unstales.add(share.hash)
         
         def compute(state, payout_script):
             if payout_script is None: