Files
py-libp2p/libp2p/host/routed_host.py
2019-03-26 20:16:16 +01:00

62 lines
2.1 KiB
Python

from libp2p.peer.peerstore import PeerStoreError
from .basic_host import BasicHost
class RoutedHost(BasicHost):
# default options constructor
def __init__(self, host, router):
super().__init__(host.network)
self.host = host
self.router = router
async def advertise(self, service):
await self.router.advertise(service)
async def connect(self, peer_info):
"""
connect ensures there is a connection between this host and the peer with
given peer_info.peer_id. connect will absorb the addresses in peer_info into its internal
peerstore. If there is not an active connection, connect will issue a
dial, and block until a connection is open, or an error is
returned.
:param peer_info: peer_info of the host we want to connect to
:type peer_info: peer.peerinfo.PeerInfo
"""
# there is already a connection to this peer
if peer_info.peer_id in self.network.connections:
return
# Check if we have some address for that peer
# if not, we use the router to get information about the peer
peer_info.addrs = await self._find_peer_addrs(peer_info.peer_id)
# if addrs are given, save them
if peer_info.addrs:
self.peerstore.add_addrs(peer_info.peer_id, peer_info.addrs, 10)
# try to connect
await super().connect(peer_info)
def find_peers(self, service):
return self.router.find_peers(service)
async def _find_peer_addrs(self, peer_id):
try:
addrs = self.peerstore.addrs(peer_id)
except PeerStoreError:
addrs = None
if not addrs:
peers_info = await self.router.find_peers(peer_id.pretty())
if not peers_info:
raise KeyError("no address found for this peer_id %s" % str(peer_id))
peer_info = peers_info[0] # todo: handle multiple response
if peer_info.peer_id != peer_id:
raise RuntimeError('routing failure: provided addrs for different peer')
addrs = peer_info.addrs
return addrs