self._inventory={}#of objects (like msg payloads and pubkey payloads) Does not include protocol headers (the first 24 bytes of each packet).
self._streams=collections.defaultdict(set)# key = streamNumer, value = a set which holds the inventory object hashes that we are aware of. This is used whenever we receive an inv message from a peer to check to see what items are new to us. We don't delete things out of it; instead, the singleCleaner thread clears and refills it every couple hours.
self.lock=RLock()# Guarantees that two receiveDataThreads don't receive and process the same message concurrently (probably sent by a malicious individual)
def__contains__(self,hash):
withself.lock:
ifhashinself._inventory:
returnTrue
returnbool(sqlQuery('SELECT 1 FROM inventory WHERE hash=?',hash))
def__getitem__(self,hash):
withself.lock:
ifhashinself._inventory:
returnself._inventory[hash]
rows=sqlQuery('SELECT objecttype, streamnumber, payload, expirestime, tag FROM inventory WHERE hash=?',hash)
ifnotrows:
raiseKeyError(hash)
returnInventoryItem(*rows[0])
def__setitem__(self,hash,value):
withself.lock:
value=InventoryItem(*value)
self._inventory[hash]=value
self._streams[value.stream].add(hash)
def__delitem__(self,hash):
raiseNotImplementedError
def__iter__(self):
withself.lock:
hashes=self._inventory.keys()[:]
hashes+=(xforx,insqlQuery('SELECT hash FROM inventory'))
returnhashes.__iter__()
def__len__(self):
withself.lock:
returnlen(self._inventory)+sqlQuery('SELECT count(*) FROM inventory')[0][0]
values+=(InventoryItem(*value)forvalueinsqlQuery('SELECT objecttype, streamnumber, payload, expirestime, tag FROM inventory WHERE objecttype=? AND tag=?',objectType,sqlite3.Binary(tag)))