diff --git a/connection/connection_interface.py b/connection/connection_interface.py deleted file mode 100644 index 813ea7d0..00000000 --- a/connection/connection_interface.py +++ /dev/null @@ -1,27 +0,0 @@ -from abc import ABC, abstractmethod - -class IConnection(ABC): - - @abstractmethod - def get_observed_addrs(self): - """ - retrieve observed addresses from underlying transport - :return: list of multiaddrs - """ - pass - - @abstractmethod - def get_peer_info(self): - """ - retrieve peer info object that the connection connects to - :return: a peer info object - """ - pass - - @abstractmethod - def set_peer_info(self, peer_info): - """ - :param peer_info: a peer info object that contains info of peer - :return: True if successful - """ - pass diff --git a/connection/raw_connection.py b/connection/raw_connection.py index e69de29b..9c77edb3 100644 --- a/connection/raw_connection.py +++ b/connection/raw_connection.py @@ -0,0 +1,14 @@ +import asyncio +from .raw_connection_interface import IRawConnection + +class RawConnection(IRawConnection): + + def __init__(self, ip, port): + self.conn_ip = ip + self.conn_port = port + self.reader = None + self.writer = None + + async def open_connection(self): + self.reader, self.writer = \ + await asyncio.open_connection(self.conn_ip, self.conn_port) diff --git a/connection/raw_connection_interface.py b/connection/raw_connection_interface.py index e69de29b..30f0f32f 100644 --- a/connection/raw_connection_interface.py +++ b/connection/raw_connection_interface.py @@ -0,0 +1,8 @@ +from abc import ABC, abstractmethod + +class IRawConnection(ABC): + + @abstractmethod + async def open_connection(self): + pass + \ No newline at end of file diff --git a/network/multiaddr.py b/network/multiaddr.py index b1245802..77075a1e 100644 --- a/network/multiaddr.py +++ b/network/multiaddr.py @@ -88,7 +88,8 @@ class MultiAddr: Gives back a dictionary with access to transport information from this multiaddr. Example: MultiAddr('/ip4/127.0.0.1/tcp/4001').to_options() = { family: 'ipv4', host: '127.0.0.1', transport: 'tcp', port: '4001' } - :return: {{family: String, host: String, transport: String, port: String}} with None if field does not exist + :return: {{family: String, host: String, transport: String, port: String}} + with None if field does not exist """ options = dict() diff --git a/network/network_interface.py b/network/network_interface.py index a7b6a697..17a859b7 100644 --- a/network/network_interface.py +++ b/network/network_interface.py @@ -2,10 +2,6 @@ from abc import ABC, abstractmethod class INetwork(ABC): - def __init__(self, my_peer_id, peer_store): - self.my_peer_id = my_peer_id - self.peer_store = peer_store - @abstractmethod def set_stream_handler(self, stream_handler): """ @@ -15,9 +11,10 @@ class INetwork(ABC): pass @abstractmethod - def new_stream(self, peer_id): + def new_stream(self, peer_id, protocol_id): """ :param peer_id: peer_id of destination + :param protocol_id: protocol id :return: stream instance """ pass @@ -28,4 +25,4 @@ class INetwork(ABC): :param *args: one or many multiaddrs to start listening on :return: True if at least one success """ - pass \ No newline at end of file + pass diff --git a/network/swarm.py b/network/swarm.py index 50f7b31b..5d570e99 100644 --- a/network/swarm.py +++ b/network/swarm.py @@ -1,10 +1,13 @@ from .network_interface import INetwork +from ..connection.muxed_connection import MuxedConnection +from ..connection.raw_connection import RawConnection class Swarm(INetwork): def __init__(self, my_peer_id, peer_store): self.my_peer_id = my_peer_id self.peer_store = peer_store + self.connections = {} def set_stream_handler(self, stream_handler): """ @@ -13,12 +16,32 @@ class Swarm(INetwork): """ pass - def new_stream(self, peer_id): + def new_stream(self, peer_id, protocol_id): """ + Determine if a connection to peer_id already exists + If a connection to peer_id exists, then + c = existing connection, + otherwise c = new muxed connection to peer_id + s = c.open_stream(protocol_id) + return s + :param peer_id: peer_id of destination + :param protocol_id: protocol id :return: stream instance """ - pass + muxed_connection = None + if peer_id in self.connections: + muxed_connection = self.connections[peer_id] + else: + addrs = self.peer_store.addrs(peer_id) + stream_ip = addrs.get_protocol_value("ip") + stream_port = addrs.get_protocol_value("port") + if len(addrs) > 0: + conn = RawConnection(stream_ip, stream_port) + muxed_connection = MuxedConnection(conn, True) + else: + raise Exception("No IP and port in addr") + return muxed_connection.open_stream(protocol_id, "") def listen(self, *args): """ diff --git a/network/walkthrough.txt b/network/walkthrough.txt new file mode 100644 index 00000000..3183d2a5 --- /dev/null +++ b/network/walkthrough.txt @@ -0,0 +1,4 @@ +host.go --> config.go + config.go: newNode --> swarm.go: newSwarm + newSwarm | initializes data stores + diff --git a/stream/stream.py b/stream/stream.py index 161a5a79..cce6ad6e 100644 --- a/stream/stream.py +++ b/stream/stream.py @@ -1,21 +1,20 @@ -from .stream_interface import IStream import asyncio +from .stream_interface import IStream class Stream(IStream): - def __init__(self, peer_id, multi_addr): + def __init__(self, peer_id, multi_addr, connection): IStream.__init__(self, peer_id, multi_addr) self.peer_id = peer_id - ip = multi_addr.get_protocol_value("ip4") - port = multi_addr.get_protocol_value("tcp") + stream_ip = multi_addr.get_protocol_value("ip4") + stream_port = multi_addr.get_protocol_value("tcp") + self.reader = connection.reader + self.writer = connection.writer + # TODO should construct protocol id from constructor + self.protocol_id = None - self.open_connection(ip, port) - - async def open_connection(self, ip, port): - self.reader, self.writer = await asyncio.open_connection(ip, port) - - def protocol(self): + def get_protocol(self): """ :return: protocol id that stream runs on """ diff --git a/stream/stream_interface.py b/stream/stream_interface.py index 124bb45b..6d63a2f0 100644 --- a/stream/stream_interface.py +++ b/stream/stream_interface.py @@ -2,12 +2,13 @@ from abc import ABC, abstractmethod class IStream(ABC): - def __init__(self, peer_id, multi_addr): + def __init__(self, peer_id, multi_addr, connection): self.peer_id = peer_id self.multi_addr = multi_addr + self.connection = connection @abstractmethod - def protocol(self): + def get_protocol(self): """ :return: protocol id that stream runs on """