List and count peers by identity - #273
Conversation
22be4c1 to
af1051f
Compare
| let entry = latest.entry(peer.id).or_insert((*arrival, peer)); | ||
| if *arrival > entry.0 { | ||
| *entry = (*arrival, peer); | ||
| } |
There was a problem hiding this comment.
so you are deduplicating from one map into another map and updating other the latest arrival time?
There was a problem hiding this comment.
why are there duplicates in the peer table? and if it is possible wouldn't it be better to replace on insertion rather than having 2 entries?
There was a problem hiding this comment.
Simplest way this may happen - outgoing and incoming connection to/from the same peer.
| *entry = (*arrival, peer); | ||
| } | ||
| } | ||
| latest.into_values().map(|(_, peer)| peer).collect() |
There was a problem hiding this comment.
and the discarding the arrival time and collecting into a vec?
There was a problem hiding this comment.
if you didn't have to track arrival times and multiple connection per Peer (i.e. deduplicate on insertion), then you could just return an impl Iterator<Item = &Peer> from self.connections.values()
There was a problem hiding this comment.
and so avoid allocating multiple collections
| pub(crate) fn len(&self) -> usize { | ||
| self.0.len() | ||
| pub(crate) fn connected(&self) -> usize { | ||
| self.by_identity().len() |
There was a problem hiding this comment.
this allocates the peer table twice
|
|
||
| pub(crate) fn matching<'a>(&'a self, filter: &'a PeerFilter) -> impl Iterator<Item = &'a Peer> { | ||
| self.0.values().filter(move |peer| filter.admits(peer)) | ||
| self.by_identity().into_iter().filter(move |peer| filter.admits(peer)) |
| pub(crate) fn insert(&mut self, connection: usize, peer: Peer) { | ||
| self.0.insert(connection, peer); | ||
| self.arrivals += 1; | ||
| self.connections.insert(connection, (self.arrivals, peer)); |
There was a problem hiding this comment.
you have the Peer here so you could deduplicate by PeerId here. And it is perfectly possible to handle event orders like Connected, Connected, Disconnected, Disconnected.
For example:
self.connections = FxHashMap::<PeerId, (Peer, u8)>::default();
fn insert(&mut self, peer: Peer) {
self.connections.entry(peer.id).and_modify(|(_, count)| (peer, *count += 1)).or_insert((peer, 1));
}
// decrement count on `remove` and actually remove if `count == 0`
// then to return peers
fn peers(&self) -> impl Iterator<Item = &Peer> {
self.connections.values().map(|(peer, _)| peer)
}
There was a problem hiding this comment.
See 012aca0
Note, this version is storing connections for each peer peers: FxHashMap<PeerId, Vec<Connection>> - this is to enable API to keep accounting of peers. There probably are alternative solutions, exploring this space.
There was a problem hiding this comment.
The reason why we need to retain Connection is that a failed handshake can produce a disconnect without a preceding connect. We need to be able to filter our such disconnects. The current implementation in PeerTable::remove does handle it gracefully; the alternative is to let PeerManager publish its selected peers - a new message, only for Beacon API. I think that would be worse.
af1051f to
37c27a4
Compare
37c27a4 to
6e4fa14
Compare
d076272 to
4b95ded
Compare
04d7d8e to
012aca0
Compare
0c091cb to
1807b97
Compare
Deduplicate peer API responses while retaining each connection until its disconnect event. Use the latest observed connection for each peer's address and direction, tracking arrival order independently of reusable connection handles. Cover duplicate identities, decreasing handles, and both disconnect orders. Check peer response JSON values and invalid-filter HTTP status without requiring exact body bytes or header order. Document the connected-only inventory, null ENRs, and missed connection events before the API's first read in ADR 0004. Assisted-by: Claude:claude-fable-5-1 Assisted-by: Codex:gpt-6-astra
Keep each identity's connections in arrival order and select the latest survivor for API output. Count identities directly and list peers through an iterator, removing per-query deduplication and its temporary map and vector. Use the identity and handle in disconnect events to remove the closed connection. Preserve the surviving connection's address and direction, including when the newest connection closes first. Extend tests for direction filters, three overlapping connections, and unknown or repeated events. Update ADR 0004's description of connection storage. Assisted-by: Codex:gpt-6-astra
3b2e7d9 to
739d7e0
Compare
Count and list unique peer identities, keeping a peer visible while any observed connection remains. Use the latest observed connection for its address and direction.
Add coverage for duplicate connections and both disconnect orders, simplify response assertions, and document peer inventory limitations in ADR 0004