diff --git a/libp2p/routing/kadmelia/__init__.py b/libp2p/routing/kadmelia/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/libp2p/routing/kadmelia/kadmelia_content_router.py b/libp2p/routing/kadmelia/kadmelia_content_router.py new file mode 100644 index 00000000..d96269a8 --- /dev/null +++ b/libp2p/routing/kadmelia/kadmelia_content_router.py @@ -0,0 +1,19 @@ +from libp2p.routing.interfaces import IContentRouting + + +class KadmeliaContentRouter(IContentRouting): + + def provide(self, cid, announce=True): + """ + Provide adds the given cid to the content routing system. If announce is True, + it also announces it, otherwise it is just kept in the local + accounting of which objects are being provided. + """ + pass + + def find_provider_iter(self, cid, count): + """ + Search for peers who are able to provide a given key + returns an iterator of peer.PeerInfo + """ + pass diff --git a/libp2p/routing/kadmelia/kadmelia_peer_router.py b/libp2p/routing/kadmelia/kadmelia_peer_router.py new file mode 100644 index 00000000..0201b7d3 --- /dev/null +++ b/libp2p/routing/kadmelia/kadmelia_peer_router.py @@ -0,0 +1,30 @@ +from libp2p.routing.interfaces import IPeerRouting +from libp2p.kademlia.utils import digest +from libp2p.peer.peerinfo import PeerInfo +from libp2p.peer.peerdata import PeerData + + +class KadmeliaPeerRouter(IPeerRouting): + + def __init__(self, dht_server): + self.server = dht_server + + def find_peer(self, peer_id): + """ + Find specific Peer + FindPeer searches for a peer with given peer_id, returns a peer.PeerInfo + with relevant addresses. + """ + value = self.server.get(peer_id) + return decode_peerinfo(value) + + +def decode_peerinfo(encoded): + if isinstance(encoded, bytes): + encoded = encoded.decode() + lines = encoded.splitlines() + peer_id = lines[0] + addrs = lines[1:] + peer_data = PeerData() + peer_data.add_addrs(addrs) + return PeerInfo(peer_id, addrs) diff --git a/tests/kademlia/test_basic.py b/tests/kademlia/test_basic.py new file mode 100644 index 00000000..e35154bf --- /dev/null +++ b/tests/kademlia/test_basic.py @@ -0,0 +1,81 @@ +import pytest +from libp2p.kademlia.network import Server + + +@pytest.mark.asyncio +async def test_example(): + node_a = Server() + await node_a.listen(5678) + + node_b = Server() + await node_b.listen(5679) + + # Bootstrap the node by connecting to other known nodes, in this case + # replace 123.123.123.123 with the IP of another node and optionally + # give as many ip/port combos as you can for other nodes. + await node_b.bootstrap([("127.0.0.1", 5678)]) + + # set a value for the key "my-key" on the network + value = "my-value" + key = "my-key" + await node_b.set(key, value) + + # get the value associated with "my-key" from the network + assert await node_b.get(key) == value + assert await node_a.get(key) == value + + +@pytest.mark.parametrize("nodes_nr", [(2**i) for i in range(2, 5)]) +@pytest.mark.asyncio +async def test_multiple_nodes_bootstrap_set_get(nodes_nr): + nodes_nr = 25 + + node_bootstrap = Server() + await node_bootstrap.listen(5678) + + nodes = [] + for i in range(nodes_nr): + node = Server() + addrs = [("127.0.0.1", 5678)] + await node.listen(5679 + i) + await node.bootstrap(addrs) + nodes.append(node) + + for i, node in enumerate(nodes): + # set a value for the key "my-key" on the network + value = "my awesome value %d" % i + key = "set from %d" % i + await node.set(key, value) + + for i in range(nodes_nr): + for node in nodes: + value = "my awesome value %d" % i + key = "set from %d" % i + assert await node.get(key) == value + + +@pytest.mark.parametrize("nodes_nr", [(2**i) for i in range(2, 5)]) +@pytest.mark.asyncio +async def test_multiple_nodes_set_bootstrap_get(nodes_nr): + nodes_nr = 25 + + node_bootstrap = Server() + await node_bootstrap.listen(5678) + + nodes = [] + for i in range(nodes_nr): + node = Server() + addrs = [("127.0.0.1", 5678)] + await node.listen(5679 + i) + await node.bootstrap(addrs) + + value = "my awesome value %d" % i + key = "set from %d" % i + await node.set(key, value) + nodes.append(node) + + for i in range(nodes_nr): + for node in nodes: + value = "my awesome value %d" % i + key = "set from %d" % i + assert await node.get(key) == value