From eb60466fa1013ddf875ffb25436236819670f340 Mon Sep 17 00:00:00 2001 From: Moses Narrow <36607567+0pcom@users.noreply.github.com> Date: Mon, 4 May 2026 14:35:39 +0000 Subject: [PATCH] transport-discovery: cap UpdateLatency at MaxReasonableRTTMs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Visors running pre-#2421 binaries push outlier max samples (e.g. 35s RTT from a straggler pong) via CXO. TPD's UpdateLatency only had a lower-bound guard (avg<=0 or any field <=0 → drop), so those reach the lat: store and pin Max for the 35-day retention regardless of how many later good samples land. Production right now: 5 transports show max>30s, all written ~10h ago, ages-out date 35d from each write. Won't go away on its own. Reject the same way the visor side does (transport.MaxReasonableRTTMs, 30s) so TPD's defense-in-depth matches the visor's. Old visors keep pushing bogus values; TPD now silently drops them, and the next good sample from any peer overwrites the stale stored max. The package already imports pkg/transport (via redis_transport.go) so MaxReasonableRTTMs comes free with no new dep. --- pkg/transport-discovery/store/redis_bandwidth.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pkg/transport-discovery/store/redis_bandwidth.go b/pkg/transport-discovery/store/redis_bandwidth.go index 855023a771..36a3c64296 100644 --- a/pkg/transport-discovery/store/redis_bandwidth.go +++ b/pkg/transport-discovery/store/redis_bandwidth.go @@ -13,6 +13,7 @@ import ( "github.com/google/uuid" "github.com/skycoin/skywire/pkg/cipher" + "github.com/skycoin/skywire/pkg/transport" ) // Bandwidth key generators @@ -122,7 +123,17 @@ func (s *redisStore) UpdateLatency(ctx context.Context, transportID string, minM // Defense-in-depth alongside the aggregator gate: any non-positive // field means the snapshot is partial, so reject the whole update // rather than persist a zero in a single field. - if minMS <= 0 || maxMS <= 0 || avgMS <= 0 { + // + // Upper bound: visors running pre-#2421 binaries don't filter + // straggler-pong outliers (35s+ RTT from a delayed pong) and push + // them via CXO. TPD must reject those at ingest, otherwise the + // 35-day lat: retention pins a bogus Max for weeks regardless + // of how many later good samples land. transport.MaxReasonableRTTMs + // is the same 30s threshold the visor side enforces post-#2421. + if minMS <= 0 || maxMS <= 0 || avgMS <= 0 || + minMS > transport.MaxReasonableRTTMs || + maxMS > transport.MaxReasonableRTTMs || + avgMS > transport.MaxReasonableRTTMs { return nil }