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