From d2cc03d3bb969c6d2ed57a443e17218a26cf7292 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Sun, 30 Jun 2024 23:22:10 +0100 Subject: Fix updating outdated events Since we updated anything matching the filters, we were some times bringing old versions of replaceable events back to life. The issue is that those were events that should be discarded since they are outdated but we still pick them up from some relays. Thus we need to index them by their naddr coordinate and only keep the latest event per naddr. I also improved logging along the way. --- src/main.rs | 63 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 01657a6..9984791 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashMap, fs::{remove_file, File}, io::{stdin, BufReader, Write}, net::IpAddr, @@ -307,33 +308,42 @@ fn get_https_connected_ips() -> Result> { async fn update_count(client: &Client, filters: &[Filter], count: u64) -> Result<()> { let events = get_relevant_events(client, filters).await?; - if events.is_empty() { - warn!("no live events") - } else { - let new_events = get_updated_events(events, client, count).await; + warn!("no live events"); + return Ok(()); + } - if new_events.is_empty() { - warn!("no events to update") - } else { - info!("broadcasting {} updated events", new_events.len()); - client - .batch_event(new_events, RelaySendOptions::new()) - .await?; - info!("updated events broadcasted"); - } + let new_events = get_updated_events(events, client, count).await; + if new_events.is_empty() { + return Ok(()); } + + info!("broadcasting {} updated events", new_events.len()); + client + .batch_event(new_events, RelaySendOptions::new()) + .await?; Ok(()) } async fn get_relevant_events(client: &Client, filters: &[Filter]) -> Result> { - let events = client - .get_events_of(filters.to_vec(), None) - .await? - .into_iter() + let events = client.get_events_of(filters.to_vec(), None).await?; + + let mut events_by_naddr: HashMap = Default::default(); + for event in events { + let naddr = get_naddr(&event).to_string(); + if let Some(dup_event) = events_by_naddr.get_mut(&naddr) { + if event.created_at() > dup_event.created_at() { + *dup_event = event; + } + } else { + events_by_naddr.insert(naddr, event); + } + } + + Ok(events_by_naddr + .into_values() .filter(|e| e.tags().iter().any(is_live_event_live)) - .collect::>(); - Ok(events) + .collect()) } fn is_live_event_live(t: &Tag) -> bool { @@ -362,20 +372,15 @@ async fn get_updated_events(events: Vec, client: &Client, count: u64) -> } async fn get_event_with_updated_count(event: &Event, client: &Client, count: u64) -> Result { + let naddr = get_naddr(event).to_bech32()?; let new_event = client .sign_event_builder(get_event_builder_with_updated_count(event, count)) .await - .context(format!( - "cannot sign {}", - get_ellipsed(&event.id().to_bech32()?) - ))?; + .context(format!("cannot sign {naddr}"))?; + info!("updating {naddr}"); Ok(new_event) } -fn get_ellipsed(input: &str) -> String { - format!("{}...{}", &input[..6], &input[input.len() - 6..]) -} - fn get_event_builder_with_updated_count(event: &Event, count: u64) -> EventBuilder { let mut tags: Vec = event .clone() @@ -386,3 +391,7 @@ fn get_event_builder_with_updated_count(event: &Event, count: u64) -> EventBuild let event_builder = EventBuilder::new(event.kind(), event.content(), tags); event_builder } + +fn get_naddr(event: &Event) -> Coordinate { + Coordinate::new(event.kind(), event.pubkey).identifier(event.identifier().unwrap_or_default()) +} -- cgit v1.2.3-70-g09d2