@@ -1638,13 +1638,32 @@ void NodeDB::addFromContact(meshtastic_SharedContact contact)
16381638 // If should_ignore is set,
16391639 // we need to clear the public key and other cruft, in addition to setting the node as ignored
16401640 info->is_ignored = true ;
1641+ info->is_favorite = false ;
16411642 info->has_device_metrics = false ;
16421643 info->has_position = false ;
16431644 info->user .public_key .size = 0 ;
16441645 info->user .public_key .bytes [0 ] = 0 ;
16451646 } else {
1646- info->last_heard = getValidTime (RTCQualityNTP);
1647- info->is_favorite = true ;
1647+ /* Clients are sending add_contact before every text message DM (because clients may hold a larger node database with
1648+ * public keys than the radio holds). However, we don't want to update last_heard just because we sent someone a DM!
1649+ */
1650+
1651+ /* "Boring old nodes" are the first to be evicted out of the node database when full. This includes a newly-zeroed
1652+ * nodeinfo because it has: !is_favorite && last_heard==0. To keep this from happening when we addFromContact, we set the
1653+ * new node as a favorite, and we leave last_heard alone (even if it's zero).
1654+ */
1655+ if (config.device .role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
1656+ // Special case for CLIENT_BASE: is_favorite has special meaning, and we don't want to automatically set it
1657+ // without the user doing so deliberately. We don't normally expect users to use a CLIENT_BASE to send DMs or to add
1658+ // contacts, but we should make sure it doesn't auto-favorite in case they do. Instead, as a workaround, we'll set
1659+ // last_heard to now, so that the add_contact node doesn't immediately get evicted.
1660+ info->last_heard = getTime ();
1661+ } else {
1662+ // Normal case: set is_favorite to prevent expiration.
1663+ // last_heard will remain as-is (or remain 0 if this entry wasn't in the nodeDB).
1664+ info->is_favorite = true ;
1665+ }
1666+
16481667 // As the clients will begin sending the contact with DMs, we want to strictly check if the node is manually verified
16491668 if (contact.manually_verified ) {
16501669 info->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
0 commit comments