From 044b5ca1116c5ef94b4bf907a45e1d17aebb7e79 Mon Sep 17 00:00:00 2001 From: cloudwithax Date: Thu, 19 Feb 2026 17:48:05 -0500 Subject: [PATCH] feat(storage): upsert directory entry to preserve existing data on conflict --- src-tauri/src/node/mod.rs | 74 +++++++++++++++++++---------------- src-tauri/src/storage/disk.rs | 10 +++-- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src-tauri/src/node/mod.rs b/src-tauri/src/node/mod.rs index 45095db..e58cf01 100644 --- a/src-tauri/src/node/mod.rs +++ b/src-tauri/src/node/mod.rs @@ -1408,10 +1408,10 @@ pub async fn start( libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService( libp2p::request_response::Event::OutboundFailure { request_id, error, .. } )) => { + log::warn!("directory: outbound failure: {:?}", error); if let Some(reply) = pending_directory_replies.remove(&request_id) { let _ = reply.send(Err(format!("directory request failed: {:?}", error))); } - log::warn!("directory: outbound failure: {:?}", error); } libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService(_)) => {} @@ -1714,24 +1714,28 @@ pub async fn start( } } Some(NodeCommand::DirectoryRegister) => { - if let Some(rp) = relay_peer { - let profile = storage.load_profile().unwrap_or_default(); - swarm_instance.behaviour_mut().directory_service.send_request( - &rp, - crate::protocol::directory::DirectoryRequest::Register { - display_name: profile.display_name, - }, - ); - log::info!("directory: sent Register (command)"); + if relay_reservation_active { + if let Some(rp) = relay_peer { + let profile = storage.load_profile().unwrap_or_default(); + swarm_instance.behaviour_mut().directory_service.send_request( + &rp, + crate::protocol::directory::DirectoryRequest::Register { + display_name: profile.display_name, + }, + ); + log::info!("directory: sent Register (command)"); + } } } Some(NodeCommand::DirectoryRemove) => { - if let Some(rp) = relay_peer { - swarm_instance.behaviour_mut().directory_service.send_request( - &rp, - crate::protocol::directory::DirectoryRequest::Remove, - ); - log::info!("directory: sent Remove (command)"); + if relay_reservation_active { + if let Some(rp) = relay_peer { + swarm_instance.behaviour_mut().directory_service.send_request( + &rp, + crate::protocol::directory::DirectoryRequest::Remove, + ); + log::info!("directory: sent Remove (command)"); + } } } Some(NodeCommand::DirectorySearch { query, reply }) => { @@ -1750,24 +1754,26 @@ pub async fn start( } Some(NodeCommand::SetRelayDiscoverable { enabled }) => { relay_discoverable = enabled; - if enabled { - if let Some(rp) = relay_peer { - let profile = storage.load_profile().unwrap_or_default(); - swarm_instance.behaviour_mut().directory_service.send_request( - &rp, - crate::protocol::directory::DirectoryRequest::Register { - display_name: profile.display_name, - }, - ); - log::info!("directory: registered after opt-in"); - } - } else { - if let Some(rp) = relay_peer { - swarm_instance.behaviour_mut().directory_service.send_request( - &rp, - crate::protocol::directory::DirectoryRequest::Remove, - ); - log::info!("directory: removed after opt-out"); + if relay_reservation_active { + if enabled { + if let Some(rp) = relay_peer { + let profile = storage.load_profile().unwrap_or_default(); + swarm_instance.behaviour_mut().directory_service.send_request( + &rp, + crate::protocol::directory::DirectoryRequest::Register { + display_name: profile.display_name, + }, + ); + log::info!("directory: registered after opt-in"); + } + } else { + if let Some(rp) = relay_peer { + swarm_instance.behaviour_mut().directory_service.send_request( + &rp, + crate::protocol::directory::DirectoryRequest::Remove, + ); + log::info!("directory: removed after opt-out"); + } } } } diff --git a/src-tauri/src/storage/disk.rs b/src-tauri/src/storage/disk.rs index c047196..356ab08 100644 --- a/src-tauri/src/storage/disk.rs +++ b/src-tauri/src/storage/disk.rs @@ -744,14 +744,16 @@ impl DiskStorage { Ok(()) } - // save a directory entry only if the peer is not already known - // preserves existing data (bio, public_key) when upserting relay stubs + // upsert a directory entry from the relay — updates display_name and last_seen but preserves bio, public_key, and is_friend pub fn save_directory_entry_if_new(&self, entry: &DirectoryEntry) -> Result<(), io::Error> { let conn = self.open_conn()?; conn.execute( - "INSERT OR IGNORE INTO directory_entries ( + "INSERT INTO directory_entries ( peer_id, display_name, bio, public_key, last_seen, is_friend - ) VALUES (?1, ?2, ?3, ?4, ?5, ?6)", + ) VALUES (?1, ?2, ?3, ?4, ?5, ?6) + ON CONFLICT(peer_id) DO UPDATE SET + display_name = excluded.display_name, + last_seen = CASE WHEN excluded.last_seen > last_seen THEN excluded.last_seen ELSE last_seen END", params![ entry.peer_id, entry.display_name,