def try_address_thread(self, address, the_node, result): if self.online and self.address == address: result.append(0) return key = self.info['key'] id_test_result = [] yield 'wait', identity_test_thread(address, key, the_node, id_test_result) if not id_test_result[0]: print "identity did not pass test" #result.append(0) #return ticket,template, wait = the_node.call(address,('identity query',)) if wait: yield 'call',(the_node,ticket) try: info = the_node.get_reply(ticket,template) except: result.append(0) return if not check.matches(info, Acquaintance.info_template): node.bad_peer(address, _("bad response to 'identity query': ") + `info`) result.append(0) return self.info = info if info.get('peer-name') == the_node.name: result.append(0) return ticket,template, wait = the_node.call(address,('identity watch',)) if wait: yield 'call',(the_node,ticket) try: status = the_node.get_reply(ticket,template) except: result.append(0) return if type(status) != types.DictionaryType: status = { } was_online = self.online self.address = address self.online = 1 self.watched = 1 self.status = status # up_time is an interval. connect_time is time in my zone. up_time = self.info.get('up time') if type(up_time) == types.IntType: self.connect_time = time.time() - up_time else: self.connect_time = None if self.drm: the_node.trusted_addresses.append(address) else: while address in the_node.trusted_addresses: the_node.trusted_addresses.remove(address) self.start_watching(the_node) self.name_server.acquaintance_status_changed(self, 'discover') result.append(not was_online) return
def gossip_fetch_thread(self,acq): self.fetch_threads+=1 if not self.running: self.fetch_threads-=1 return if acq.distance != None: #acq.start_watching(self.node, 1) acq.lock.acquire() online = acq.online address = acq.address distance = acq.distance acq.lock.release() if distance == None or not online: self.fetch_threads-=1 return pos = 0 fetch_timeout = node.make_timeout(settings.gossip_fetch_time) while not node.is_timed_out(fetch_timeout): try: ticket, template, wait = self.node.call(address,('gossip list',pos,pos+20)) if wait: yield 'call',(self.node,ticket) result = self.node.get_reply(ticket,template) if not check.matches(result, [(types.IntType, 'any', 'any')]): node.bad_peer(address, _("Bad reply to 'gossip list': ") + `result`) break if len(result) == 0: break all_ok = 1 # effic: sort self.gossip, sort the returned results, # to speed up searches for signatures. However, I # haven't yet seen gossip_fetch_task come up in # profiles. for item in result: already_there = 0 for wodge in self.gossip: if wodge.signature == item[2]: #if wodge.distance(self.app.name_server) > from_fixed(item[0])+distance: # # TODO: What to do with unit_decay_time? # wodge.initial_distance = from_fixed(item[0])+distance # wodge.initial_time = time.time() wodge.opinions[acq.name] = from_fixed(item[0]) - wodge.decay() already_there = 1 break if already_there: continue try: ticket, template, wait = self.node.call( address,('gossip get',item[2])) if wait: yield 'call',(self.node,ticket) string = self.node.get_reply(ticket, template) wodgewodge = safe_pickle.loads(string) except error.Error: all_ok = 0 break #TODO: Confirm signature of known people wodge = Wodge({ 'wodge': wodgewodge, 'string': string, 'signature': item[2], 'initial_time': time.time(), 'initial_distance': None, #'initial_distance': from_fixed(item[0]) + distance 'unit_decay_time': item[1], 'opinions': { acq.name : from_fixed(item[0]) }, 'collapsed': 0}) if not self.insert_wodge(wodge): all_ok = 0 break if not all_ok: break pos = pos + 18 except error.Error: break self.fetch_threads-=1