Skip to content

TMM & Warmstore key source naming#11119

Open
NomDeTom wants to merge 6 commits into
meshtastic:developfrom
NomDeTom:tmm-provenance-naming
Open

TMM & Warmstore key source naming#11119
NomDeTom wants to merge 6 commits into
meshtastic:developfrom
NomDeTom:tmm-provenance-naming

Conversation

@NomDeTom

@NomDeTom NomDeTom commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

This pull request updates the documentation and implementation for node information storage, focusing on clarifying and unifying the handling of key provenance, especially the distinction between XEdDSA-signed and manually verified keys. It also standardizes terminology and field names across the codebase and documentation, and updates the persistence and storage descriptions for the various node info tiers.

Key provenance and terminology updates:

  • Documentation in docs/node_info_stores.md now clearly distinguishes between XEdDSA-signed (keyXeddsaSigned) and manually verified (keyManuallyVerified) key provenance for nodes, replacing the previous generic "signer" terminology throughout. The keyProven() predicate now covers both cases, and relevant table entries and descriptions have been updated for clarity. [1] [2] [3] [4]
  • The signer bit in the warm node store and related code has been renamed to "xeddsa-signed" for accuracy, and all comments, log messages, and docstrings now reflect this terminology. [1] [2] [3] [4] [5] [6] [7] [8] [9]

Persistence and storage clarifications:

  • Documentation now specifies that the node database uses LittleFS for persistence, and clarifies the storage locations for the warm tier and cache across different platforms (e.g., PSRAM, heap). [1] [2] [3]

Traffic management and replay gate logic:

  • The signer-provenance gate in docs/traffic_management_module.md is now described as requiring the key to be "proven" (either XEdDSA-signed or manually verified), matching the updated code logic and terminology.

Other improvements:

  • The migration and upgrade logic for the warm node store has been updated to handle the renamed signer bit and ensure compatibility with previous versions. [1] [2]
  • Documentation and inline comments have been clarified to prevent confusion around direct key assignment and cache divergence, and to describe the handling of key provenance in various commit paths. [1] [2]

These changes improve clarity, correctness, and maintainability of both the documentation and implementation for node info storage and provenance handling.

🤝 Attestations

  • I have tested that my proposed changes behave as described.
  • I have tested that my proposed changes do not cause any obvious regressions on the following devices:
    • Heltec (Lora32) V3
    • LilyGo T-Deck
    • LilyGo T-Beam
    • RAK WisBlock 4631
    • Seeed Studio T-1000E tracker card
    • Other (please specify below)

Summary by CodeRabbit

  • Bug Fixes
    • Improved NodeInfo identity trust by separating provenance into two sources: XEdDSA-signed and manually verified.
    • Fixed warm-tier persistence and replay to use the correct XEdDSA-signed provenance bit.
    • Updated direct-serve replay/eviction gating so an identity is treated as proven when either provenance source is present.
  • Documentation
    • Clarified the updated two-bit “key provenance” model and its direct-serve/replay rules.
  • Tests
    • Updated warm-store and Traffic Management test coverage and helpers for the new XEdDSA-signed and manual verification semantics.

@NomDeTom
NomDeTom requested a review from Copilot July 21, 2026 11:13
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

TrafficManagementModule now tracks XEdDSA-signed and manually verified key provenance separately. WarmNodeStore and NodeDB use explicit XEdDSA metadata, while documentation and tests reflect the revised cache, replay-gate, and migration behavior.

Changes

Node-key provenance

