feat(storage): upsert directory entry to preserve existing data on conflict

This commit is contained in:
cloudwithax 2026-02-19 17:48:05 -05:00
parent ef6114a751
commit 044b5ca111
2 changed files with 46 additions and 38 deletions

View File

@ -1408,10 +1408,10 @@ pub async fn start(
libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService( libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService(
libp2p::request_response::Event::OutboundFailure { request_id, error, .. } libp2p::request_response::Event::OutboundFailure { request_id, error, .. }
)) => { )) => {
log::warn!("directory: outbound failure: {:?}", error);
if let Some(reply) = pending_directory_replies.remove(&request_id) { if let Some(reply) = pending_directory_replies.remove(&request_id) {
let _ = reply.send(Err(format!("directory request failed: {:?}", error))); let _ = reply.send(Err(format!("directory request failed: {:?}", error)));
} }
log::warn!("directory: outbound failure: {:?}", error);
} }
libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService(_)) => {} libp2p::swarm::SwarmEvent::Behaviour(behaviour::DuskBehaviourEvent::DirectoryService(_)) => {}
@ -1714,24 +1714,28 @@ pub async fn start(
} }
} }
Some(NodeCommand::DirectoryRegister) => { Some(NodeCommand::DirectoryRegister) => {
if let Some(rp) = relay_peer { if relay_reservation_active {
let profile = storage.load_profile().unwrap_or_default(); if let Some(rp) = relay_peer {
swarm_instance.behaviour_mut().directory_service.send_request( let profile = storage.load_profile().unwrap_or_default();
&rp, swarm_instance.behaviour_mut().directory_service.send_request(
crate::protocol::directory::DirectoryRequest::Register { &rp,
display_name: profile.display_name, crate::protocol::directory::DirectoryRequest::Register {
}, display_name: profile.display_name,
); },
log::info!("directory: sent Register (command)"); );
log::info!("directory: sent Register (command)");
}
} }
} }
Some(NodeCommand::DirectoryRemove) => { Some(NodeCommand::DirectoryRemove) => {
if let Some(rp) = relay_peer { if relay_reservation_active {
swarm_instance.behaviour_mut().directory_service.send_request( if let Some(rp) = relay_peer {
&rp, swarm_instance.behaviour_mut().directory_service.send_request(
crate::protocol::directory::DirectoryRequest::Remove, &rp,
); crate::protocol::directory::DirectoryRequest::Remove,
log::info!("directory: sent Remove (command)"); );
log::info!("directory: sent Remove (command)");
}
} }
} }
Some(NodeCommand::DirectorySearch { query, reply }) => { Some(NodeCommand::DirectorySearch { query, reply }) => {
@ -1750,24 +1754,26 @@ pub async fn start(
} }
Some(NodeCommand::SetRelayDiscoverable { enabled }) => { Some(NodeCommand::SetRelayDiscoverable { enabled }) => {
relay_discoverable = enabled; relay_discoverable = enabled;
if enabled { if relay_reservation_active {
if let Some(rp) = relay_peer { if enabled {
let profile = storage.load_profile().unwrap_or_default(); if let Some(rp) = relay_peer {
swarm_instance.behaviour_mut().directory_service.send_request( let profile = storage.load_profile().unwrap_or_default();
&rp, swarm_instance.behaviour_mut().directory_service.send_request(
crate::protocol::directory::DirectoryRequest::Register { &rp,
display_name: profile.display_name, crate::protocol::directory::DirectoryRequest::Register {
}, display_name: profile.display_name,
); },
log::info!("directory: registered after opt-in"); );
} log::info!("directory: registered after opt-in");
} else { }
if let Some(rp) = relay_peer { } else {
swarm_instance.behaviour_mut().directory_service.send_request( if let Some(rp) = relay_peer {
&rp, swarm_instance.behaviour_mut().directory_service.send_request(
crate::protocol::directory::DirectoryRequest::Remove, &rp,
); crate::protocol::directory::DirectoryRequest::Remove,
log::info!("directory: removed after opt-out"); );
log::info!("directory: removed after opt-out");
}
} }
} }
} }

View File

@ -744,14 +744,16 @@ impl DiskStorage {
Ok(()) Ok(())
} }
// save a directory entry only if the peer is not already known // upsert a directory entry from the relay — updates display_name and last_seen but preserves bio, public_key, and is_friend
// preserves existing data (bio, public_key) when upserting relay stubs
pub fn save_directory_entry_if_new(&self, entry: &DirectoryEntry) -> Result<(), io::Error> { pub fn save_directory_entry_if_new(&self, entry: &DirectoryEntry) -> Result<(), io::Error> {
let conn = self.open_conn()?; let conn = self.open_conn()?;
conn.execute( conn.execute(
"INSERT OR IGNORE INTO directory_entries ( "INSERT INTO directory_entries (
peer_id, display_name, bio, public_key, last_seen, is_friend 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![ params![
entry.peer_id, entry.peer_id,
entry.display_name, entry.display_name,