Skip to content

feat(node): list traceroutes other nodes ran to us on our own node - #7764

Merged
jamesarich merged 1 commit into
mainfrom
feat/own-node-traced-by
Oct 26, 2026
Merged

jamesarich merged 1 commit into
mainfrom
feat/own-node-traced-by

Conversation

@jamesarich

@jamesarich jamesarich commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

Traceroutes other nodes run to us are logged under each tracer, so the only way to see who traced you was to open every node's page. Our own node now lists them all, as suggested in #android.

🌟 New Features

🛠️ Refactoring & Architecture

  • MeshLogDao.getLogsOnPort and MeshLogRepository.getInboundRequestLogs read one port's logs across all other nodes. Only the local node's page queries it. The LIMIT of DEFAULT_MAX_LOGS (5000) applies before the want_response filter, because that flag lives in the stored proto - the per-node page has the same bound.

Testing Performed

  • TracerouteHistoryUseCaseTest: our own history gathers traces from two nodes, newest first, and ignores one addressed elsewhere.
  • MeshLogDaoTest: getLogsOnPort spans nodes, skips the excluded node and other ports.
  • Full baseline with kmpSmokeCompile and -PwarningsAsErrors=true green except the known TakCertificateGeneratorTest timeout in core:takserver, which this change doesn't touch.

Summary by CodeRabbit

  • New Features
    • Traceroute history for your node now includes incoming traces from other nodes.
  • Bug Fixes
    • The traceroute action is no longer available for your own node.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The repository now provides inbound request logs filtered by port and want_response. Node details use inbound traceroute requests to build the local node’s traceroute history. The traceroute request action is disabled for the local node.

Changes: Inbound Traceroute History

Layer / File(s) Summary
Retrieve inbound request logs
core/database/.../MeshLogDao.kt, core/repository/.../MeshLogRepository.kt, core/data/.../MeshLogRepositoryImpl.kt, core/testing/.../FakeMeshLogRepository.kt, core/database/.../MeshLogDaoTest.kt
The DAO returns recent logs for a port while excluding a sender. The repository API and implementations provide inbound request logs, filtering for want_response. The DAO test checks port filtering, sender exclusion, and ordering.
Use inbound requests in node history
feature/node/.../CommonGetNodeDetailsUseCase.kt, feature/node/.../TelemetricActionsSection.kt, feature/node/.../TracerouteHistoryUseCaseTest.kt
Node details collect inbound traceroute requests for the local node and use them for tracerouteTracedBy. Other nodes continue to use traceroute results. The local node’s traceroute request action is disabled. The test checks local history entries from multiple nodes and excludes a request addressed elsewhere.

Priority: Normal

Merge Risk: Low · up to 2ce69

Inbound traceroute history has no established production failure from this discrepancy. The test double can be aligned with production as a bounded follow-up.

Pre-merge checks: Passed 6 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Tests Prove The Path, Not The End State Warning The added DAO test is strong: it uses an in-memory database and asserts the exact surviving UUIDs and order, so it does not only check a count. The added `our own history gathers the traces every node… Replace the fake-store round-trip assertion with a test double that records the intended interaction, such as a call counter or mock verification that getInboundRequestLogs(PortNum.TRACEROUTE_APP) is called only for the local node. Cover …
Regression Coverage For Changed Behavior Warning Regression coverage has three gaps. 1. MeshLogDao.getLogsOnPort adds a LIMIT and newest-first query (core/database/.../MeshLogDao.kt:76-84), but testGetLogsOnPortSpansNodesAndSkipsExcludedNode… Add a DAO test with multiple matching rows and a small maxItem, including the newest-first assertion; add a real CommonMeshLogRepositoryTest for getInboundRequestLogs with remote/local senders, traceroute and other ports, `want_respon…
Passed Passed checks: 6 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly describes the main change: showing traceroutes that other nodes ran to the local node.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Sibling Call Sites And Presence Semantics Passed The diff does not change a physical measurement field, remove a zero-guard, or add a new field with a zero default. The only null assignment is TelemetricFeature.requestAction; its field was already…
Moved Code Diffed Against Its Original Passed PASS: The pull request does not move or extract an existing type or function. The authoritative diff has no deleted files, renames, copies, or deleted declarations; it adds getInboundRequestLogs and…
Full details: Sibling Call Sites And Presence Semantics

Explanation

The diff does not change a physical measurement field, remove a zero-guard, or add a new field with a zero default. The only null assignment is TelemetricFeature.requestAction; its field was already nullable in the base revision, and the existing consumer checks feature.requestAction != null before invocation. No sibling call site requires an update, and no NodeItem or NodeItemCompact file changed.

Full details: Moved Code Diffed Against Its Original

Explanation

