commit
fc4fc74b87
|
@ -6,8 +6,10 @@ from .peer.peerstore import PeerStore
|
|||
from .peer.id import id_from_public_key
|
||||
from .network.swarm import Swarm
|
||||
from .host.basic_host import BasicHost
|
||||
from .kademlia.routed_host import RoutedHost
|
||||
from .transport.upgrader import TransportUpgrader
|
||||
from .transport.tcp.tcp import TCP
|
||||
from .kademlia.network import KademliaServer
|
||||
|
||||
|
||||
async def cleanup_done_tasks():
|
||||
|
@ -23,6 +25,30 @@ async def cleanup_done_tasks():
|
|||
# Some sleep necessary to context switch
|
||||
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(
|
||||
id_opt=None, transport_opt=None,
|
||||
|
@ -37,10 +63,9 @@ def initialize_default_swarm(
|
|||
:return: return a default swarm instance
|
||||
"""
|
||||
# pylint: disable=too-many-arguments, unused-argument
|
||||
|
||||
if not id_opt:
|
||||
new_key = RSA.generate(2048, e=65537)
|
||||
id_opt = id_from_public_key(new_key.publickey())
|
||||
# private_key = new_key.exportKey("PEM")
|
||||
id_opt = generate_id()
|
||||
|
||||
transport_opt = transport_opt or ["/ip4/127.0.0.1/tcp/8001"]
|
||||
transport = [multiaddr.Multiaddr(t) for t in transport_opt]
|
||||
|
@ -58,7 +83,8 @@ def initialize_default_swarm(
|
|||
|
||||
async def new_node(
|
||||
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
|
||||
:param id_opt: optional id for host
|
||||
|
@ -69,6 +95,10 @@ async def new_node(
|
|||
:return: return a default swarm instance
|
||||
"""
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
if not id_opt:
|
||||
id_opt = generate_id()
|
||||
|
||||
if not swarm_opt:
|
||||
swarm_opt = initialize_default_swarm(
|
||||
id_opt=id_opt, transport_opt=transport_opt,
|
||||
|
@ -77,7 +107,10 @@ async def new_node(
|
|||
|
||||
# TODO enable support for other host type
|
||||
# TODO routing unimplemented
|
||||
host = BasicHost(swarm_opt)
|
||||
if not disc_opt:
|
||||
host = BasicHost(swarm_opt)
|
||||
else:
|
||||
host = RoutedHost(swarm_opt, disc_opt)
|
||||
|
||||
# Kick off cleanup job
|
||||
asyncio.ensure_future(cleanup_done_tasks())
|
||||
|
|
|
@ -15,9 +15,8 @@ class KadPeerInfo(PeerInfo):
|
|||
def __init__(self, peer_id, peer_data=None):
|
||||
super(KadPeerInfo, self).__init__(peer_id, peer_data)
|
||||
|
||||
# pylint: disable=protected-access
|
||||
self.peer_id = peer_id._id_str
|
||||
self.long_id = int(digest(peer_id._id_str).hex(), 16)
|
||||
self.peer_id = peer_id.get_raw_id()
|
||||
self.long_id = int(digest(peer_id.get_raw_id()).hex(), 16)
|
||||
|
||||
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
|
||||
class Server:
|
||||
class KademliaServer:
|
||||
"""
|
||||
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.
|
||||
|
@ -219,7 +219,7 @@ class Server:
|
|||
log.info("Loading state from %s", fname)
|
||||
with open(fname, 'rb') as file:
|
||||
data = pickle.load(file)
|
||||
svr = Server(data['ksize'], data['alpha'], data['id'])
|
||||
svr = KademliaServer(data['ksize'], data['alpha'], data['id'])
|
||||
if data['neighbors']:
|
||||
svr.bootstrap(data['neighbors'])
|
||||
return svr
|
||||
|
|
21
libp2p/kademlia/routed_host.py
Normal file
21
libp2p/kademlia/routed_host.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
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 routed_listen(self, port, interface='0.0.0.0'):
|
||||
return self.kad_network.listen(port, interface)
|
||||
|
||||
def routed_get(self, key):
|
||||
return self.kad_network.get(key)
|
||||
|
||||
def routed_set(self, key, value):
|
||||
return self.kad_network.set(key, value)
|
||||
|
||||
def routed_set_digest(self, dkey, value):
|
||||
return self.kad_network.set_digest(dkey, value)
|
|
@ -15,6 +15,9 @@ class ID:
|
|||
def __init__(self, id_str):
|
||||
self._id_str = id_str
|
||||
|
||||
def get_raw_id(self):
|
||||
return self._id_str
|
||||
|
||||
def pretty(self):
|
||||
return base58.b58encode(self._id_str).decode()
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import pytest
|
||||
from libp2p.kademlia.network import Server
|
||||
from libp2p.kademlia.network import KademliaServer
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_example():
|
||||
node_a = Server()
|
||||
node_a = KademliaServer()
|
||||
await node_a.listen(5678)
|
||||
|
||||
node_b = Server()
|
||||
node_b = KademliaServer()
|
||||
await node_b.listen(5679)
|
||||
|
||||
# Bootstrap the node by connecting to other known nodes, in this case
|
||||
|
@ -29,12 +29,12 @@ async def test_example():
|
|||
@pytest.mark.asyncio
|
||||
async def test_multiple_nodes_bootstrap_set_get(nodes_nr):
|
||||
|
||||
node_bootstrap = Server()
|
||||
node_bootstrap = KademliaServer()
|
||||
await node_bootstrap.listen(3000 + nodes_nr * 2)
|
||||
|
||||
nodes = []
|
||||
for i in range(nodes_nr):
|
||||
node = Server()
|
||||
node = KademliaServer()
|
||||
addrs = [("127.0.0.1", 3000 + nodes_nr * 2)]
|
||||
await node.listen(3001 + i + nodes_nr * 2)
|
||||
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.asyncio
|
||||
async def test_multiple_nodes_set_bootstrap_get(nodes_nr):
|
||||
node_bootstrap = Server()
|
||||
node_bootstrap = KademliaServer()
|
||||
await node_bootstrap.listen(2000 + nodes_nr * 2)
|
||||
|
||||
nodes = []
|
||||
for i in range(nodes_nr):
|
||||
node = Server()
|
||||
node = KademliaServer()
|
||||
addrs = [("127.0.0.1", 2000 + nodes_nr * 2)]
|
||||
await node.listen(2001 + i + nodes_nr * 2)
|
||||
await node.bootstrap(addrs)
|
||||
|
|
Loading…
Reference in New Issue
Block a user