linter respacing

This commit is contained in:
lla-dane
2025-07-09 12:33:27 +05:30
parent aa6039bcd3
commit ecc443dcfe
2 changed files with 91 additions and 78 deletions

View File

@ -1,52 +1,53 @@
import time
import threading import threading
from typing import Optional import time
from multiaddr import Multiaddr
from libp2p.abc import IPeerRecord from libp2p.abc import IPeerRecord
import libp2p.peer.pb.peer_record_pb2 as pb
from multiaddr import Multiaddr
from libp2p.peer.peerinfo import PeerInfo
from libp2p.peer.id import ID from libp2p.peer.id import ID
import libp2p.peer.pb.peer_record_pb2 as pb
from libp2p.peer.peerinfo import PeerInfo
PEER_RECORD_ENVELOPE_DOMAIN = "libp2p-peer-record" PEER_RECORD_ENVELOPE_DOMAIN = "libp2p-peer-record"
PEER_RECORD_ENVELOPE_PAYLOAD_TYPE = b'\x03\x01' PEER_RECORD_ENVELOPE_PAYLOAD_TYPE = b"\x03\x01"
_last_timestamp_lock = threading.Lock() _last_timestamp_lock = threading.Lock()
_last_timestamp: int = 0 _last_timestamp: int = 0
class PeerRecord(IPeerRecord): class PeerRecord(IPeerRecord):
""" """
A record that contains metatdata about a peer in the libp2p network. A record that contains metatdata about a peer in the libp2p network.
This includes: This includes:
- `peer_id`: The peer's globally unique indentifier. - `peer_id`: The peer's globally unique indentifier.
- `addrs`: A list of the peer's publicly reachable multiaddrs. - `addrs`: A list of the peer's publicly reachable multiaddrs.
- `seq`: A strictly monotonically increasing timestamp used - `seq`: A strictly monotonically increasing timestamp used
to order records over time. to order records over time.
PeerRecords are designed to be signed and transmitted in libp2p routing Envelopes. PeerRecords are designed to be signed and transmitted in libp2p routing Envelopes.
""" """
peer_id: ID peer_id: ID
addrs: list[Multiaddr] addrs: list[Multiaddr]
seq: int seq: int
def __init__( def __init__(
self, self,
peer_id: Optional[ID] = None, peer_id: ID | None = None,
addrs: Optional[list[Multiaddr]] = None, addrs: list[Multiaddr] | None = None,
seq: Optional[int] = None, seq: int | None = None,
) -> None: ) -> None:
""" """
Initialize a new PeerRecord. Initialize a new PeerRecord.
If `seq` is not provided, a timestamp-based strictly increasing sequence If `seq` is not provided, a timestamp-based strictly increasing sequence
number will be generated. number will be generated.
:param peer_id: ID of the peer this record refers to. :param peer_id: ID of the peer this record refers to.
:param addrs: Public multiaddrs of the peer. :param addrs: Public multiaddrs of the peer.
:param seq: Monotonic sequence number. :param seq: Monotonic sequence number.
""" """
if peer_id is not None: if peer_id is not None:
self.peer_id = peer_id self.peer_id = peer_id
self.addrs = addrs or [] self.addrs = addrs or []
@ -54,27 +55,27 @@ class PeerRecord(IPeerRecord):
self.seq = seq self.seq = seq
else: else:
self.seq = timestamp_seq() self.seq = timestamp_seq()
def domain(self) -> str: def domain(self) -> str:
""" """
Return the domain string associated with this PeerRecord. Return the domain string associated with this PeerRecord.
Used during record signing and envelope validation to identify the record type. Used during record signing and envelope validation to identify the record type.
""" """
return PEER_RECORD_ENVELOPE_DOMAIN return PEER_RECORD_ENVELOPE_DOMAIN
def codec(self) -> bytes: def codec(self) -> bytes:
""" """
Return the codec identifier for PeerRecords. Return the codec identifier for PeerRecords.
This binary perfix helps distinguish PeerRecords in serialized envelopes. This binary perfix helps distinguish PeerRecords in serialized envelopes.
""" """
return PEER_RECORD_ENVELOPE_PAYLOAD_TYPE return PEER_RECORD_ENVELOPE_PAYLOAD_TYPE
def to_protobuf(self) -> pb.PeerRecord: def to_protobuf(self) -> pb.PeerRecord:
""" """
Convert the current PeerRecord into a ProtoBuf PeerRecord message. Convert the current PeerRecord into a ProtoBuf PeerRecord message.
:raises ValueError: if peer_id serialization fails. :raises ValueError: if peer_id serialization fails.
:return: A ProtoBuf-encoded PeerRecord message object. :return: A ProtoBuf-encoded PeerRecord message object.
""" """
@ -82,36 +83,36 @@ class PeerRecord(IPeerRecord):
id_bytes = self.peer_id.to_bytes() id_bytes = self.peer_id.to_bytes()
except Exception as e: except Exception as e:
raise ValueError(f"failed to marshal peer_id: {e}") raise ValueError(f"failed to marshal peer_id: {e}")
msg = pb.PeerRecord() msg = pb.PeerRecord()
msg.peer_id = id_bytes msg.peer_id = id_bytes
msg.seq = self.seq msg.seq = self.seq
msg.addresses.extend(addrs_to_protobuf(self.addrs)) msg.addresses.extend(addrs_to_protobuf(self.addrs))
return msg return msg
def marshal_record(self) -> bytes: def marshal_record(self) -> bytes:
""" """
Serialize a PeerRecord into raw bytes suitable for embedding in an Envelope. Serialize a PeerRecord into raw bytes suitable for embedding in an Envelope.
This is typically called during the process of signing or sealing the record. This is typically called during the process of signing or sealing the record.
:raises ValueError: if serialization to protobuf fails. :raises ValueError: if serialization to protobuf fails.
:return: Serialized PeerRecord bytes. :return: Serialized PeerRecord bytes.
""" """
try: try:
msg = self.to_protobuf() msg = self.to_protobuf()
return msg.SerializeToString() return msg.SerializeToString()
except Exception as e: except Exception as e:
raise ValueError(f"failed to marshal PeerRecord: {e}") raise ValueError(f"failed to marshal PeerRecord: {e}")
def equal(self, other) -> bool: def equal(self, other) -> bool:
""" """
Check if this PeerRecord is identical to another. Check if this PeerRecord is identical to another.
Two PeerRecords are considered equal if: Two PeerRecords are considered equal if:
- Their peer IDs match. - Their peer IDs match.
- Their sequence numbers are identical. - Their sequence numbers are identical.
- Their address lists are identical and in the same order. - Their address lists are identical and in the same order.
:param other: Another PeerRecord instance. :param other: Another PeerRecord instance.
:return: True if all fields mathch, False otherwise. :return: True if all fields mathch, False otherwise.
""" """
@ -122,45 +123,47 @@ class PeerRecord(IPeerRecord):
for a1, a2 in zip(self.addrs, other.addrs): for a1, a2 in zip(self.addrs, other.addrs):
if a1 == a2: if a1 == a2:
continue continue
else: else:
return False return False
return True return True
return False return False
def unmarshal_record(data: bytes) -> PeerRecord: def unmarshal_record(data: bytes) -> PeerRecord:
""" """
Deserialize a PeerRecord from its serialized byte representation. Deserialize a PeerRecord from its serialized byte representation.
Typically used when receiveing a PeerRecord inside a signed routing Envelope. Typically used when receiveing a PeerRecord inside a signed routing Envelope.
:param data: Serialized protobuf-encoded bytes. :param data: Serialized protobuf-encoded bytes.
:raises ValueError: if parsing or conversion fails. :raises ValueError: if parsing or conversion fails.
:reurn: A valid PeerRecord instance. :reurn: A valid PeerRecord instance.
""" """
if data is None: if data is None:
raise ValueError("cannot unmarshal PeerRecord from None") raise ValueError("cannot unmarshal PeerRecord from None")
msg = pb.PeerRecord() msg = pb.PeerRecord()
try: try:
msg.ParseFromString(data) msg.ParseFromString(data)
except Exception as e: except Exception as e:
raise ValueError(f"Failed to parse PeerRecord protobuf: {e}") raise ValueError(f"Failed to parse PeerRecord protobuf: {e}")
try: try:
record = peer_record_from_protobuf(msg) record = peer_record_from_protobuf(msg)
except Exception as e: except Exception as e:
raise ValueError(f"Failed to convert protobuf to PeerRecord: {e}") raise ValueError(f"Failed to convert protobuf to PeerRecord: {e}")
return record return record
def timestamp_seq() -> int: def timestamp_seq() -> int:
""" """
Generate a strictly increasing timestamp-based sequence number. Generate a strictly increasing timestamp-based sequence number.
Ensures that even if multiple PeerRecords are generated in the same nanosecond, Ensures that even if multiple PeerRecords are generated in the same nanosecond,
their `seq` values will still be strictly increasing by using a lock to track the their `seq` values will still be strictly increasing by using a lock to track the
last value. last value.
:return: A strictly increasing integer timestamp. :return: A strictly increasing integer timestamp.
""" """
global _last_timestamp global _last_timestamp
@ -171,11 +174,11 @@ def timestamp_seq() -> int:
_last_timestamp = now _last_timestamp = now
return now return now
def peer_record_from_peer_info(info: PeerInfo) -> PeerRecord: def peer_record_from_peer_info(info: PeerInfo) -> PeerRecord:
""" """
Create a PeerRecord from a PeerInfo object. Create a PeerRecord from a PeerInfo object.
This automatically assigns a timestamp-based sequence number to the record. This automatically assigns a timestamp-based sequence number to the record.
:param info: A PeerInfo instance (contains peer_id and addrs). :param info: A PeerInfo instance (contains peer_id and addrs).
:return: A PeerRecord instance. :return: A PeerRecord instance.
@ -185,6 +188,7 @@ def peer_record_from_peer_info(info: PeerInfo) -> PeerRecord:
record.addrs = info.addrs record.addrs = info.addrs
return record return record
def peer_record_from_protobuf(msg: pb.PeerRecord) -> PeerRecord: def peer_record_from_protobuf(msg: pb.PeerRecord) -> PeerRecord:
""" """
Convert a protobuf PeerRecord message into a PeerRecord object. Convert a protobuf PeerRecord message into a PeerRecord object.
@ -220,6 +224,7 @@ def addrs_from_protobuf(addrs: list[pb.PeerRecord.AddressInfo]) -> list[Multiadd
continue continue
return out return out
def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo]: def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo]:
""" """
Convert a list of Multiaddr objects into their protobuf representation. Convert a list of Multiaddr objects into their protobuf representation.
@ -230,6 +235,6 @@ def addrs_to_protobuf(addrs: list[Multiaddr]) -> list[pb.PeerRecord.AddressInfo]
out = [] out = []
for addr in addrs: for addr in addrs:
addr_info = pb.PeerRecord.AddressInfo() addr_info = pb.PeerRecord.AddressInfo()
addr_info.multiaddr = addr.to_bytes() addr_info.multiaddr = addr.to_bytes()
out.append(addr_info) out.append(addr_info)
return out return out

