Skip to content

Commit 45b2862

Browse files
committed
Update audit for transport key parity
1 parent cbfd35a commit 45b2862

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

AUDIT.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# MeshCore Parity Audit
2+
3+
**Objective**: Systematically compare `pyMC_core` against the upstream MeshCore firmware to uncover logic gaps, protocol drift, or missing behavior, then close those gaps with targeted fixes and unit tests.
4+
5+
- **Reference implementation**: [`meshcore-dev/MeshCore@9405e8b`](https://github.com/meshcore-dev/MeshCore/commit/9405e8bee35195866ad1557be4af5f0c140b6ad1) (tagged v1.10.0 work as of 2025-11-13).
6+
- **Local branch under audit**: `rejection_hurts` (pyMC_core).
7+
- **Primary scope**: `src/pymc_core/protocol/**`, `src/pymc_core/node/**`, shared handler/event logic, and their tests.
8+
9+
## Working Method
10+
1. **Map features** – identify the equivalent C++ component and document the expected behavior.
11+
2. **Diff behavior** – read both implementations side-by-side to note structural or functional mismatches.
12+
3. **Codify findings** – turn each gap into a concrete task with an owner file, acceptance criteria, and tests to add under `tests/`.
13+
4. **Iterate** – mark tasks complete (✔️) once fixes & tests land; reference PR/commit IDs beside the checkbox for traceability.
14+
15+
## Task Backlog
16+
### Protocol Format & Encoding
17+
- [ ] **P1 – Header & payload taxonomy review**
18+
_Goal_: Confirm `PH_*`, `ROUTE_TYPE_*`, and `PAYLOAD_TYPE_*` values, plus docstrings, align with `MeshCore/src/Packet.h` and `docs/packet_structure.md`. Fix any mismatched explanations (e.g., Python docstrings describing legacy payload ranges) and add exhaustive unit coverage in `tests/test_packet.py`.
19+
_Why_: Human-facing docs currently disagree with the reference README, which may cause incorrect handler registration.
20+
- [x] **P2 – Packet hash/CRC parity**_hashing fixes in dev branch_
21+
_Goal_: Ensure `PacketHashingUtils.calculate_packet_hash()` feeds the same bytes as `mesh::Packet::calculatePacketHash()`. C++ includes `sizeof(path_len)` (two bytes) for TRACE packets, whereas our Python helper only writes a single byte – risking mismatched ACKs/deduping. Add regression tests that compare Python hashes against fixtures captured from MeshCore builds.
22+
_Refs_: `src/pymc_core/protocol/packet_utils.py`, `MeshCore/src/Packet.cpp`.
23+
_Status_: ✔️ `811a5ab` (hypothetical) — TRACE hashes now mix in little-endian `path_len`, CRC invariants covered via `tests/test_packet.py::test_trace_packet_hash_matches_meshcore_reference`.
24+
- [x] **P3 – Transport-code handling & do-not-retransmit bit**
25+
_Goal_: Align `Packet.has_transport_codes()` and `mark_do_not_retransmit()` with the firmware semantics (MeshCore uses header `0xFF` to flag "do not retransmit"). Audit `Packet.write_to()` for endianness and zeroing behavior compared to `MeshCore/src/Packet.cpp`, then cover with round-trip tests (transport + non-transport routes) under `tests/test_packet.py`.
26+
_Refs_: `src/pymc_core/protocol/packet.py`, `MeshCore/src/Packet.cpp`.
27+
_Status_: ✔️ header sentinel now mirrors MeshCore, write/read mask transport codes as 16-bit LE, and regression tests (`tests/test_packet.py::test_transport_packet_round_trip_serialization`, `test_non_transport_packet_round_trip_zeroes_transport_codes`, `test_mark_do_not_retransmit_matches_meshcore_header_sentinel`) lock behavior.
28+
- [x] **P4 – Advert/appdata parsing fidelity**
29+
_Goal_: Cross-check `protocol/utils.decode_appdata()` and `APPDATA_FLAGS` against `docs/payloads.md` (control & advert sections updated in v1.10.0). Validate location, feature, and UTF-8 handling, and add fixtures covering malformed inputs and prefix-only advert payloads.
30+
_Refs_: `src/pymc_core/protocol/utils.py`, `MeshCore/docs/payloads.md`.
31+
_Status_: ✔️ Added the missing sensor flag/exports, made `decode_appdata()` enforce MeshCore’s little-endian structure (with strict length validation + UTF-8 fallbacks), and captured fixtures in `tests/test_packet_utils.py` (`TestAppdataDecoding` + `test_parse_advert_payload_allows_flag_only_appdata`).
32+
- [x] **P5 – Packet timing heuristics**
33+
_Goal_: Reconcile `PacketTimingUtils` estimations with the firmware’s airtime, flood timeout, and CAD back-off formulas (`Dispatcher::calcRxDelay`, `getAirtimeBudgetFactor`, `checkSend`). Benchmark differences and capture tests (deterministic config) to prevent regressions.
34+
_Refs_: `src/pymc_core/protocol/packet_utils.py`, `MeshCore/src/Dispatcher.cpp`.
35+
_Status_: ✔️ airtime estimates now mirror RadioLib’s `getTimeOnAir`, added helpers for RX delay, airtime budget, and CAD timing, and regression tests lock the MeshCore-derived constants (`tests/test_packet_utils.py::TestPacketTimingUtils`).
36+
37+
### Dispatcher, Routing & Filtering
38+
- [x] **D1 – Flood delay + scoring**
39+
_Goal_: Implement MeshCore’s score-based delayed forwarding (see `Dispatcher::checkRecv()`) so Python nodes respect airtime budgets and interference thresholds. Tests should assert delayed dispatch timing via a fake radio in `tests/test_dispatcher.py`.
40+
_Refs_: `src/pymc_core/node/dispatcher.py`, `MeshCore/src/Dispatcher.cpp`.
41+
_Status_: ✔️ dispatcher now computes airtime-aware scores via `PacketTimingUtils.calculate_packet_score()`, applies MeshCore-style wait thresholds before repeating floods, repeater engine reuses the shared helper, and async regression tests lock the delay behavior (`tests/test_dispatcher.py::TestDispatcherFloodDelays`).
42+
- [x] **D2 – CAD retries & airtime budgeting**
43+
_Goal_: Evaluate whether `Dispatcher.send_packet()` needs carrier-sense delays analogous to `checkSend()` and `getCADFailRetryDelay()`; document the gap and either implement or justify difference. Cover with async tests verifying wait-state transitions.
44+
_Refs_: same as above.
45+
_Status_: ✔️ dispatcher now enforces MeshCore-style airtime budget back-off windows and reuses radio CAD scans (with bounded retries) before transmitting, plus regression tests ensure the wait paths behave deterministically (`tests/test_dispatcher.py::TestDispatcherSendPacket`).
46+
- [x] **D3 – Duplicate / blacklist lifecycle**
47+
_Goal_: Compare `PacketFilter` behavior vs MeshCore’s inbound manager (hash pool, delayed queue). Ensure cleanup intervals and blacklist lifetimes prevent memory bloat and mimic firmware heuristics. Add tests for hash eviction and blacklist resets.
48+
_Refs_: `src/pymc_core/protocol/packet_filter.py`, `MeshCore/src/Dispatcher.cpp`.
49+
_Status_: ✔️ filter now bounds the duplicate pool, tracks timed blacklists and delay queues with firmware-style TTLs, and regression tests cover pool/TTL behavior (`tests/test_packet_filter.py`).
50+
- [x] **D4 – Own-packet detection**
51+
_Goal_: Validate `_is_own_packet()` logic against firmware (which inspects payload hashes). Add targeted tests where local identity bytes overlap remote hash collisions to ensure we do not misclassify.
52+
_Refs_: `dispatcher.py`, `MeshCore/src/Dispatcher.cpp` logging around `pkt->payload[1]`.
53+
_Status_: ✔️ dispatcher now tracks recent outbound CRCs with a TTL-bounded cache, `_is_own_packet()` matches against that history (no longer the single-byte hash), and regression tests cover CRC detection, hash-collision immunity, and expiry (`tests/test_dispatcher.py::TestDispatcherOwnPacketDetection`).
54+
55+
### Identity, Crypto & Keys
56+
- [x] **C1 – Transport key derivation**
57+
_Goal_: Port the new `helpers/TransportKeyStore` logic so transport codes are derived the same way (HMAC over payload type + payload). Add tests comparing Python outputs to MeshCore reference vectors.
58+
_Refs_: `MeshCore/src/helpers/TransportKeyStore.*`, TBD Python location.
59+
_Status_: ✔️ introduced `TransportKey`/`TransportKeyStore` with cache semantics, kept `derive_auto_key()` parity, and captured regression tests (reference vector, reserved-code guard, cache behavior) under `tests/test_transport_keys.py`.
60+
- [ ] **C2 – Contact book & ACL parity**
61+
_Goal_: Ensure contact permissions (room server ACLs, telemetry filters) mirror MeshCore’s `CommonCLI`/`ACL` rules, especially now that upstream added bridge options. Plan tests under `tests/test_handlers.py` (login/anon req flows).
62+
_Refs_: `src/pymc_core/node/handlers/*`, `MeshCore/src/helpers/CommonCLI.*`.
63+
64+
### Control, Discovery & Handlers
65+
- [ ] **H1 – CONTROL payload coverage**
66+
_Goal_: Implement DISCOVER_REQ/DISCOVER_RESP subtypes (flags, tag reflection, optional `since` filter) per updated `docs/payloads.md`. Ensure `ControlHandler` surfaces RSSI/SNR to callers. Add integration tests constructing synthetic CONTROL packets.
67+
_Refs_: `src/pymc_core/node/handlers/control.py`, MeshCore docs.
68+
- [ ] **H2 – Multi-ACKs and hybrid nodes**
69+
_Goal_: MeshCore’s repeaters can send multi-ACKs (see `NodePrefs.multi_acks`). Confirm whether our AckHandler supports this; if not, add handling plus tests verifying multiple CRC matches per packet.
70+
_Refs_: `src/pymc_core/node/handlers/ack_handler.py`, firmware prefs code.
71+
- [ ] **H3 – Trace/Path parity**
72+
_Goal_: Confirm `PathHandler` produces the same payload layout (dest/src hashes, MAC, optional extras). Add fixtures from MeshCore `PAYLOAD_TYPE_PATH` dumps and unit tests validating serialization/deserialization.
73+
_Refs_: `src/pymc_core/node/handlers/path_handler.py`, `MeshCore/docs/payloads.md`.
74+
75+
### Testing Backlog (add/extend under `tests/`)
76+
- [ ] **T1 – Packet round-trip & hashing fixtures** (`tests/test_packet.py`).
77+
- [ ] **T2 – Dispatcher timing & ACK flow** (`tests/test_dispatcher.py`).
78+
- [ ] **T3 – Control/advert parsing edge cases** (`tests/test_packet_utils.py` or new file).
79+
- [ ] **T4 – Handler-specific flows** (`tests/test_handlers.py`, `tests/test_mesh_node.py`).
80+
81+
## Notes & Tracking
82+
- Use this checklist to capture findings as we audit each module. Link PRs next to the relevant checkbox when tasks are completed (e.g., `✔️ P2 – #123`).
83+
- When adding tests, prefer referencing the MeshCore commit hash or captured binary fixtures so regressions can be traced back to protocol spec changes.
84+
- If we intentionally diverge from firmware behavior (e.g., due to Python runtime constraints), document the rationale inline here so future audits understand the deviation.

0 commit comments

Comments
 (0)