added new_share_type share wrapper and finished new p2p code
authorForrest Voight <forrest.voight@gmail.com>
Fri, 25 Nov 2011 22:05:22 +0000 (17:05 -0500)
committerForrest Voight <forrest.voight@gmail.com>
Fri, 25 Nov 2011 22:05:22 +0000 (17:05 -0500)
p2pool/data.py
p2pool/p2p.py

index 53e4736..1810398 100644 (file)
@@ -77,6 +77,15 @@ new_share1b_type = bitcoin_data.ComposedType([
     ('other_txs', bitcoin_data.ListType(bitcoin_data.tx_type)),
 ])
 
+# type:
+# 0: new_share1a
+# 1: new_share1b
+
+new_share_type = bitcoin_data.ComposedType([
+    ('type', bitcoin_data.VarIntType()),
+    ('contents', bitcoin_data.VarStrType()),
+])
+
 def calculate_merkle_branch(txs, index):
     hash_list = [(bitcoin_data.tx_type.hash256(tx), i == index, []) for i, tx in enumerate(txs)]
     
@@ -235,6 +244,29 @@ class Share(object):
         return '<Share %s>' % (' '.join('%s=%r' % (k, getattr(self, k)) for k in self.__slots__),)
 
 class NewShare(Share):
+    @classmethod
+    def from_share(cls, share, net):
+        if share['type'] == 0:
+            res = self.from_share1a(new_share1a_type.unpack(share['contents']), net)
+            if not (res.pow_hash > res.header['target']):
+                raise ValueError('invalid share type')
+            return res
+        elif share['type'] == 1:
+            res = self.from_share1b(new_share1b_type.unpack(share['contents']), net)
+            if not (res.pow_hash <= res.header['target']):
+                raise ValueError('invalid share type')
+            return res
+        else:
+            raise ValueError('unknown share type: %r' % (share['type'],))
+    
+    def as_share(self):
+        if self.pow_hash > self.header['target']: # new_share1a
+            return dict(type=0, contents=new_share1a_type.pack(self.as_share1a()))
+        elif self.pow_hash <= self.header['target']: # new_share1b
+            return dict(type=1, contents=new_share1b_type.pack(self.as_share1b()))
+        else:
+            raise AssertionError()
+    
     def __init__(self, net, header, new_share_info, merkle_branch=None, other_txs=None):
         if merkle_branch is None and other_txs is None:
             raise ValueError('need either merkle_branch or other_txs')
@@ -660,12 +692,8 @@ class ShareStore(object):
                             verified_hash = int(data_hex, 16)
                             yield 'verified_hash', verified_hash
                             verified_hashes.add(verified_hash)
-                        elif type_id == 3:
-                            share = NewShare.from_share1a(new_share1a_type.unpack(data_hex.decode('hex')), self.net)
-                            yield 'share', share
-                            share_hashes.add(share.hash)
-                        elif type_id == 4:
-                            share = NewShare.from_share1b(new_share1b_type.unpack(data_hex.decode('hex')), self.net)
+                        elif type_id == 5:
+                            share = NewShare.from_share(new_share_type.unpack(data_hex.decode('hex')), self.net)
                             yield 'share', share
                             share_hashes.add(share.hash)
                         else:
@@ -687,10 +715,8 @@ class ShareStore(object):
         return filename
     
     def add_share(self, share):
-        if isinstance(share, NewShare) and share.pow_hash <= share.header['target']:
-            type_id, data = 4, new_share1b_type.pack(share.as_share1b())
-        elif isinstance(share, NewShare):
-            type_id, data = 3, new_share1a_type.pack(share.as_share1a())
+        if isinstance(share, NewShare):
+            type_id, data = 5, new_share_type.pack(share.as_share())
         elif share.pow_hash <= share.header['target']:
             type_id, data = 1, share1b_type.pack(share.as_share1b())
         else:
index 78ae6e9..49f3d7d 100644 (file)
@@ -207,11 +207,10 @@ class Protocol(bitcoin_p2p.BaseProtocol):
         self.node.handle_share_hashes(hashes, self)
     
     message_shares = bitcoin_data.ComposedType([
-        ('share1as', bitcoin_data.ListType(p2pool_data.new_share1a_type)),
-        ('share1bs', bitcoin_data.ListType(p2pool_data.new_share1b_type)),
+        ('shares', bitcoin_data.ListType(p2pool_data.new_share_type)),
     ])
-    def handle_shares(self):
-        xxx
+    def handle_shares(self, shares):
+        self.node.handle_shares([p2pool_data.Share.from_share(x, self.node.net) for x in shares], self)
     
     message_share1as = bitcoin_data.ComposedType([
         ('share1as', bitcoin_data.ListType(p2pool_data.share1a_type)),
@@ -247,21 +246,12 @@ class Protocol(bitcoin_p2p.BaseProtocol):
         share0s = []
         share1as = []
         share1bs = []
-        new_share1as = []
-        new_share1bs = []
+        new_shares = []
         # XXX doesn't need to send full block when it's not urgent
         # eg. when getting history
         for share in shares:
             if isinstance(share, p2pool_data.NewShare):
-                if share.pow_hash <= share.header['target']:
-                    new_share1bs.append(share.as_share1b())
-                else:
-                    if self.mode == 0 and not full:
-                        share0s.append(share.hash)
-                    elif self.mode == 1 or full:
-                        new_share1as.append(share.as_share1a())
-                    else:
-                        raise ValueError(self.mode)
+                new_shares.append(share.as_share())
             else:
                 if share.pow_hash <= share.header['target']:
                     share1bs.append(share.as_share1b())
@@ -281,7 +271,7 @@ class Protocol(bitcoin_p2p.BaseProtocol):
         if share0s: att(self.send_share0s, hashes=share0s)
         if share1as: att(self.send_share1as, share1as=share1as)
         if share1bs: att(self.send_share1bs, share1bs=share1bs)
-        if new_share1as or new_share1bs: att(self.send_shares, share1as=new_share1as, share1bs=new_share1bs)
+        if new_shares: att(self.send_shares, shares=new_shares)
     
     def connectionLost(self, reason):
         if self.node_var_watch is not None: