ft. modernise py-libp2p (#618)

* fix pyproject.toml , add ruff

* rm lock

* make progress

* add poetry lock ignore

* fix type issues

* fix tcp type errors

* fix text example - type error - wrong args

* add setuptools to dev

* test ci

* fix docs build

* fix type issues for new_swarm & new_host

* fix types in gossipsub

* fix type issues in noise

* wip: factories

* revert factories

* fix more type issues

* more type fixes

* fix: add null checks for noise protocol initialization and key handling

* corrected argument-errors in peerId and Multiaddr in peer tests

* fix: Noice - remove redundant type casts in BaseNoiseMsgReadWriter

* fix: update test_notify.py to use SwarmFactory.create_batch_and_listen, fix type hints, and comment out ClosedStream assertions

* Fix type checks for pubsub module

Signed-off-by: sukhman <sukhmansinghsaluja@gmail.com>

* Fix type checks for pubsub module-tests

Signed-off-by: sukhman <sukhmansinghsaluja@gmail.com>

* noise: add checks for uninitialized protocol and key states in PatternXX

Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>

* pubsub: add None checks for optional fields in FloodSub and Pubsub

Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>

* Fix type hints and improve testing

Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>

* remove redundant checks

Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>

* fix build issues

* add optional to trio service

* fix types

* fix type errors

* Fix type errors

Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>

* fixed more-type checks in crypto and peer_data files

* wip: factories

* replaced union with optional

* fix: type-error in interp-utils and peerinfo

* replace pyright with pyrefly

* add pyrefly.toml

* wip: fix multiselect issues

* try typecheck

* base check

* mcache test fixes , typecheck ci update

* fix ci

* will this work

* minor fix

* use poetry

* fix wokflow

* use cache,fix err

* fix pyrefly.toml

* fix pyrefly.toml

* fix cache in ci

* deploy commit

* add main baseline

* update to v5

* improve typecheck ci (#14)

* fix typo

* remove holepunching code (#16)

* fix gossipsub typeerrors (#17)

* fix: ensure initiator user includes remote peer id in handshake (#15)

* fix ci (#19)

* typefix: custom_types | core/peerinfo/test_peer_info | io/abc | pubsub/floodsub | protocol_muxer/multiselect (#18)

* fix: Typefixes in PeerInfo  (#21)

* fix minor type issue (#22)

* fix type errors in pubsub (#24)

* fix: Minor typefixes in tests (#23)

* Fix failing tests for type-fixed test/pubsub (#8)

* move pyrefly & ruff to pyproject.toml & rm .project-template (#28)

* move the async_context file to tests/core

* move crypto test to crypto folder

* fix: some typefixes (#25)

* fix type errors

* fix type issues

* fix: update gRPC API usage in autonat_pb2_grpc.py (#31)

* md: typecheck ci

* rm comments

* clean up : from review suggestions

* use | None over Optional as per new python standards

* drop supporto for py3.9

* newsfragments

---------

Signed-off-by: sukhman <sukhmansinghsaluja@gmail.com>
Signed-off-by: varun-r-mallya <varunrmallya@gmail.com>
Co-authored-by: acul71 <luca.pisani@birdo.net>
Co-authored-by: kaneki003 <sakshamchauhan707@gmail.com>
Co-authored-by: sukhman <sukhmansinghsaluja@gmail.com>
Co-authored-by: varun-r-mallya <varunrmallya@gmail.com>
Co-authored-by: varunrmallya <100590632+varun-r-mallya@users.noreply.github.com>
Co-authored-by: lla-dane <abhinavagarwalla6@gmail.com>
Co-authored-by: Collins <ArtemisfowlX@protonmail.com>
Co-authored-by: Abhinav Agarwalla <120122716+lla-dane@users.noreply.github.com>
Co-authored-by: guha-rahul <52607971+guha-rahul@users.noreply.github.com>
Co-authored-by: Sukhman Singh <63765293+sukhman-sukh@users.noreply.github.com>
Co-authored-by: acul71 <34693171+acul71@users.noreply.github.com>
Co-authored-by: pacrob <5199899+pacrob@users.noreply.github.com>
This commit is contained in:
Arush Kurundodi
2025-06-09 23:09:59 +05:30
committed by GitHub
parent d020bbc066
commit bdadec7519
111 changed files with 1537 additions and 1401 deletions

View File

@ -1,5 +1,9 @@
import pytest
from multiaddr import (
Multiaddr,
)
from libp2p.peer.id import ID
from libp2p.peer.peerstore import (
PeerStore,
PeerStoreError,
@ -11,51 +15,72 @@ from libp2p.peer.peerstore import (
def test_addrs_empty():
with pytest.raises(PeerStoreError):
store = PeerStore()
val = store.addrs("peer")
val = store.addrs(ID(b"peer"))
assert not val
def test_add_addr_single():
store = PeerStore()
store.add_addr("peer1", "/foo", 10)
store.add_addr("peer1", "/bar", 10)
store.add_addr("peer2", "/baz", 10)
store.add_addr(ID(b"peer1"), Multiaddr("/ip4/127.0.0.1/tcp/4001"), 10)
store.add_addr(ID(b"peer1"), Multiaddr("/ip4/127.0.0.1/tcp/4002"), 10)
store.add_addr(ID(b"peer2"), Multiaddr("/ip4/127.0.0.1/tcp/4003"), 10)
assert store.addrs("peer1") == ["/foo", "/bar"]
assert store.addrs("peer2") == ["/baz"]
assert store.addrs(ID(b"peer1")) == [
Multiaddr("/ip4/127.0.0.1/tcp/4001"),
Multiaddr("/ip4/127.0.0.1/tcp/4002"),
]
assert store.addrs(ID(b"peer2")) == [Multiaddr("/ip4/127.0.0.1/tcp/4003")]
def test_add_addrs_multiple():
store = PeerStore()
store.add_addrs("peer1", ["/foo1", "/bar1"], 10)
store.add_addrs("peer2", ["/foo2"], 10)
store.add_addrs(
ID(b"peer1"),
[Multiaddr("/ip4/127.0.0.1/tcp/40011"), Multiaddr("/ip4/127.0.0.1/tcp/40021")],
10,
)
store.add_addrs(ID(b"peer2"), [Multiaddr("/ip4/127.0.0.1/tcp/40012")], 10)
assert store.addrs("peer1") == ["/foo1", "/bar1"]
assert store.addrs("peer2") == ["/foo2"]
assert store.addrs(ID(b"peer1")) == [
Multiaddr("/ip4/127.0.0.1/tcp/40011"),
Multiaddr("/ip4/127.0.0.1/tcp/40021"),
]
assert store.addrs(ID(b"peer2")) == [Multiaddr("/ip4/127.0.0.1/tcp/40012")]
def test_clear_addrs():
store = PeerStore()
store.add_addrs("peer1", ["/foo1", "/bar1"], 10)
store.add_addrs("peer2", ["/foo2"], 10)
store.clear_addrs("peer1")
store.add_addrs(
ID(b"peer1"),
[Multiaddr("/ip4/127.0.0.1/tcp/40011"), Multiaddr("/ip4/127.0.0.1/tcp/40021")],
10,
)
store.add_addrs(ID(b"peer2"), [Multiaddr("/ip4/127.0.0.1/tcp/40012")], 10)
store.clear_addrs(ID(b"peer1"))
assert store.addrs("peer1") == []
assert store.addrs("peer2") == ["/foo2"]
assert store.addrs(ID(b"peer1")) == []
assert store.addrs(ID(b"peer2")) == [Multiaddr("/ip4/127.0.0.1/tcp/40012")]
store.add_addrs("peer1", ["/foo1", "/bar1"], 10)
store.add_addrs(
ID(b"peer1"),
[Multiaddr("/ip4/127.0.0.1/tcp/40011"), Multiaddr("/ip4/127.0.0.1/tcp/40021")],
10,
)
assert store.addrs("peer1") == ["/foo1", "/bar1"]
assert store.addrs(ID(b"peer1")) == [
Multiaddr("/ip4/127.0.0.1/tcp/40011"),
Multiaddr("/ip4/127.0.0.1/tcp/40021"),
]
def test_peers_with_addrs():
store = PeerStore()
store.add_addrs("peer1", [], 10)
store.add_addrs("peer2", ["/foo"], 10)
store.add_addrs("peer3", ["/bar"], 10)
store.add_addrs(ID(b"peer1"), [], 10)
store.add_addrs(ID(b"peer2"), [Multiaddr("/ip4/127.0.0.1/tcp/4001")], 10)
store.add_addrs(ID(b"peer3"), [Multiaddr("/ip4/127.0.0.1/tcp/4002")], 10)
assert set(store.peers_with_addrs()) == {"peer2", "peer3"}
assert set(store.peers_with_addrs()) == {ID(b"peer2"), ID(b"peer3")}
store.clear_addrs("peer2")
store.clear_addrs(ID(b"peer2"))
assert set(store.peers_with_addrs()) == {"peer3"}
assert set(store.peers_with_addrs()) == {ID(b"peer3")}

View File

@ -23,9 +23,7 @@ kBZ7WvkmPV3aPL6jnwp2pXepntdVnaTiSxJ1dkXShZ/VSSDNZMYKY306EtHrIu3NZHtXhdyHKcggDXr
qkBrdgErAkAlpGPojUwemOggr4FD8sLX1ot2hDJyyV7OK2FXfajWEYJyMRL1Gm9Uk1+Un53RAkJneqp
JGAzKpyttXBTIDO51AkEA98KTiROMnnU8Y6Mgcvr68/SMIsvCYMt9/mtwSBGgl80VaTQ5Hpaktl6Xbh
VUt5Wv0tRxlXZiViCGCD1EtrrwTw==
""".replace(
"\n", ""
)
""".replace("\n", "")
EXPECTED_PEER_ID = "QmRK3JgmVEGiewxWbhpXLJyjWuGuLeSTMTndA1coMHEy5o"

View File

@ -1,4 +1,7 @@
from collections.abc import Sequence
import pytest
from multiaddr import Multiaddr
from libp2p.crypto.secp256k1 import (
create_new_key_pair,
@ -8,7 +11,7 @@ from libp2p.peer.peerdata import (
PeerDataError,
)
MOCK_ADDR = "/peer"
MOCK_ADDR = Multiaddr("/ip4/127.0.0.1/tcp/4001")
MOCK_KEYPAIR = create_new_key_pair()
MOCK_PUBKEY = MOCK_KEYPAIR.public_key
MOCK_PRIVKEY = MOCK_KEYPAIR.private_key
@ -23,7 +26,7 @@ def test_get_protocols_empty():
# Test case when adding protocols
def test_add_protocols():
peer_data = PeerData()
protocols = ["protocol1", "protocol2"]
protocols: Sequence[str] = ["protocol1", "protocol2"]
peer_data.add_protocols(protocols)
assert peer_data.get_protocols() == protocols
@ -31,7 +34,7 @@ def test_add_protocols():
# Test case when setting protocols
def test_set_protocols():
peer_data = PeerData()
protocols = ["protocolA", "protocolB"]
protocols: Sequence[str] = ["protocol1", "protocol2"]
peer_data.set_protocols(protocols)
assert peer_data.get_protocols() == protocols
@ -39,7 +42,7 @@ def test_set_protocols():
# Test case when adding addresses
def test_add_addrs():
peer_data = PeerData()
addresses = [MOCK_ADDR]
addresses: Sequence[Multiaddr] = [MOCK_ADDR]
peer_data.add_addrs(addresses)
assert peer_data.get_addrs() == addresses
@ -47,7 +50,7 @@ def test_add_addrs():
# Test case when adding same address more than once
def test_add_dup_addrs():
peer_data = PeerData()
addresses = [MOCK_ADDR, MOCK_ADDR]
addresses: Sequence[Multiaddr] = [MOCK_ADDR, MOCK_ADDR]
peer_data.add_addrs(addresses)
peer_data.add_addrs(addresses)
assert peer_data.get_addrs() == [MOCK_ADDR]
@ -56,7 +59,7 @@ def test_add_dup_addrs():
# Test case for clearing addresses
def test_clear_addrs():
peer_data = PeerData()
addresses = [MOCK_ADDR]
addresses: Sequence[Multiaddr] = [MOCK_ADDR]
peer_data.add_addrs(addresses)
peer_data.clear_addrs()
assert peer_data.get_addrs() == []

View File

@ -6,16 +6,12 @@ import multihash
from libp2p.crypto.rsa import (
create_new_key_pair,
)
import libp2p.peer.id as PeerID
from libp2p.peer.id import (
ID,
)
ALPHABETS = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
# ensure we are not in "debug" mode for the following tests
PeerID.FRIENDLY_IDS = False
def test_eq_impl_for_bytes():
random_id_string = ""
@ -70,8 +66,8 @@ def test_eq_true():
def test_eq_false():
peer_id = ID("efgh")
other = ID("abcd")
peer_id = ID(b"efgh")
other = ID(b"abcd")
assert peer_id != other
@ -91,7 +87,7 @@ def test_id_from_base58():
for _ in range(10):
random_id_string += random.choice(ALPHABETS)
expected = ID(base58.b58decode(random_id_string))
actual = ID.from_base58(random_id_string.encode())
actual = ID.from_base58(random_id_string)
assert actual == expected

View File

@ -17,10 +17,14 @@ VALID_MULTI_ADDR_STR = "/ip4/127.0.0.1/tcp/8000/p2p/3YgLAeMKSAPcGqZkAt8mREqhQXmJ
def test_init_():
random_addrs = [random.randint(0, 255) for r in range(4)]
random_addrs = [
multiaddr.Multiaddr(f"/ip4/127.0.0.1/tcp/{1000 + i}") for i in range(4)
]
random_id_string = ""
for _ in range(10):
random_id_string += random.SystemRandom().choice(ALPHABETS)
peer_id = ID(random_id_string.encode())
peer_info = PeerInfo(peer_id, random_addrs)

View File

@ -1,5 +1,6 @@
import pytest
from libp2p.peer.id import ID
from libp2p.peer.peerstore import (
PeerStore,
PeerStoreError,
@ -11,36 +12,36 @@ from libp2p.peer.peerstore import (
def test_get_empty():
with pytest.raises(PeerStoreError):
store = PeerStore()
val = store.get("peer", "key")
val = store.get(ID(b"peer"), "key")
assert not val
def test_put_get_simple():
store = PeerStore()
store.put("peer", "key", "val")
assert store.get("peer", "key") == "val"
store.put(ID(b"peer"), "key", "val")
assert store.get(ID(b"peer"), "key") == "val"
def test_put_get_update():
store = PeerStore()
store.put("peer", "key1", "val1")
store.put("peer", "key2", "val2")
store.put("peer", "key2", "new val2")
store.put(ID(b"peer"), "key1", "val1")
store.put(ID(b"peer"), "key2", "val2")
store.put(ID(b"peer"), "key2", "new val2")
assert store.get("peer", "key1") == "val1"
assert store.get("peer", "key2") == "new val2"
assert store.get(ID(b"peer"), "key1") == "val1"
assert store.get(ID(b"peer"), "key2") == "new val2"
def test_put_get_two_peers():
store = PeerStore()
store.put("peer1", "key1", "val1")
store.put("peer2", "key1", "val1 prime")
store.put(ID(b"peer1"), "key1", "val1")
store.put(ID(b"peer2"), "key1", "val1 prime")
assert store.get("peer1", "key1") == "val1"
assert store.get("peer2", "key1") == "val1 prime"
assert store.get(ID(b"peer1"), "key1") == "val1"
assert store.get(ID(b"peer2"), "key1") == "val1 prime"
# Try update
store.put("peer2", "key1", "new val1")
store.put(ID(b"peer2"), "key1", "new val1")
assert store.get("peer1", "key1") == "val1"
assert store.get("peer2", "key1") == "new val1"
assert store.get(ID(b"peer1"), "key1") == "val1"
assert store.get(ID(b"peer2"), "key1") == "new val1"

View File

@ -1,5 +1,7 @@
import pytest
from multiaddr import Multiaddr
from libp2p.peer.id import ID
from libp2p.peer.peerstore import (
PeerStore,
PeerStoreError,
@ -11,52 +13,52 @@ from libp2p.peer.peerstore import (
def test_peer_info_empty():
store = PeerStore()
with pytest.raises(PeerStoreError):
store.peer_info("peer")
store.peer_info(ID(b"peer"))
def test_peer_info_basic():
store = PeerStore()
store.add_addr("peer", "/foo", 10)
info = store.peer_info("peer")
store.add_addr(ID(b"peer"), Multiaddr("/ip4/127.0.0.1/tcp/4001"), 10)
info = store.peer_info(ID(b"peer"))
assert info.peer_id == "peer"
assert info.addrs == ["/foo"]
assert info.peer_id == ID(b"peer")
assert info.addrs == [Multiaddr("/ip4/127.0.0.1/tcp/4001")]
def test_add_get_protocols_basic():
store = PeerStore()
store.add_protocols("peer1", ["p1", "p2"])
store.add_protocols("peer2", ["p3"])
store.add_protocols(ID(b"peer1"), ["p1", "p2"])
store.add_protocols(ID(b"peer2"), ["p3"])
assert set(store.get_protocols("peer1")) == {"p1", "p2"}
assert set(store.get_protocols("peer2")) == {"p3"}
assert set(store.get_protocols(ID(b"peer1"))) == {"p1", "p2"}
assert set(store.get_protocols(ID(b"peer2"))) == {"p3"}
def test_add_get_protocols_extend():
store = PeerStore()
store.add_protocols("peer1", ["p1", "p2"])
store.add_protocols("peer1", ["p3"])
store.add_protocols(ID(b"peer1"), ["p1", "p2"])
store.add_protocols(ID(b"peer1"), ["p3"])
assert set(store.get_protocols("peer1")) == {"p1", "p2", "p3"}
assert set(store.get_protocols(ID(b"peer1"))) == {"p1", "p2", "p3"}
def test_set_protocols():
store = PeerStore()
store.add_protocols("peer1", ["p1", "p2"])
store.add_protocols("peer2", ["p3"])
store.add_protocols(ID(b"peer1"), ["p1", "p2"])
store.add_protocols(ID(b"peer2"), ["p3"])
store.set_protocols("peer1", ["p4"])
store.set_protocols("peer2", [])
store.set_protocols(ID(b"peer1"), ["p4"])
store.set_protocols(ID(b"peer2"), [])
assert set(store.get_protocols("peer1")) == {"p4"}
assert set(store.get_protocols("peer2")) == set()
assert set(store.get_protocols(ID(b"peer1"))) == {"p4"}
assert set(store.get_protocols(ID(b"peer2"))) == set()
# Test with methods from other Peer interfaces.
def test_peers():
store = PeerStore()
store.add_protocols("peer1", [])
store.put("peer2", "key", "val")
store.add_addr("peer3", "/foo", 10)
store.add_protocols(ID(b"peer1"), [])
store.put(ID(b"peer2"), "key", "val")
store.add_addr(ID(b"peer3"), Multiaddr("/ip4/127.0.0.1/tcp/4001"), 10)
assert set(store.peer_ids()) == {"peer1", "peer2", "peer3"}
assert set(store.peer_ids()) == {ID(b"peer1"), ID(b"peer2"), ID(b"peer3")}