From d7eab27564fbc104bd862a678088a4facf7cdb80 Mon Sep 17 00:00:00 2001 From: Khwahish Patel <111347042+Khwahish29@users.noreply.github.com> Date: Sat, 22 Feb 2025 04:31:45 +0530 Subject: [PATCH] refactored and moved all interfaces to abc.py (#504) * refactored : host_interface Co-authored-by: mystical-prog * refactored : network_interface Co-authored-by: mystical-prog * refactored : notifee_interface Co-authored-by: mystical-prog * refactored : net_connection_interface Co-authored-by: mystical-prog * refactored: raw_connection_interface, secure_conn_interface and stream_muxer abc.py * refactored: addrbook_interface * refactored :peerdata_interface Co-authored-by: mystical-prog * refactored :peermetadata_interface Co-authored-by: mystical-prog * refactored :multiselect_client_interface Co-authored-by: mystical-prog * refactored :multiselect_communicator_interface Co-authored-by: mystical-prog * refactored :multiselect_muxer_interface Co-authored-by: mystical-prog * refactored :interfaces Co-authored-by: mystical-prog * refactored :security_transport_interface Co-authored-by: mystical-prog * refactored :listener_interface Co-authored-by: mystical-prog * moved all interfaces and typing files Co-authored-by: mystical-prog * fixed documentation and moved pubsub abc.py Co-authored-by: Khwahish Patel * added exclude-members in custom_types docs * added : newsfragment for moving all interfaces to libp2p.abc --------- Co-authored-by: mystical-prog Co-authored-by: Mystical <125946525+mystical-prog@users.noreply.github.com> --- README.md | 152 +-- docs/libp2p.host.rst | 8 - docs/libp2p.network.connection.rst | 16 - docs/libp2p.network.rst | 16 - docs/libp2p.network.stream.rst | 8 - docs/libp2p.peer.rst | 32 - docs/libp2p.protocol_muxer.rst | 24 - docs/libp2p.pubsub.rst | 16 - docs/libp2p.routing.rst | 21 - docs/libp2p.rst | 10 +- docs/libp2p.security.rst | 16 - docs/libp2p.stream_muxer.rst | 8 - docs/libp2p.transport.rst | 24 - libp2p/__init__.py | 24 +- libp2p/abc.py | 1050 +++++++++++++++++ libp2p/custom_types.py | 38 +- libp2p/host/basic_host.py | 19 +- libp2p/host/defaults.py | 2 +- libp2p/host/host_interface.py | 133 --- libp2p/host/ping.py | 10 +- libp2p/host/routed_host.py | 10 +- libp2p/identity/identify/protocol.py | 10 +- .../connection/net_connection_interface.py | 28 - libp2p/network/connection/raw_connection.py | 6 +- .../connection/raw_connection_interface.py | 9 - libp2p/network/connection/swarm_connection.py | 8 +- libp2p/network/network_interface.py | 100 -- libp2p/network/notifee_interface.py | 65 - libp2p/network/stream/net_stream.py | 10 +- libp2p/network/stream/net_stream_interface.py | 33 - libp2p/network/swarm.py | 34 +- libp2p/peer/addrbook_interface.py | 61 - libp2p/peer/peerdata.py | 7 +- libp2p/peer/peerdata_interface.py | 100 -- libp2p/peer/peermetadata_interface.py | 31 - libp2p/peer/peerstore.py | 6 +- libp2p/peer/peerstore_interface.py | 161 --- libp2p/protocol_muxer/multiselect.py | 10 +- libp2p/protocol_muxer/multiselect_client.py | 10 +- .../multiselect_client_interface.py | 58 - .../multiselect_communicator.py | 6 +- .../multiselect_communicator_interface.py | 24 - .../multiselect_muxer_interface.py | 47 - libp2p/pubsub/abc.py | 158 --- libp2p/pubsub/floodsub.py | 6 +- libp2p/pubsub/gossipsub.py | 6 +- libp2p/pubsub/pubsub.py | 24 +- libp2p/pubsub/pubsub_notifee.py | 12 +- libp2p/pubsub/subscription.py | 9 +- libp2p/pubsub/typing.py | 21 - libp2p/routing/__init__.py | 0 libp2p/routing/interfaces.py | 42 - libp2p/security/base_session.py | 6 +- libp2p/security/base_transport.py | 6 +- libp2p/security/insecure/transport.py | 10 +- libp2p/security/noise/io.py | 6 +- libp2p/security/noise/patterns.py | 10 +- libp2p/security/noise/transport.py | 14 +- libp2p/security/secio/transport.py | 10 +- libp2p/security/secure_conn_interface.py | 44 - libp2p/security/secure_transport_interface.py | 42 - libp2p/security/security_multistream.py | 18 +- libp2p/stream_muxer/abc.py | 85 -- libp2p/stream_muxer/mplex/mplex.py | 12 +- libp2p/stream_muxer/mplex/mplex_stream.py | 2 +- libp2p/stream_muxer/muxer_multistream.py | 23 +- libp2p/tools/factories.py | 36 +- libp2p/tools/pubsub/dummy_account_node.py | 2 +- libp2p/tools/pubsub/utils.py | 2 +- libp2p/tools/utils.py | 6 +- libp2p/transport/listener_interface.py | 32 - libp2p/transport/tcp/tcp.py | 20 +- libp2p/transport/transport_interface.py | 41 - libp2p/transport/typing.py | 25 - libp2p/transport/upgrader.py | 27 +- newsfragments/228.internal.rst | 1 + tests/core/network/test_notify.py | 2 +- 77 files changed, 1338 insertions(+), 1883 deletions(-) delete mode 100644 docs/libp2p.routing.rst create mode 100644 libp2p/abc.py delete mode 100644 libp2p/host/host_interface.py delete mode 100644 libp2p/network/connection/net_connection_interface.py delete mode 100644 libp2p/network/connection/raw_connection_interface.py delete mode 100644 libp2p/network/network_interface.py delete mode 100644 libp2p/network/notifee_interface.py delete mode 100644 libp2p/network/stream/net_stream_interface.py delete mode 100644 libp2p/peer/addrbook_interface.py delete mode 100644 libp2p/peer/peerdata_interface.py delete mode 100644 libp2p/peer/peermetadata_interface.py delete mode 100644 libp2p/peer/peerstore_interface.py delete mode 100644 libp2p/protocol_muxer/multiselect_client_interface.py delete mode 100644 libp2p/protocol_muxer/multiselect_communicator_interface.py delete mode 100644 libp2p/protocol_muxer/multiselect_muxer_interface.py delete mode 100644 libp2p/pubsub/abc.py delete mode 100644 libp2p/pubsub/typing.py delete mode 100644 libp2p/routing/__init__.py delete mode 100644 libp2p/routing/interfaces.py delete mode 100644 libp2p/security/secure_conn_interface.py delete mode 100644 libp2p/security/secure_transport_interface.py delete mode 100644 libp2p/stream_muxer/abc.py delete mode 100644 libp2p/transport/listener_interface.py delete mode 100644 libp2p/transport/transport_interface.py delete mode 100644 libp2p/transport/typing.py create mode 100644 newsfragments/228.internal.rst diff --git a/README.md b/README.md index cf8fe5f1..ada1e405 100644 --- a/README.md +++ b/README.md @@ -29,94 +29,94 @@ py-libp2p aims for conformity with [the standard libp2p modules](https://libp2p. > Legend: ✅: Done   🛠️: In Progress   🚫: Missing   ❌: Not planned -| libp2p Node | Status | -| ------------ | :-----------: | -| **`libp2p`** | ✅ | +| libp2p Node | Status | +| ------------ | :----: | +| **`libp2p`** | ✅ | -| Core Protocols | Status | -| -------------- | :-----------: | -| **`Ping`** | ✅ | -| **`Identify`** | ✅ | +| Core Protocols | Status | +| -------------- | :----: | +| **`Ping`** | ✅ | +| **`Identify`** | ✅ | -| Transport Protocols | Status | -| ------------------- | :-----------: | -| **`TCP`** | ✅| -| **`QUIC`** | 🛠️ | +| Transport Protocols | Status | +| ------------------- | :----: | +| **`TCP`** | ✅ | +| **`QUIC`** | 🛠️ | | **`UDP`** | 🚫 | -| **`WebSockets`** | ❌ | -| **`UTP`** | ❌ | -| **`WebRTC`** | ❌ | -| **`SCTP`** | ❌ | -| **`Tor`** | ❌ | -| **`i2p`** | ❌ | -| **`cjdns`** | ❌ | -| **`Bluetooth LE`** | ❌ | -| **`Audio TP`** | ❌ | -| **`Zerotier`** | ❌ | +| **`WebSockets`** | ❌ | +| **`UTP`** | ❌ | +| **`WebRTC`** | ❌ | +| **`SCTP`** | ❌ | +| **`Tor`** | ❌ | +| **`i2p`** | ❌ | +| **`cjdns`** | ❌ | +| **`Bluetooth LE`** | ❌ | +| **`Audio TP`** | ❌ | +| **`Zerotier`** | ❌ | -| Stream Muxers | Status | -| ---------------- | :-----------: | -| **`multiplex`** | ✅ | -| **`yamux`** | 🚫 | -| **`benchmarks`** | ❌ | -| **`muxado`** | ❌ | -| **`spdystream`** | ❌ | -| **`spdy`** | ❌ | -| **`http2`** | ❌ | -| **`QUIC`** | ❌ | +| Stream Muxers | Status | +| ---------------- | :----: | +| **`multiplex`** | ✅ | +| **`yamux`** | 🚫 | +| **`benchmarks`** | ❌ | +| **`muxado`** | ❌ | +| **`spdystream`** | ❌ | +| **`spdy`** | ❌ | +| **`http2`** | ❌ | +| **`QUIC`** | ❌ | -| Protocol Muxers | Status | -| ----------------- | :-----------: | -| **`multiselect`** | ✅ | +| Protocol Muxers | Status | +| ----------------- | :----: | +| **`multiselect`** | ✅ | -| Switch (Swarm) | Status | -| ------------------ | :-----------: | -| **`Switch`** | ✅ | -| **`Dialer stack`** | ✅ | +| Switch (Swarm) | Status | +| ------------------ | :----: | +| **`Switch`** | ✅ | +| **`Dialer stack`** | ✅ | -| Peer Discovery | Status | -| -------------------- | :--------: | -| **`bootstrap list`** | 🚫 | -| **`Kademlia DHT`** | ❌ | -| **`mDNS`** | ❌ | -| **`PEX`** | ❌ | -| **`DNS`** | ❌ | +| Peer Discovery | Status | +| -------------------- | :----: | +| **`bootstrap list`** | 🚫 | +| **`Kademlia DHT`** | ❌ | +| **`mDNS`** | ❌ | +| **`PEX`** | ❌ | +| **`DNS`** | ❌ | -| Content Routing | Status | -| ------------------ | :-----------: | -| **`Kademlia DHT`** | ❌ | -| **`floodsub`** | ✅ | -| **`gossipsub`** | ✅ | -| **`PHT`** | ❌ | +| Content Routing | Status | +| ------------------ | :----: | +| **`Kademlia DHT`** | ❌ | +| **`floodsub`** | ✅ | +| **`gossipsub`** | ✅ | +| **`PHT`** | ❌ | -| Peer Routing | Status | -| ------------------ | :-----------: | -| **`Kademlia DHT`** | ❌ | -| **`floodsub`** | ✅| -| **`gossipsub`** | ✅ | -| **`PHT`** | ❌ | +| Peer Routing | Status | +| ------------------ | :----: | +| **`Kademlia DHT`** | ❌ | +| **`floodsub`** | ✅ | +| **`gossipsub`** | ✅ | +| **`PHT`** | ❌ | -| NAT Traversal | Status | -| ------------------------ | :--------: | -| **`nat-pmp`** | ❌ | -| **`upnp`** | ❌ | -| **`ext addr discovery`** | ❌ | -| **`STUN-like`** | ❌ | -| **`line-switch relay`** | ❌ | -| **`pkt-switch relay`** | ❌ | +| NAT Traversal | Status | +| ------------------------ | :----: | +| **`nat-pmp`** | ❌ | +| **`upnp`** | ❌ | +| **`ext addr discovery`** | ❌ | +| **`STUN-like`** | ❌ | +| **`line-switch relay`** | ❌ | +| **`pkt-switch relay`** | ❌ | -| Exchange | Status | -| ---------------- | :--------: | -| **`HTTP`** | ❌ | -| **`Bitswap`** | ❌ | -| **`Bittorrent`** | ❌ | +| Exchange | Status | +| ---------------- | :----: | +| **`HTTP`** | ❌ | +| **`Bitswap`** | ❌ | +| **`Bittorrent`** | ❌ | -| Consensus | Status | -| -------------- | :--------: | -| **`Paxos`** | ❌ | -| **`Raft`** | ❌ | -| **`PBTF`** | ❌ | -| **`Nakamoto`** | ❌ | +| Consensus | Status | +| -------------- | :----: | +| **`Paxos`** | ❌ | +| **`Raft`** | ❌ | +| **`PBTF`** | ❌ | +| **`Nakamoto`** | ❌ | ## Explanation of Basic Two Node Communication diff --git a/docs/libp2p.host.rst b/docs/libp2p.host.rst index 95debb94..3f43e49e 100644 --- a/docs/libp2p.host.rst +++ b/docs/libp2p.host.rst @@ -28,14 +28,6 @@ libp2p.host.exceptions module :undoc-members: :show-inheritance: -libp2p.host.host\_interface module ----------------------------------- - -.. automodule:: libp2p.host.host_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.host.ping module ----------------------- diff --git a/docs/libp2p.network.connection.rst b/docs/libp2p.network.connection.rst index 17d87695..d242e097 100644 --- a/docs/libp2p.network.connection.rst +++ b/docs/libp2p.network.connection.rst @@ -12,14 +12,6 @@ libp2p.network.connection.exceptions module :undoc-members: :show-inheritance: -libp2p.network.connection.net\_connection\_interface module ------------------------------------------------------------ - -.. automodule:: libp2p.network.connection.net_connection_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.network.connection.raw\_connection module ------------------------------------------------ @@ -28,14 +20,6 @@ libp2p.network.connection.raw\_connection module :undoc-members: :show-inheritance: -libp2p.network.connection.raw\_connection\_interface module ------------------------------------------------------------ - -.. automodule:: libp2p.network.connection.raw_connection_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.network.connection.swarm\_connection module -------------------------------------------------- diff --git a/docs/libp2p.network.rst b/docs/libp2p.network.rst index 0b2644c6..fcdabe3b 100644 --- a/docs/libp2p.network.rst +++ b/docs/libp2p.network.rst @@ -21,22 +21,6 @@ libp2p.network.exceptions module :undoc-members: :show-inheritance: -libp2p.network.network\_interface module ----------------------------------------- - -.. automodule:: libp2p.network.network_interface - :members: - :undoc-members: - :show-inheritance: - -libp2p.network.notifee\_interface module ----------------------------------------- - -.. automodule:: libp2p.network.notifee_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.network.swarm module --------------------------- diff --git a/docs/libp2p.network.stream.rst b/docs/libp2p.network.stream.rst index 9acddf35..c02e04d8 100644 --- a/docs/libp2p.network.stream.rst +++ b/docs/libp2p.network.stream.rst @@ -20,14 +20,6 @@ libp2p.network.stream.net\_stream module :undoc-members: :show-inheritance: -libp2p.network.stream.net\_stream\_interface module ---------------------------------------------------- - -.. automodule:: libp2p.network.stream.net_stream_interface - :members: - :undoc-members: - :show-inheritance: - Module contents --------------- diff --git a/docs/libp2p.peer.rst b/docs/libp2p.peer.rst index 34dc59a6..0d6db7f8 100644 --- a/docs/libp2p.peer.rst +++ b/docs/libp2p.peer.rst @@ -4,14 +4,6 @@ libp2p.peer package Submodules ---------- -libp2p.peer.addrbook\_interface module --------------------------------------- - -.. automodule:: libp2p.peer.addrbook_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.peer.id module --------------------- @@ -28,14 +20,6 @@ libp2p.peer.peerdata module :undoc-members: :show-inheritance: -libp2p.peer.peerdata\_interface module --------------------------------------- - -.. automodule:: libp2p.peer.peerdata_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.peer.peerinfo module --------------------------- @@ -44,14 +28,6 @@ libp2p.peer.peerinfo module :undoc-members: :show-inheritance: -libp2p.peer.peermetadata\_interface module ------------------------------------------- - -.. automodule:: libp2p.peer.peermetadata_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.peer.peerstore module ---------------------------- @@ -60,14 +36,6 @@ libp2p.peer.peerstore module :undoc-members: :show-inheritance: -libp2p.peer.peerstore\_interface module ---------------------------------------- - -.. automodule:: libp2p.peer.peerstore_interface - :members: - :undoc-members: - :show-inheritance: - Module contents --------------- diff --git a/docs/libp2p.protocol_muxer.rst b/docs/libp2p.protocol_muxer.rst index 3c7f3270..f3583aaf 100644 --- a/docs/libp2p.protocol_muxer.rst +++ b/docs/libp2p.protocol_muxer.rst @@ -28,14 +28,6 @@ libp2p.protocol\_muxer.multiselect\_client module :undoc-members: :show-inheritance: -libp2p.protocol\_muxer.multiselect\_client\_interface module ------------------------------------------------------------- - -.. automodule:: libp2p.protocol_muxer.multiselect_client_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.protocol\_muxer.multiselect\_communicator module ------------------------------------------------------- @@ -44,22 +36,6 @@ libp2p.protocol\_muxer.multiselect\_communicator module :undoc-members: :show-inheritance: -libp2p.protocol\_muxer.multiselect\_communicator\_interface module ------------------------------------------------------------------- - -.. automodule:: libp2p.protocol_muxer.multiselect_communicator_interface - :members: - :undoc-members: - :show-inheritance: - -libp2p.protocol\_muxer.multiselect\_muxer\_interface module ------------------------------------------------------------ - -.. automodule:: libp2p.protocol_muxer.multiselect_muxer_interface - :members: - :undoc-members: - :show-inheritance: - Module contents --------------- diff --git a/docs/libp2p.pubsub.rst b/docs/libp2p.pubsub.rst index e3a9bdff..131b135b 100644 --- a/docs/libp2p.pubsub.rst +++ b/docs/libp2p.pubsub.rst @@ -12,14 +12,6 @@ Subpackages Submodules ---------- -libp2p.pubsub.abc module ------------------------- - -.. automodule:: libp2p.pubsub.abc - :members: - :undoc-members: - :show-inheritance: - libp2p.pubsub.exceptions module ------------------------------- @@ -76,14 +68,6 @@ libp2p.pubsub.subscription module :undoc-members: :show-inheritance: -libp2p.pubsub.typing module ---------------------------- - -.. automodule:: libp2p.pubsub.typing - :members: - :undoc-members: - :show-inheritance: - libp2p.pubsub.validators module ------------------------------- diff --git a/docs/libp2p.routing.rst b/docs/libp2p.routing.rst deleted file mode 100644 index a456e457..00000000 --- a/docs/libp2p.routing.rst +++ /dev/null @@ -1,21 +0,0 @@ -libp2p.routing package -====================== - -Submodules ----------- - -libp2p.routing.interfaces module --------------------------------- - -.. automodule:: libp2p.routing.interfaces - :members: - :undoc-members: - :show-inheritance: - -Module contents ---------------- - -.. automodule:: libp2p.routing - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/libp2p.rst b/docs/libp2p.rst index c3153546..8b1a8f08 100644 --- a/docs/libp2p.rst +++ b/docs/libp2p.rst @@ -15,7 +15,6 @@ Subpackages libp2p.peer libp2p.protocol_muxer libp2p.pubsub - libp2p.routing libp2p.security libp2p.stream_muxer libp2p.tools @@ -24,6 +23,14 @@ Subpackages Submodules ---------- +libp2p.abc module +-------------------------- + +.. automodule:: libp2p.abc + :members: + :undoc-members: + :show-inheritance: + libp2p.exceptions module ------------------------ @@ -39,6 +46,7 @@ libp2p.custom_types module :members: :undoc-members: :show-inheritance: + :exclude-members: INetStream, IMuxedConn, ISecureTransport libp2p.utils module ------------------- diff --git a/docs/libp2p.security.rst b/docs/libp2p.security.rst index c559a319..04a7374b 100644 --- a/docs/libp2p.security.rst +++ b/docs/libp2p.security.rst @@ -38,14 +38,6 @@ libp2p.security.exceptions module :undoc-members: :show-inheritance: -libp2p.security.secure\_conn\_interface module ----------------------------------------------- - -.. automodule:: libp2p.security.secure_conn_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.security.secure\_session module -------------------------------------- @@ -54,14 +46,6 @@ libp2p.security.secure\_session module :undoc-members: :show-inheritance: -libp2p.security.secure\_transport\_interface module ---------------------------------------------------- - -.. automodule:: libp2p.security.secure_transport_interface - :members: - :undoc-members: - :show-inheritance: - libp2p.security.security\_multistream module -------------------------------------------- diff --git a/docs/libp2p.stream_muxer.rst b/docs/libp2p.stream_muxer.rst index de1a9156..6cc0e0b9 100644 --- a/docs/libp2p.stream_muxer.rst +++ b/docs/libp2p.stream_muxer.rst @@ -12,14 +12,6 @@ Subpackages Submodules ---------- -libp2p.stream\_muxer.abc module -------------------------------- - -.. automodule:: libp2p.stream_muxer.abc - :members: - :undoc-members: - :show-inheritance: - libp2p.stream\_muxer.exceptions module -------------------------------------- diff --git a/docs/libp2p.transport.rst b/docs/libp2p.transport.rst index 6541f52d..0d92c48f 100644 --- a/docs/libp2p.transport.rst +++ b/docs/libp2p.transport.rst @@ -20,30 +20,6 @@ libp2p.transport.exceptions module :undoc-members: :show-inheritance: -libp2p.transport.listener\_interface module -------------------------------------------- - -.. automodule:: libp2p.transport.listener_interface - :members: - :undoc-members: - :show-inheritance: - -libp2p.transport.transport\_interface module --------------------------------------------- - -.. automodule:: libp2p.transport.transport_interface - :members: - :undoc-members: - :show-inheritance: - -libp2p.transport.typing module ------------------------------- - -.. automodule:: libp2p.transport.typing - :members: - :undoc-members: - :show-inheritance: - libp2p.transport.upgrader module -------------------------------- diff --git a/libp2p/__init__.py b/libp2p/__init__.py index 0bd528ba..bc7e7510 100644 --- a/libp2p/__init__.py +++ b/libp2p/__init__.py @@ -1,5 +1,11 @@ from importlib.metadata import version as __version +from libp2p.abc import ( + IHost, + INetworkService, + IPeerRouting, + IPeerStore, +) from libp2p.crypto.keys import ( KeyPair, ) @@ -7,20 +13,16 @@ from libp2p.crypto.rsa import ( create_new_key_pair, ) from libp2p.custom_types import ( + TMuxerOptions, TProtocol, + TSecurityOptions, ) from libp2p.host.basic_host import ( BasicHost, ) -from libp2p.host.host_interface import ( - IHost, -) from libp2p.host.routed_host import ( RoutedHost, ) -from libp2p.network.network_interface import ( - INetworkService, -) from libp2p.network.swarm import ( Swarm, ) @@ -30,12 +32,6 @@ from libp2p.peer.id import ( from libp2p.peer.peerstore import ( PeerStore, ) -from libp2p.peer.peerstore_interface import ( - IPeerStore, -) -from libp2p.routing.interfaces import ( - IPeerRouting, -) from libp2p.security.insecure.transport import ( PLAINTEXT_PROTOCOL_ID, InsecureTransport, @@ -48,10 +44,6 @@ from libp2p.stream_muxer.mplex.mplex import ( from libp2p.transport.tcp.tcp import ( TCP, ) -from libp2p.transport.typing import ( - TMuxerOptions, - TSecurityOptions, -) from libp2p.transport.upgrader import ( TransportUpgrader, ) diff --git a/libp2p/abc.py b/libp2p/abc.py new file mode 100644 index 00000000..b5a59a76 --- /dev/null +++ b/libp2p/abc.py @@ -0,0 +1,1050 @@ +from abc import ( + ABC, + abstractmethod, +) +from collections.abc import ( + AsyncIterable, + Iterable, + KeysView, + Sequence, +) +from typing import ( + TYPE_CHECKING, + Any, + AsyncContextManager, +) + +from multiaddr import ( + Multiaddr, +) +import trio + +from libp2p.crypto.keys import ( + KeyPair, + PrivateKey, + PublicKey, +) +from libp2p.custom_types import ( + StreamHandlerFn, + THandler, + TProtocol, + ValidatorFn, +) +from libp2p.io.abc import ( + Closer, + ReadWriteCloser, +) +from libp2p.peer.id import ( + ID, +) +from libp2p.peer.peerinfo import ( + PeerInfo, +) + +if TYPE_CHECKING: + from libp2p.pubsub.pubsub import ( + Pubsub, + ) + +from libp2p.pubsub.pb import ( + rpc_pb2, +) +from libp2p.tools.async_service import ( + ServiceAPI, +) + +# -------------------------- raw_connection interface.py -------------------------- + + +class IRawConnection(ReadWriteCloser): + """A Raw Connection provides a Reader and a Writer.""" + + is_initiator: bool + + +# -------------------------- secure_conn interface.py -------------------------- + + +""" +Represents a secured connection object, which includes a connection and details about +the security involved in the secured connection + +Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interface.go +""" + + +class AbstractSecureConn(ABC): + @abstractmethod + def get_local_peer(self) -> ID: + pass + + @abstractmethod + def get_local_private_key(self) -> PrivateKey: + pass + + @abstractmethod + def get_remote_peer(self) -> ID: + pass + + @abstractmethod + def get_remote_public_key(self) -> PublicKey: + pass + + +class ISecureConn(AbstractSecureConn, IRawConnection): + pass + + +# -------------------------- stream_muxer abc.py -------------------------- + + +class IMuxedConn(ABC): + """ + reference: https://github.com/libp2p/go-stream-muxer/blob/master/muxer.go + """ + + peer_id: ID + event_started: trio.Event + + @abstractmethod + def __init__(self, conn: ISecureConn, peer_id: ID) -> None: + """ + Create a new muxed connection. + + :param conn: an instance of secured connection + for new muxed streams + :param peer_id: peer_id of peer the connection is to + """ + + @property + @abstractmethod + def is_initiator(self) -> bool: + """If this connection is the initiator.""" + + @abstractmethod + async def start(self) -> None: + """Start the multiplexer.""" + + @abstractmethod + async def close(self) -> None: + """Close connection.""" + + @property + @abstractmethod + def is_closed(self) -> bool: + """ + Check connection is fully closed. + + :return: true if successful + """ + + @abstractmethod + async def open_stream(self) -> "IMuxedStream": + """ + Create a new muxed_stream. + + :return: a new ``IMuxedStream`` stream + """ + + @abstractmethod + async def accept_stream(self) -> "IMuxedStream": + """Accept a muxed stream opened by the other end.""" + + +class IMuxedStream(ReadWriteCloser): + muxed_conn: IMuxedConn + + @abstractmethod + async def reset(self) -> None: + """Close both ends of the stream tells this remote side to hang up.""" + + @abstractmethod + def set_deadline(self, ttl: int) -> bool: + """ + Set deadline for muxed stream. + + :return: a new stream + """ + + +# -------------------------- net_stream interface.py -------------------------- + + +class INetStream(ReadWriteCloser): + muxed_conn: IMuxedConn + + @abstractmethod + def get_protocol(self) -> TProtocol: + """ + :return: protocol id that stream runs on + """ + + @abstractmethod + def set_protocol(self, protocol_id: TProtocol) -> None: + """ + :param protocol_id: protocol id that stream runs on + """ + + @abstractmethod + async def reset(self) -> None: + """Close both ends of the stream.""" + + +# -------------------------- net_connection interface.py -------------------------- + + +class INetConn(Closer): + muxed_conn: IMuxedConn + event_started: trio.Event + + @abstractmethod + async def new_stream(self) -> INetStream: + ... + + @abstractmethod + def get_streams(self) -> tuple[INetStream, ...]: + ... + + +# -------------------------- peermetadata interface.py -------------------------- + + +class IPeerMetadata(ABC): + @abstractmethod + def get(self, peer_id: ID, key: str) -> Any: + """ + :param peer_id: peer ID to lookup key for + :param key: key to look up + :return: value at key for given peer + :raise Exception: peer ID not found + """ + + @abstractmethod + def put(self, peer_id: ID, key: str, val: Any) -> None: + """ + :param peer_id: peer ID to lookup key for + :param key: key to associate with peer + :param val: value to associated with key + :raise Exception: unsuccessful put + """ + + +# -------------------------- addrbook interface.py -------------------------- + + +class IAddrBook(ABC): + @abstractmethod + def add_addr(self, peer_id: ID, addr: Multiaddr, ttl: int) -> None: + """ + Calls add_addrs(peer_id, [addr], ttl) + + :param peer_id: the peer to add address for + :param addr: multiaddress of the peer + :param ttl: time-to-live for the address (after this time, address is no longer valid) + """ # noqa: E501 + + @abstractmethod + def add_addrs(self, peer_id: ID, addrs: Sequence[Multiaddr], ttl: int) -> None: + """ + Adds addresses for a given peer all with the same time-to-live. If one + of the addresses already exists for the peer and has a longer TTL, no + operation should take place. If one of the addresses exists with a + shorter TTL, extend the TTL to equal param ttl. + + :param peer_id: the peer to add address for + :param addr: multiaddresses of the peer + :param ttl: time-to-live for the address (after this time, address is no longer valid + """ # noqa: E501 + + @abstractmethod + def addrs(self, peer_id: ID) -> list[Multiaddr]: + """ + :param peer_id: peer to get addresses of + :return: all known (and valid) addresses for the given peer + """ + + @abstractmethod + def clear_addrs(self, peer_id: ID) -> None: + """ + Removes all previously stored addresses. + + :param peer_id: peer to remove addresses of + """ + + @abstractmethod + def peers_with_addrs(self) -> list[ID]: + """ + :return: all of the peer IDs stored with addresses + """ + + +# -------------------------- peerstore interface.py -------------------------- + + +class IPeerStore(IAddrBook, IPeerMetadata): + @abstractmethod + def peer_info(self, peer_id: ID) -> PeerInfo: + """ + :param peer_id: peer ID to get info for + :return: peer info object + """ + + @abstractmethod + def get_protocols(self, peer_id: ID) -> list[str]: + """ + :param peer_id: peer ID to get protocols for + :return: protocols (as list of strings) + :raise PeerStoreError: if peer ID not found + """ + + @abstractmethod + def add_protocols(self, peer_id: ID, protocols: Sequence[str]) -> None: + """ + :param peer_id: peer ID to add protocols for + :param protocols: protocols to add + """ + + @abstractmethod + def set_protocols(self, peer_id: ID, protocols: Sequence[str]) -> None: + """ + :param peer_id: peer ID to set protocols for + :param protocols: protocols to set + """ + + @abstractmethod + def peer_ids(self) -> list[ID]: + """ + :return: all of the peer IDs stored in peer store + """ + + @abstractmethod + def get(self, peer_id: ID, key: str) -> Any: + """ + :param peer_id: peer ID to get peer data for + :param key: the key to search value for + :return: value corresponding to the key + :raise PeerStoreError: if peer ID or value not found + """ + + @abstractmethod + def put(self, peer_id: ID, key: str, val: Any) -> None: + """ + :param peer_id: peer ID to put peer data for + :param key: + :param value: + """ + + @abstractmethod + def add_addr(self, peer_id: ID, addr: Multiaddr, ttl: int) -> None: + """ + :param peer_id: peer ID to add address for + :param addr: + :param ttl: time-to-live for the this record + """ + + @abstractmethod + def add_addrs(self, peer_id: ID, addrs: Sequence[Multiaddr], ttl: int) -> None: + """ + :param peer_id: peer ID to add address for + :param addrs: + :param ttl: time-to-live for the this record + """ + + @abstractmethod + def addrs(self, peer_id: ID) -> list[Multiaddr]: + """ + :param peer_id: peer ID to get addrs for + :return: list of addrs + """ + + @abstractmethod + def clear_addrs(self, peer_id: ID) -> None: + """ + :param peer_id: peer ID to clear addrs for + """ + + @abstractmethod + def peers_with_addrs(self) -> list[ID]: + """ + :return: all of the peer IDs which has addrs stored in peer store + """ + + @abstractmethod + def add_pubkey(self, peer_id: ID, pubkey: PublicKey) -> None: + """ + :param peer_id: peer ID to add public key for + :param pubkey: + :raise PeerStoreError: if peer ID already has pubkey set + """ + + @abstractmethod + def pubkey(self, peer_id: ID) -> PublicKey: + """ + :param peer_id: peer ID to get public key for + :return: public key of the peer + :raise PeerStoreError: if peer ID not found + """ + + @abstractmethod + def add_privkey(self, peer_id: ID, privkey: PrivateKey) -> None: + """ + :param peer_id: peer ID to add private key for + :param privkey: + :raise PeerStoreError: if peer ID already has privkey set + """ + + @abstractmethod + def privkey(self, peer_id: ID) -> PrivateKey: + """ + :param peer_id: peer ID to get private key for + :return: private key of the peer + :raise PeerStoreError: if peer ID not found + """ + + @abstractmethod + def add_key_pair(self, peer_id: ID, key_pair: KeyPair) -> None: + """ + :param peer_id: peer ID to add private key for + :param key_pair: + :raise PeerStoreError: if peer ID already has pubkey or privkey set + """ + + +# -------------------------- listener interface.py -------------------------- + + +class IListener(ABC): + @abstractmethod + async def listen(self, maddr: Multiaddr, nursery: trio.Nursery) -> bool: + """ + Put listener in listening mode and wait for incoming connections. + + :param maddr: multiaddr of peer + :return: return True if successful + """ + + @abstractmethod + def get_addrs(self) -> tuple[Multiaddr, ...]: + """ + Retrieve list of addresses the listener is listening on. + + :return: return list of addrs + """ + + @abstractmethod + async def close(self) -> None: + ... + + +# -------------------------- network interface.py -------------------------- + + +class INetwork(ABC): + peerstore: IPeerStore + connections: dict[ID, INetConn] + listeners: dict[str, IListener] + + @abstractmethod + def get_peer_id(self) -> ID: + """ + :return: the peer id + """ + + @abstractmethod + async def dial_peer(self, peer_id: ID) -> INetConn: + """ + dial_peer try to create a connection to peer_id. + + :param peer_id: peer if we want to dial + :raises SwarmException: raised when an error occurs + :return: muxed connection + """ + + @abstractmethod + async def new_stream(self, peer_id: ID) -> INetStream: + """ + :param peer_id: peer_id of destination + :param protocol_ids: available protocol ids to use for stream + :return: net stream instance + """ + + @abstractmethod + def set_stream_handler(self, stream_handler: StreamHandlerFn) -> None: + """Set the stream handler for all incoming streams.""" + + @abstractmethod + async def listen(self, *multiaddrs: Sequence[Multiaddr]) -> bool: + """ + :param multiaddrs: one or many multiaddrs to start listening on + :return: True if at least one success + """ + + @abstractmethod + def register_notifee(self, notifee: "INotifee") -> None: + """ + :param notifee: object implementing Notifee interface + :return: true if notifee registered successfully, false otherwise + """ + + @abstractmethod + async def close(self) -> None: + pass + + @abstractmethod + async def close_peer(self, peer_id: ID) -> None: + pass + + +class INetworkService(INetwork, ServiceAPI): + pass + + +# -------------------------- notifee interface.py -------------------------- + + +class INotifee(ABC): + @abstractmethod + async def opened_stream(self, network: "INetwork", stream: INetStream) -> None: + """ + :param network: network the stream was opened on + :param stream: stream that was opened + """ + + @abstractmethod + async def closed_stream(self, network: "INetwork", stream: INetStream) -> None: + """ + :param network: network the stream was closed on + :param stream: stream that was closed + """ + + @abstractmethod + async def connected(self, network: "INetwork", conn: INetConn) -> None: + """ + :param network: network the connection was opened on + :param conn: connection that was opened + """ + + @abstractmethod + async def disconnected(self, network: "INetwork", conn: INetConn) -> None: + """ + :param network: network the connection was closed on + :param conn: connection that was closed + """ + + @abstractmethod + async def listen(self, network: "INetwork", multiaddr: Multiaddr) -> None: + """ + :param network: network the listener is listening on + :param multiaddr: multiaddress listener is listening on + """ + + @abstractmethod + async def listen_close(self, network: "INetwork", multiaddr: Multiaddr) -> None: + """ + :param network: network the connection was opened on + :param multiaddr: multiaddress listener is no longer listening on + """ + + +# -------------------------- host interface.py -------------------------- + + +class IHost(ABC): + @abstractmethod + def get_id(self) -> ID: + """ + :return: peer_id of host + """ + + @abstractmethod + def get_public_key(self) -> PublicKey: + """ + :return: the public key belonging to the peer + """ + + @abstractmethod + def get_private_key(self) -> PrivateKey: + """ + :return: the private key belonging to the peer + """ + + @abstractmethod + def get_network(self) -> INetworkService: + """ + :return: network instance of host + """ + + # FIXME: Replace with correct return type + @abstractmethod + def get_mux(self) -> Any: + """ + :return: mux instance of host + """ + + @abstractmethod + def get_addrs(self) -> list[Multiaddr]: + """ + :return: all the multiaddr addresses this host is listening to + """ + + @abstractmethod + def get_connected_peers(self) -> list[ID]: + """ + :return: all the ids of peers this host is currently connected to + """ + + @abstractmethod + def run(self, listen_addrs: Sequence[Multiaddr]) -> AsyncContextManager[None]: + """ + Run the host instance and listen to ``listen_addrs``. + + :param listen_addrs: a sequence of multiaddrs that we want to listen to + """ + + @abstractmethod + def set_stream_handler( + self, protocol_id: TProtocol, stream_handler: StreamHandlerFn + ) -> None: + """ + Set stream handler for host. + + :param protocol_id: protocol id used on stream + :param stream_handler: a stream handler function + """ + + # protocol_id can be a list of protocol_ids + # stream will decide which protocol_id to run on + @abstractmethod + async def new_stream( + self, peer_id: ID, protocol_ids: Sequence[TProtocol] + ) -> INetStream: + """ + :param peer_id: peer_id that host is connecting + :param protocol_ids: available protocol ids to use for stream + :return: stream: new stream created + """ + + @abstractmethod + async def connect(self, peer_info: PeerInfo) -> None: + """ + Ensure 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 + opened, or an error is returned. + + :param peer_info: peer_info of the peer we want to connect to + :type peer_info: peer.peerinfo.PeerInfo + """ + + @abstractmethod + async def disconnect(self, peer_id: ID) -> None: + pass + + @abstractmethod + async def close(self) -> None: + pass + + +# -------------------------- peerdata interface.py -------------------------- + + +class IPeerData(ABC): + @abstractmethod + def get_protocols(self) -> list[str]: + """ + :return: all protocols associated with given peer + """ + + @abstractmethod + def add_protocols(self, protocols: Sequence[str]) -> None: + """ + :param protocols: protocols to add + """ + + @abstractmethod + def set_protocols(self, protocols: Sequence[str]) -> None: + """ + :param protocols: protocols to set + """ + + @abstractmethod + def add_addrs(self, addrs: Sequence[Multiaddr]) -> None: + """ + :param addrs: multiaddresses to add + """ + + @abstractmethod + def get_addrs(self) -> list[Multiaddr]: + """ + :return: all multiaddresses + """ + + @abstractmethod + def clear_addrs(self) -> None: + """Clear all addresses.""" + + @abstractmethod + def put_metadata(self, key: str, val: Any) -> None: + """ + :param key: key in KV pair + :param val: val to associate with key + """ + + @abstractmethod + def get_metadata(self, key: str) -> IPeerMetadata: + """ + :param key: key in KV pair + :return: val for key + :raise PeerDataError: key not found + """ + + @abstractmethod + def add_pubkey(self, pubkey: PublicKey) -> None: + """ + :param pubkey: + """ + + @abstractmethod + def get_pubkey(self) -> PublicKey: + """ + :return: public key of the peer + :raise PeerDataError: if public key not found + """ + + @abstractmethod + def add_privkey(self, privkey: PrivateKey) -> None: + """ + :param privkey: + """ + + @abstractmethod + def get_privkey(self) -> PrivateKey: + """ + :return: private key of the peer + :raise PeerDataError: if private key not found + """ + + +# ------------------ multiselect_communicator interface.py ------------------ + + +class IMultiselectCommunicator(ABC): + """ + Communicator helper class that ensures both the client and multistream + module will follow the same multistream protocol, which is necessary for + them to work. + """ + + @abstractmethod + async def write(self, msg_str: str) -> None: + """ + Write message to stream. + + :param msg_str: message to write + """ + + @abstractmethod + async def read(self) -> str: + """Reads message from stream until EOF.""" + + +# -------------------------- multiselect_client interface.py -------------------------- + + +class IMultiselectClient(ABC): + """ + Client for communicating with receiver's multiselect module in order to + select a protocol id to communicate over. + """ + + @abstractmethod + async def handshake(self, communicator: IMultiselectCommunicator) -> None: + """ + Ensure that the client and multiselect are both using the same + multiselect protocol. + + :param stream: stream to communicate with multiselect over + :raise Exception: multiselect protocol ID mismatch + """ + + @abstractmethod + async def select_one_of( + self, protocols: Sequence[TProtocol], communicator: IMultiselectCommunicator + ) -> TProtocol: + """ + For each protocol, send message to multiselect selecting protocol and + fail if multiselect does not return same protocol. Returns first + protocol that multiselect agrees on (i.e. that multiselect selects) + + :param protocol: protocol to select + :param stream: stream to communicate with multiselect over + :return: selected protocol + """ + + @abstractmethod + async def try_select( + self, communicator: IMultiselectCommunicator, protocol: TProtocol + ) -> TProtocol: + """ + Try to select the given protocol or raise exception if fails. + + :param communicator: communicator to use to communicate with counterparty + :param protocol: protocol to select + :raise Exception: error in protocol selection + :return: selected protocol + """ + + +# -------------------------- multiselect_muxer interface.py -------------------------- + + +class IMultiselectMuxer(ABC): + """ + Multiselect module that is responsible for responding to a multiselect + client and deciding on a specific protocol and handler pair to use for + communication. + """ + + handlers: dict[TProtocol, StreamHandlerFn] + + @abstractmethod + def add_handler(self, protocol: TProtocol, handler: StreamHandlerFn) -> None: + """ + Store the handler with the given protocol. + + :param protocol: protocol name + :param handler: handler function + """ + + def get_protocols(self) -> tuple[TProtocol, ...]: + return tuple(self.handlers.keys()) + + @abstractmethod + async def negotiate( + self, communicator: IMultiselectCommunicator + ) -> tuple[TProtocol, StreamHandlerFn]: + """ + Negotiate performs protocol selection. + + :param stream: stream to negotiate on + :return: selected protocol name, handler function + :raise Exception: negotiation failed exception + """ + + +# -------------------------- routing interface.py -------------------------- + + +class IContentRouting(ABC): + @abstractmethod + def provide(self, cid: bytes, announce: bool = True) -> None: + """ + 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. + """ + + @abstractmethod + def find_provider_iter(self, cid: bytes, count: int) -> Iterable[PeerInfo]: + """ + Search for peers who are able to provide a given key returns an + iterator of peer.PeerInfo. + """ + + +class IPeerRouting(ABC): + @abstractmethod + async def find_peer(self, peer_id: ID) -> PeerInfo: + """ + Find specific Peer FindPeer searches for a peer with given peer_id, + returns a peer.PeerInfo with relevant addresses. + """ + + +# -------------------------- security_transport interface.py -------------------------- + + +""" +Transport that is used to secure a connection. This transport is +chosen by a security transport multistream module. + +Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interface.go +""" + + +class ISecureTransport(ABC): + @abstractmethod + async def secure_inbound(self, conn: IRawConnection) -> ISecureConn: + """ + Secure the connection, either locally or by communicating with opposing + node via conn, for an inbound connection (i.e. we are not the + initiator) + + :return: secure connection object (that implements secure_conn_interface) + """ + + @abstractmethod + async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn: + """ + Secure the connection, either locally or by communicating with opposing + node via conn, for an inbound connection (i.e. we are the initiator) + + :return: secure connection object (that implements secure_conn_interface) + """ + + +# -------------------------- transport interface.py -------------------------- + + +class ITransport(ABC): + @abstractmethod + async def dial(self, maddr: Multiaddr) -> IRawConnection: + """ + Dial a transport to peer listening on multiaddr. + + :param multiaddr: multiaddr of peer + :param self_id: peer_id of the dialer (to send to receiver) + :return: list of multiaddrs + """ + + @abstractmethod + def create_listener(self, handler_function: THandler) -> IListener: + """ + Create listener on transport. + + :param handler_function: a function called when a new conntion is received + that takes a connection as argument which implements interface-connection + :return: a listener object that implements listener_interface.py + """ + + +# -------------------------- pubsub abc.py -------------------------- + + +class ISubscriptionAPI( + AsyncContextManager["ISubscriptionAPI"], AsyncIterable[rpc_pb2.Message] +): + @abstractmethod + async def unsubscribe(self) -> None: + ... + + @abstractmethod + async def get(self) -> rpc_pb2.Message: + ... + + +class IPubsubRouter(ABC): + @abstractmethod + def get_protocols(self) -> list[TProtocol]: + """ + :return: the list of protocols supported by the router + """ + + @abstractmethod + def attach(self, pubsub: "Pubsub") -> None: + """ + Attach is invoked by the PubSub constructor to attach the router to a + freshly initialized PubSub instance. + + :param pubsub: pubsub instance to attach to + """ + + @abstractmethod + def add_peer(self, peer_id: ID, protocol_id: TProtocol) -> None: + """ + Notifies the router that a new peer has been connected. + + :param peer_id: id of peer to add + :param protocol_id: router protocol the peer speaks, e.g., floodsub, gossipsub + """ + + @abstractmethod + def remove_peer(self, peer_id: ID) -> None: + """ + Notifies the router that a peer has been disconnected. + + :param peer_id: id of peer to remove + """ + + @abstractmethod + async def handle_rpc(self, rpc: rpc_pb2.RPC, sender_peer_id: ID) -> None: + """ + Invoked to process control messages in the RPC envelope. + It is invoked after subscriptions and payload messages have been processed + + :param rpc: RPC message + :param sender_peer_id: id of the peer who sent the message + """ + + @abstractmethod + async def publish(self, msg_forwarder: ID, pubsub_msg: rpc_pb2.Message) -> None: + """ + Invoked to forward a new message that has been validated. + + :param msg_forwarder: peer_id of message sender + :param pubsub_msg: pubsub message to forward + """ + + @abstractmethod + async def join(self, topic: str) -> None: + """ + Join notifies the router that we want to receive and forward messages + in a topic. It is invoked after the subscription announcement. + + :param topic: topic to join + """ + + @abstractmethod + async def leave(self, topic: str) -> None: + """ + Leave notifies the router that we are no longer interested in a topic. + It is invoked after the unsubscription announcement. + + :param topic: topic to leave + """ + + +class IPubsub(ServiceAPI): + @property + @abstractmethod + def my_id(self) -> ID: + ... + + @property + @abstractmethod + def protocols(self) -> tuple[TProtocol, ...]: + ... + + @property + @abstractmethod + def topic_ids(self) -> KeysView[str]: + ... + + @abstractmethod + def set_topic_validator( + self, topic: str, validator: ValidatorFn, is_async_validator: bool + ) -> None: + ... + + @abstractmethod + def remove_topic_validator(self, topic: str) -> None: + ... + + @abstractmethod + async def wait_until_ready(self) -> None: + ... + + @abstractmethod + async def subscribe(self, topic_id: str) -> ISubscriptionAPI: + ... + + @abstractmethod + async def unsubscribe(self, topic_id: str) -> None: + ... + + @abstractmethod + async def publish(self, topic_id: str, data: bytes) -> None: + ... diff --git a/libp2p/custom_types.py b/libp2p/custom_types.py index 103c6520..1789844c 100644 --- a/libp2p/custom_types.py +++ b/libp2p/custom_types.py @@ -1,15 +1,49 @@ from collections.abc import ( Awaitable, + Mapping, ) from typing import ( TYPE_CHECKING, Callable, NewType, + Union, ) if TYPE_CHECKING: - from libp2p.network.stream.net_stream_interface import INetStream # noqa: F401 - from libp2p.stream_muxer.abc import IMuxedStream # noqa: F401 + from libp2p.abc import ( + IMuxedConn, + INetStream, + ISecureTransport, + ) +else: + + class INetStream: + pass + + class IMuxedConn: + pass + + class ISecureTransport: + pass + + +from libp2p.io.abc import ( + ReadWriteCloser, +) +from libp2p.peer.id import ( + ID, +) +from libp2p.pubsub.pb import ( + rpc_pb2, +) TProtocol = NewType("TProtocol", str) StreamHandlerFn = Callable[["INetStream"], Awaitable[None]] +THandler = Callable[[ReadWriteCloser], Awaitable[None]] +TSecurityOptions = Mapping[TProtocol, "ISecureTransport"] +TMuxerClass = type["IMuxedConn"] +TMuxerOptions = Mapping[TProtocol, TMuxerClass] +SyncValidatorFn = Callable[[ID, rpc_pb2.Message], bool] +AsyncValidatorFn = Callable[[ID, rpc_pb2.Message], Awaitable[bool]] +ValidatorFn = Union[SyncValidatorFn, AsyncValidatorFn] +UnsubscribeFn = Callable[[], Awaitable[None]] diff --git a/libp2p/host/basic_host.py b/libp2p/host/basic_host.py index fff4124c..fbe2e667 100644 --- a/libp2p/host/basic_host.py +++ b/libp2p/host/basic_host.py @@ -12,6 +12,12 @@ from typing import ( import multiaddr +from libp2p.abc import ( + IHost, + INetStream, + INetworkService, + IPeerStore, +) from libp2p.crypto.keys import ( PrivateKey, PublicKey, @@ -26,21 +32,12 @@ from libp2p.host.defaults import ( from libp2p.host.exceptions import ( StreamFailure, ) -from libp2p.network.network_interface import ( - INetworkService, -) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from libp2p.peer.id import ( ID, ) from libp2p.peer.peerinfo import ( PeerInfo, ) -from libp2p.peer.peerstore_interface import ( - IPeerStore, -) from libp2p.protocol_muxer.exceptions import ( MultiselectClientError, MultiselectError, @@ -58,10 +55,6 @@ from libp2p.tools.async_service import ( background_trio_service, ) -from .host_interface import ( - IHost, -) - if TYPE_CHECKING: from collections import ( OrderedDict, diff --git a/libp2p/host/defaults.py b/libp2p/host/defaults.py index 624c71f8..93634233 100644 --- a/libp2p/host/defaults.py +++ b/libp2p/host/defaults.py @@ -5,7 +5,7 @@ from typing import ( TYPE_CHECKING, ) -from libp2p.host.host_interface import ( +from libp2p.abc import ( IHost, ) from libp2p.host.ping import ( diff --git a/libp2p/host/host_interface.py b/libp2p/host/host_interface.py deleted file mode 100644 index 00b83303..00000000 --- a/libp2p/host/host_interface.py +++ /dev/null @@ -1,133 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Sequence, -) -from typing import ( - Any, - AsyncContextManager, -) - -import multiaddr - -from libp2p.crypto.keys import ( - PrivateKey, - PublicKey, -) -from libp2p.custom_types import ( - StreamHandlerFn, - TProtocol, -) -from libp2p.network.network_interface import ( - INetworkService, -) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) -from libp2p.peer.id import ( - ID, -) -from libp2p.peer.peerinfo import ( - PeerInfo, -) - - -class IHost(ABC): - @abstractmethod - def get_id(self) -> ID: - """ - :return: peer_id of host - """ - - @abstractmethod - def get_public_key(self) -> PublicKey: - """ - :return: the public key belonging to the peer - """ - - @abstractmethod - def get_private_key(self) -> PrivateKey: - """ - :return: the private key belonging to the peer - """ - - @abstractmethod - def get_network(self) -> INetworkService: - """ - :return: network instance of host - """ - - # FIXME: Replace with correct return type - @abstractmethod - def get_mux(self) -> Any: - """ - :return: mux instance of host - """ - - @abstractmethod - def get_addrs(self) -> list[multiaddr.Multiaddr]: - """ - :return: all the multiaddr addresses this host is listening to - """ - - @abstractmethod - def get_connected_peers(self) -> list[ID]: - """ - :return: all the ids of peers this host is currently connected to - """ - - @abstractmethod - def run( - self, listen_addrs: Sequence[multiaddr.Multiaddr] - ) -> AsyncContextManager[None]: - """ - Run the host instance and listen to ``listen_addrs``. - - :param listen_addrs: a sequence of multiaddrs that we want to listen to - """ - - @abstractmethod - def set_stream_handler( - self, protocol_id: TProtocol, stream_handler: StreamHandlerFn - ) -> None: - """ - Set stream handler for host. - - :param protocol_id: protocol id used on stream - :param stream_handler: a stream handler function - """ - - # protocol_id can be a list of protocol_ids - # stream will decide which protocol_id to run on - @abstractmethod - async def new_stream( - self, peer_id: ID, protocol_ids: Sequence[TProtocol] - ) -> INetStream: - """ - :param peer_id: peer_id that host is connecting - :param protocol_ids: available protocol ids to use for stream - :return: stream: new stream created - """ - - @abstractmethod - async def connect(self, peer_info: PeerInfo) -> None: - """ - Ensure 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 - opened, or an error is returned. - - :param peer_info: peer_info of the peer we want to connect to - :type peer_info: peer.peerinfo.PeerInfo - """ - - @abstractmethod - async def disconnect(self, peer_id: ID) -> None: - pass - - @abstractmethod - async def close(self) -> None: - pass diff --git a/libp2p/host/ping.py b/libp2p/host/ping.py index e1906146..4cc16bc4 100644 --- a/libp2p/host/ping.py +++ b/libp2p/host/ping.py @@ -4,20 +4,18 @@ import time import trio +from libp2p.abc import ( + IHost, + INetStream, +) from libp2p.custom_types import ( TProtocol, ) -from libp2p.host.host_interface import ( - IHost, -) from libp2p.network.stream.exceptions import ( StreamClosed, StreamEOF, StreamReset, ) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from libp2p.peer.id import ID as PeerID ID = TProtocol("/ipfs/ping/1.0.0") diff --git a/libp2p/host/routed_host.py b/libp2p/host/routed_host.py index 3a4b1a28..7cbe81d9 100644 --- a/libp2p/host/routed_host.py +++ b/libp2p/host/routed_host.py @@ -1,18 +1,16 @@ +from libp2p.abc import ( + INetworkService, + IPeerRouting, +) from libp2p.host.basic_host import ( BasicHost, ) from libp2p.host.exceptions import ( ConnectionFailure, ) -from libp2p.network.network_interface import ( - INetworkService, -) from libp2p.peer.peerinfo import ( PeerInfo, ) -from libp2p.routing.interfaces import ( - IPeerRouting, -) # RoutedHost is a p2p Host that includes a routing system. diff --git a/libp2p/identity/identify/protocol.py b/libp2p/identity/identify/protocol.py index 3bf6ae1f..bb3bd9d6 100644 --- a/libp2p/identity/identify/protocol.py +++ b/libp2p/identity/identify/protocol.py @@ -4,19 +4,17 @@ from multiaddr import ( Multiaddr, ) +from libp2p.abc import ( + IHost, + INetStream, +) from libp2p.custom_types import ( StreamHandlerFn, TProtocol, ) -from libp2p.host.host_interface import ( - IHost, -) from libp2p.network.stream.exceptions import ( StreamClosed, ) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from .pb.identify_pb2 import ( Identify, diff --git a/libp2p/network/connection/net_connection_interface.py b/libp2p/network/connection/net_connection_interface.py deleted file mode 100644 index 4e5930d6..00000000 --- a/libp2p/network/connection/net_connection_interface.py +++ /dev/null @@ -1,28 +0,0 @@ -from abc import ( - abstractmethod, -) - -import trio - -from libp2p.io.abc import ( - Closer, -) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) -from libp2p.stream_muxer.abc import ( - IMuxedConn, -) - - -class INetConn(Closer): - muxed_conn: IMuxedConn - event_started: trio.Event - - @abstractmethod - async def new_stream(self) -> INetStream: - ... - - @abstractmethod - def get_streams(self) -> tuple[INetStream, ...]: - ... diff --git a/libp2p/network/connection/raw_connection.py b/libp2p/network/connection/raw_connection.py index 98961296..fc2ea61b 100644 --- a/libp2p/network/connection/raw_connection.py +++ b/libp2p/network/connection/raw_connection.py @@ -1,3 +1,6 @@ +from libp2p.abc import ( + IRawConnection, +) from libp2p.io.abc import ( ReadWriteCloser, ) @@ -8,9 +11,6 @@ from libp2p.io.exceptions import ( from .exceptions import ( RawConnError, ) -from .raw_connection_interface import ( - IRawConnection, -) class RawConnection(IRawConnection): diff --git a/libp2p/network/connection/raw_connection_interface.py b/libp2p/network/connection/raw_connection_interface.py deleted file mode 100644 index 6f2bab2b..00000000 --- a/libp2p/network/connection/raw_connection_interface.py +++ /dev/null @@ -1,9 +0,0 @@ -from libp2p.io.abc import ( - ReadWriteCloser, -) - - -class IRawConnection(ReadWriteCloser): - """A Raw Connection provides a Reader and a Writer.""" - - is_initiator: bool diff --git a/libp2p/network/connection/swarm_connection.py b/libp2p/network/connection/swarm_connection.py index 1490ab60..0470d3bb 100644 --- a/libp2p/network/connection/swarm_connection.py +++ b/libp2p/network/connection/swarm_connection.py @@ -4,16 +4,14 @@ from typing import ( import trio -from libp2p.network.connection.net_connection_interface import ( +from libp2p.abc import ( + IMuxedConn, + IMuxedStream, INetConn, ) from libp2p.network.stream.net_stream import ( NetStream, ) -from libp2p.stream_muxer.abc import ( - IMuxedConn, - IMuxedStream, -) from libp2p.stream_muxer.exceptions import ( MuxedConnUnavailable, ) diff --git a/libp2p/network/network_interface.py b/libp2p/network/network_interface.py deleted file mode 100644 index 6f97f71a..00000000 --- a/libp2p/network/network_interface.py +++ /dev/null @@ -1,100 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Sequence, -) -from typing import ( - TYPE_CHECKING, -) - -from multiaddr import ( - Multiaddr, -) - -from libp2p.custom_types import ( - StreamHandlerFn, -) -from libp2p.network.connection.net_connection_interface import ( - INetConn, -) -from libp2p.peer.id import ( - ID, -) -from libp2p.peer.peerstore_interface import ( - IPeerStore, -) -from libp2p.tools.async_service import ( - ServiceAPI, -) -from libp2p.transport.listener_interface import ( - IListener, -) - -from .stream.net_stream_interface import ( - INetStream, -) - -if TYPE_CHECKING: - from .notifee_interface import INotifee # noqa: F401 - - -class INetwork(ABC): - peerstore: IPeerStore - connections: dict[ID, INetConn] - listeners: dict[str, IListener] - - @abstractmethod - def get_peer_id(self) -> ID: - """ - :return: the peer id - """ - - @abstractmethod - async def dial_peer(self, peer_id: ID) -> INetConn: - """ - dial_peer try to create a connection to peer_id. - - :param peer_id: peer if we want to dial - :raises SwarmException: raised when an error occurs - :return: muxed connection - """ - - @abstractmethod - async def new_stream(self, peer_id: ID) -> INetStream: - """ - :param peer_id: peer_id of destination - :param protocol_ids: available protocol ids to use for stream - :return: net stream instance - """ - - @abstractmethod - def set_stream_handler(self, stream_handler: StreamHandlerFn) -> None: - """Set the stream handler for all incoming streams.""" - - @abstractmethod - async def listen(self, *multiaddrs: Sequence[Multiaddr]) -> bool: - """ - :param multiaddrs: one or many multiaddrs to start listening on - :return: True if at least one success - """ - - @abstractmethod - def register_notifee(self, notifee: "INotifee") -> None: - """ - :param notifee: object implementing Notifee interface - :return: true if notifee registered successfully, false otherwise - """ - - @abstractmethod - async def close(self) -> None: - pass - - @abstractmethod - async def close_peer(self, peer_id: ID) -> None: - pass - - -class INetworkService(INetwork, ServiceAPI): - pass diff --git a/libp2p/network/notifee_interface.py b/libp2p/network/notifee_interface.py deleted file mode 100644 index 22deb575..00000000 --- a/libp2p/network/notifee_interface.py +++ /dev/null @@ -1,65 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from typing import ( - TYPE_CHECKING, -) - -from multiaddr import ( - Multiaddr, -) - -from libp2p.network.connection.net_connection_interface import ( - INetConn, -) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) - -if TYPE_CHECKING: - from .network_interface import INetwork # noqa: F401 - - -class INotifee(ABC): - @abstractmethod - async def opened_stream(self, network: "INetwork", stream: INetStream) -> None: - """ - :param network: network the stream was opened on - :param stream: stream that was opened - """ - - @abstractmethod - async def closed_stream(self, network: "INetwork", stream: INetStream) -> None: - """ - :param network: network the stream was closed on - :param stream: stream that was closed - """ - - @abstractmethod - async def connected(self, network: "INetwork", conn: INetConn) -> None: - """ - :param network: network the connection was opened on - :param conn: connection that was opened - """ - - @abstractmethod - async def disconnected(self, network: "INetwork", conn: INetConn) -> None: - """ - :param network: network the connection was closed on - :param conn: connection that was closed - """ - - @abstractmethod - async def listen(self, network: "INetwork", multiaddr: Multiaddr) -> None: - """ - :param network: network the listener is listening on - :param multiaddr: multiaddress listener is listening on - """ - - @abstractmethod - async def listen_close(self, network: "INetwork", multiaddr: Multiaddr) -> None: - """ - :param network: network the connection was opened on - :param multiaddr: multiaddress listener is no longer listening on - """ diff --git a/libp2p/network/stream/net_stream.py b/libp2p/network/stream/net_stream.py index 90d4c55c..5dc053c4 100644 --- a/libp2p/network/stream/net_stream.py +++ b/libp2p/network/stream/net_stream.py @@ -2,12 +2,13 @@ from typing import ( Optional, ) +from libp2p.abc import ( + IMuxedStream, + INetStream, +) from libp2p.custom_types import ( TProtocol, ) -from libp2p.stream_muxer.abc import ( - IMuxedStream, -) from libp2p.stream_muxer.exceptions import ( MuxedStreamClosed, MuxedStreamEOF, @@ -19,9 +20,6 @@ from .exceptions import ( StreamEOF, StreamReset, ) -from .net_stream_interface import ( - INetStream, -) # TODO: Handle exceptions from `muxed_stream` diff --git a/libp2p/network/stream/net_stream_interface.py b/libp2p/network/stream/net_stream_interface.py deleted file mode 100644 index ceaede3a..00000000 --- a/libp2p/network/stream/net_stream_interface.py +++ /dev/null @@ -1,33 +0,0 @@ -from abc import ( - abstractmethod, -) - -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.io.abc import ( - ReadWriteCloser, -) -from libp2p.stream_muxer.abc import ( - IMuxedConn, -) - - -class INetStream(ReadWriteCloser): - muxed_conn: IMuxedConn - - @abstractmethod - def get_protocol(self) -> TProtocol: - """ - :return: protocol id that stream runs on - """ - - @abstractmethod - def set_protocol(self, protocol_id: TProtocol) -> None: - """ - :param protocol_id: protocol id that stream runs on - """ - - @abstractmethod - async def reset(self) -> None: - """Close both ends of the stream.""" diff --git a/libp2p/network/swarm.py b/libp2p/network/swarm.py index 647a073a..348c7d97 100644 --- a/libp2p/network/swarm.py +++ b/libp2p/network/swarm.py @@ -8,27 +8,28 @@ from multiaddr import ( ) import trio +from libp2p.abc import ( + IListener, + IMuxedConn, + INetConn, + INetStream, + INetworkService, + INotifee, + IPeerStore, + ITransport, +) from libp2p.custom_types import ( StreamHandlerFn, ) from libp2p.io.abc import ( ReadWriteCloser, ) -from libp2p.network.connection.net_connection_interface import ( - INetConn, -) from libp2p.peer.id import ( ID, ) from libp2p.peer.peerstore import ( PeerStoreError, ) -from libp2p.peer.peerstore_interface import ( - IPeerStore, -) -from libp2p.stream_muxer.abc import ( - IMuxedConn, -) from libp2p.tools.async_service import ( Service, ) @@ -37,12 +38,6 @@ from libp2p.transport.exceptions import ( OpenConnectionError, SecurityUpgradeFailure, ) -from libp2p.transport.listener_interface import ( - IListener, -) -from libp2p.transport.transport_interface import ( - ITransport, -) from libp2p.transport.upgrader import ( TransportUpgrader, ) @@ -59,15 +54,6 @@ from .connection.swarm_connection import ( from .exceptions import ( SwarmException, ) -from .network_interface import ( - INetworkService, -) -from .notifee_interface import ( - INotifee, -) -from .stream.net_stream_interface import ( - INetStream, -) logger = logging.getLogger("libp2p.network.swarm") diff --git a/libp2p/peer/addrbook_interface.py b/libp2p/peer/addrbook_interface.py deleted file mode 100644 index 35dcbd8c..00000000 --- a/libp2p/peer/addrbook_interface.py +++ /dev/null @@ -1,61 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Sequence, -) - -from multiaddr import ( - Multiaddr, -) - -from .id import ( - ID, -) - - -class IAddrBook(ABC): - @abstractmethod - def add_addr(self, peer_id: ID, addr: Multiaddr, ttl: int) -> None: - """ - Calls add_addrs(peer_id, [addr], ttl) - - :param peer_id: the peer to add address for - :param addr: multiaddress of the peer - :param ttl: time-to-live for the address (after this time, address is no longer valid) - """ # noqa: E501 - - @abstractmethod - def add_addrs(self, peer_id: ID, addrs: Sequence[Multiaddr], ttl: int) -> None: - """ - Adds addresses for a given peer all with the same time-to-live. If one - of the addresses already exists for the peer and has a longer TTL, no - operation should take place. If one of the addresses exists with a - shorter TTL, extend the TTL to equal param ttl. - - :param peer_id: the peer to add address for - :param addr: multiaddresses of the peer - :param ttl: time-to-live for the address (after this time, address is no longer valid - """ # noqa: E501 - - @abstractmethod - def addrs(self, peer_id: ID) -> list[Multiaddr]: - """ - :param peer_id: peer to get addresses of - :return: all known (and valid) addresses for the given peer - """ - - @abstractmethod - def clear_addrs(self, peer_id: ID) -> None: - """ - Removes all previously stored addresses. - - :param peer_id: peer to remove addresses of - """ - - @abstractmethod - def peers_with_addrs(self) -> list[ID]: - """ - :return: all of the peer IDs stored with addresses - """ diff --git a/libp2p/peer/peerdata.py b/libp2p/peer/peerdata.py index bd22d729..f0e52463 100644 --- a/libp2p/peer/peerdata.py +++ b/libp2p/peer/peerdata.py @@ -9,15 +9,14 @@ from multiaddr import ( Multiaddr, ) +from libp2p.abc import ( + IPeerData, +) from libp2p.crypto.keys import ( PrivateKey, PublicKey, ) -from .peerdata_interface import ( - IPeerData, -) - class PeerData(IPeerData): pubkey: PublicKey diff --git a/libp2p/peer/peerdata_interface.py b/libp2p/peer/peerdata_interface.py deleted file mode 100644 index a2c61a5c..00000000 --- a/libp2p/peer/peerdata_interface.py +++ /dev/null @@ -1,100 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Sequence, -) -from typing import ( - Any, -) - -from multiaddr import ( - Multiaddr, -) - -from libp2p.crypto.keys import ( - PrivateKey, - PublicKey, -) - -from .peermetadata_interface import ( - IPeerMetadata, -) - - -class IPeerData(ABC): - @abstractmethod - def get_protocols(self) -> list[str]: - """ - :return: all protocols associated with given peer - """ - - @abstractmethod - def add_protocols(self, protocols: Sequence[str]) -> None: - """ - :param protocols: protocols to add - """ - - @abstractmethod - def set_protocols(self, protocols: Sequence[str]) -> None: - """ - :param protocols: protocols to set - """ - - @abstractmethod - def add_addrs(self, addrs: Sequence[Multiaddr]) -> None: - """ - :param addrs: multiaddresses to add - """ - - @abstractmethod - def get_addrs(self) -> list[Multiaddr]: - """ - :return: all multiaddresses - """ - - @abstractmethod - def clear_addrs(self) -> None: - """Clear all addresses.""" - - @abstractmethod - def put_metadata(self, key: str, val: Any) -> None: - """ - :param key: key in KV pair - :param val: val to associate with key - """ - - @abstractmethod - def get_metadata(self, key: str) -> IPeerMetadata: - """ - :param key: key in KV pair - :return: val for key - :raise PeerDataError: key not found - """ - - @abstractmethod - def add_pubkey(self, pubkey: PublicKey) -> None: - """ - :param pubkey: - """ - - @abstractmethod - def get_pubkey(self) -> PublicKey: - """ - :return: public key of the peer - :raise PeerDataError: if public key not found - """ - - @abstractmethod - def add_privkey(self, privkey: PrivateKey) -> None: - """ - :param privkey: - """ - - @abstractmethod - def get_privkey(self) -> PrivateKey: - """ - :return: private key of the peer - :raise PeerDataError: if private key not found - """ diff --git a/libp2p/peer/peermetadata_interface.py b/libp2p/peer/peermetadata_interface.py deleted file mode 100644 index 39d8967d..00000000 --- a/libp2p/peer/peermetadata_interface.py +++ /dev/null @@ -1,31 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from typing import ( - Any, -) - -from .id import ( - ID, -) - - -class IPeerMetadata(ABC): - @abstractmethod - def get(self, peer_id: ID, key: str) -> Any: - """ - :param peer_id: peer ID to lookup key for - :param key: key to look up - :return: value at key for given peer - :raise Exception: peer ID not found - """ - - @abstractmethod - def put(self, peer_id: ID, key: str, val: Any) -> None: - """ - :param peer_id: peer ID to lookup key for - :param key: key to associate with peer - :param val: value to associated with key - :raise Exception: unsuccessful put - """ diff --git a/libp2p/peer/peerstore.py b/libp2p/peer/peerstore.py index f418dad6..f49739ba 100644 --- a/libp2p/peer/peerstore.py +++ b/libp2p/peer/peerstore.py @@ -12,6 +12,9 @@ from multiaddr import ( Multiaddr, ) +from libp2p.abc import ( + IPeerStore, +) from libp2p.crypto.keys import ( KeyPair, PrivateKey, @@ -28,9 +31,6 @@ from .peerdata import ( from .peerinfo import ( PeerInfo, ) -from .peerstore_interface import ( - IPeerStore, -) class PeerStore(IPeerStore): diff --git a/libp2p/peer/peerstore_interface.py b/libp2p/peer/peerstore_interface.py deleted file mode 100644 index 1b5db069..00000000 --- a/libp2p/peer/peerstore_interface.py +++ /dev/null @@ -1,161 +0,0 @@ -from abc import ( - abstractmethod, -) -from collections.abc import ( - Sequence, -) -from typing import ( - Any, -) - -from multiaddr import ( - Multiaddr, -) - -from libp2p.crypto.keys import ( - KeyPair, - PrivateKey, - PublicKey, -) - -from .addrbook_interface import ( - IAddrBook, -) -from .id import ( - ID, -) -from .peerinfo import ( - PeerInfo, -) -from .peermetadata_interface import ( - IPeerMetadata, -) - - -class IPeerStore(IAddrBook, IPeerMetadata): - @abstractmethod - def peer_info(self, peer_id: ID) -> PeerInfo: - """ - :param peer_id: peer ID to get info for - :return: peer info object - """ - - @abstractmethod - def get_protocols(self, peer_id: ID) -> list[str]: - """ - :param peer_id: peer ID to get protocols for - :return: protocols (as list of strings) - :raise PeerStoreError: if peer ID not found - """ - - @abstractmethod - def add_protocols(self, peer_id: ID, protocols: Sequence[str]) -> None: - """ - :param peer_id: peer ID to add protocols for - :param protocols: protocols to add - """ - - @abstractmethod - def set_protocols(self, peer_id: ID, protocols: Sequence[str]) -> None: - """ - :param peer_id: peer ID to set protocols for - :param protocols: protocols to set - """ - - @abstractmethod - def peer_ids(self) -> list[ID]: - """ - :return: all of the peer IDs stored in peer store - """ - - @abstractmethod - def get(self, peer_id: ID, key: str) -> Any: - """ - :param peer_id: peer ID to get peer data for - :param key: the key to search value for - :return: value corresponding to the key - :raise PeerStoreError: if peer ID or value not found - """ - - @abstractmethod - def put(self, peer_id: ID, key: str, val: Any) -> None: - """ - :param peer_id: peer ID to put peer data for - :param key: - :param value: - """ - - @abstractmethod - def add_addr(self, peer_id: ID, addr: Multiaddr, ttl: int) -> None: - """ - :param peer_id: peer ID to add address for - :param addr: - :param ttl: time-to-live for the this record - """ - - @abstractmethod - def add_addrs(self, peer_id: ID, addrs: Sequence[Multiaddr], ttl: int) -> None: - """ - :param peer_id: peer ID to add address for - :param addrs: - :param ttl: time-to-live for the this record - """ - - @abstractmethod - def addrs(self, peer_id: ID) -> list[Multiaddr]: - """ - :param peer_id: peer ID to get addrs for - :return: list of addrs - """ - - @abstractmethod - def clear_addrs(self, peer_id: ID) -> None: - """ - :param peer_id: peer ID to clear addrs for - """ - - @abstractmethod - def peers_with_addrs(self) -> list[ID]: - """ - :return: all of the peer IDs which has addrs stored in peer store - """ - - @abstractmethod - def add_pubkey(self, peer_id: ID, pubkey: PublicKey) -> None: - """ - :param peer_id: peer ID to add public key for - :param pubkey: - :raise PeerStoreError: if peer ID already has pubkey set - """ - - @abstractmethod - def pubkey(self, peer_id: ID) -> PublicKey: - """ - :param peer_id: peer ID to get public key for - :return: public key of the peer - :raise PeerStoreError: if peer ID not found - """ - - @abstractmethod - def add_privkey(self, peer_id: ID, privkey: PrivateKey) -> None: - """ - :param peer_id: peer ID to add private key for - :param privkey: - :raise PeerStoreError: if peer ID already has privkey set - """ - - @abstractmethod - def privkey(self, peer_id: ID) -> PrivateKey: - """ - :param peer_id: peer ID to get private key for - :return: private key of the peer - :raise PeerStoreError: if peer ID not found - """ - - @abstractmethod - def add_key_pair(self, peer_id: ID, key_pair: KeyPair) -> None: - """ - :param peer_id: peer ID to add private key for - :param key_pair: - :raise PeerStoreError: if peer ID already has pubkey or privkey set - """ diff --git a/libp2p/protocol_muxer/multiselect.py b/libp2p/protocol_muxer/multiselect.py index 69ea2754..ed9bccca 100644 --- a/libp2p/protocol_muxer/multiselect.py +++ b/libp2p/protocol_muxer/multiselect.py @@ -1,3 +1,7 @@ +from libp2p.abc import ( + IMultiselectCommunicator, + IMultiselectMuxer, +) from libp2p.custom_types import ( StreamHandlerFn, TProtocol, @@ -7,12 +11,6 @@ from .exceptions import ( MultiselectCommunicatorError, MultiselectError, ) -from .multiselect_communicator_interface import ( - IMultiselectCommunicator, -) -from .multiselect_muxer_interface import ( - IMultiselectMuxer, -) MULTISELECT_PROTOCOL_ID = "/multistream/1.0.0" PROTOCOL_NOT_FOUND_MSG = "na" diff --git a/libp2p/protocol_muxer/multiselect_client.py b/libp2p/protocol_muxer/multiselect_client.py index d8806521..abbab54c 100644 --- a/libp2p/protocol_muxer/multiselect_client.py +++ b/libp2p/protocol_muxer/multiselect_client.py @@ -2,6 +2,10 @@ from collections.abc import ( Sequence, ) +from libp2p.abc import ( + IMultiselectClient, + IMultiselectCommunicator, +) from libp2p.custom_types import ( TProtocol, ) @@ -10,12 +14,6 @@ from .exceptions import ( MultiselectClientError, MultiselectCommunicatorError, ) -from .multiselect_client_interface import ( - IMultiselectClient, -) -from .multiselect_communicator_interface import ( - IMultiselectCommunicator, -) MULTISELECT_PROTOCOL_ID = "/multistream/1.0.0" PROTOCOL_NOT_FOUND_MSG = "na" diff --git a/libp2p/protocol_muxer/multiselect_client_interface.py b/libp2p/protocol_muxer/multiselect_client_interface.py deleted file mode 100644 index 180aa4f6..00000000 --- a/libp2p/protocol_muxer/multiselect_client_interface.py +++ /dev/null @@ -1,58 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Sequence, -) - -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.protocol_muxer.multiselect_communicator_interface import ( - IMultiselectCommunicator, -) - - -class IMultiselectClient(ABC): - """ - Client for communicating with receiver's multiselect module in order to - select a protocol id to communicate over. - """ - - @abstractmethod - async def handshake(self, communicator: IMultiselectCommunicator) -> None: - """ - Ensure that the client and multiselect are both using the same - multiselect protocol. - - :param stream: stream to communicate with multiselect over - :raise Exception: multiselect protocol ID mismatch - """ - - @abstractmethod - async def select_one_of( - self, protocols: Sequence[TProtocol], communicator: IMultiselectCommunicator - ) -> TProtocol: - """ - For each protocol, send message to multiselect selecting protocol and - fail if multiselect does not return same protocol. Returns first - protocol that multiselect agrees on (i.e. that multiselect selects) - - :param protocol: protocol to select - :param stream: stream to communicate with multiselect over - :return: selected protocol - """ - - @abstractmethod - async def try_select( - self, communicator: IMultiselectCommunicator, protocol: TProtocol - ) -> TProtocol: - """ - Try to select the given protocol or raise exception if fails. - - :param communicator: communicator to use to communicate with counterparty - :param protocol: protocol to select - :raise Exception: error in protocol selection - :return: selected protocol - """ diff --git a/libp2p/protocol_muxer/multiselect_communicator.py b/libp2p/protocol_muxer/multiselect_communicator.py index f4ecc369..c52266fd 100644 --- a/libp2p/protocol_muxer/multiselect_communicator.py +++ b/libp2p/protocol_muxer/multiselect_communicator.py @@ -1,3 +1,6 @@ +from libp2p.abc import ( + IMultiselectCommunicator, +) from libp2p.exceptions import ( ParseError, ) @@ -15,9 +18,6 @@ from libp2p.utils import ( from .exceptions import ( MultiselectCommunicatorError, ) -from .multiselect_communicator_interface import ( - IMultiselectCommunicator, -) class MultiselectCommunicator(IMultiselectCommunicator): diff --git a/libp2p/protocol_muxer/multiselect_communicator_interface.py b/libp2p/protocol_muxer/multiselect_communicator_interface.py deleted file mode 100644 index c6e097c0..00000000 --- a/libp2p/protocol_muxer/multiselect_communicator_interface.py +++ /dev/null @@ -1,24 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - - -class IMultiselectCommunicator(ABC): - """ - Communicator helper class that ensures both the client and multistream - module will follow the same multistream protocol, which is necessary for - them to work. - """ - - @abstractmethod - async def write(self, msg_str: str) -> None: - """ - Write message to stream. - - :param msg_str: message to write - """ - - @abstractmethod - async def read(self) -> str: - """Reads message from stream until EOF.""" diff --git a/libp2p/protocol_muxer/multiselect_muxer_interface.py b/libp2p/protocol_muxer/multiselect_muxer_interface.py deleted file mode 100644 index f0ecf063..00000000 --- a/libp2p/protocol_muxer/multiselect_muxer_interface.py +++ /dev/null @@ -1,47 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -from libp2p.custom_types import ( - StreamHandlerFn, - TProtocol, -) - -from .multiselect_communicator_interface import ( - IMultiselectCommunicator, -) - - -class IMultiselectMuxer(ABC): - """ - Multiselect module that is responsible for responding to a multiselect - client and deciding on a specific protocol and handler pair to use for - communication. - """ - - handlers: dict[TProtocol, StreamHandlerFn] - - @abstractmethod - def add_handler(self, protocol: TProtocol, handler: StreamHandlerFn) -> None: - """ - Store the handler with the given protocol. - - :param protocol: protocol name - :param handler: handler function - """ - - def get_protocols(self) -> tuple[TProtocol, ...]: - return tuple(self.handlers.keys()) - - @abstractmethod - async def negotiate( - self, communicator: IMultiselectCommunicator - ) -> tuple[TProtocol, StreamHandlerFn]: - """ - Negotiate performs protocol selection. - - :param stream: stream to negotiate on - :return: selected protocol name, handler function - :raise Exception: negotiation failed exception - """ diff --git a/libp2p/pubsub/abc.py b/libp2p/pubsub/abc.py deleted file mode 100644 index 8d6ba44b..00000000 --- a/libp2p/pubsub/abc.py +++ /dev/null @@ -1,158 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - AsyncIterable, - KeysView, -) -from typing import ( - TYPE_CHECKING, - AsyncContextManager, -) - -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.peer.id import ( - ID, -) -from libp2p.tools.async_service import ( - ServiceAPI, -) - -from .pb import ( - rpc_pb2, -) -from .typing import ( - ValidatorFn, -) - -if TYPE_CHECKING: - from .pubsub import Pubsub # noqa: F401 - - -class ISubscriptionAPI( - AsyncContextManager["ISubscriptionAPI"], AsyncIterable[rpc_pb2.Message] -): - @abstractmethod - async def unsubscribe(self) -> None: - ... - - @abstractmethod - async def get(self) -> rpc_pb2.Message: - ... - - -class IPubsubRouter(ABC): - @abstractmethod - def get_protocols(self) -> list[TProtocol]: - """ - :return: the list of protocols supported by the router - """ - - @abstractmethod - def attach(self, pubsub: "Pubsub") -> None: - """ - Attach is invoked by the PubSub constructor to attach the router to a - freshly initialized PubSub instance. - - :param pubsub: pubsub instance to attach to - """ - - @abstractmethod - def add_peer(self, peer_id: ID, protocol_id: TProtocol) -> None: - """ - Notifies the router that a new peer has been connected. - - :param peer_id: id of peer to add - :param protocol_id: router protocol the peer speaks, e.g., floodsub, gossipsub - """ - - @abstractmethod - def remove_peer(self, peer_id: ID) -> None: - """ - Notifies the router that a peer has been disconnected. - - :param peer_id: id of peer to remove - """ - - @abstractmethod - async def handle_rpc(self, rpc: rpc_pb2.RPC, sender_peer_id: ID) -> None: - """ - Invoked to process control messages in the RPC envelope. - It is invoked after subscriptions and payload messages have been processed - - :param rpc: RPC message - :param sender_peer_id: id of the peer who sent the message - """ - - @abstractmethod - async def publish(self, msg_forwarder: ID, pubsub_msg: rpc_pb2.Message) -> None: - """ - Invoked to forward a new message that has been validated. - - :param msg_forwarder: peer_id of message sender - :param pubsub_msg: pubsub message to forward - """ - - @abstractmethod - async def join(self, topic: str) -> None: - """ - Join notifies the router that we want to receive and forward messages - in a topic. It is invoked after the subscription announcement. - - :param topic: topic to join - """ - - @abstractmethod - async def leave(self, topic: str) -> None: - """ - Leave notifies the router that we are no longer interested in a topic. - It is invoked after the unsubscription announcement. - - :param topic: topic to leave - """ - - -class IPubsub(ServiceAPI): - @property - @abstractmethod - def my_id(self) -> ID: - ... - - @property - @abstractmethod - def protocols(self) -> tuple[TProtocol, ...]: - ... - - @property - @abstractmethod - def topic_ids(self) -> KeysView[str]: - ... - - @abstractmethod - def set_topic_validator( - self, topic: str, validator: ValidatorFn, is_async_validator: bool - ) -> None: - ... - - @abstractmethod - def remove_topic_validator(self, topic: str) -> None: - ... - - @abstractmethod - async def wait_until_ready(self) -> None: - ... - - @abstractmethod - async def subscribe(self, topic_id: str) -> ISubscriptionAPI: - ... - - @abstractmethod - async def unsubscribe(self, topic_id: str) -> None: - ... - - @abstractmethod - async def publish(self, topic_id: str, data: bytes) -> None: - ... diff --git a/libp2p/pubsub/floodsub.py b/libp2p/pubsub/floodsub.py index d99be87b..884dc89a 100644 --- a/libp2p/pubsub/floodsub.py +++ b/libp2p/pubsub/floodsub.py @@ -6,6 +6,9 @@ import logging import trio +from libp2p.abc import ( + IPubsubRouter, +) from libp2p.custom_types import ( TProtocol, ) @@ -19,9 +22,6 @@ from libp2p.utils import ( encode_varint_prefixed, ) -from .abc import ( - IPubsubRouter, -) from .pb import ( rpc_pb2, ) diff --git a/libp2p/pubsub/gossipsub.py b/libp2p/pubsub/gossipsub.py index f23040f6..006b024d 100644 --- a/libp2p/pubsub/gossipsub.py +++ b/libp2p/pubsub/gossipsub.py @@ -17,6 +17,9 @@ from typing import ( import trio +from libp2p.abc import ( + IPubsubRouter, +) from libp2p.custom_types import ( TProtocol, ) @@ -36,9 +39,6 @@ from libp2p.utils import ( encode_varint_prefixed, ) -from .abc import ( - IPubsubRouter, -) from .exceptions import ( NoPubsubAttached, ) diff --git a/libp2p/pubsub/pubsub.py b/libp2p/pubsub/pubsub.py index 1b1fe19f..044b6f89 100644 --- a/libp2p/pubsub/pubsub.py +++ b/libp2p/pubsub/pubsub.py @@ -23,19 +23,25 @@ from lru import ( ) import trio +from libp2p.abc import ( + IHost, + INetStream, + IPubsub, + ISubscriptionAPI, +) from libp2p.crypto.keys import ( PrivateKey, ) from libp2p.custom_types import ( + AsyncValidatorFn, + SyncValidatorFn, TProtocol, + ValidatorFn, ) from libp2p.exceptions import ( ParseError, ValidationError, ) -from libp2p.host.host_interface import ( - IHost, -) from libp2p.io.exceptions import ( IncompleteReadError, ) @@ -47,9 +53,6 @@ from libp2p.network.stream.exceptions import ( StreamEOF, StreamReset, ) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from libp2p.peer.id import ( ID, ) @@ -61,10 +64,6 @@ from libp2p.utils import ( read_varint_prefixed_bytes, ) -from .abc import ( - IPubsub, - ISubscriptionAPI, -) from .pb import ( rpc_pb2, ) @@ -74,11 +73,6 @@ from .pubsub_notifee import ( from .subscription import ( TrioSubscriptionAPI, ) -from .typing import ( - AsyncValidatorFn, - SyncValidatorFn, - ValidatorFn, -) from .validators import ( PUBSUB_SIGNING_PREFIX, signature_validator, diff --git a/libp2p/pubsub/pubsub_notifee.py b/libp2p/pubsub/pubsub_notifee.py index ae54d137..624aab6d 100644 --- a/libp2p/pubsub/pubsub_notifee.py +++ b/libp2p/pubsub/pubsub_notifee.py @@ -7,17 +7,11 @@ from multiaddr import ( ) import trio -from libp2p.network.connection.net_connection_interface import ( +from libp2p.abc import ( INetConn, -) -from libp2p.network.network_interface import ( - INetwork, -) -from libp2p.network.notifee_interface import ( - INotifee, -) -from libp2p.network.stream.net_stream_interface import ( INetStream, + INetwork, + INotifee, ) if TYPE_CHECKING: diff --git a/libp2p/pubsub/subscription.py b/libp2p/pubsub/subscription.py index bb915cb8..ab83d15f 100644 --- a/libp2p/pubsub/subscription.py +++ b/libp2p/pubsub/subscription.py @@ -11,15 +11,16 @@ from typing import ( import trio -from .abc import ( +from libp2p.abc import ( ISubscriptionAPI, ) +from libp2p.custom_types import ( + UnsubscribeFn, +) + from .pb import ( rpc_pb2, ) -from .typing import ( - UnsubscribeFn, -) class BaseSubscriptionAPI(ISubscriptionAPI): diff --git a/libp2p/pubsub/typing.py b/libp2p/pubsub/typing.py deleted file mode 100644 index 05964082..00000000 --- a/libp2p/pubsub/typing.py +++ /dev/null @@ -1,21 +0,0 @@ -from collections.abc import ( - Awaitable, -) -from typing import ( - Callable, - Union, -) - -from libp2p.peer.id import ( - ID, -) - -from .pb import ( - rpc_pb2, -) - -SyncValidatorFn = Callable[[ID, rpc_pb2.Message], bool] -AsyncValidatorFn = Callable[[ID, rpc_pb2.Message], Awaitable[bool]] -ValidatorFn = Union[SyncValidatorFn, AsyncValidatorFn] - -UnsubscribeFn = Callable[[], Awaitable[None]] diff --git a/libp2p/routing/__init__.py b/libp2p/routing/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/libp2p/routing/interfaces.py b/libp2p/routing/interfaces.py deleted file mode 100644 index 29f63af3..00000000 --- a/libp2p/routing/interfaces.py +++ /dev/null @@ -1,42 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) -from collections.abc import ( - Iterable, -) - -from libp2p.peer.id import ( - ID, -) -from libp2p.peer.peerinfo import ( - PeerInfo, -) - - -class IContentRouting(ABC): - @abstractmethod - def provide(self, cid: bytes, announce: bool = True) -> None: - """ - 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. - """ - - @abstractmethod - def find_provider_iter(self, cid: bytes, count: int) -> Iterable[PeerInfo]: - """ - Search for peers who are able to provide a given key returns an - iterator of peer.PeerInfo. - """ - - -class IPeerRouting(ABC): - @abstractmethod - async def find_peer(self, peer_id: ID) -> PeerInfo: - """ - Find specific Peer FindPeer searches for a peer with given peer_id, - returns a peer.PeerInfo with relevant addresses. - """ diff --git a/libp2p/security/base_session.py b/libp2p/security/base_session.py index 07ed74fc..fa99a62a 100644 --- a/libp2p/security/base_session.py +++ b/libp2p/security/base_session.py @@ -2,6 +2,9 @@ from typing import ( Optional, ) +from libp2p.abc import ( + ISecureConn, +) from libp2p.crypto.keys import ( PrivateKey, PublicKey, @@ -9,9 +12,6 @@ from libp2p.crypto.keys import ( from libp2p.peer.id import ( ID, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) class BaseSession(ISecureConn): diff --git a/libp2p/security/base_transport.py b/libp2p/security/base_transport.py index 5d055c2f..108ded01 100644 --- a/libp2p/security/base_transport.py +++ b/libp2p/security/base_transport.py @@ -3,15 +3,15 @@ from typing import ( Callable, ) +from libp2p.abc import ( + ISecureTransport, +) from libp2p.crypto.keys import ( KeyPair, ) from libp2p.peer.id import ( ID, ) -from libp2p.security.secure_transport_interface import ( - ISecureTransport, -) def default_secure_bytes_provider(n: int) -> bytes: diff --git a/libp2p/security/insecure/transport.py b/libp2p/security/insecure/transport.py index a60b3a61..8a0e3939 100644 --- a/libp2p/security/insecure/transport.py +++ b/libp2p/security/insecure/transport.py @@ -1,3 +1,7 @@ +from libp2p.abc import ( + IRawConnection, + ISecureConn, +) from libp2p.crypto.exceptions import ( MissingDeserializerError, ) @@ -23,9 +27,6 @@ from libp2p.io.msgio import ( from libp2p.network.connection.exceptions import ( RawConnError, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.peer.id import ( ID, ) @@ -38,9 +39,6 @@ from libp2p.security.base_transport import ( from libp2p.security.exceptions import ( HandshakeFailure, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) from .pb import ( plaintext_pb2, diff --git a/libp2p/security/noise/io.py b/libp2p/security/noise/io.py index 725c809b..c69b10a8 100644 --- a/libp2p/security/noise/io.py +++ b/libp2p/security/noise/io.py @@ -4,6 +4,9 @@ from typing import ( from noise.connection import NoiseConnection as NoiseState +from libp2p.abc import ( + IRawConnection, +) from libp2p.io.abc import ( EncryptedMsgReadWriter, MsgReadWriteCloser, @@ -12,9 +15,6 @@ from libp2p.io.abc import ( from libp2p.io.msgio import ( FixedSizeLenMsgReadWriter, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) SIZE_NOISE_MESSAGE_LEN = 2 MAX_NOISE_MESSAGE_LEN = 2 ** (8 * SIZE_NOISE_MESSAGE_LEN) - 1 diff --git a/libp2p/security/noise/patterns.py b/libp2p/security/noise/patterns.py index 0803060e..27b8d63b 100644 --- a/libp2p/security/noise/patterns.py +++ b/libp2p/security/noise/patterns.py @@ -10,6 +10,10 @@ from noise.backends.default.keypairs import KeyPair as NoiseKeyPair from noise.connection import Keypair as NoiseKeypairEnum from noise.connection import NoiseConnection as NoiseState +from libp2p.abc import ( + IRawConnection, + ISecureConn, +) from libp2p.crypto.ed25519 import ( Ed25519PublicKey, ) @@ -17,15 +21,9 @@ from libp2p.crypto.keys import ( PrivateKey, PublicKey, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.peer.id import ( ID, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) from libp2p.security.secure_session import ( SecureSession, ) diff --git a/libp2p/security/noise/transport.py b/libp2p/security/noise/transport.py index d335d438..e90dcc64 100644 --- a/libp2p/security/noise/transport.py +++ b/libp2p/security/noise/transport.py @@ -1,3 +1,8 @@ +from libp2p.abc import ( + IRawConnection, + ISecureConn, + ISecureTransport, +) from libp2p.crypto.keys import ( KeyPair, PrivateKey, @@ -5,18 +10,9 @@ from libp2p.crypto.keys import ( from libp2p.custom_types import ( TProtocol, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.peer.id import ( ID, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) -from libp2p.security.secure_transport_interface import ( - ISecureTransport, -) from .patterns import ( IPattern, diff --git a/libp2p/security/secio/transport.py b/libp2p/security/secio/transport.py index ac328698..343c9a1a 100644 --- a/libp2p/security/secio/transport.py +++ b/libp2p/security/secio/transport.py @@ -8,6 +8,10 @@ from typing import ( import multihash +from libp2p.abc import ( + IRawConnection, + ISecureConn, +) from libp2p.crypto.authenticated_encryption import ( EncryptionParameters as AuthenticatedEncryptionParameters, ) @@ -47,16 +51,10 @@ from libp2p.io.exceptions import ( from libp2p.io.msgio import ( FixedSizeLenMsgReadWriter, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.peer.id import ID as PeerID from libp2p.security.base_transport import ( BaseSecureTransport, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) from libp2p.security.secure_session import ( SecureSession, ) diff --git a/libp2p/security/secure_conn_interface.py b/libp2p/security/secure_conn_interface.py deleted file mode 100644 index 245b5f58..00000000 --- a/libp2p/security/secure_conn_interface.py +++ /dev/null @@ -1,44 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -from libp2p.crypto.keys import ( - PrivateKey, - PublicKey, -) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) -from libp2p.peer.id import ( - ID, -) - -""" -Represents a secured connection object, which includes a connection and details about -the security involved in the secured connection - -Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interface.go -""" - - -class AbstractSecureConn(ABC): - @abstractmethod - def get_local_peer(self) -> ID: - pass - - @abstractmethod - def get_local_private_key(self) -> PrivateKey: - pass - - @abstractmethod - def get_remote_peer(self) -> ID: - pass - - @abstractmethod - def get_remote_public_key(self) -> PublicKey: - pass - - -class ISecureConn(AbstractSecureConn, IRawConnection): - pass diff --git a/libp2p/security/secure_transport_interface.py b/libp2p/security/secure_transport_interface.py deleted file mode 100644 index 5fcf2732..00000000 --- a/libp2p/security/secure_transport_interface.py +++ /dev/null @@ -1,42 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) -from libp2p.peer.id import ( - ID, -) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) - -""" -Transport that is used to secure a connection. This transport is -chosen by a security transport multistream module. - -Relevant go repo: https://github.com/libp2p/go-conn-security/blob/master/interface.go -""" - - -class ISecureTransport(ABC): - @abstractmethod - async def secure_inbound(self, conn: IRawConnection) -> ISecureConn: - """ - Secure the connection, either locally or by communicating with opposing - node via conn, for an inbound connection (i.e. we are not the - initiator) - - :return: secure connection object (that implements secure_conn_interface) - """ - - @abstractmethod - async def secure_outbound(self, conn: IRawConnection, peer_id: ID) -> ISecureConn: - """ - Secure the connection, either locally or by communicating with opposing - node via conn, for an inbound connection (i.e. we are the initiator) - - :return: secure connection object (that implements secure_conn_interface) - """ diff --git a/libp2p/security/security_multistream.py b/libp2p/security/security_multistream.py index 3f708b99..193cc092 100644 --- a/libp2p/security/security_multistream.py +++ b/libp2p/security/security_multistream.py @@ -5,11 +5,14 @@ from collections import ( OrderedDict, ) +from libp2p.abc import ( + IRawConnection, + ISecureConn, + ISecureTransport, +) from libp2p.custom_types import ( TProtocol, -) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, + TSecurityOptions, ) from libp2p.peer.id import ( ID, @@ -23,15 +26,6 @@ from libp2p.protocol_muxer.multiselect_client import ( from libp2p.protocol_muxer.multiselect_communicator import ( MultiselectCommunicator, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) -from libp2p.security.secure_transport_interface import ( - ISecureTransport, -) -from libp2p.transport.typing import ( - TSecurityOptions, -) """ Represents a secured connection object, which includes a connection and details about diff --git a/libp2p/stream_muxer/abc.py b/libp2p/stream_muxer/abc.py deleted file mode 100644 index a054bef6..00000000 --- a/libp2p/stream_muxer/abc.py +++ /dev/null @@ -1,85 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -import trio - -from libp2p.io.abc import ( - ReadWriteCloser, -) -from libp2p.peer.id import ( - ID, -) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) - - -class IMuxedConn(ABC): - """ - reference: https://github.com/libp2p/go-stream-muxer/blob/master/muxer.go - """ - - peer_id: ID - event_started: trio.Event - - @abstractmethod - def __init__(self, conn: ISecureConn, peer_id: ID) -> None: - """ - Create a new muxed connection. - - :param conn: an instance of secured connection - for new muxed streams - :param peer_id: peer_id of peer the connection is to - """ - - @property - @abstractmethod - def is_initiator(self) -> bool: - """If this connection is the initiator.""" - - @abstractmethod - async def start(self) -> None: - """Start the multiplexer.""" - - @abstractmethod - async def close(self) -> None: - """Close connection.""" - - @property - @abstractmethod - def is_closed(self) -> bool: - """ - Check connection is fully closed. - - :return: true if successful - """ - - @abstractmethod - async def open_stream(self) -> "IMuxedStream": - """ - Create a new muxed_stream. - - :return: a new ``IMuxedStream`` stream - """ - - @abstractmethod - async def accept_stream(self) -> "IMuxedStream": - """Accept a muxed stream opened by the other end.""" - - -class IMuxedStream(ReadWriteCloser): - muxed_conn: IMuxedConn - - @abstractmethod - async def reset(self) -> None: - """Close both ends of the stream tells this remote side to hang up.""" - - @abstractmethod - def set_deadline(self, ttl: int) -> bool: - """ - Set deadline for muxed stream. - - :return: a new stream - """ diff --git a/libp2p/stream_muxer/mplex/mplex.py b/libp2p/stream_muxer/mplex/mplex.py index b63b0dc7..332a84ae 100644 --- a/libp2p/stream_muxer/mplex/mplex.py +++ b/libp2p/stream_muxer/mplex/mplex.py @@ -5,6 +5,11 @@ from typing import ( import trio +from libp2p.abc import ( + IMuxedConn, + IMuxedStream, + ISecureConn, +) from libp2p.custom_types import ( TProtocol, ) @@ -20,13 +25,6 @@ from libp2p.network.connection.exceptions import ( from libp2p.peer.id import ( ID, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) -from libp2p.stream_muxer.abc import ( - IMuxedConn, - IMuxedStream, -) from libp2p.utils import ( decode_uvarint_from_stream, encode_uvarint, diff --git a/libp2p/stream_muxer/mplex/mplex_stream.py b/libp2p/stream_muxer/mplex/mplex_stream.py index 6714604c..3026b824 100644 --- a/libp2p/stream_muxer/mplex/mplex_stream.py +++ b/libp2p/stream_muxer/mplex/mplex_stream.py @@ -4,7 +4,7 @@ from typing import ( import trio -from libp2p.stream_muxer.abc import ( +from libp2p.abc import ( IMuxedStream, ) from libp2p.stream_muxer.exceptions import ( diff --git a/libp2p/stream_muxer/muxer_multistream.py b/libp2p/stream_muxer/muxer_multistream.py index 13e7e301..a57f40ef 100644 --- a/libp2p/stream_muxer/muxer_multistream.py +++ b/libp2p/stream_muxer/muxer_multistream.py @@ -2,11 +2,15 @@ from collections import ( OrderedDict, ) -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.network.connection.raw_connection_interface import ( +from libp2p.abc import ( + IMuxedConn, IRawConnection, + ISecureConn, +) +from libp2p.custom_types import ( + TMuxerClass, + TMuxerOptions, + TProtocol, ) from libp2p.peer.id import ( ID, @@ -20,17 +24,6 @@ from libp2p.protocol_muxer.multiselect_client import ( from libp2p.protocol_muxer.multiselect_communicator import ( MultiselectCommunicator, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) -from libp2p.transport.typing import ( - TMuxerClass, - TMuxerOptions, -) - -from .abc import ( - IMuxedConn, -) # FIXME: add negotiate timeout to `MuxerMultistream` DEFAULT_NEGOTIATE_TIMEOUT = 60 diff --git a/libp2p/tools/factories.py b/libp2p/tools/factories.py index 795870a8..0558a062 100644 --- a/libp2p/tools/factories.py +++ b/libp2p/tools/factories.py @@ -22,6 +22,15 @@ from libp2p import ( generate_new_rsa_identity, generate_peer_id_from, ) +from libp2p.abc import ( + IHost, + INetStream, + IPeerRouting, + IPubsubRouter, + IRawConnection, + ISecureConn, + ISecureTransport, +) from libp2p.crypto.ed25519 import create_new_key_pair as create_ed25519_key_pair from libp2p.crypto.keys import ( KeyPair, @@ -29,14 +38,13 @@ from libp2p.crypto.keys import ( ) from libp2p.crypto.secp256k1 import create_new_key_pair as create_secp256k1_key_pair from libp2p.custom_types import ( + TMuxerOptions, TProtocol, + TSecurityOptions, ) from libp2p.host.basic_host import ( BasicHost, ) -from libp2p.host.host_interface import ( - IHost, -) from libp2p.host.routed_host import ( RoutedHost, ) @@ -46,15 +54,9 @@ from libp2p.io.abc import ( from libp2p.network.connection.raw_connection import ( RawConnection, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.network.connection.swarm_connection import ( SwarmConn, ) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from libp2p.network.swarm import ( Swarm, ) @@ -67,9 +69,6 @@ from libp2p.peer.peerinfo import ( from libp2p.peer.peerstore import ( PeerStore, ) -from libp2p.pubsub.abc import ( - IPubsubRouter, -) from libp2p.pubsub.floodsub import ( FloodSub, ) @@ -81,9 +80,6 @@ from libp2p.pubsub.pubsub import ( Pubsub, get_peer_and_seqno_msg_id, ) -from libp2p.routing.interfaces import ( - IPeerRouting, -) from libp2p.security.insecure.transport import ( PLAINTEXT_PROTOCOL_ID, InsecureTransport, @@ -95,12 +91,6 @@ from libp2p.security.noise.messages import ( from libp2p.security.noise.transport import PROTOCOL_ID as NOISE_PROTOCOL_ID from libp2p.security.noise.transport import Transport as NoiseTransport import libp2p.security.secio.transport as secio -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) -from libp2p.security.secure_transport_interface import ( - ISecureTransport, -) from libp2p.stream_muxer.mplex.mplex import ( MPLEX_PROTOCOL_ID, Mplex, @@ -117,10 +107,6 @@ from libp2p.tools.constants import ( from libp2p.transport.tcp.tcp import ( TCP, ) -from libp2p.transport.typing import ( - TMuxerOptions, - TSecurityOptions, -) from libp2p.transport.upgrader import ( TransportUpgrader, ) diff --git a/libp2p/tools/pubsub/dummy_account_node.py b/libp2p/tools/pubsub/dummy_account_node.py index 8c24e6ea..17dab92d 100644 --- a/libp2p/tools/pubsub/dummy_account_node.py +++ b/libp2p/tools/pubsub/dummy_account_node.py @@ -6,7 +6,7 @@ from contextlib import ( asynccontextmanager, ) -from libp2p.host.host_interface import ( +from libp2p.abc import ( IHost, ) from libp2p.pubsub.pubsub import ( diff --git a/libp2p/tools/pubsub/utils.py b/libp2p/tools/pubsub/utils.py index 6b1482d6..3437916a 100644 --- a/libp2p/tools/pubsub/utils.py +++ b/libp2p/tools/pubsub/utils.py @@ -2,7 +2,7 @@ from collections.abc import ( Sequence, ) -from libp2p.host.host_interface import ( +from libp2p.abc import ( IHost, ) from libp2p.peer.id import ( diff --git a/libp2p/tools/utils.py b/libp2p/tools/utils.py index ba9af8f9..da3f66c1 100644 --- a/libp2p/tools/utils.py +++ b/libp2p/tools/utils.py @@ -5,15 +5,13 @@ from typing import ( Callable, ) -from libp2p.host.host_interface import ( +from libp2p.abc import ( IHost, + INetStream, ) from libp2p.network.stream.exceptions import ( StreamError, ) -from libp2p.network.stream.net_stream_interface import ( - INetStream, -) from libp2p.network.swarm import ( Swarm, ) diff --git a/libp2p/transport/listener_interface.py b/libp2p/transport/listener_interface.py deleted file mode 100644 index 8ca75f8e..00000000 --- a/libp2p/transport/listener_interface.py +++ /dev/null @@ -1,32 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -from multiaddr import ( - Multiaddr, -) -import trio - - -class IListener(ABC): - @abstractmethod - async def listen(self, maddr: Multiaddr, nursery: trio.Nursery) -> bool: - """ - Put listener in listening mode and wait for incoming connections. - - :param maddr: multiaddr of peer - :return: return True if successful - """ - - @abstractmethod - def get_addrs(self) -> tuple[Multiaddr, ...]: - """ - Retrieve list of addresses the listener is listening on. - - :return: return list of addrs - """ - - @abstractmethod - async def close(self) -> None: - ... diff --git a/libp2p/transport/tcp/tcp.py b/libp2p/transport/tcp/tcp.py index aacaad55..dfa22425 100644 --- a/libp2p/transport/tcp/tcp.py +++ b/libp2p/transport/tcp/tcp.py @@ -15,27 +15,23 @@ from trio_typing import ( TaskStatus, ) +from libp2p.abc import ( + IListener, + IRawConnection, + ITransport, +) +from libp2p.custom_types import ( + THandler, +) from libp2p.io.trio import ( TrioTCPStream, ) from libp2p.network.connection.raw_connection import ( RawConnection, ) -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) from libp2p.transport.exceptions import ( OpenConnectionError, ) -from libp2p.transport.listener_interface import ( - IListener, -) -from libp2p.transport.transport_interface import ( - ITransport, -) -from libp2p.transport.typing import ( - THandler, -) logger = logging.getLogger("libp2p.transport.tcp") diff --git a/libp2p/transport/transport_interface.py b/libp2p/transport/transport_interface.py deleted file mode 100644 index 32feab4a..00000000 --- a/libp2p/transport/transport_interface.py +++ /dev/null @@ -1,41 +0,0 @@ -from abc import ( - ABC, - abstractmethod, -) - -from multiaddr import ( - Multiaddr, -) - -from libp2p.network.connection.raw_connection_interface import ( - IRawConnection, -) - -from .listener_interface import ( - IListener, -) -from .typing import ( - THandler, -) - - -class ITransport(ABC): - @abstractmethod - async def dial(self, maddr: Multiaddr) -> IRawConnection: - """ - Dial a transport to peer listening on multiaddr. - - :param multiaddr: multiaddr of peer - :param self_id: peer_id of the dialer (to send to receiver) - :return: list of multiaddrs - """ - - @abstractmethod - def create_listener(self, handler_function: THandler) -> IListener: - """ - Create listener on transport. - - :param handler_function: a function called when a new conntion is received - that takes a connection as argument which implements interface-connection - :return: a listener object that implements listener_interface.py - """ diff --git a/libp2p/transport/typing.py b/libp2p/transport/typing.py deleted file mode 100644 index 71d8c256..00000000 --- a/libp2p/transport/typing.py +++ /dev/null @@ -1,25 +0,0 @@ -from collections.abc import ( - Awaitable, - Mapping, -) -from typing import ( - Callable, -) - -from libp2p.custom_types import ( - TProtocol, -) -from libp2p.io.abc import ( - ReadWriteCloser, -) -from libp2p.security.secure_transport_interface import ( - ISecureTransport, -) -from libp2p.stream_muxer.abc import ( - IMuxedConn, -) - -THandler = Callable[[ReadWriteCloser], Awaitable[None]] -TSecurityOptions = Mapping[TProtocol, ISecureTransport] -TMuxerClass = type[IMuxedConn] -TMuxerOptions = Mapping[TProtocol, TMuxerClass] diff --git a/libp2p/transport/upgrader.py b/libp2p/transport/upgrader.py index 4203b718..f1c49af1 100644 --- a/libp2p/transport/upgrader.py +++ b/libp2p/transport/upgrader.py @@ -1,5 +1,13 @@ -from libp2p.network.connection.raw_connection_interface import ( +from libp2p.abc import ( + IListener, + IMuxedConn, IRawConnection, + ISecureConn, + ITransport, +) +from libp2p.custom_types import ( + TMuxerOptions, + TSecurityOptions, ) from libp2p.peer.id import ( ID, @@ -11,15 +19,9 @@ from libp2p.protocol_muxer.exceptions import ( from libp2p.security.exceptions import ( HandshakeFailure, ) -from libp2p.security.secure_conn_interface import ( - ISecureConn, -) from libp2p.security.security_multistream import ( SecurityMultistream, ) -from libp2p.stream_muxer.abc import ( - IMuxedConn, -) from libp2p.stream_muxer.muxer_multistream import ( MuxerMultistream, ) @@ -27,17 +29,6 @@ from libp2p.transport.exceptions import ( MuxerUpgradeFailure, SecurityUpgradeFailure, ) -from libp2p.transport.typing import ( - TMuxerOptions, - TSecurityOptions, -) - -from .listener_interface import ( - IListener, -) -from .transport_interface import ( - ITransport, -) class TransportUpgrader: diff --git a/newsfragments/228.internal.rst b/newsfragments/228.internal.rst new file mode 100644 index 00000000..6e9badb6 --- /dev/null +++ b/newsfragments/228.internal.rst @@ -0,0 +1 @@ +moved all interfaces to ``libp2p.abc`` along with all libp2p custom types to ``libp2p.custom_types``. diff --git a/tests/core/network/test_notify.py b/tests/core/network/test_notify.py index b9b7ed8e..f74f3aec 100644 --- a/tests/core/network/test_notify.py +++ b/tests/core/network/test_notify.py @@ -13,7 +13,7 @@ import enum import pytest import trio -from libp2p.network.notifee_interface import ( +from libp2p.abc import ( INotifee, ) from libp2p.tools.async_service import (