working on tracker
authorforrest <forrest@470744a7-cac9-478e-843e-5ec1b25c69e8>
Sun, 10 Jul 2011 15:19:20 +0000 (15:19 +0000)
committerforrest <forrest@470744a7-cac9-478e-843e-5ec1b25c69e8>
Sun, 10 Jul 2011 15:19:20 +0000 (15:19 +0000)
git-svn-id: svn://forre.st/p2pool@1372 470744a7-cac9-478e-843e-5ec1b25c69e8

p2pool/bitcoin/p2p.py
p2pool/data.py
p2pool/p2p.py
p2pool/util/math.py

index aba9532..b756c2d 100644 (file)
@@ -35,6 +35,13 @@ class BaseProtocol(protocol.Protocol):
             
             payload = yield length
             
+            if self.compress:
+                try:
+                    payload = zlib.decompress(payload)
+                except:
+                    print 'FAILURE DECOMPRESSING'
+                    continue
+            
             if checksum is not None:
                 if hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] != checksum:
                     print 'RECV', command, checksum.encode('hex') if checksum is not None else None, repr(payload.encode('hex')), len(payload)
@@ -69,20 +76,21 @@ class BaseProtocol(protocol.Protocol):
                 traceback.print_exc()
                 continue
     
-    def sendPacket(self, command, payload2={}):
+    def sendPacket(self, command, payload2):
+        if len(command) >= 12:
+            raise ValueError('command too long')
         type_ = getattr(self, "message_" + command, None)
         if type_ is None:
             raise ValueError('invalid command')
         payload = type_.pack(payload2)
-        if len(command) >= 12:
-            raise ValueError('command too long')
         if self.use_checksum:
             checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
         else:
             checksum = ''
+        if self.compress:
+            payload = zlib.compress(payload)
         data = self._prefix + struct.pack('<12sI', command, len(payload)) + checksum + payload
         self.transport.write(data)
-        #print 'SEND', command, payload2
     
     def __getattr__(self, attr):
         prefix = 'send_'
@@ -98,6 +106,7 @@ class Protocol(BaseProtocol):
     
     version = 0
     
+    compress = False
     @property
     def use_checksum(self):
         return self.version >= 209
index 7bf30e3..6b2c4ee 100644 (file)
@@ -203,7 +203,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc
         share = dict(target=target2)
     
     dest_weights = {}
-    for share in itertools.chain([fake_share], itertools.islice(tracker.get_chain(previous_share_hash), net.CHAIN_LENGTH)):
+    for i, share in enumerate(itertools.chain([fake_share], itertools.islice(tracker.get_chain(previous_share_hash), net.CHAIN_LENGTH))):
         weight = bitcoin_data.target_to_average_attempts(share.share['target'])
         weight = max(weight, attempts_to_block - total_weight)
         
@@ -212,6 +212,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc
         
         if total_weight == attempts_to_block:
             break
+    assert total_weight == attempts_to_block or i == net.CHAIN_LENGTH + 1
     
     amounts = dict((script, subsidy*(199*weight)//(200*total_weight)) for (script, weight) in dest_weights.iteritems())
     amounts[net.SCRIPT] = amounts.get(net.SCRIPT, 0) + subsidy*1//200 # prevent fake previous p2pool blocks
@@ -243,13 +244,15 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc
 
 
 class Tracker(object):
-    def __init__(self):
+    def __init__(self, net):
+        self.net = net
+        
         self.shares = {} # hash -> share
         self.reverse_shares = {} # previous_share_hash -> share_hash
         
         self.heads = {} # head hash -> tail_hash
         self.tails = {} # tail hash -> set of head hashes
-        self.heights = {} # share hash -> height, to_share_hash
+        self.heights = {} # share_hash -> height_to, other_share_hash
     
     def add_share(self, share):
         if share.hash in self.shares:
@@ -335,8 +338,9 @@ if __name__ == '__main__':
         print share_hash, t.get_height_and_last(share_hash)
 
 class OkayTracker(Tracker):
-    def __init__(self):
-        Tracker.__init__(self)
+    def __init__(self, net):
+        Tracker.__init__(self, net)
+    """
         self.okay_cache = {} # hash -> height
     
     def is_okay(self, start, _height_after=0):
@@ -364,15 +368,32 @@ class OkayTracker(Tracker):
         # picking up last share from for loop, ew
         self.okay_cache.add(share)
         return validate(share, to_end_rev[::-1])
-    
-    def accept_share(self, share):
-        self.add_share(share)
-        
+    """
+    def think(self):
+        desired = set()
         for head in self.heads:
             height, last = self.get_height(head)
-            if last is None or height >= 2*self.net.CHAIN_LENGTH:
-                a
+            if last is not None and height < 2*self.net.CHAIN_LENGTH:
+                desired.add(last)
+                continue
+            first_to_verify = math.nth(self.get_chain(head), self.net.CHAIN_LENGTH - 1)
+            to_verify = []
+            for share_hash in self.get_chain(head):
+                if share_hash not in self.verified:
+                    to_verify.append(share_hash)
+            for share_hash in reversed(to_verify):
+                try:
+                    share.check(self, self.net)
+                except:
+                    print
+                    print "Share check failed:"
+                    traceback.print_exc()
+                    print
+                    break
+            else:
                 a
+        return desired
+
 class Chain(object):
     def __init__(self):
         pass
index cf53011..2aa5093 100644 (file)
@@ -25,6 +25,7 @@ class Protocol(bitcoin_p2p.BaseProtocol):
         self._prefix = self.node.net.PREFIX
     
     use_checksum = True
+    compress = True
     
     other_version = None
     node_var_watch = None
index 1c09e55..67a883d 100644 (file)
@@ -29,3 +29,9 @@ def clip(x, (low, high)):
         return high
     else:
         return x
+
+def nth(i, n=0):
+    i = iter(i)
+    for _ in xrange(n):
+        i.next()
+    return i.next()