memory reductions
authorForrest Voight <forrest@forre.st>
Thu, 28 Jul 2011 00:40:48 +0000 (20:40 -0400)
committerForrest Voight <forrest@forre.st>
Thu, 28 Jul 2011 00:40:48 +0000 (20:40 -0400)
p2pool/bitcoin/data.py
p2pool/bitcoin/getwork.py
p2pool/bitcoin/p2p.py
p2pool/data.py
p2pool/p2p.py

index f49d1c9..1fd550f 100644 (file)
@@ -235,12 +235,41 @@ class IPV6AddressType(Type):
         assert len(data) == 16, len(data)
         return file, data
 
+_record_types = {}
+
+def get_record(fields):
+    fields = tuple(sorted(fields))
+    if 'keys' in fields:
+        raise ValueError()
+    if fields not in _record_types:
+        class _Record(object):
+            __slots__ = fields
+            def __getitem__(self, key):
+                return getattr(self, key)
+            def __setitem__(self, key, value):
+                setattr(self, key, value)
+            #def __iter__(self):
+            #    for field in self.__slots__:
+            #        yield field, getattr(self, field)
+            def keys(self):
+                return self.__slots__
+            def __eq__(self, other):
+                if isinstance(other, dict):
+                    return dict(self) == other
+                elif isinstance(other, _Record):
+                    return all(self[k] == other[k] for k in self.keys())
+                raise TypeError()
+            def __ne__(self, other):
+                return not (self == other)
+        _record_types[fields] = _Record
+    return _record_types[fields]()
+
 class ComposedType(Type):
     def __init__(self, fields):
         self.fields = fields
     
     def read(self, file):
-        item = {}
+        item = get_record(k for k, v in self.fields)
         for key, type_ in self.fields:
             item[key], file = type_.read(file)
         return item, file
@@ -419,7 +448,7 @@ def pubkey_hash_to_script2(pubkey_hash):
 class Tracker(object):
     def __init__(self):
         self.shares = {} # hash -> share
-        self.ids = {} # hash -> (id, height)
+        #self.ids = {} # hash -> (id, height)
         self.reverse_shares = {} # previous_hash -> set of share_hashes
         
         self.heads = {} # head hash -> tail_hash
@@ -427,8 +456,10 @@ class Tracker(object):
         
         self.heights = {} # share_hash -> height_to, other_share_hash
         
+        '''
         self.id_generator = itertools.count()
         self.tails_by_id = {}
+        '''
         
         self.get_nth_parent_hash = skiplist.DistanceSkipList(self)
     
@@ -437,6 +468,7 @@ class Tracker(object):
         if share.hash in self.shares:
             return # XXX raise exception?
         
+        '''
         parent_id = self.ids.get(share.previous_hash, None)
         children_ids = set(self.ids.get(share2_hash) for share2_hash in self.reverse_shares.get(share.hash, set()))
         infos = set()
@@ -448,6 +480,7 @@ class Tracker(object):
             infos.add((self.id_generator.next(), 0))
         chosen = min(infos)
         self.ids[share.hash] = chosen
+        '''
         
         self.shares[share.hash] = share
         self.reverse_shares.setdefault(share.previous_hash, set()).add(share.hash)
index 88c2233..c973a2a 100644 (file)
@@ -56,7 +56,7 @@ class BlockAttempt(object):
     
     @classmethod
     def from_getwork(cls, getwork, _check=3):
-        attrs = decode_data(getwork['data'])
+        attrs = dict(decode_data(getwork['data']))
         attrs.pop('nonce')
         attrs['target2'] = int(getwork['target'].decode('hex')[::-1].encode('hex'), 16)
         
index 3df304d..9ac30bb 100644 (file)
@@ -314,10 +314,12 @@ class ClientFactory(protocol.ReconnectingClientFactory):
         return self.conn.get_not_none()
 
 class HeaderWrapper(object):
+    target = -1
+    __slots__ = 'hash previous_hash'.split(' ')
+    
     def __init__(self, header):
         self.hash = bitcoin_data.block_header_type.hash256(header)
         self.previous_hash = header['previous_block']
-        self.target = header['target']
 
 class HeightTracker(object):
     '''Point this at a factory and let it take care of getting block heights'''
index 78fa21e..ea12863 100644 (file)
@@ -97,9 +97,6 @@ def share_info_to_gentx(share_info, block_target, tracker, net):
     )
 
 class Share(object):
-    peer = None
-    highest_block_on_arrival = None
-    
     @classmethod
     def from_block(cls, block):
         return cls(block['header'], gentx_to_share_info(block['txs'][0]), other_txs=block['txs'][1:])
@@ -112,6 +109,8 @@ class Share(object):
     def from_share1b(cls, share1b):
         return cls(**share1b)
     
+    __slots__ = 'header previous_block share_info merkle_branch other_txs timestamp share_data new_script subsidy previous_hash previous_share_hash target nonce bitcoin_hash hash time_seen shared peer'.split(' ')
+    
     def __init__(self, header, 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')
@@ -158,8 +157,10 @@ class Share(object):
         if script.get_sigop_count(self.new_script) > 1:
             raise ValueError('too many sigops!')
         
+        # XXX eww
         self.time_seen = time.time()
         self.shared = False
+        self.peer = None
     
     def as_block(self, tracker, net):
         if self.other_txs is None:
@@ -195,8 +196,6 @@ class Share(object):
             
             if len(bitcoin_data.block_type.pack(dict(header=self.header, txs=[gentx] + self.other_txs))) > 1000000 - 1000:
                 raise ValueError('''block size too large''')
-        
-        self.gentx = gentx
     
     def flag_shared(self):
         self.shared = True
index 113eaed..88d8cf6 100644 (file)
@@ -206,7 +206,6 @@ class Protocol(bitcoin_p2p.BaseProtocol):
                 return
             share = p2pool_data.Share.from_share1a(share1a)
             share.peer = self # XXX
-            share.highest_block_on_arrival = self.node.current_work.value['previous_block'] # XXX
             shares.append(share)
         self.node.handle_shares(shares, self)
     
@@ -223,7 +222,6 @@ class Protocol(bitcoin_p2p.BaseProtocol):
                 return
             share = p2pool_data.Share.from_share1b(share1b)
             share.peer = self # XXX
-            share.highest_block_on_arrival = self.node.current_work.value['previous_block'] # XXX
             shares.append(share)
         self.node.handle_shares(shares, self)