mirror of
https://github.com/varun-r-mallya/py-libp2p.git
synced 2026-02-11 07:30:55 +00:00
update kadmelia lib
This commit is contained in:
committed by
Christophe de Carvalho
parent
57077cd3b4
commit
c24a279d2d
@ -4,41 +4,41 @@ import logging
|
||||
|
||||
from rpcudp.protocol import RPCProtocol
|
||||
|
||||
from .kademlia.node import Node
|
||||
from .kademlia.routing import RoutingTable
|
||||
from .kademlia.utils import digest
|
||||
from .node import Node
|
||||
from .routing import RoutingTable
|
||||
from .utils import digest
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
log = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||
|
||||
|
||||
class KademliaProtocol(RPCProtocol):
|
||||
def __init__(self, sourceNode, storage, ksize):
|
||||
def __init__(self, source_node, storage, ksize):
|
||||
RPCProtocol.__init__(self)
|
||||
self.router = RoutingTable(self, ksize, sourceNode)
|
||||
self.router = RoutingTable(self, ksize, source_node)
|
||||
self.storage = storage
|
||||
self.sourceNode = sourceNode
|
||||
self.source_node = source_node
|
||||
|
||||
def getRefreshIDs(self):
|
||||
def get_refresh_ids(self):
|
||||
"""
|
||||
Get ids to search for to keep old buckets up to date.
|
||||
"""
|
||||
ids = []
|
||||
for bucket in self.router.getLonelyBuckets():
|
||||
for bucket in self.router.lonely_buckets():
|
||||
rid = random.randint(*bucket.range).to_bytes(20, byteorder='big')
|
||||
ids.append(rid)
|
||||
return ids
|
||||
|
||||
def rpc_stun(self, sender):
|
||||
def rpc_stun(self, sender): # pylint: disable=no-self-use
|
||||
return sender
|
||||
|
||||
def rpc_ping(self, sender, nodeid):
|
||||
source = Node(nodeid, sender[0], sender[1])
|
||||
self.welcomeIfNewNode(source)
|
||||
return self.sourceNode.id
|
||||
self.welcome_if_new(source)
|
||||
return self.source_node.id
|
||||
|
||||
def rpc_store(self, sender, nodeid, key, value):
|
||||
source = Node(nodeid, sender[0], sender[1])
|
||||
self.welcomeIfNewNode(source)
|
||||
self.welcome_if_new(source)
|
||||
log.debug("got a store request from %s, storing '%s'='%s'",
|
||||
sender, key.hex(), value)
|
||||
self.storage[key] = value
|
||||
@ -48,42 +48,42 @@ class KademliaProtocol(RPCProtocol):
|
||||
log.info("finding neighbors of %i in local table",
|
||||
int(nodeid.hex(), 16))
|
||||
source = Node(nodeid, sender[0], sender[1])
|
||||
self.welcomeIfNewNode(source)
|
||||
self.welcome_if_new(source)
|
||||
node = Node(key)
|
||||
neighbors = self.router.findNeighbors(node, exclude=source)
|
||||
neighbors = self.router.find_neighbors(node, exclude=source)
|
||||
return list(map(tuple, neighbors))
|
||||
|
||||
def rpc_find_value(self, sender, nodeid, key):
|
||||
source = Node(nodeid, sender[0], sender[1])
|
||||
self.welcomeIfNewNode(source)
|
||||
self.welcome_if_new(source)
|
||||
value = self.storage.get(key, None)
|
||||
if value is None:
|
||||
return self.rpc_find_node(sender, nodeid, key)
|
||||
return {'value': value}
|
||||
|
||||
async def callFindNode(self, nodeToAsk, nodeToFind):
|
||||
address = (nodeToAsk.ip, nodeToAsk.port)
|
||||
result = await self.find_node(address, self.sourceNode.id,
|
||||
nodeToFind.id)
|
||||
return self.handleCallResponse(result, nodeToAsk)
|
||||
async def call_find_node(self, node_to_ask, node_to_find):
|
||||
address = (node_to_ask.ip, node_to_ask.port)
|
||||
result = await self.find_node(address, self.source_node.id,
|
||||
node_to_find.id)
|
||||
return self.handle_call_response(result, node_to_ask)
|
||||
|
||||
async def callFindValue(self, nodeToAsk, nodeToFind):
|
||||
address = (nodeToAsk.ip, nodeToAsk.port)
|
||||
result = await self.find_value(address, self.sourceNode.id,
|
||||
nodeToFind.id)
|
||||
return self.handleCallResponse(result, nodeToAsk)
|
||||
async def call_find_value(self, node_to_ask, node_to_find):
|
||||
address = (node_to_ask.ip, node_to_ask.port)
|
||||
result = await self.find_value(address, self.source_node.id,
|
||||
node_to_find.id)
|
||||
return self.handle_call_response(result, node_to_ask)
|
||||
|
||||
async def callPing(self, nodeToAsk):
|
||||
address = (nodeToAsk.ip, nodeToAsk.port)
|
||||
result = await self.ping(address, self.sourceNode.id)
|
||||
return self.handleCallResponse(result, nodeToAsk)
|
||||
async def call_ping(self, node_to_ask):
|
||||
address = (node_to_ask.ip, node_to_ask.port)
|
||||
result = await self.ping(address, self.source_node.id)
|
||||
return self.handle_call_response(result, node_to_ask)
|
||||
|
||||
async def callStore(self, nodeToAsk, key, value):
|
||||
address = (nodeToAsk.ip, nodeToAsk.port)
|
||||
result = await self.store(address, self.sourceNode.id, key, value)
|
||||
return self.handleCallResponse(result, nodeToAsk)
|
||||
async def call_store(self, node_to_ask, key, value):
|
||||
address = (node_to_ask.ip, node_to_ask.port)
|
||||
result = await self.store(address, self.source_node.id, key, value)
|
||||
return self.handle_call_response(result, node_to_ask)
|
||||
|
||||
def welcomeIfNewNode(self, node):
|
||||
def welcome_if_new(self, node):
|
||||
"""
|
||||
Given a new node, send it all the keys/values it should be storing,
|
||||
then add it to the routing table.
|
||||
@ -97,32 +97,32 @@ class KademliaProtocol(RPCProtocol):
|
||||
is closer than the closest in that list, then store the key/value
|
||||
on the new node (per section 2.5 of the paper)
|
||||
"""
|
||||
if not self.router.isNewNode(node):
|
||||
if not self.router.is_new_node(node):
|
||||
return
|
||||
|
||||
log.info("never seen %s before, adding to router", node)
|
||||
for key, value in self.storage.items():
|
||||
for key, value in self.storage:
|
||||
keynode = Node(digest(key))
|
||||
neighbors = self.router.findNeighbors(keynode)
|
||||
if len(neighbors) > 0:
|
||||
last = neighbors[-1].distanceTo(keynode)
|
||||
newNodeClose = node.distanceTo(keynode) < last
|
||||
first = neighbors[0].distanceTo(keynode)
|
||||
thisNodeClosest = self.sourceNode.distanceTo(keynode) < first
|
||||
if len(neighbors) == 0 or (newNodeClose and thisNodeClosest):
|
||||
asyncio.ensure_future(self.callStore(node, key, value))
|
||||
self.router.addContact(node)
|
||||
neighbors = self.router.find_neighbors(keynode)
|
||||
if neighbors:
|
||||
last = neighbors[-1].distance_to(keynode)
|
||||
new_node_close = node.distance_to(keynode) < last
|
||||
first = neighbors[0].distance_to(keynode)
|
||||
this_closest = self.source_node.distance_to(keynode) < first
|
||||
if not neighbors or (new_node_close and this_closest):
|
||||
asyncio.ensure_future(self.call_store(node, key, value))
|
||||
self.router.add_contact(node)
|
||||
|
||||
def handleCallResponse(self, result, node):
|
||||
def handle_call_response(self, result, node):
|
||||
"""
|
||||
If we get a response, add the node to the routing table. If
|
||||
we get no response, make sure it's removed from the routing table.
|
||||
"""
|
||||
if not result[0]:
|
||||
log.warning("no response from %s, removing from router", node)
|
||||
self.router.removeContact(node)
|
||||
self.router.remove_contact(node)
|
||||
return result
|
||||
|
||||
log.info("got successful response from %s", node)
|
||||
self.welcomeIfNewNode(node)
|
||||
self.welcome_if_new(node)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user