fix: accept new nodeNum on reboot and fix isLocked desync#2106
Conversation
When the firmware reboots with a different nodeNum but the same device_id, accept the new nodeNum instead of rejecting it. The old approach caused identity mismatches because the firmware was already broadcasting on the new nodeNum while MeshMonitor kept using the old one. Also fix a desync where node names changed outside MeshMonitor (e.g., via the Meshtastic app) were never picked up because the isLocked flag on localNodeInfo blocked updates from NodeInfo packets — the authoritative source for node identity. Now processNodeInfoProtobuf always updates localNodeInfo regardless of isLocked state, and refreshNodeDatabase clears the lock before requesting fresh config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Claude finished @Yeraze's task —— View job Code Review Complete ✅I've thoroughly analyzed the PR changes. Here's my comprehensive feedback:
Overall AssessmentThis is a well-implemented fix that addresses real protocol synchronization issues. The solution properly handles Meshtastic firmware behavior and maintains data integrity. 🟢 Strengths1. Sound Architecture Decision
2. Robust Merge Strategy (
3. Excellent Test Coverage
🟡 Areas for Improvement1. Error Handling in Async Operations // Current (line 2935-2942)
setTimeout(async () => {
try {
await this.sendRemoveNode(prevNumToRemove);
} catch (err) {
logger.warn(`⚠️ Could not remove old nodeNum...`, err);
}
}, 5000);Issue: If 2. Magic Numbers setTimeout(async () => {
// ...cleanup logic
}, 5000); // Why 5 seconds?Suggestion: Extract to named constant: 3. Type Safety ( firmwareVersion: (newNode as any)?.firmwareVersion || (oldNode as any)?.firmwareVersion || undefined,Issue: Using 🔵 Minor Issues1. Logging Consistency
2. Test Organization
🟢 Security & PerformanceSecurity: ✅ Clean
Performance: ✅ Acceptable
🔍 Potential Edge Cases
📋 Recommendations Before Merge
✅ VerdictAPPROVE - This PR solves real synchronization issues with a thoughtful approach. The benefits far outweigh the minor improvements suggested above. The code quality is high and the test coverage is comprehensive. The solution correctly handles the fundamental challenge of keeping MeshMonitor's state synchronized with firmware that can change its identity autonomously. |
Summary
isLockedflag onlocalNodeInfowas blocking updates fromprocessNodeInfoProtobuf— the authoritative source for node identity.Changes
src/server/meshtasticManager.tsprocessMyNodeInfosame-device-reboot branch (~line 2876): Rewritten from "reject new nodeNum" to "accept + merge". Fetches old node data, merges metadata into the new node entry (new node's data takes priority), deletes the old ghost, updates settings, clearsinitConfigCache, and schedules a deferredsendRemoveNodeto clean up the old nodeNum from the physical device's NodeDB.processNodeInfoProtobuf(~line 5608): Removed the!isLockedguard so NodeInfo always updateslocalNodeInfofor the local node. NodeInfo is the device's source of truth for names — the lock should only preventprocessMyNodeInfo(which doesn't carry names) from overwriting with incomplete data. Adds an info log when names change.refreshNodeDatabase(~line 11737): ClearsisLockedbefore sendingwant_config_idsoprocessMyNodeInfocan also run during manual refresh to update hwModel, rebootCount, etc.src/server/meshtasticManager.test.tssimulateProcessMyNodeInfohelper: newmerged_and_acceptedaction replacesrejected_new_nodenumTest plan
npx vitest run— 2771 tests passed (4 new)tests/system-tests.sh— run before merge🤖 Generated with Claude Code