added RoutedHost and updated new_node to support it
This commit is contained in:
parent
367a939087
commit
e7424d3673
|
@ -6,8 +6,10 @@ from .peer.peerstore import PeerStore
|
||||||
from .peer.id import id_from_public_key
|
from .peer.id import id_from_public_key
|
||||||
from .network.swarm import Swarm
|
from .network.swarm import Swarm
|
||||||
from .host.basic_host import BasicHost
|
from .host.basic_host import BasicHost
|
||||||
|
from .kademlia.routed_host import RoutedHost
|
||||||
from .transport.upgrader import TransportUpgrader
|
from .transport.upgrader import TransportUpgrader
|
||||||
from .transport.tcp.tcp import TCP
|
from .transport.tcp.tcp import TCP
|
||||||
|
from .kademlia.network import KademliaServer
|
||||||
|
|
||||||
|
|
||||||
async def cleanup_done_tasks():
|
async def cleanup_done_tasks():
|
||||||
|
@ -23,6 +25,30 @@ async def cleanup_done_tasks():
|
||||||
# Some sleep necessary to context switch
|
# Some sleep necessary to context switch
|
||||||
await asyncio.sleep(3)
|
await asyncio.sleep(3)
|
||||||
|
|
||||||
|
def generate_id():
|
||||||
|
new_key = RSA.generate(2048, e=65537)
|
||||||
|
new_id = id_from_public_key(new_key.publickey())
|
||||||
|
# private_key = new_key.exportKey("PEM")
|
||||||
|
return new_id
|
||||||
|
|
||||||
|
def initialize_default_kademlia(
|
||||||
|
ksize=20, alpha=3, id_opt=None, storage=None):
|
||||||
|
"""
|
||||||
|
initialize swam when no swarm is passed in
|
||||||
|
:param ksize: The k parameter from the paper
|
||||||
|
:param alpha: The alpha parameter from the paper
|
||||||
|
:param id_opt: optional id for host
|
||||||
|
:param storage: An instance that implements
|
||||||
|
:interface:`~kademlia.storage.IStorage`
|
||||||
|
:return: return a default kademlia instance
|
||||||
|
"""
|
||||||
|
if not id_opt:
|
||||||
|
id_opt = generate_id()
|
||||||
|
|
||||||
|
node_id = id_opt.get_raw_id()
|
||||||
|
return KademliaServer(ksize=ksize, alpha=alpha,
|
||||||
|
node_id=node_id, storage=storage)
|
||||||
|
|
||||||
|
|
||||||
def initialize_default_swarm(
|
def initialize_default_swarm(
|
||||||
id_opt=None, transport_opt=None,
|
id_opt=None, transport_opt=None,
|
||||||
|
@ -37,10 +63,9 @@ def initialize_default_swarm(
|
||||||
:return: return a default swarm instance
|
:return: return a default swarm instance
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-arguments, unused-argument
|
# pylint: disable=too-many-arguments, unused-argument
|
||||||
|
|
||||||
if not id_opt:
|
if not id_opt:
|
||||||
new_key = RSA.generate(2048, e=65537)
|
id_opt = generate_id()
|
||||||
id_opt = id_from_public_key(new_key.publickey())
|
|
||||||
# private_key = new_key.exportKey("PEM")
|
|
||||||
|
|
||||||
transport_opt = transport_opt or ["/ip4/127.0.0.1/tcp/8001"]
|
transport_opt = transport_opt or ["/ip4/127.0.0.1/tcp/8001"]
|
||||||
transport = [multiaddr.Multiaddr(t) for t in transport_opt]
|
transport = [multiaddr.Multiaddr(t) for t in transport_opt]
|
||||||
|
@ -58,7 +83,8 @@ def initialize_default_swarm(
|
||||||
|
|
||||||
async def new_node(
|
async def new_node(
|
||||||
swarm_opt=None, id_opt=None, transport_opt=None,
|
swarm_opt=None, id_opt=None, transport_opt=None,
|
||||||
muxer_opt=None, sec_opt=None, peerstore_opt=None):
|
muxer_opt=None, sec_opt=None, peerstore_opt=None,
|
||||||
|
disc_opt=None):
|
||||||
"""
|
"""
|
||||||
create new libp2p node
|
create new libp2p node
|
||||||
:param id_opt: optional id for host
|
:param id_opt: optional id for host
|
||||||
|
@ -69,15 +95,22 @@ async def new_node(
|
||||||
:return: return a default swarm instance
|
:return: return a default swarm instance
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
|
|
||||||
|
if not id_opt:
|
||||||
|
id_opt = generate_id()
|
||||||
|
|
||||||
if not swarm_opt:
|
if not swarm_opt:
|
||||||
swarm_opt = initialize_default_swarm(
|
swarm_opt = initialize_default_swarm(
|
||||||
id_opt=id_opt, transport_opt=transport_opt,
|
id_opt=id_opt, transport_opt=transport_opt,
|
||||||
muxer_opt=muxer_opt, sec_opt=sec_opt,
|
muxer_opt=muxer_opt, sec_opt=sec_opt,
|
||||||
peerstore_opt=peerstore_opt)
|
peerstore_opt=peerstore_opt)
|
||||||
|
if not disc_opt:
|
||||||
|
disc_opt = initialize_default_kademlia(ksize=20, alpha=3,
|
||||||
|
id_opt=id_opt, storage=None)
|
||||||
|
|
||||||
# TODO enable support for other host type
|
# TODO enable support for other host type
|
||||||
# TODO routing unimplemented
|
# TODO routing unimplemented
|
||||||
host = BasicHost(swarm_opt)
|
host = RoutedHost(swarm_opt, disc_opt)
|
||||||
|
|
||||||
# Kick off cleanup job
|
# Kick off cleanup job
|
||||||
asyncio.ensure_future(cleanup_done_tasks())
|
asyncio.ensure_future(cleanup_done_tasks())
|
||||||
|
|
|
@ -15,8 +15,7 @@ class KadPeerInfo(PeerInfo):
|
||||||
def __init__(self, peer_id, peer_data=None):
|
def __init__(self, peer_id, peer_data=None):
|
||||||
super(KadPeerInfo, self).__init__(peer_id, peer_data)
|
super(KadPeerInfo, self).__init__(peer_id, peer_data)
|
||||||
|
|
||||||
# pylint: disable=protected-access
|
self.peer_id = peer_id.get_raw_id()
|
||||||
self.peer_id = peer_id._id_str
|
|
||||||
self.long_id = int(digest(peer_id._id_str).hex(), 16)
|
self.long_id = int(digest(peer_id._id_str).hex(), 16)
|
||||||
|
|
||||||
self.addrs = peer_data.get_addrs() if peer_data else None
|
self.addrs = peer_data.get_addrs() if peer_data else None
|
||||||
|
|
|
@ -16,7 +16,7 @@ log = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
class Server:
|
class KademliaServer:
|
||||||
"""
|
"""
|
||||||
High level view of a node instance. This is the object that should be
|
High level view of a node instance. This is the object that should be
|
||||||
created to start listening as an active node on the network.
|
created to start listening as an active node on the network.
|
||||||
|
|
35
libp2p/kademlia/routed_host.py
Normal file
35
libp2p/kademlia/routed_host.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
from libp2p.host.basic_host import BasicHost
|
||||||
|
|
||||||
|
class RoutedHost(BasicHost):
|
||||||
|
def __init__(self, _network, _kad_network):
|
||||||
|
super(RoutedHost, self).__init__(_network)
|
||||||
|
self.kad_network = _kad_network
|
||||||
|
|
||||||
|
def get_kad_network(self):
|
||||||
|
return self.kad_network
|
||||||
|
|
||||||
|
def kad_listen(self, port, interface='0.0.0.0'):
|
||||||
|
return self.kad_network.listen(port, interface)
|
||||||
|
|
||||||
|
def kad_get(self, key):
|
||||||
|
return self.kad_network.get(key)
|
||||||
|
|
||||||
|
def kad_set(self, key, value):
|
||||||
|
return self.kad_network.set(key, value)
|
||||||
|
|
||||||
|
def kad_set_digest(self, dkey, value):
|
||||||
|
return self.kad_network.set_digest(dkey, value)
|
||||||
|
|
||||||
|
def check_dht_value_type(value):
|
||||||
|
"""
|
||||||
|
Checks to see if the type of the value is a valid type for
|
||||||
|
placing in the dht.
|
||||||
|
"""
|
||||||
|
typeset = [
|
||||||
|
int,
|
||||||
|
float,
|
||||||
|
bool,
|
||||||
|
str,
|
||||||
|
bytes
|
||||||
|
]
|
||||||
|
return type(value) in typeset # pylint: disable=unidiomatic-typecheck
|
|
@ -15,6 +15,9 @@ class ID:
|
||||||
def __init__(self, id_str):
|
def __init__(self, id_str):
|
||||||
self._id_str = id_str
|
self._id_str = id_str
|
||||||
|
|
||||||
|
def get_raw_id(self):
|
||||||
|
return self._id_str
|
||||||
|
|
||||||
def pretty(self):
|
def pretty(self):
|
||||||
return base58.b58encode(self._id_str).decode()
|
return base58.b58encode(self._id_str).decode()
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import pytest
|
import pytest
|
||||||
from libp2p.kademlia.network import Server
|
from libp2p.kademlia.network import KademliaServer
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_example():
|
async def test_example():
|
||||||
node_a = Server()
|
node_a = KademliaServer()
|
||||||
await node_a.listen(5678)
|
await node_a.listen(5678)
|
||||||
|
|
||||||
node_b = Server()
|
node_b = KademliaServer()
|
||||||
await node_b.listen(5679)
|
await node_b.listen(5679)
|
||||||
|
|
||||||
# Bootstrap the node by connecting to other known nodes, in this case
|
# Bootstrap the node by connecting to other known nodes, in this case
|
||||||
|
@ -29,12 +29,12 @@ async def test_example():
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_multiple_nodes_bootstrap_set_get(nodes_nr):
|
async def test_multiple_nodes_bootstrap_set_get(nodes_nr):
|
||||||
|
|
||||||
node_bootstrap = Server()
|
node_bootstrap = KademliaServer()
|
||||||
await node_bootstrap.listen(3000 + nodes_nr * 2)
|
await node_bootstrap.listen(3000 + nodes_nr * 2)
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for i in range(nodes_nr):
|
for i in range(nodes_nr):
|
||||||
node = Server()
|
node = KademliaServer()
|
||||||
addrs = [("127.0.0.1", 3000 + nodes_nr * 2)]
|
addrs = [("127.0.0.1", 3000 + nodes_nr * 2)]
|
||||||
await node.listen(3001 + i + nodes_nr * 2)
|
await node.listen(3001 + i + nodes_nr * 2)
|
||||||
await node.bootstrap(addrs)
|
await node.bootstrap(addrs)
|
||||||
|
@ -56,12 +56,12 @@ async def test_multiple_nodes_bootstrap_set_get(nodes_nr):
|
||||||
@pytest.mark.parametrize("nodes_nr", [(2**i) for i in range(2, 5)])
|
@pytest.mark.parametrize("nodes_nr", [(2**i) for i in range(2, 5)])
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_multiple_nodes_set_bootstrap_get(nodes_nr):
|
async def test_multiple_nodes_set_bootstrap_get(nodes_nr):
|
||||||
node_bootstrap = Server()
|
node_bootstrap = KademliaServer()
|
||||||
await node_bootstrap.listen(2000 + nodes_nr * 2)
|
await node_bootstrap.listen(2000 + nodes_nr * 2)
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for i in range(nodes_nr):
|
for i in range(nodes_nr):
|
||||||
node = Server()
|
node = KademliaServer()
|
||||||
addrs = [("127.0.0.1", 2000 + nodes_nr * 2)]
|
addrs = [("127.0.0.1", 2000 + nodes_nr * 2)]
|
||||||
await node.listen(2001 + i + nodes_nr * 2)
|
await node.listen(2001 + i + nodes_nr * 2)
|
||||||
await node.bootstrap(addrs)
|
await node.bootstrap(addrs)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user