From 08b57fa2ee24adc3af0b6678afe5b3eb523bb8a9 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Fri, 25 Oct 2019 18:51:24 +0900 Subject: [PATCH] Add core handler for `identify` protocol --- libp2p/identity/__init__.py | 0 libp2p/identity/identify/__init__.py | 0 libp2p/identity/identify/pb/__init__.py | 0 libp2p/identity/identify/pb/identify.proto | 12 +++ libp2p/identity/identify/pb/identify_pb2.py | 105 +++++++++++++++++++ libp2p/identity/identify/pb/identify_pb2.pyi | 53 ++++++++++ libp2p/identity/identify/protocol.py | 46 ++++++++ 7 files changed, 216 insertions(+) create mode 100644 libp2p/identity/__init__.py create mode 100644 libp2p/identity/identify/__init__.py create mode 100644 libp2p/identity/identify/pb/__init__.py create mode 100644 libp2p/identity/identify/pb/identify.proto create mode 100644 libp2p/identity/identify/pb/identify_pb2.py create mode 100644 libp2p/identity/identify/pb/identify_pb2.pyi create mode 100644 libp2p/identity/identify/protocol.py diff --git a/libp2p/identity/__init__.py b/libp2p/identity/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libp2p/identity/identify/__init__.py b/libp2p/identity/identify/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libp2p/identity/identify/pb/__init__.py b/libp2p/identity/identify/pb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/libp2p/identity/identify/pb/identify.proto b/libp2p/identity/identify/pb/identify.proto new file mode 100644 index 0000000..c9390bb --- /dev/null +++ b/libp2p/identity/identify/pb/identify.proto @@ -0,0 +1,12 @@ +syntax = "proto2"; + +package identify.pb; + +message Identify { + optional string protocol_version = 5; + optional string agent_version = 6; + optional bytes public_key = 1; + repeated bytes listen_addrs = 2; + optional bytes observed_addr = 4; + repeated string protocols = 3; +} \ No newline at end of file diff --git a/libp2p/identity/identify/pb/identify_pb2.py b/libp2p/identity/identify/pb/identify_pb2.py new file mode 100644 index 0000000..a843465 --- /dev/null +++ b/libp2p/identity/identify/pb/identify_pb2.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: libp2p/identity/identify/pb/identify.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='libp2p/identity/identify/pb/identify.proto', + package='identify.pb', + syntax='proto2', + serialized_options=None, + serialized_pb=_b('\n*libp2p/identity/identify/pb/identify.proto\x12\x0bidentify.pb\"\x8f\x01\n\x08Identify\x12\x18\n\x10protocol_version\x18\x05 \x01(\t\x12\x15\n\ragent_version\x18\x06 \x01(\t\x12\x12\n\npublic_key\x18\x01 \x01(\x0c\x12\x14\n\x0clisten_addrs\x18\x02 \x03(\x0c\x12\x15\n\robserved_addr\x18\x04 \x01(\x0c\x12\x11\n\tprotocols\x18\x03 \x03(\t') +) + + + + +_IDENTIFY = _descriptor.Descriptor( + name='Identify', + full_name='identify.pb.Identify', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='protocol_version', full_name='identify.pb.Identify.protocol_version', index=0, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='agent_version', full_name='identify.pb.Identify.agent_version', index=1, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='public_key', full_name='identify.pb.Identify.public_key', index=2, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='listen_addrs', full_name='identify.pb.Identify.listen_addrs', index=3, + number=2, type=12, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='observed_addr', full_name='identify.pb.Identify.observed_addr', index=4, + number=4, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + _descriptor.FieldDescriptor( + name='protocols', full_name='identify.pb.Identify.protocols', index=5, + number=3, type=9, cpp_type=9, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + serialized_options=None, + is_extendable=False, + syntax='proto2', + extension_ranges=[], + oneofs=[ + ], + serialized_start=60, + serialized_end=203, +) + +DESCRIPTOR.message_types_by_name['Identify'] = _IDENTIFY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +Identify = _reflection.GeneratedProtocolMessageType('Identify', (_message.Message,), { + 'DESCRIPTOR' : _IDENTIFY, + '__module__' : 'libp2p.identity.identify.pb.identify_pb2' + # @@protoc_insertion_point(class_scope:identify.pb.Identify) + }) +_sym_db.RegisterMessage(Identify) + + +# @@protoc_insertion_point(module_scope) diff --git a/libp2p/identity/identify/pb/identify_pb2.pyi b/libp2p/identity/identify/pb/identify_pb2.pyi new file mode 100644 index 0000000..9ad7350 --- /dev/null +++ b/libp2p/identity/identify/pb/identify_pb2.pyi @@ -0,0 +1,53 @@ +# @generated by generate_proto_mypy_stubs.py. Do not edit! +import sys +from google.protobuf.descriptor import ( + Descriptor as google___protobuf___descriptor___Descriptor, +) + +from google.protobuf.internal.containers import ( + RepeatedScalarFieldContainer as google___protobuf___internal___containers___RepeatedScalarFieldContainer, +) + +from google.protobuf.message import ( + Message as google___protobuf___message___Message, +) + +from typing import ( + Iterable as typing___Iterable, + Optional as typing___Optional, + Text as typing___Text, +) + +from typing_extensions import ( + Literal as typing_extensions___Literal, +) + + +class Identify(google___protobuf___message___Message): + DESCRIPTOR: google___protobuf___descriptor___Descriptor = ... + protocol_version = ... # type: typing___Text + agent_version = ... # type: typing___Text + public_key = ... # type: bytes + listen_addrs = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[bytes] + observed_addr = ... # type: bytes + protocols = ... # type: google___protobuf___internal___containers___RepeatedScalarFieldContainer[typing___Text] + + def __init__(self, + *, + protocol_version : typing___Optional[typing___Text] = None, + agent_version : typing___Optional[typing___Text] = None, + public_key : typing___Optional[bytes] = None, + listen_addrs : typing___Optional[typing___Iterable[bytes]] = None, + observed_addr : typing___Optional[bytes] = None, + protocols : typing___Optional[typing___Iterable[typing___Text]] = None, + ) -> None: ... + @classmethod + def FromString(cls, s: bytes) -> Identify: ... + def MergeFrom(self, other_msg: google___protobuf___message___Message) -> None: ... + def CopyFrom(self, other_msg: google___protobuf___message___Message) -> None: ... + if sys.version_info >= (3,): + def HasField(self, field_name: typing_extensions___Literal[u"agent_version",u"observed_addr",u"protocol_version",u"public_key"]) -> bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"agent_version",u"listen_addrs",u"observed_addr",u"protocol_version",u"protocols",u"public_key"]) -> None: ... + else: + def HasField(self, field_name: typing_extensions___Literal[u"agent_version",b"agent_version",u"observed_addr",b"observed_addr",u"protocol_version",b"protocol_version",u"public_key",b"public_key"]) -> bool: ... + def ClearField(self, field_name: typing_extensions___Literal[u"agent_version",b"agent_version",u"listen_addrs",b"listen_addrs",u"observed_addr",b"observed_addr",u"protocol_version",b"protocol_version",u"protocols",b"protocols",u"public_key",b"public_key"]) -> None: ... diff --git a/libp2p/identity/identify/protocol.py b/libp2p/identity/identify/protocol.py new file mode 100644 index 0000000..a71d624 --- /dev/null +++ b/libp2p/identity/identify/protocol.py @@ -0,0 +1,46 @@ +import logging +from typing import Sequence + +from multiaddr import Multiaddr + +from libp2p.crypto.keys import PublicKey +from libp2p.network.stream.net_stream_interface import INetStream +from libp2p.typing import StreamHandlerFn, TProtocol + +from .pb.identify_pb2 import Identify + +ID = "/ipfs/id/1.0.0" +PROTOCOL_VERSION = "ipfs/0.1.0" +# TODO dynamically generate the agent version +AGENT_VERSION = "py-libp2p/alpha" +logger = logging.getLogger("libp2p.identity.identify") + + +def _multiaddr_to_bytes(maddr: Multiaddr) -> bytes: + return maddr.to_bytes() + + +def identify_handler_for( + public_key: PublicKey, laddrs: Sequence[Multiaddr], protocols: Sequence[TProtocol] +) -> StreamHandlerFn: + async def handle_identify(stream: INetStream) -> None: + logger.debug("received a request for % from %", ID, stream.mplex_conn.peer_id) + + protobuf = Identify( + protocol_version=PROTOCOL_VERSION, + agent_version=AGENT_VERSION, + public_key=public_key.serialize(), + listen_addrs=map(_multiaddr_to_bytes, laddrs), + # TODO send observed address from ``stream`` + observed_addr=b"", + protocols=protocols, + ) + response = protobuf.SerializeToString() + + await stream.write(response) + await stream.close() + logger.debug( + "succesfully handled request for % from %", ID, stream.mplex_conn.peer_id + ) + + return handle_identify