fix(net): room creator can rejoin a room they left (A8)
The gossip bootstrap list was derived solely from the ticket: a client dialed the host, but "we are the host" produced an EMPTY list. So when the room CREATOR rejoined their own room (their ticket names themselves as host) they dialed nobody and never re-entered the swarm — the remaining peer stayed stuck until it too left and rejoined. (First 2-human field test, 2026-06-14; user-confirmed call-breaking, P1.) Fix: retain the peers seen in the current room across leave (core `known_peers`, updated by the event task; reset only when the joined ticket changes) and pass them to `RoomState::join` as extra bootstrap targets. The new pure `compute_bootstrap` seam unions the ticket host + retained peers, drops self, and de-dups; address resolution rides the persistent lookup. - `RoomState::join` gains `extra_bootstrap: Vec<EndpointAddr>` (test_net callers pass vec![]). - +4 unit tests on `compute_bootstrap`, incl. the host-rejoin regression case. Tests-green (208 lib + 6 + 4 integration), clippy clean. NOT yet 2-machine field-verified — needs a live host leave→rejoin call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -63,7 +63,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
addr: endpoint_a.addr(),
|
||||
sharing: None,
|
||||
};
|
||||
room_a.join(&ticket_str, state_a).await?;
|
||||
room_a.join(&ticket_str, state_a, vec![]).await?;
|
||||
println!("Node A joined topic.");
|
||||
|
||||
// Subscribe to events on Node A
|
||||
@@ -81,7 +81,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
addr: endpoint_b.addr(),
|
||||
sharing: None,
|
||||
};
|
||||
room_b.join(&ticket_str, state_b).await?;
|
||||
room_b.join(&ticket_str, state_b, vec![]).await?;
|
||||
println!("Node B joined topic.");
|
||||
|
||||
// Subscribe to events on Node B
|
||||
|
||||
Reference in New Issue
Block a user