|
2 | 2 | defaultdict,
|
3 | 3 | )
|
4 | 4 | from collections.abc import (
|
| 5 | + AsyncIterable, |
5 | 6 | Sequence,
|
6 | 7 | )
|
7 | 8 | from typing import (
|
|
11 | 12 | from multiaddr import (
|
12 | 13 | Multiaddr,
|
13 | 14 | )
|
| 15 | +import trio |
| 16 | +from trio import MemoryReceiveChannel, MemorySendChannel |
14 | 17 |
|
15 | 18 | from libp2p.abc import (
|
16 | 19 | IPeerStore,
|
@@ -40,6 +43,7 @@ class PeerStore(IPeerStore):
|
40 | 43 |
|
41 | 44 | def __init__(self) -> None:
|
42 | 45 | self.peer_data_map = defaultdict(PeerData)
|
| 46 | + self.addr_update_channels: dict[ID, MemorySendChannel[Multiaddr]] = {} |
43 | 47 |
|
44 | 48 | def peer_info(self, peer_id: ID) -> PeerInfo:
|
45 | 49 | """
|
@@ -178,6 +182,13 @@ def add_addrs(self, peer_id: ID, addrs: Sequence[Multiaddr], ttl: int = 0) -> No
|
178 | 182 | peer_data.set_ttl(ttl)
|
179 | 183 | peer_data.update_last_identified()
|
180 | 184 |
|
| 185 | + if peer_id in self.addr_update_channels: |
| 186 | + for addr in addrs: |
| 187 | + try: |
| 188 | + self.addr_update_channels[peer_id].send_nowait(addr) |
| 189 | + except trio.WouldBlock: |
| 190 | + pass # Or consider logging / dropping / replacing stream |
| 191 | + |
181 | 192 | def addrs(self, peer_id: ID) -> list[Multiaddr]:
|
182 | 193 | """
|
183 | 194 | :param peer_id: peer ID to get addrs for
|
@@ -217,6 +228,25 @@ def peers_with_addrs(self) -> list[ID]:
|
217 | 228 | peer_data.clear_addrs()
|
218 | 229 | return output
|
219 | 230 |
|
| 231 | + async def addr_stream(self, peer_id: ID) -> AsyncIterable[Multiaddr]: |
| 232 | + """ |
| 233 | + Returns an async stream of newly added addresses for the given peer. |
| 234 | +
|
| 235 | + This function allows consumers to subscribe to address updates for a peer |
| 236 | + and receive each new address as it is added via `add_addr` or `add_addrs`. |
| 237 | +
|
| 238 | + :param peer_id: The ID of the peer to monitor address updates for. |
| 239 | + :return: An async iterator yielding Multiaddr instances as they are added. |
| 240 | + """ |
| 241 | + send: MemorySendChannel[Multiaddr] |
| 242 | + receive: MemoryReceiveChannel[Multiaddr] |
| 243 | + |
| 244 | + send, receive = trio.open_memory_channel(0) |
| 245 | + self.addr_update_channels[peer_id] = send |
| 246 | + |
| 247 | + async for addr in receive: |
| 248 | + yield addr |
| 249 | + |
220 | 250 | # -------KEY-BOOK---------
|
221 | 251 |
|
222 | 252 | def add_pubkey(self, peer_id: ID, pubkey: PublicKey) -> None:
|
|
0 commit comments