From ac581fccda8d77fb968e9ee45dcf827f4ae6f66e Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Tue, 12 May 2026 09:25:31 -0600 Subject: [PATCH] spec(routing): align path-learning with upstream and document PATH_RETURN delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes: 1. CORRECTION. The path-learning subsection previously described the reference implementation's path-replacement as "replace only if the new path's hash size is not smaller and SNR is not materially worse" — but upstream's BaseChatMesh::onContactPathRecv() does an UNCONDITIONAL replace, with an inline comment flagging hash-size/ SNR selection as future work. The spec now reflects upstream's actual behavior and notes that quality heuristics are an implementation extension, not a reference-implementation behavior. Likewise, removed the implication that the reference implementation has a cached-path TTL — it doesn't. 2. ADDITION. Document PATH_RETURN scheduling delay (TXT_ACK_DELAY=200ms default in upstream BaseChatMesh.cpp:9), with the rationale of spacing PATH_RETURN, ACK, and reply across distinct slots. Validated against upstream meshcore-dev/MeshCore @ 1a7b361 (BaseChatMesh.cpp:304-307 unconditional replace; cpp:228, 255 TXT_ACK_DELAY-spaced PATH_RETURN emission). Co-Authored-By: Claude Opus 4.7 (1M context) --- spec/17-routing.md | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/spec/17-routing.md b/spec/17-routing.md index c575567..8b25bfd 100644 --- a/spec/17-routing.md +++ b/spec/17-routing.md @@ -112,14 +112,20 @@ parameters (timeouts, queue sizes, retry counts) are implementation-defined. `path` field records the hops the packet traversed. The receiving node SHOULD cache the **reversed** path keyed by the peer's source hash and subsequently use that cached path to send direct-routed traffic back. -- When multiple paths are observed for the same peer, implementations SHOULD - prefer the higher-quality path. The reference implementation's heuristic is - to replace the cached path only if the new path's hash size is not smaller - and its SNR is not materially worse than the cached path's SNR. The exact - threshold is implementation-defined. -- Cached paths SHOULD expire after a period of inactivity; they MAY be - refreshed whenever a new packet is observed from the same peer. The - reference implementation does not persist paths across reboots. +- When multiple paths are observed for the same peer, the **reference + implementation unconditionally replaces** the cached path with the most + recently observed one (`BaseChatMesh::onContactPathRecv()` in + `src/helpers/BaseChatMesh.cpp` — its source comment explicitly flags + hash-size or SNR-based selection as future work). Implementations MAY + layer a quality heuristic on top (e.g., prefer larger hash sizes or + better SNR margin) if they store and compare multiple candidate paths, + but this is not part of the reference behavior and the exact policy is + implementation-defined. +- Cached paths in the reference implementation do **not** expire on a + timer; they live as long as the contact entry, and are overwritten + whenever a fresher path is observed. Implementations MAY add a TTL or + age-based eviction policy as an extension. The reference implementation + does not persist paths across reboots. #### PATH_RETURN @@ -130,6 +136,12 @@ sender learn a direct return path before its first reply, converting subsequent traffic from flood to direct routing. See `BaseChatMesh::onPeerDataRecv()` and `Mesh::createPathReturn()`. +The reference implementation schedules the PATH_RETURN transmission with a +small delay (`TXT_ACK_DELAY`, default 200 ms) to avoid colliding with other +packets the receiver is about to emit. Exact timing is +implementation-defined; the goal is to space PATH_RETURN, ACK, and any +application reply across distinct on-air slots. + #### Flood Fallback and Retries - A sender SHOULD track outstanding DMs by their expected `ack_crc`