fix(repeater): feed each bridge every pre-dedup flood copy

A bridge's return-path teacher can only pick the best-received route if it
sees every copy of a flood reply. It does not: the router hands a bridge
only the first copy, later ones being dropped by the engine's seen-table,
and the pre-dedup firehose lives on the dispatcher, which the bridge does
not own. So the teacher always taught from the first-arrived route, which on
a live mesh is routinely the worst one -- observed here, four copies of one
login reply landed over ~1.8s and the teach went out 0.4s in, embedding the
marginal first route.

Subscribe each bridge's note_flood_copy to the dispatcher's raw packet
subscribers at both bridge-creation sites, next to the existing region_map
handoff.
This commit is contained in:
agessaman
2026-07-24 15:07:12 -07:00
parent 3d89174038
commit 05dae761e7
+18
View File
@@ -850,6 +850,15 @@ class RepeaterDaemon:
# its own flood replies to the region the request arrived under.
bridge.region_map = self._region_map
# Feed this bridge every pre-dedup copy of a flood reply so its
# return-path teacher can pick the best-received route rather than
# the first-arrived one. The router hands a bridge only the first
# copy (later ones are dropped by the engine's seen-table) and the
# pre-dedup firehose lives on the dispatcher, which the bridge does
# not own -- so the host has to wire it.
if self.dispatcher:
self.dispatcher.add_raw_packet_subscriber(bridge.note_flood_copy)
# Restore persisted state (contacts/channels/messages) from SQLite.
# Raises CompanionStateLoadError instead of continuing with an
# empty store when persisted rows exist but cannot be loaded.
@@ -1088,6 +1097,15 @@ class RepeaterDaemon:
# re-scopes its flood replies to the region the request arrived under.
bridge.region_map = self._region_map
# Feed this bridge every pre-dedup copy of a flood reply so its
# return-path teacher can pick the best-received route rather than
# the first-arrived one. The router hands a bridge only the first
# copy (later ones are dropped by the engine's seen-table) and the
# pre-dedup firehose lives on the dispatcher, which the bridge does
# not own -- so the host has to wire it.
if self.dispatcher:
self.dispatcher.add_raw_packet_subscriber(bridge.note_flood_copy)
# Restore persisted state; raises CompanionStateLoadError when persisted
# rows exist but cannot be loaded (hot-reload callers surface the error).
if sqlite_handler: