diff --git a/libp2p/abc.py b/libp2p/abc.py index 6d405040..ecd71528 100644 --- a/libp2p/abc.py +++ b/libp2p/abc.py @@ -1842,7 +1842,7 @@ class IPeerRecord(ABC): """ @abstractmethod - def to_protobuf(self) -> pb.PeerRecord: # type: ignore[name-defined, attr-defined] + def to_protobuf(self) -> pb.PeerRecord: """ Convert this PeerRecord into its Protobuf representation. diff --git a/libp2p/peer/envelope.py b/libp2p/peer/envelope.py index f058dbf7..189eea91 100644 --- a/libp2p/peer/envelope.py +++ b/libp2p/peer/envelope.py @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, cast from libp2p.crypto.ed25519 import Ed25519PublicKey from libp2p.crypto.keys import PrivateKey, PublicKey @@ -58,7 +58,7 @@ class Envelope: :return: Serialized envelope as bytes. """ - pb_env = pb.Envelope( # type: ignore[attr-defined] + pb_env = pb.Envelope( public_key=pub_key_to_protobuf(self.public_key), payload_type=self.payload_type, payload=self.raw_payload, @@ -97,7 +97,7 @@ class Envelope: try: if self.payload_type != PEER_RECORD_CODEC: raise ValueError("Unsuported payload type in envelope") - msg = record_pb.PeerRecord() # type: ignore[attr-defined] + msg = record_pb.PeerRecord() msg.ParseFromString(self.raw_payload) self._cached_record = peer_record_from_protobuf(msg) @@ -128,20 +128,21 @@ class Envelope: return False -def pub_key_to_protobuf(pub_key: PublicKey) -> cryto_pb.PublicKey: # type: ignore[name-defined] +def pub_key_to_protobuf(pub_key: PublicKey) -> cryto_pb.PublicKey: """ Convert a Python PublicKey object to its protobuf equivalent. :param pub_key: A libp2p-compatible PublicKey instance. :return: Serialized protobuf PublicKey message. """ - key_type = pub_key.get_type().value + internal_key_type = pub_key.get_type() + key_type = cast(cryto_pb.KeyType, internal_key_type.value) data = pub_key.to_bytes() - protobuf_key = cryto_pb.PublicKey(Type=key_type, Data=data) # type: ignore[attr-defined] + protobuf_key = cryto_pb.PublicKey(Type=key_type, Data=data) return protobuf_key -def pub_key_from_protobuf(pb_key: cryto_pb.PublicKey) -> PublicKey: # type: ignore[name-defined] +def pub_key_from_protobuf(pb_key: cryto_pb.PublicKey) -> PublicKey: """ Parse a protobuf PublicKey message into a native libp2p PublicKey. @@ -151,11 +152,11 @@ def pub_key_from_protobuf(pb_key: cryto_pb.PublicKey) -> PublicKey: # type: ign :return: Parsed PublicKey object. :raises ValueError: If the key type is unrecognized. """ - if pb_key.Type == cryto_pb.KeyType.Ed25519: # type: ignore[attr-defined] + if pb_key.Type == cryto_pb.KeyType.Ed25519: return Ed25519PublicKey.from_bytes(pb_key.Data) - elif pb_key.Type == cryto_pb.KeyType.RSA: # type: ignore[attr-defined] + elif pb_key.Type == cryto_pb.KeyType.RSA: return RSAPublicKey.from_bytes(pb_key.Data) - elif pb_key.Type == cryto_pb.KeyType.Secp256k1: # type: ignore[attr-defined] + elif pb_key.Type == cryto_pb.KeyType.Secp256k1: return Secp256k1PublicKey.from_bytes(pb_key.Data) # TODO: Add suport fot ECDSA parsing also else: @@ -214,7 +215,7 @@ def unmarshal_envelope(data: bytes) -> Envelope: :return: Parsed Envelope object. :raises DecodeError: If protobuf parsing fails. """ - pb_env = pb.Envelope() # type: ignore[attr-defined] + pb_env = pb.Envelope() pb_env.ParseFromString(data) pk = pub_key_from_protobuf(pb_env.public_key) diff --git a/libp2p/peer/pb/crypto_pb2.py b/libp2p/peer/pb/crypto_pb2.py index 66c81cea..d7cd0e76 100644 --- a/libp2p/peer/pb/crypto_pb2.py +++ b/libp2p/peer/pb/crypto_pb2.py @@ -14,7 +14,8 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1blibp2p/peer/pb/crypto.proto\x12\x15libp2p.peer.pb.crypto\"G\n\tPublicKey\x12,\n\x04Type\x18\x01 \x01(\x0e\x32\x1e.libp2p.peer.pb.crypto.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x01(\x0c\"H\n\nPrivateKey\x12,\n\x04Type\x18\x01 \x01(\x0e\x32\x1e.libp2p.peer.pb.crypto.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x01(\x0c*9\n\x07KeyType\x12\x07\n\x03RSA\x10\x00\x12\x0b\n\x07\x45\x64\x32\x35\x35\x31\x39\x10\x01\x12\r\n\tSecp256k1\x10\x02\x12\t\n\x05\x45\x43\x44SA\x10\x03\x42,Z*github.com/libp2p/go-libp2p/core/crypto/pbb\x06proto3') # type: ignore[no-untyped-call] +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1blibp2p/peer/pb/crypto.proto\x12\x15libp2p.peer.pb.crypto\"G\n\tPublicKey\x12,\n\x04Type\x18\x01 \x01(\x0e\x32\x1e.libp2p.peer.pb.crypto.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x01(\x0c\"H\n\nPrivateKey\x12,\n\x04Type\x18\x01 \x01(\x0e\x32\x1e.libp2p.peer.pb.crypto.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x01(\x0c*9\n\x07KeyType\x12\x07\n\x03RSA\x10\x00\x12\x0b\n\x07\x45\x64\x32\x35\x35\x31\x39\x10\x01\x12\r\n\tSecp256k1\x10\x02\x12\t\n\x05\x45\x43\x44SA\x10\x03\x42,Z*github.com/libp2p/go-libp2p/core/crypto/pbb\x06proto3') + _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'libp2p.peer.pb.crypto_pb2', _globals) diff --git a/libp2p/peer/pb/crypto_pb2.pyi b/libp2p/peer/pb/crypto_pb2.pyi new file mode 100644 index 00000000..f23c1b65 --- /dev/null +++ b/libp2p/peer/pb/crypto_pb2.pyi @@ -0,0 +1,33 @@ +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class KeyType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): + __slots__ = () + RSA: _ClassVar[KeyType] + Ed25519: _ClassVar[KeyType] + Secp256k1: _ClassVar[KeyType] + ECDSA: _ClassVar[KeyType] +RSA: KeyType +Ed25519: KeyType +Secp256k1: KeyType +ECDSA: KeyType + +class PublicKey(_message.Message): + __slots__ = ("Type", "Data") + TYPE_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + Type: KeyType + Data: bytes + def __init__(self, Type: _Optional[_Union[KeyType, str]] = ..., Data: _Optional[bytes] = ...) -> None: ... + +class PrivateKey(_message.Message): + __slots__ = ("Type", "Data") + TYPE_FIELD_NUMBER: _ClassVar[int] + DATA_FIELD_NUMBER: _ClassVar[int] + Type: KeyType + Data: bytes + def __init__(self, Type: _Optional[_Union[KeyType, str]] = ..., Data: _Optional[bytes] = ...) -> None: ... diff --git a/libp2p/peer/pb/envelope_pb2.py b/libp2p/peer/pb/envelope_pb2.py index c031a54b..f731cb25 100644 --- a/libp2p/peer/pb/envelope_pb2.py +++ b/libp2p/peer/pb/envelope_pb2.py @@ -15,7 +15,8 @@ _sym_db = _symbol_database.Default() from libp2p.peer.pb import crypto_pb2 as libp2p_dot_peer_dot_pb_dot_crypto__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dlibp2p/peer/pb/envelope.proto\x12\x15libp2p.peer.pb.record\x1a\x1blibp2p/peer/pb/crypto.proto\"z\n\x08\x45nvelope\x12\x34\n\npublic_key\x18\x01 \x01(\x0b\x32 .libp2p.peer.pb.crypto.PublicKey\x12\x14\n\x0cpayload_type\x18\x02 \x01(\x0c\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x12\x11\n\tsignature\x18\x05 \x01(\x0c\x42,Z*github.com/libp2p/go-libp2p/core/record/pbb\x06proto3') # type: ignore[no-untyped-call] +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dlibp2p/peer/pb/envelope.proto\x12\x15libp2p.peer.pb.record\x1a\x1blibp2p/peer/pb/crypto.proto\"z\n\x08\x45nvelope\x12\x34\n\npublic_key\x18\x01 \x01(\x0b\x32 .libp2p.peer.pb.crypto.PublicKey\x12\x14\n\x0cpayload_type\x18\x02 \x01(\x0c\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\x12\x11\n\tsignature\x18\x05 \x01(\x0c\x42,Z*github.com/libp2p/go-libp2p/core/record/pbb\x06proto3') + _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'libp2p.peer.pb.envelope_pb2', _globals) diff --git a/libp2p/peer/pb/envelope_pb2.pyi b/libp2p/peer/pb/envelope_pb2.pyi new file mode 100644 index 00000000..c6f383aa --- /dev/null +++ b/libp2p/peer/pb/envelope_pb2.pyi @@ -0,0 +1,18 @@ +from libp2p.peer.pb import crypto_pb2 as _crypto_pb2 +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class Envelope(_message.Message): + __slots__ = ("public_key", "payload_type", "payload", "signature") + PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int] + PAYLOAD_TYPE_FIELD_NUMBER: _ClassVar[int] + PAYLOAD_FIELD_NUMBER: _ClassVar[int] + SIGNATURE_FIELD_NUMBER: _ClassVar[int] + public_key: _crypto_pb2.PublicKey + payload_type: bytes + payload: bytes + signature: bytes + def __init__(self, public_key: _Optional[_Union[_crypto_pb2.PublicKey, _Mapping]] = ..., payload_type: _Optional[bytes] = ..., payload: _Optional[bytes] = ..., signature: _Optional[bytes] = ...) -> None: ... # type: ignore[type-arg] diff --git a/libp2p/peer/pb/peer_record_pb2.py b/libp2p/peer/pb/peer_record_pb2.py index 82b16747..9a7f3a6f 100644 --- a/libp2p/peer/pb/peer_record_pb2.py +++ b/libp2p/peer/pb/peer_record_pb2.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! -# source: peer_record.proto +# source: libp2p/peer/pb/peer_record.proto # Protobuf Python Version: 4.25.3 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor @@ -14,15 +14,16 @@ _sym_db = _symbol_database.Default() -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11peer_record.proto\x12\x07peer.pb\"\x80\x01\n\nPeerRecord\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0b\n\x03seq\x18\x02 \x01(\x04\x12\x32\n\taddresses\x18\x03 \x03(\x0b\x32\x1f.peer.pb.PeerRecord.AddressInfo\x1a \n\x0b\x41\x64\x64ressInfo\x12\x11\n\tmultiaddr\x18\x01 \x01(\x0c\x42*Z(github.com/libp2p/go-libp2p/core/peer/pbb\x06proto3') # type: ignore[no-untyped-call] +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n libp2p/peer/pb/peer_record.proto\x12\x07peer.pb\"\x80\x01\n\nPeerRecord\x12\x0f\n\x07peer_id\x18\x01 \x01(\x0c\x12\x0b\n\x03seq\x18\x02 \x01(\x04\x12\x32\n\taddresses\x18\x03 \x03(\x0b\x32\x1f.peer.pb.PeerRecord.AddressInfo\x1a \n\x0b\x41\x64\x64ressInfo\x12\x11\n\tmultiaddr\x18\x01 \x01(\x0c\x42*Z(github.com/libp2p/go-libp2p/core/peer/pbb\x06proto3') + _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'peer_record_pb2', _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'libp2p.peer.pb.peer_record_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'Z(github.com/libp2p/go-libp2p/core/peer/pb' - _globals['_PEERRECORD']._serialized_start=31 - _globals['_PEERRECORD']._serialized_end=159 - _globals['_PEERRECORD_ADDRESSINFO']._serialized_start=127 - _globals['_PEERRECORD_ADDRESSINFO']._serialized_end=159 + _globals['_PEERRECORD']._serialized_start=46 + _globals['_PEERRECORD']._serialized_end=174 + _globals['_PEERRECORD_ADDRESSINFO']._serialized_start=142 + _globals['_PEERRECORD_ADDRESSINFO']._serialized_end=174 # @@protoc_insertion_point(module_scope) diff --git a/libp2p/peer/pb/peer_record_pb2.pyi b/libp2p/peer/pb/peer_record_pb2.pyi new file mode 100644 index 00000000..97ee1657 --- /dev/null +++ b/libp2p/peer/pb/peer_record_pb2.pyi @@ -0,0 +1,21 @@ +from google.protobuf.internal import containers as _containers +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union + +DESCRIPTOR: _descriptor.FileDescriptor + +class PeerRecord(_message.Message): + __slots__ = ("peer_id", "seq", "addresses") + class AddressInfo(_message.Message): + __slots__ = ("multiaddr",) + MULTIADDR_FIELD_NUMBER: _ClassVar[int] + multiaddr: bytes + def __init__(self, multiaddr: _Optional[bytes] = ...) -> None: ... + PEER_ID_FIELD_NUMBER: _ClassVar[int] + SEQ_FIELD_NUMBER: _ClassVar[int] + ADDRESSES_FIELD_NUMBER: _ClassVar[int] + peer_id: bytes + seq: int + addresses: _containers.RepeatedCompositeFieldContainer[PeerRecord.AddressInfo] + def __init__(self, peer_id: _Optional[bytes] = ..., seq: _Optional[int] = ..., addresses: _Optional[_Iterable[_Union[PeerRecord.AddressInfo, _Mapping]]] = ...) -> None: ... # type: ignore[type-arg] diff --git a/libp2p/peer/peer_record.py b/libp2p/peer/peer_record.py index e0ff1d11..15eda1bb 100644 --- a/libp2p/peer/peer_record.py +++ b/libp2p/peer/peer_record.py @@ -1,3 +1,4 @@ +from collections.abc import Sequence import threading import time from typing import Any @@ -73,7 +74,7 @@ class PeerRecord(IPeerRecord): """ return PEER_RECORD_ENVELOPE_PAYLOAD_TYPE - def to_protobuf(self) -> pb.PeerRecord: # type: ignore[attr-defined, name-defined] + def to_protobuf(self) -> pb.PeerRecord: """ Convert the current PeerRecord into a ProtoBuf PeerRecord message. @@ -85,7 +86,7 @@ class PeerRecord(IPeerRecord): except Exception as e: raise ValueError(f"failed to marshal peer_id: {e}") - msg = pb.PeerRecord() # type: ignore[attr-defined] + msg = pb.PeerRecord() msg.peer_id = id_bytes msg.seq = self.seq msg.addresses.extend(addrs_to_protobuf(self.addrs)) @@ -143,7 +144,7 @@ def unmarshal_record(data: bytes) -> PeerRecord: if data is None: raise ValueError("cannot unmarshal PeerRecord from None") - msg = pb.PeerRecord() # type: ignore[attr-defined] + msg = pb.PeerRecord() try: msg.ParseFromString(data) except Exception as e: @@ -190,7 +191,7 @@ def peer_record_from_peer_info(info: PeerInfo) -> PeerRecord: return record -def peer_record_from_protobuf(msg: pb.PeerRecord) -> PeerRecord: # type: ignore[attr-defined, name-defined] +def peer_record_from_protobuf(msg: pb.PeerRecord) -> PeerRecord: """ Convert a protobuf PeerRecord message into a PeerRecord object. @@ -209,7 +210,7 @@ def peer_record_from_protobuf(msg: pb.PeerRecord) -> PeerRecord: # type: ignore return PeerRecord(peer_id, addrs, seq) -def addrs_from_protobuf(addrs: list[pb.PeerRecord.AddressInfo]) -> list[Multiaddr]: # type: ignore[attr-defined, name-defined] +def addrs_from_protobuf(addrs: Sequence[pb.PeerRecord.AddressInfo]) -> list[Multiaddr]: """ Convert a list of protobuf address records to Multiaddr objects. @@ -226,7 +227,7 @@ def addrs_from_protobuf(addrs: list[pb.PeerRecord.AddressInfo]) -> list[Multiadd return out -def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo]: # type: ignore[attr-defined, name-defined] +def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo]: """ Convert a list of Multiaddr objects into their protobuf representation. @@ -235,7 +236,7 @@ def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo] """ out = [] for addr in addrs: - addr_info = pb.PeerRecord.AddressInfo() # type: ignore[attr-defined] + addr_info = pb.PeerRecord.AddressInfo() addr_info.multiaddr = addr.to_bytes() out.append(addr_info) return out diff --git a/tests/core/peer/test_envelope.py b/tests/core/peer/test_envelope.py index 52afc9ea..74d46077 100644 --- a/tests/core/peer/test_envelope.py +++ b/tests/core/peer/test_envelope.py @@ -19,11 +19,11 @@ DOMAIN = "libp2p-peer-record" def test_basic_protobuf_serialization_deserialization(): - pubkey = crypto_pb.PublicKey() # type: ignore[attr-defined] - pubkey.Type = crypto_pb.KeyType.Ed25519 # type: ignore[attr-defined] + pubkey = crypto_pb.PublicKey() + pubkey.Type = crypto_pb.KeyType.Ed25519 pubkey.Data = b"\x01\x02\x03" - env = env_pb.Envelope() # type: ignore[attr-defined] + env = env_pb.Envelope() env.public_key.CopyFrom(pubkey) env.payload_type = b"\x03\x01" env.payload = b"test-payload" @@ -31,10 +31,10 @@ def test_basic_protobuf_serialization_deserialization(): serialized = env.SerializeToString() - new_env = env_pb.Envelope() # type: ignore[attr-defined] + new_env = env_pb.Envelope() new_env.ParseFromString(serialized) - assert new_env.public_key.Type == crypto_pb.KeyType.Ed25519 # type: ignore[attr-defined] + assert new_env.public_key.Type == crypto_pb.KeyType.Ed25519 assert new_env.public_key.Data == b"\x01\x02\x03" assert new_env.payload_type == b"\x03\x01" assert new_env.payload == b"test-payload" diff --git a/tests/core/peer/test_peer_record.py b/tests/core/peer/test_peer_record.py index 12e94e5b..2e4a6029 100644 --- a/tests/core/peer/test_peer_record.py +++ b/tests/core/peer/test_peer_record.py @@ -15,11 +15,11 @@ from libp2p.peer.peer_record import ( def test_basic_protobuf_serializatrion_deserialization(): - record = pb.PeerRecord() # type: ignore[attr-defined] + record = pb.PeerRecord() record.seq = 1 serialized = record.SerializeToString() - new_record = pb.PeerRecord() # type: ignore[attr-defined] + new_record = pb.PeerRecord() new_record.ParseFromString(serialized) assert new_record.seq == 1 @@ -39,10 +39,10 @@ def test_addrs_from_protobuf_multiple_addresses(): ma1 = Multiaddr("/ip4/127.0.0.1/tcp/4001") ma2 = Multiaddr("/ip4/127.0.0.1/tcp/4002") - addr_info1 = pb.PeerRecord.AddressInfo() # type: ignore[attr-defined] + addr_info1 = pb.PeerRecord.AddressInfo() addr_info1.multiaddr = ma1.to_bytes() - addr_info2 = pb.PeerRecord.AddressInfo() # type: ignore[attr-defined] + addr_info2 = pb.PeerRecord.AddressInfo() addr_info2.multiaddr = ma2.to_bytes() result = addrs_from_protobuf([addr_info1, addr_info2]) @@ -51,13 +51,13 @@ def test_addrs_from_protobuf_multiple_addresses(): def test_peer_record_from_protobuf(): peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px") - record = pb.PeerRecord() # type: ignore[attr-defined] + record = pb.PeerRecord() record.peer_id = peer_id.to_bytes() record.seq = 42 for addr_str in ["/ip4/127.0.0.1/tcp/4001", "/ip4/127.0.0.1/tcp/4002"]: ma = Multiaddr(addr_str) - addr_info = pb.PeerRecord.AddressInfo() # type: ignore[attr-defined] + addr_info = pb.PeerRecord.AddressInfo() addr_info.multiaddr = ma.to_bytes() record.addresses.append(addr_info) @@ -78,7 +78,7 @@ def test_to_protobuf_generates_correct_message(): record = PeerRecord(peer_id, addrs, seq) proto = record.to_protobuf() - assert isinstance(proto, pb.PeerRecord) # type: ignore[attr-defined] + assert isinstance(proto, pb.PeerRecord) assert proto.peer_id == peer_id.to_bytes() assert proto.seq == seq assert len(proto.addresses) == 1