def __init__(self, protocol, node, peers, ksize, alpha): self.protocol = protocol self.ksize = ksize self.alpha = alpha self.node = node self.nearest = NodeHeap(self.node, self.ksize) self.last_ids_crawled = [] log.info("creating spider with peers: %s", peers) self.nearest.push(peers)
class SpiderCrawl: def __init__(self, protocol, node, peers, ksize, alpha): self.protocol = protocol self.ksize = ksize self.alpha = alpha self.node = node self.nearest = NodeHeap(self.node, self.ksize) self.last_ids_crawled = [] log.info("creating spider with peers: %s", peers) self.nearest.push(peers) async def _find(self, rpcmethod): log.info("crawling network with nearest: %s", str(tuple(self.nearest))) count = self.alpha if self.nearest.get_ids() == self.last_ids_crawled: count = len(self.nearest) self.last_ids_crawled = self.nearest.get_ids() dicts = {} for peer in self.nearest.get_uncontacted()[:count]: dicts[peer.id] = rpcmethod(peer, self.node) self.nearest.mark_contacted(peer) found = await gather_dict(dicts) return await self._nodes_found(found) async def _nodes_found(self, responses): raise NotImplementedError
def __init__(self, protocol, node, peers, ksize, alpha): """ Create a new C{SpiderCrawl}er. Args: protocol: A :class:`~kademlia.protocol.KademliaProtocol` instance. node: A :class:`~kademlia.node.Node` representing the key we're looking for peers: A list of :class:`~kademlia.node.Node` instances that provide the entry point for the network ksize: The value for k based on the paper alpha: The value for alpha based on the paper """ self.protocol = protocol self.ksize = ksize self.alpha = alpha self.node = node self.nearest = NodeHeap(self.node, self.ksize) self.lastIDsCrawled = [] self.log = Logger(system=self) self.log.info("creating spider with peers: %s" % peers) self.nearest.push(peers)
class ValueSpiderCrawl(SpiderCrawl): def __init__(self, protocol, node, peers, ksize, alpha): SpiderCrawl.__init__(self, protocol, node, peers, ksize, alpha) # keep track of the single nearest node without value - per # section 2.3 so we can set the key there if found self.nearestWithoutValue = NodeHeap(self.node, 1) def find(self): """ Find either the closest nodes or the value requested. """ return self._find(self.protocol.callGetPeers) def _nodesFound(self, responses): """ Handle the result of an iteration in _find. """ toremove = [] foundValues = [] for peerid, response in responses.items(): response = RPCFindResponse(response) if not response.happened(): toremove.append(peerid) elif response.hasValues(): foundValues.extend(response.getValues()) else: peer = self.nearest.getNodeById(peerid) self.nearestWithoutValue.push(peer) self.nearest.push(response.getNodeList()) self.nearest.remove(toremove) if len(foundValues) > 0: return list(set(foundValues)) # return unique list of values elif self.nearest.allBeenContacted(): return None # not found! else: return self.find()
class ValueSpiderCrawl(SpiderCrawl): def __init__(self, protocol, node, peers, ksize, alpha): SpiderCrawl.__init__(self, protocol, node, peers, ksize, alpha) self.nearest_without_value = NodeHeap(self.node, 1) async def find(self): return await self._find(self.protocol.call_find_value) async def _nodes_found(self, responses): toremove = [] found_values = [] for peerid, response in responses.items(): response = RPCFindResponse(response) if not response.happened(): toremove.append(peerid) elif response.has_value(): found_values.append(response.get_value()) else: peer = self.nearest.get_node(peerid) self.nearest_without_value.push(peer) self.nearest.push(response.get_node_list()) self.nearest.remove(toremove) if found_values: return await self._handle_found_values(found_values) if self.nearest.have_contacted_all(): # not found! return None return await self.find() async def _handle_found_values(self, values): value_counts = Counter(values) if len(value_counts) != 1: pass # log.warning("Got multiple values for key %i: %s", self.node.long_id, str(values)) value = value_counts.most_common(1)[0][0] peer = self.nearest_without_value.popleft() if peer: await self.protocol.call_store(peer, self.node.id, value) return value
class SpiderCrawl(object): """ Crawl the network and look for given 160-bit keys. """ def __init__(self, protocol, node, peers, ksize, alpha): """ Create a new C{SpiderCrawl}er. Args: protocol: A :class:`~kademlia.protocol.KademliaProtocol` instance. node: A :class:`~kademlia.node.Node` representing the key we're looking for peers: A list of :class:`~kademlia.node.Node` instances that provide the entry point for the network ksize: The value for k based on the paper alpha: The value for alpha based on the paper """ self.protocol = protocol self.ksize = ksize self.alpha = alpha self.node = node self.nearest = NodeHeap(self.node, self.ksize) self.lastIDsCrawled = [] self.log = Logger(system=self) self.log.info("creating spider with peers: %s" % peers) self.nearest.push(peers) def _find(self, rpcmethod): """ Get either a value or list of nodes. Args: rpcmethod: The protocol's callfindValue or callFindNode. The process: 1. calls find_* to current ALPHA nearest not already queried nodes, adding results to current nearest list of k nodes. 2. current nearest list needs to keep track of who has been queried already sort by nearest, keep KSIZE 3. if list is same as last time, next call should be to everyone not yet queried 4. repeat, unless nearest list has all been queried, then ur done """ self.log.info("crawling with nearest: %s" % str(tuple(self.nearest))) count = self.alpha if self.nearest.getIDs() == self.lastIDsCrawled: self.log.info( "last iteration same as current - checking all in list now") count = len(self.nearest) self.lastIDsCrawled = self.nearest.getIDs() ds = {} for peer in self.nearest.getUncontacted()[:count]: ds[peer.id] = rpcmethod(peer, self.node) self.nearest.markContacted(peer) return deferred_dict(ds).addCallback(self._nodesFound)
def __init__(self, protocol, node, peers, ksize, alpha): SpiderCrawl.__init__(self, protocol, node, peers, ksize, alpha) # keep track of the single nearest node without value - per # section 2.3 so we can set the key there if found self.nearestWithoutValue = NodeHeap(self.node, 1)
def __init__(self, protocol, node, peers, ksize, alpha): SpiderCrawl.__init__(self, protocol, node, peers, ksize, alpha) self.nearest_without_value = NodeHeap(self.node, 1)