From 9e4217085a5138ebbf04265cc409d4f6fd449633 Mon Sep 17 00:00:00 2001 From: DeFiDude <59237470+DeFiDude@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:11:31 -0600 Subject: [PATCH] Reduce device freeze on large TCP hubs, reduce announce processing overhead --- src/config/Config.h | 2 +- src/main.cpp | 5 +++++ src/reticulum/AnnounceManager.cpp | 10 +++++----- src/reticulum/AnnounceManager.h | 2 +- src/transport/TCPClientInterface.cpp | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/config/Config.h b/src/config/Config.h index cbd2d9f..e04364a 100644 --- a/src/config/Config.h +++ b/src/config/Config.h @@ -50,7 +50,7 @@ #define RATDECK_MAX_ANNOUNCES_PER_SEC 5 // Transport-level rate limit (before Ed25519 verify) // --- Limits --- -#define RATDECK_MAX_NODES 200 // PSRAM allows more +#define RATDECK_MAX_NODES 100 // Endpoint device, not transport node #define RATDECK_MAX_MESSAGES_PER_CONV 100 #define FLASH_MSG_CACHE_LIMIT 20 #define RATDECK_MAX_OUTQUEUE 20 diff --git a/src/main.cpp b/src/main.cpp index e8fad02..59078bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -985,6 +985,11 @@ void loop() { } } + // 4.5 Keep LVGL responsive after heavy RNS processing (announce floods) + if (rnsDuration > LVGL_INTERVAL_MS && powerMgr.isScreenOn()) { + lv_timer_handler(); + } + // 5. Auto-announce every 5-360 minutes (user configured) const unsigned long announceInterval = (unsigned long)userConfig.settings().announceInterval * 60000; // m -> ms if (bootComplete && millis() - lastAutoAnnounce >= announceInterval) { diff --git a/src/reticulum/AnnounceManager.cpp b/src/reticulum/AnnounceManager.cpp index f044084..a186cec 100644 --- a/src/reticulum/AnnounceManager.cpp +++ b/src/reticulum/AnnounceManager.cpp @@ -154,13 +154,13 @@ void AnnounceManager::received_announce( if (!name.empty()) node.name = name; if (!idHex.empty()) node.identityHex = idHex; node.lastSeen = now; - node.hops = RNS::Transport::hops_to(destination_hash); + // hops_to() is expensive (linear routing table scan) — only call for saved contacts + if (node.saved) node.hops = RNS::Transport::hops_to(destination_hash); if (_loraIf) { node.rssi = _loraIf->lastRxRssi(); node.snr = _loraIf->lastRxSnr(); } if (node.saved) _contactsDirty = true; - // Only compute toHex for log + name cache when node actually updated - std::string destHex = destination_hash.toHex(); - Serial.printf("[ANNOUNCE] Update: %s name=\"%s\"\n", destHex.c_str(), name.c_str()); + // Name cache update — skip expensive toHex() for unnamed re-announces if (!name.empty()) { + std::string destHex = destination_hash.toHex(); auto nc = _nameCache.find(destHex); if (nc == _nameCache.end() || nc->second != name) { _nameCache[destHex] = name; @@ -229,7 +229,7 @@ void AnnounceManager::received_announce( node.name = name.empty() ? destHex.substr(0, 12) : name; node.identityHex = idHex; node.lastSeen = millis(); - node.hops = RNS::Transport::hops_to(destination_hash); + // Skip hops_to() for new (unsaved) nodes — resolved when added as contact if (_loraIf) { node.rssi = _loraIf->lastRxRssi(); node.snr = _loraIf->lastRxSnr(); } _hashIndex[key] = (int)_nodes.size(); _nodes.push_back(node); diff --git a/src/reticulum/AnnounceManager.h b/src/reticulum/AnnounceManager.h index 88194a4..1264f7f 100644 --- a/src/reticulum/AnnounceManager.h +++ b/src/reticulum/AnnounceManager.h @@ -73,7 +73,7 @@ private: unsigned long _globalAnnounceWindowStart = 0; unsigned int _globalAnnounceCount = 0; static constexpr unsigned int MAX_GLOBAL_ANNOUNCES_PER_SEC = 10; - static constexpr int MAX_NODES = 200; + static constexpr int MAX_NODES = 100; static constexpr int MAX_NAME_CACHE = 300; static constexpr unsigned long CONTACT_SAVE_INTERVAL_MS = 30000; static constexpr unsigned long ANNOUNCE_MIN_INTERVAL_MS = 200; // Rate-limit announce processing diff --git a/src/transport/TCPClientInterface.cpp b/src/transport/TCPClientInterface.cpp index bd7a797..6b1e9f9 100644 --- a/src/transport/TCPClientInterface.cpp +++ b/src/transport/TCPClientInterface.cpp @@ -83,9 +83,9 @@ void TCPClientInterface::loop() { return; // Will reconnect on next loop iteration } - // Drain multiple incoming frames per loop (up to 15, time-boxed) + // Drain incoming frames per loop (up to 5, time-boxed to prevent announce flood blocking) unsigned long tcpStart = millis(); - for (int i = 0; i < 15 && _client.available() && (millis() - tcpStart < TCP_LOOP_BUDGET_MS); i++) { + for (int i = 0; i < 5 && _client.available() && (millis() - tcpStart < TCP_LOOP_BUDGET_MS); i++) { unsigned long rxStart = millis(); int len = readFrame(); if (len > 0) {