Layer / File(s) Summary
Split provenance model
src/modules/TrafficManagementModule.*
NodeInfo cache entries maintain keyXeddsaSigned and keyManuallyVerified, with keyProven() combining them for reconciliation, cache access, eviction, and direct-response gating.
Warm-tier XEdDSA metadata
src/mesh/WarmNodeStore.*, test/test_warm_store/test_main.cpp
Warm-tier packing, accessors, APIs, migration normalization, and tests use the XEdDSA-signed bit.
NodeDB warm-tier integration
src/mesh/NodeDB.*
Warm-tier signer checks and node rehydration read XEdDSA-signed metadata.
Documentation and replay validation
docs/*, src/mesh/Router.cpp, test/test_traffic_management/test_main.cpp
Trust, replay-gating, anti-entropy, persistence, PKI-boundary descriptions, and provenance tests reflect the updated model.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant NodeInfoPacket
  participant TrafficManagementModule
  participant NodeDB
  NodeInfoPacket->>TrafficManagementModule: deliver key and signature state
  TrafficManagementModule->>NodeDB: request signer or manual verification state
  NodeDB-->>TrafficManagementModule: return provenance state
  TrafficManagementModule->>TrafficManagementModule: evaluate keyProven()
Loading

Possibly related PRs

Suggested reviewers: caveman99, thebentern

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related but too generic to identify the main change clearly. Use a more specific title, such as "Split node key provenance into xeddsa-signed and manually verified bits".
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description is substantive and on-topic, but it omits the template's attestations/testing checklist section.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@NomDeTom NomDeTom added tech debt Code or lib references that are not up to date or propper standards cleanup Code cleanup or refactor labels Jul 21, 2026

Copilot AI 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.

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Unifies key provenance terminology across implementation and docs by replacing the ambiguous “signer” concept with explicit XEdDSA-signed vs manually-verified provenance, and updates warm-store persistence/migration notes accordingly.

Changes:

  • Renames warm-store “signer” bit to “xeddsa-signed” and updates related APIs, tests, comments, and logs.
  • Splits TMM NodeInfo cache provenance into keyXeddsaSigned and keyManuallyVerified, with a combined keyProven() predicate.
  • Updates documentation to clarify storage/persistence details (LittleFS, PSRAM/heap) and provenance gates.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/test_warm_store/test_main.cpp Updates tests to use renamed warm-store XEdDSA-signed bit accessors/params.
test/test_traffic_management/test_main.cpp Updates traffic-management tests and mock helpers for renamed provenance param naming.
src/modules/TrafficManagementModule.h Splits provenance flags and adds keyProven() helper predicate.
src/modules/TrafficManagementModule.cpp Updates eviction/gates and reconcile logic to use combined provenance and re-seed manual verification.
src/mesh/WarmNodeStore.h Renames on-disk “signer” metadata bit to explicit XEdDSA-signed naming in API and helpers.
src/mesh/WarmNodeStore.cpp Updates persistence/migration logic and logging for renamed warm-store bit.
src/mesh/NodeDB.h / src/mesh/NodeDB.cpp Updates warm-store signer queries/carry-over to new hasXeddsaSigned naming and accessor.
docs/traffic_management_module.md / docs/node_info_stores.md Updates docs to reflect new provenance model and persistence/storage clarifications.

Comment thread src/modules/TrafficManagementModule.cpp
Comment thread src/modules/TrafficManagementModule.cpp Outdated
Comment thread src/modules/TrafficManagementModule.cpp Outdated
Comment thread src/modules/TrafficManagementModule.cpp
Comment thread docs/node_info_stores.md Outdated
Comment thread src/modules/TrafficManagementModule.cpp
Comment thread test/test_traffic_management/test_main.cpp Outdated

@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)
test/test_traffic_management/test_main.cpp (1)

110-112: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep the helper comment within the two-line limit.

The updated comment occupies three lines. Please condense it while retaining the XEdDSA terminology. As per coding guidelines, comments must be minimal and limited to one or two lines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_traffic_management/test_main.cpp` around lines 110 - 112, Condense
the helper comment above the full-identity seed setup to no more than two lines,
preserving the XEdDSA terminology and the key details about the hot-store index
and reconcile/seeding tests.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/test_traffic_management/test_main.cpp`:
- Around line 110-112: Condense the helper comment above the full-identity seed
setup to no more than two lines, preserving the XEdDSA terminology and the key
details about the hot-store index and reconcile/seeding tests.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d510b3d5-ed8e-4c6a-b009-10818ba11c9f

📥 Commits

Reviewing files that changed from the base of the PR and between 5671620 and 93acc79.

📒 Files selected for processing (4)
  • docs/node_info_stores.md
  • src/modules/TrafficManagementModule.cpp
  • src/modules/TrafficManagementModule.h
  • test/test_traffic_management/test_main.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/modules/TrafficManagementModule.h
  • docs/node_info_stores.md
  • src/modules/TrafficManagementModule.cpp

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Flash this PR in the Web Flasher

firmware commit boards expires

Warning

This is an automated, unreviewed CI test build. Back up your device configuration
before flashing, and only flash devices you are able to recover.

Supported boards built by this PR (30)
Device Board Platform
Crowpanel Adv 3.5 TFT elecrow-adv-35-tft esp32-s3
Heltec HT62 heltec-ht62-esp32c3-sx1262 esp32-c3
Heltec Mesh Node 096 heltec-mesh-node-t096 nrf52840
Heltec Mesh Node T1 heltec-mesh-node-t1 nrf52840
Heltec Mesh Node T114 heltec-mesh-node-t114 nrf52840
Heltec V3 heltec-v3 esp32-s3
Heltec V4 heltec-v4 esp32-s3
Meshnology W10 meshnology_w10 esp32-s3
Raspberry Pi Pico pico rp2040
Raspberry Pi Pico W picow rp2040
RAK WisMesh Pocket V3 rak_wismesh_pocket nrf52840
RAK WisMesh Pod rak_wismesh_pod nrf52840
RAK WisMesh Repeater Mini V2 rak_wismesh_repeater_mini nrf52840
RAK WisMesh Tag rak_wismeshtag nrf52840
RAK WisBlock 11200 rak11200 esp32
RAK WisBlock 11310 rak11310 rp2040
RAK3312 rak3312 esp32-s3
RAK WisBlock 4631 rak4631 nrf52840
Seeed SenseCAP Mesh-Tracker-X1 seeed_mesh_tracker_X1 nrf52840
Seeed Wio Tracker L1 seeed_wio_tracker_L1 nrf52840
Seeed Xiao NRF52840 Kit seeed_xiao_nrf52840_kit nrf52840
Seeed Xiao ESP32-S3 seeed-xiao-s3 esp32-s3
Station G2 station-g2 esp32-s3
Station G3 station-g3 esp32-s3
LILYGO T-Deck t-deck-tft esp32-s3
LILYGO T-Echo t-echo nrf52840
LILYGO T-Echo Plus t-echo-plus nrf52840
LILYGO T-Impulse Plus t-impulse-plus nrf52840
LilyGo T3-C6 tlora-c6 esp32-c6
Seeed SenseCAP T1000-E tracker-t1000-e nrf52840

Build artifacts expire on 2026-08-22. Updated for acd27f9.

Copilot AI 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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (2)

docs/node_info_stores.md:36

  • This section still refers to the warm rehydration carrying a "signer bit" and the hot store as the source of "signer provenance". With the terminology update in this PR, these should be updated to "XEdDSA-signed bit" and more generally "key provenance" for consistency and to avoid mixing old/new terms.
  the node's essentials are **absorbed into the warm tier** (see §2); on re-admission the
  warm record is rehydrated back (`take()`), including the signer bit.
- **Persistence:** the node database file in LittleFS, saved on the usual NodeDB cadence.
- **Authority:** key pinning (`updateUser`'s "Public Key mismatch" drop), signer
  provenance, and identity content all originate here. The lookup helpers that other

docs/node_info_stores.md:62

  • This warm-tier bullet still says it restores "role/protected/signer bits", but the field being restored is specifically the XEdDSA-signed bit. Updating the wording improves clarity, especially now that "key provenance" can also include manual verification in other tiers.
- **Persistence:** nRF52840 uses a 12 KB raw-flash record-ring below LittleFS
  (append/replay/compact); everywhere else `/prefs/warm.dat` (LittleFS).
- **Membership invariant:** a node lives in the hot **XOR** warm tier. `take()` removes
  the warm record when the node is re-admitted hot, restoring role/protected/signer bits.

Comment thread src/modules/TrafficManagementModule.h Outdated
Comment thread src/modules/TrafficManagementModule.h Outdated
Comment thread src/modules/TrafficManagementModule.cpp Outdated
Comment thread src/modules/TrafficManagementModule.cpp
Comment thread docs/traffic_management_module.md Outdated
Comment thread src/modules/TrafficManagementModule.cpp Outdated
@NomDeTom

Copy link
Copy Markdown
Collaborator Author

@caveman99 the copilot stuff is just nitpicks, right?

@caveman99

Copy link
Copy Markdown
Member

@caveman99 the copilot stuff is just nitpicks, right?

It's a bit more - 4 of them are outdated comments, one is a semantic thing. functionality is not reflected in the name. It's not a bug, just makes maintenance harder.

NomDeTom and others added 4 commits July 22, 2026 10:26
- Log line now says "not key-proven" (gate is XEdDSA OR manual, not just signer)
- Rename markKeySignerProvenForTest -> markKeyXeddsaSignedForTest (sets only the XEdDSA bit)
- Docs + test comments: "signer bit" -> "XEdDSA-signed bit"

clod helped too
Address PR meshtastic#11119 review: the copyPublicKey()/copyUser() out-parameter and
the cache-path replay gate now report entry->keyProven() (XEdDSA-signed OR
manually verified), so the "signerProven" name and "signer-proven" comments
were misleading. Rename the public out-param to keyProven, the local
cachedKeySignerProven to cachedKeyProven, and update coupled callers, log
strings, docs headings, and comments to say "key-proven".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@NomDeTom
NomDeTom force-pushed the tmm-provenance-naming branch from 93acc79 to 1bad60f Compare July 22, 2026 09:36
@NomDeTom
NomDeTom requested a review from Copilot July 22, 2026 09:38

@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)
src/mesh/Router.cpp (1)

818-822: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Shorten this comment to the essential trust boundary.

The PKI provenance rationale is useful, but this five-line comment exceeds the project’s one-or-two-line comment guideline and includes implementation detail. Preserve the non-obvious security constraint concisely:

Proposed revision
-        // Resolve the sender's key only for actual PKI-decrypt candidates, not every encrypted channel
-        // packet: copyPublicKeyForDecrypt() can fall through to a linear scan of TrafficManagement's large
-        // NodeInfo cache. It returns authoritative keys (hot/warm), or a cold-tier cache key only when it is
-        // key-proven - an unverified TOFU cache key must not back authenticated (pki_encrypted, p->from)
-        // DM attribution.
+        // Resolve the sender key only for PKI candidates; this lookup may scan the NodeInfo cache.
+        // Only authoritative or key-proven cache keys may back PKI sender attribution.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mesh/Router.cpp` around lines 818 - 822, Shorten the comment immediately
above the sender-key resolution logic to one or two lines, preserving only the
trust boundary: resolve keys for actual PKI-decrypt candidates, and never use
unverified TOFU cache keys for authenticated DM attribution. Remove the scan and
cache-tier implementation details.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/mesh/Router.cpp`:
- Around line 818-822: Shorten the comment immediately above the sender-key
resolution logic to one or two lines, preserving only the trust boundary:
resolve keys for actual PKI-decrypt candidates, and never use unverified TOFU
cache keys for authenticated DM attribution. Remove the scan and cache-tier
implementation details.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a3fbb4f-debf-41de-8f31-48c373486a8b

📥 Commits

Reviewing files that changed from the base of the PR and between 93acc79 and 1bad60f.

📒 Files selected for processing (11)
  • docs/node_info_stores.md
  • docs/traffic_management_module.md
  • src/mesh/NodeDB.cpp
  • src/mesh/NodeDB.h
  • src/mesh/Router.cpp
  • src/mesh/WarmNodeStore.cpp
  • src/mesh/WarmNodeStore.h
  • src/modules/TrafficManagementModule.cpp
  • src/modules/TrafficManagementModule.h
  • test/test_traffic_management/test_main.cpp
  • test/test_warm_store/test_main.cpp
🚧 Files skipped from review as they are similar to previous changes (9)
  • docs/traffic_management_module.md
  • src/mesh/WarmNodeStore.cpp
  • src/mesh/NodeDB.h
  • src/modules/TrafficManagementModule.h
  • src/mesh/WarmNodeStore.h
  • test/test_warm_store/test_main.cpp
  • src/mesh/NodeDB.cpp
  • src/modules/TrafficManagementModule.cpp
  • test/test_traffic_management/test_main.cpp

Copilot AI 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.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Comment thread src/modules/TrafficManagementModule.cpp
Comment thread src/modules/TrafficManagementModule.cpp
Comment thread docs/node_info_stores.md
Comment thread docs/node_info_stores.md Outdated
Comment thread src/modules/TrafficManagementModule.cpp

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/modules/TrafficManagementModule.cpp (1)

1502-1509: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stale macro reference in comment.

The comment says "See TMM_NODEINFO_REPLAY_REQUIRE_SIGNED" but the actual guard on line 1502 is TMM_NODEINFO_REPLAY_SIGNED_GATE. This looks like a leftover reference from before the gate was renamed. Per the PR's own thread, this is exactly the kind of outdated-comment issue that "make[s] maintenance harder" even though it isn't a functional bug.

🧹 Suggested fix
-    // usedFallback entries were already gated above. See TMM_NODEINFO_REPLAY_REQUIRE_SIGNED.
+    // usedFallback entries were already gated above. See TMM_NODEINFO_REPLAY_SIGNED_GATE.

Based on the PR objectives note that Caveman99 confirmed several comments in this PR are outdated and "not bugs but make maintenance harder."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/modules/TrafficManagementModule.cpp` around lines 1502 - 1509, Update the
comment above the guard in the TMM_NODEINFO_REPLAY_SIGNED_GATE block to
reference TMM_NODEINFO_REPLAY_SIGNED_GATE instead of the stale
TMM_NODEINFO_REPLAY_REQUIRE_SIGNED macro name; leave the guard logic unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/modules/TrafficManagementModule.cpp`:
- Around line 1502-1509: Update the comment above the guard in the
TMM_NODEINFO_REPLAY_SIGNED_GATE block to reference
TMM_NODEINFO_REPLAY_SIGNED_GATE instead of the stale
TMM_NODEINFO_REPLAY_REQUIRE_SIGNED macro name; leave the guard logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 46d783e7-fcad-454e-8102-32bacd933614

📥 Commits

Reviewing files that changed from the base of the PR and between 1bad60f and 94f19ce.

📒 Files selected for processing (4)
  • docs/node_info_stores.md
  • src/modules/TrafficManagementModule.cpp
  • test/test_traffic_management/test_main.cpp
  • test/test_warm_store/test_main.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/test_warm_store/test_main.cpp

@NomDeTom
NomDeTom force-pushed the tmm-provenance-naming branch from 94f19ce to af82974 Compare July 22, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup Code cleanup or refactor tech debt Code or lib references that are not up to date or propper standards

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants