diff options
Diffstat (limited to 'src/lib/client.rs')
| -rw-r--r-- | src/lib/client.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/lib/client.rs b/src/lib/client.rs index 3f1f22e..8ae9820 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -840,6 +840,33 @@ impl Connect for Client { | |||
| 840 | let events: Vec<nostr::Event> = get_events_of(&relay, filters.clone(), pb).await?; | 840 | let events: Vec<nostr::Event> = get_events_of(&relay, filters.clone(), pb).await?; |
| 841 | // TODO: try reconcile | 841 | // TODO: try reconcile |
| 842 | 842 | ||
| 843 | // Track the best state event seen from this relay so callers can | ||
| 844 | // determine which relays have a stale or absent state event. | ||
| 845 | // We must do this before process_fetched_events because the local | ||
| 846 | // database only stores the canonical latest event; per-relay | ||
| 847 | // visibility is only available here. | ||
| 848 | for event in &events { | ||
| 849 | if event.kind.eq(&STATE_KIND) { | ||
| 850 | let entry = report | ||
| 851 | .state_per_relay | ||
| 852 | .entry(relay_url.clone()) | ||
| 853 | .or_insert(None); | ||
| 854 | let is_newer = entry.as_ref().is_none_or(|existing: &nostr::Event| { | ||
| 855 | event.created_at.gt(&existing.created_at) | ||
| 856 | || (event.created_at.eq(&existing.created_at) | ||
| 857 | && event.id.gt(&existing.id)) | ||
| 858 | }); | ||
| 859 | if is_newer { | ||
| 860 | *entry = Some(event.clone()); | ||
| 861 | } | ||
| 862 | } | ||
| 863 | } | ||
| 864 | // Mark relay as queried even if no state event was returned. | ||
| 865 | report | ||
| 866 | .state_per_relay | ||
| 867 | .entry(relay_url.clone()) | ||
| 868 | .or_insert(None); | ||
| 869 | |||
| 843 | process_fetched_events( | 870 | process_fetched_events( |
| 844 | events, | 871 | events, |
| 845 | &request, | 872 | &request, |
| @@ -2018,6 +2045,30 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo | |||
| 2018 | for c in relay_report.profile_updates { | 2045 | for c in relay_report.profile_updates { |
| 2019 | report.profile_updates.insert(c); | 2046 | report.profile_updates.insert(c); |
| 2020 | } | 2047 | } |
| 2048 | // Per-relay state events are independent: each relay entry is kept as-is. | ||
| 2049 | // If a relay appears in multiple per-relay reports (shouldn't happen in | ||
| 2050 | // practice but possible in tests), keep the newer event. | ||
| 2051 | for (relay_url, maybe_event) in relay_report.state_per_relay { | ||
| 2052 | match report.state_per_relay.entry(relay_url) { | ||
| 2053 | std::collections::hash_map::Entry::Vacant(e) => { | ||
| 2054 | e.insert(maybe_event); | ||
| 2055 | } | ||
| 2056 | std::collections::hash_map::Entry::Occupied(mut e) => { | ||
| 2057 | let keep = match (e.get(), &maybe_event) { | ||
| 2058 | (None, Some(_)) => true, | ||
| 2059 | (Some(existing), Some(incoming)) => { | ||
| 2060 | incoming.created_at.gt(&existing.created_at) | ||
| 2061 | || (incoming.created_at.eq(&existing.created_at) | ||
| 2062 | && incoming.id.gt(&existing.id)) | ||
| 2063 | } | ||
| 2064 | _ => false, | ||
| 2065 | }; | ||
| 2066 | if keep { | ||
| 2067 | e.insert(maybe_event); | ||
| 2068 | } | ||
| 2069 | } | ||
| 2070 | } | ||
| 2071 | } | ||
| 2021 | } | 2072 | } |
| 2022 | report | 2073 | report |
| 2023 | } | 2074 | } |
| @@ -2146,6 +2197,12 @@ pub struct FetchReport { | |||
| 2146 | statuses: HashSet<EventId>, | 2197 | statuses: HashSet<EventId>, |
| 2147 | contributor_profiles: HashSet<PublicKey>, | 2198 | contributor_profiles: HashSet<PublicKey>, |
| 2148 | profile_updates: HashSet<PublicKey>, | 2199 | profile_updates: HashSet<PublicKey>, |
| 2200 | /// The best (newest) state event seen on each relay during the fetch. | ||
| 2201 | /// `None` as a value means the relay was queried but returned no state | ||
| 2202 | /// event at all. Relays that were never queried are absent from the map. | ||
| 2203 | /// This is the only point at which per-relay state visibility is available; | ||
| 2204 | /// the local database only stores the canonical latest event. | ||
| 2205 | pub state_per_relay: HashMap<RelayUrl, Option<nostr::Event>>, | ||
| 2149 | } | 2206 | } |
| 2150 | 2207 | ||
| 2151 | impl Display for FetchReport { | 2208 | impl Display for FetchReport { |