View File

@ -1,8 +1,9 @@
import time import time
from libp2p.peer.id import ID
import libp2p.peer.pb.peer_record_pb2 as pb
from multiaddr import Multiaddr from multiaddr import Multiaddr
from libp2p.peer.id import ID
import libp2p.peer.pb.peer_record_pb2 as pb
from libp2p.peer.peer_record import ( from libp2p.peer.peer_record import (
PeerRecord, PeerRecord,
addrs_from_protobuf, addrs_from_protobuf,
@ -12,93 +13,100 @@ from libp2p.peer.peer_record import (
# Testing methods from PeerRecord base class and PeerRecord protobuf: # Testing methods from PeerRecord base class and PeerRecord protobuf:
def test_basic_protobuf_serializatrion_deserialization(): def test_basic_protobuf_serializatrion_deserialization():
record = pb.PeerRecord() record = pb.PeerRecord()
record.seq = 1 record.seq = 1
serialized = record.SerializeToString() serialized = record.SerializeToString()
new_record = pb.PeerRecord() new_record = pb.PeerRecord()
new_record.ParseFromString(serialized) new_record.ParseFromString(serialized)
assert new_record.seq == 1 assert new_record.seq == 1
def test_timestamp_seq_monotonicity(): def test_timestamp_seq_monotonicity():
rec1 = PeerRecord() rec1 = PeerRecord()
time.sleep(1) time.sleep(1)
rec2 = PeerRecord() rec2 = PeerRecord()
assert isinstance(rec1.seq, int) assert isinstance(rec1.seq, int)
assert isinstance(rec2.seq, int) assert isinstance(rec2.seq, int)
assert rec2.seq > rec1.seq, f"Expected seq2 ({rec2.seq}) > seq1 ({rec1.seq})" assert rec2.seq > rec1.seq, f"Expected seq2 ({rec2.seq}) > seq1 ({rec1.seq})"
def test_addrs_from_protobuf_multiple_addresses(): def test_addrs_from_protobuf_multiple_addresses():
ma1 = Multiaddr("/ip4/127.0.0.1/tcp/4001") ma1 = Multiaddr("/ip4/127.0.0.1/tcp/4001")
ma2 = Multiaddr("/ip4/127.0.0.1/tcp/4002") ma2 = Multiaddr("/ip4/127.0.0.1/tcp/4002")
addr_info1 = pb.PeerRecord.AddressInfo() addr_info1 = pb.PeerRecord.AddressInfo()
addr_info1.multiaddr = ma1.to_bytes() addr_info1.multiaddr = ma1.to_bytes()
addr_info2 = pb.PeerRecord.AddressInfo() addr_info2 = pb.PeerRecord.AddressInfo()
addr_info2.multiaddr = ma2.to_bytes() addr_info2.multiaddr = ma2.to_bytes()
result = addrs_from_protobuf([addr_info1, addr_info2]) result = addrs_from_protobuf([addr_info1, addr_info2])
assert result == [ma1, ma2] assert result == [ma1, ma2]
def test_peer_record_from_protobuf(): def test_peer_record_from_protobuf():
peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px") peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px")
record = pb.PeerRecord() record = pb.PeerRecord()
record.peer_id = peer_id.to_bytes() record.peer_id = peer_id.to_bytes()
record.seq = 42 record.seq = 42
for addr_str in ["/ip4/127.0.0.1/tcp/4001", "/ip4/127.0.0.1/tcp/4002"]: for addr_str in ["/ip4/127.0.0.1/tcp/4001", "/ip4/127.0.0.1/tcp/4002"]:
ma = Multiaddr(addr_str) ma = Multiaddr(addr_str)
addr_info = pb.PeerRecord.AddressInfo() addr_info = pb.PeerRecord.AddressInfo()
addr_info.multiaddr = ma.to_bytes() addr_info.multiaddr = ma.to_bytes()
record.addresses.append(addr_info) record.addresses.append(addr_info)
result = peer_record_from_protobuf(record) result = peer_record_from_protobuf(record)
assert result.peer_id == peer_id assert result.peer_id == peer_id
assert result.seq == 42 assert result.seq == 42
assert len(result.addrs) == 2 assert len(result.addrs) == 2
assert str(result.addrs[0]) == "/ip4/127.0.0.1/tcp/4001" assert str(result.addrs[0]) == "/ip4/127.0.0.1/tcp/4001"
assert str(result.addrs[1]) == "/ip4/127.0.0.1/tcp/4002" assert str(result.addrs[1]) == "/ip4/127.0.0.1/tcp/4002"
def test_to_protobuf_generates_correct_message(): def test_to_protobuf_generates_correct_message():
peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px") peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px")
addrs = [Multiaddr("/ip4/127.0.0.1/tcp/4001")] addrs = [Multiaddr("/ip4/127.0.0.1/tcp/4001")]
seq = 12345 seq = 12345
record = PeerRecord(peer_id, addrs, seq) record = PeerRecord(peer_id, addrs, seq)
proto = record.to_protobuf() proto = record.to_protobuf()
assert isinstance(proto, pb.PeerRecord) assert isinstance(proto, pb.PeerRecord)
assert proto.peer_id == peer_id.to_bytes() assert proto.peer_id == peer_id.to_bytes()
assert proto.seq == seq assert proto.seq == seq
assert len(proto.addresses) == 1 assert len(proto.addresses) == 1
assert proto.addresses[0].multiaddr == addrs[0].to_bytes() assert proto.addresses[0].multiaddr == addrs[0].to_bytes()
def test_unmarshal_record_roundtrip(): def test_unmarshal_record_roundtrip():
record = PeerRecord( record = PeerRecord(
peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px"), peer_id=ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px"),
addrs = [Multiaddr("/ip4/127.0.0.1/tcp/4001")], addrs=[Multiaddr("/ip4/127.0.0.1/tcp/4001")],
seq = 999, seq=999,
) )
serialized = record.to_protobuf().SerializeToString() serialized = record.to_protobuf().SerializeToString()
deserialized = unmarshal_record(serialized) deserialized = unmarshal_record(serialized)
assert deserialized.peer_id == record.peer_id assert deserialized.peer_id == record.peer_id
assert deserialized.seq == record.seq assert deserialized.seq == record.seq
assert len(deserialized.addrs) == 1 assert len(deserialized.addrs) == 1
assert deserialized.addrs[0] == record.addrs[0] assert deserialized.addrs[0] == record.addrs[0]
def test_marshal_record_and_equal(): def test_marshal_record_and_equal():
peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px") peer_id = ID.from_base58("QmNM23MiU1Kd7yfiKVdUnaDo8RYca8By4zDmr7uSaVV8Px")
addrs = [Multiaddr("/ip4/127.0.0.1/tcp/4001")] addrs = [Multiaddr("/ip4/127.0.0.1/tcp/4001")]
original = PeerRecord(peer_id, addrs) original = PeerRecord(peer_id, addrs)
serialized = original.marshal_record() serialized = original.marshal_record()
deserailzed = unmarshal_record(serialized) deserailzed = unmarshal_record(serialized)
assert original.equal(deserailzed) assert original.equal(deserailzed)