MeshCore bearer: end-to-end reliability over the flood (#26) - #163
Merged
Conversation
Channel messages are fire-and-forget floods with no link ACK, so DAPPS adds its own datagram-style reliability (NOT a session): the receiver ACKs any data message addressed to it (a tiny mc-ack control broadcast), the sender resends unacked messages on exponential backoff until acked or their lifetime expires, and the receiver dedups by message id so a resend after a lost ACK is delivered to the app only once. Resends/ACKs are ordinary channel traffic (governor + adaptive apply). - MeshCoreReliability: pending-table bookkeeping (Track/OnAck/DueResends/MarkResent/ DropExpired) + ACK build/detect. - MeshCoreInbound: receiver-side idempotency (delivered-ids dedup), unconditional ACK consumption, ACK generation for messages addressed to us. - MeshCoreCompanionBackhaul: SendCoreAsync + ResendAsync (bypasses coalescing); tracks sent data messages. - MeshCoreBearer: resend loop; DAPPS_MESHCORE_RELIABLE_DELIVERY config. Fixes from an adversarial review of the reliability code: - Idempotency was missing (the existing inbox flood-dedup is gated on FloodHopsRemaining, which these messages don't carry) -> added receiver dedup. - Resends no longer burn backoff slots when refused by congestion/budget (DueResends peeks; MarkResent advances only on a real send). - TxBudget refund is now token-based (concurrent sends can't refund each other's reservations); ToFrames nonce made thread-safe (now called concurrently). - Transport _compressed map no longer leaks entries for incomplete reassemblies. - ACKs consumed unconditionally; failed ACK sends logged. Tests: 21 MeshCore unit tests. On-air soak with 40% induced loss: delivered==distinct (no duplicate app delivery), lost messages recovered by resend+ACK, nothing expired. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KLbwvhE2cKCe8WPZNg8k17
This was referenced Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
End-to-end reliability (#26) for the MeshCore bearer. The channel is a fire-and-forget flood with no link ACK, so DAPPS adds its own — datagram-style, not a session (no handshake, no window, no ordered stream).
How it works
mc-ackcontrol broadcast).DAPPS_MESHCORE_RELIABLE_DELIVERY(defaulttrue).Adversarial-review fixes folded in
FloodHopsRemaining, which these messages don't carry, so resends were double-delivering. Added an explicit receiver-side delivered-ids dedup.DueResendspeeks;MarkResentadvances only on a real send).TxBudgetrefund is token-based (concurrent sends can't refund each other's reservations);ToFramesnonce made thread-safe (now called concurrently by OMM send + resend loop + inbound ACKs)._compressedmap no longer leaks for incomplete reassemblies.Validation
delivered == distinct(no duplicate app delivery), lost messages recovered by resend+ACK, nothing expired.Builds on #162. Inert unless
MeshCoreEnabled=true.🤖 Generated with Claude Code
https://claude.ai/code/session_01KLbwvhE2cKCe8WPZNg8k17