From c5c94fe60acf4d2cc160e5983ed5d8b2b9fb7c18 Mon Sep 17 00:00:00 2001 From: agessaman Date: Sun, 22 Mar 2026 15:26:28 -0700 Subject: [PATCH] feat: exclude TRACE packets from logging in RepeaterHandler and PacketRouter - Updated record_packet_only method to skip logging for TRACE packets, as TraceHelper manages trace paths. - Enhanced documentation to clarify the handling of TRACE packets in the web UI. - Added tests to ensure TRACE packets are not recorded, maintaining data integrity. --- repeater/engine.py | 6 ++++++ repeater/packet_router.py | 4 +++- tests/test_engine.py | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/repeater/engine.py b/repeater/engine.py index 0657f1e..50c9f5c 100644 --- a/repeater/engine.py +++ b/repeater/engine.py @@ -12,6 +12,7 @@ from pymc_core.protocol.constants import ( MAX_PATH_SIZE, PAYLOAD_TYPE_ADVERT, PAYLOAD_TYPE_ANON_REQ, + PAYLOAD_TYPE_TRACE, PH_ROUTE_MASK, PH_TYPE_MASK, PH_TYPE_SHIFT, @@ -412,6 +413,9 @@ class RepeaterHandler(BaseHandler): Used by the packet router for injection-only types (ANON_REQ, ACK, PATH, etc.) so they still appear in the web UI. + + TRACE packets are excluded: TraceHelper.log_trace_record stores the real trace path; + packet.path on TRACE holds SNR bytes, not routing hashes. """ if not self.storage: return @@ -423,6 +427,8 @@ class RepeaterHandler(BaseHandler): header_info = PacketHeaderUtils.parse_header(packet.header) payload_type = header_info["payload_type"] route_type = header_info["route_type"] + if payload_type == PAYLOAD_TYPE_TRACE: + return original_path_hashes = packet.get_path_hashes_hex() path_hash_size = packet.get_path_hash_size() path_hash = self._path_hash_display(original_path_hashes) diff --git a/repeater/packet_router.py b/repeater/packet_router.py index 23bded4..090949f 100644 --- a/repeater/packet_router.py +++ b/repeater/packet_router.py @@ -163,7 +163,9 @@ class PacketRouter: await self.daemon.trace_helper.process_trace_packet(packet) # Skip engine processing for trace packets - they're handled by trace helper processed_by_injection = True - self._record_for_ui(packet, metadata) + # Do not call _record_for_ui: TraceHelper.log_trace_record already persists the + # trace path from the payload. record_packet_only would treat packet.path (SNR bytes) + # as routing hashes and log bogus duplicate rows. elif payload_type == ControlHandler.payload_type(): # Process control/discovery packet diff --git a/tests/test_engine.py b/tests/test_engine.py index b35b031..6b309c5 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -15,7 +15,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest -from pymc_core.protocol import Packet +from pymc_core.protocol import Packet, PacketBuilder from pymc_core.protocol.constants import ( MAX_PATH_SIZE, PH_ROUTE_MASK, @@ -1366,3 +1366,16 @@ class TestBadPacketArray: assert pkt_hash not in handler.seen_packets, ( f"[{name}] bad packet was incorrectly added to seen cache" ) + + +class TestRecordPacketOnlyTrace: + """record_packet_only must not log TRACE: TraceHelper owns trace path; packet.path is SNR.""" + + def test_record_packet_only_skips_trace(self, handler): + storage = handler.storage + storage.record_packet.reset_mock() + pkt = PacketBuilder.create_trace(tag=1, auth_code=2, flags=0, path=[0xAB, 0xCD]) + n_before = len(handler.recent_packets) + handler.record_packet_only(pkt, {"rssi": -80, "snr": 10.0}) + storage.record_packet.assert_not_called() + assert len(handler.recent_packets) == n_before