PASS: The pull request does not move or extract an existing type or function. The authoritative diff has no deleted files, renames, copies, or deleted declarations; it adds getInboundRequestLogs and changes one requestAction expression in place. Therefore the moved-code failure conditions do not apply.

Full details: Tests Prove The Path, Not The End State

Explanation

The added DAO test is strong: it uses an in-memory database and asserts the exact surviving UUIDs and order, so it does not only check a count. The added our own history gathers the traces every node ran to us test seeds FakeMeshLogRepository with setLogs(...) and then asserts those seeded entries return through the use case at lines 154-170. This matches the explicit failure condition for tests that seed a fake backing store and assert the value comes back. It does not assert a side effect unique to the intended path.

Resolution

Replace the fake-store round-trip assertion with a test double that records the intended interaction, such as a call counter or mock verification that getInboundRequestLogs(PortNum.TRACEROUTE_APP) is called only for the local node. Cover the exact filtering and ordering with a real repository/DAO test or a focused implementation test rather than relying on FakeMeshLogRepository.setLogs(...) as the source of truth.

Full details: Regression Coverage For Changed Behavior

Explanation

Regression coverage has three gaps. 1. MeshLogDao.getLogsOnPort adds a LIMIT and newest-first query (core/database/.../MeshLogDao.kt:76-84), but testGetLogsOnPortSpansNodesAndSkipsExcludedNode passes Int.MAX_VALUE (MeshLogDaoTest.kt:121-133). The test does not detect a broken limit or the stated limit-before-filter behavior. 2. MeshLogRepositoryImpl.getInboundRequestLogs filters decoded want_response packets and applies the real database Flow (MeshLogRepositoryImpl.kt:140-146). The new use-case test uses FakeMeshLogRepository, so it does not exercise this implementation. A broken production filter could pass. 3. TelemetricActionsSection now removes the TraceRoute request action for local nodes (TelemetricActionsSection.kt:155-161). No UI test verifies that a local node with traceroute logs shows the log action but no trace request action, while a non-local node retains the request action.

Resolution

Add a DAO test with multiple matching rows and a small maxItem, including the newest-first assertion; add a real CommonMeshLogRepositoryTest for getInboundRequestLogs with remote/local senders, traceroute and other ports, want_response true/false, missing packets, ordering, and the 5,000-row boundary if the limit-before-filter contract is required; add a Compose/component test for TelemetricActionsSection that verifies local traceroute logs render navigation only and non-local traceroute rows still render NodeMenuAction.TraceRoute.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 25, 2026
@jamesarich
jamesarich marked this pull request as ready for review October 25, 2026 23:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments: 1
core/testing/src/commonMain/kotlin/org/meshtastic/core/testing/FakeMeshLogRepository.kt: 1

91-92: Trivial · Functional Correctness · Low value

Match the production query order and limit in the fake.

This is a test-fidelity improvement rather than a current production or test failure. The final traceroute history sorts independently, and the existing test uses only three logs. A fixture with more than 5,000 port-and-sender matches can still include older want_response entries that production omits.

Apply the operations in this order: filter by port and sender, sort and limit, then filter want_response.

Suggested fix
+import org.meshtastic.core.repository.MeshLogRepository.Companion.DEFAULT_MAX_LOGS
...
     override fun getInboundRequestLogs(portNum: PortNum): Flow<List<MeshLog>> = logsFlow.map {
         it.filter { log ->
             log.fromNum != MeshLog.NODE_NUM_LOCAL &&
-                log.portNum == portNum.value &&
+                log.portNum == portNum.value
+        }
+            .sortedByDescending(MeshLog::received_date)
+            .take(DEFAULT_MAX_LOGS)
+            .filter { log ->
                 log.fromRadio.packet?.decoded?.want_response == true
-        }
+            }
     }

Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 0e0b15c and 2ce6911.

Files selected for processing: 8
  • core/data/src/commonMain/kotlin/org/meshtastic/core/data/repository/MeshLogRepositoryImpl.kt
  • core/database/src/commonMain/kotlin/org/meshtastic/core/database/dao/MeshLogDao.kt
  • core/database/src/commonTest/kotlin/org/meshtastic/core/database/dao/MeshLogDaoTest.kt
  • core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/MeshLogRepository.kt
  • core/testing/src/commonMain/kotlin/org/meshtastic/core/testing/FakeMeshLogRepository.kt
  • feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/component/TelemetricActionsSection.kt
  • feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/domain/usecase/CommonGetNodeDetailsUseCase.kt
  • feature/node/src/commonTest/kotlin/org/meshtastic/feature/node/domain/usecase/TracerouteHistoryUseCaseTest.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

@jamesarich
jamesarich added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit c4164f2 Oct 26, 2026
14 checks passed
@jamesarich
jamesarich deleted the feat/own-node-traced-by branch October 26, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant