From 024458e67a4cb6f29bf1ff346c9f953781006129 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 1 Nov 2026 05:13:59 +0100 Subject: libp2p: introduce rehoming --- src/transport/libp2p/book.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'src/transport/libp2p/book.rs') diff --git a/src/transport/libp2p/book.rs b/src/transport/libp2p/book.rs index 7de4be7..f466aef 100644 --- a/src/transport/libp2p/book.rs +++ b/src/transport/libp2p/book.rs @@ -70,6 +70,9 @@ pub(super) struct Book { pub(super) failed_relays: HashMap, /// Relays that granted us a slot we hold. pub(super) slots: std::collections::HashSet, + /// Relays we hold a slot on whose duplicate connections we closed, and when + /// (`duplicates`): a slot lost then moves to the connection kept, it isn't lost. + pub(super) rehoming: HashMap, /// Peers holding a slot on this node, as a relay. pub(super) slots_here: std::collections::HashSet, /// Peers connected only through a relay, dialled directly (`upgrade`): when to again @@ -117,17 +120,16 @@ impl Book { book_connection(&self.connections, peer) } - /// The connections to `peer` to close, of several: all but one, the oldest direct - /// one (the oldest relayed one if none is direct). + /// The connections to `peer` to close, of several: all but the one to keep + /// (`ranked`). /// - /// None between a relay and a node with a slot on it, or reserving one (`reserving`): - /// a slot lives on one connection, which libp2p doesn't tell, and closing it would - /// end the slot, and with it every circuit to the node (the relay then answers - /// `NoReservation`). - pub(super) fn duplicates(&self, peer: &PeerId, reserving: bool) -> Vec { - if reserving || self.slots.contains(peer) || self.slots_here.contains(peer) { - return Vec::new(); - } + /// Between a relay and a node with a slot on it too: messages go over any of the + /// connections (libp2p-stream picks one at random for each), so a slower one kept + /// would carry half of them. A slot lives on one connection, which libp2p doesn't + /// tell; if that one closes, the slot ends, and the node reserves it again at once, + /// over the connection kept (`Book::rehoming`, not counted as lost); circuits + /// through it end, and are made again with the next message. + pub(super) fn duplicates(&self, peer: &PeerId) -> Vec { self.ranked(peer).into_iter().skip(1).collect() } -- cgit v1.3.1