notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 482313f883ec384b1af9afb7e065a1c2c5ad04a3
parent f0588a7f6b1adf02c3f60b7877527fec301da7ac
Author: Ken Sedgwick <ken@bonsai.com>
Date:   Tue,  4 Feb 2025 16:19:40 -0800

add relay hints to Mention::{Profile,Event} and UnknownIds

Diffstat:
MCargo.lock | 2+-
MCargo.toml | 2+-
Mcrates/notedeck/src/unknowns.rs | 88++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mcrates/notedeck_columns/src/app.rs | 5+++--
Mcrates/notedeck_columns/src/unknowns.rs | 4++--
5 files changed, 63 insertions(+), 38 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -2728,7 +2728,7 @@ dependencies = [ [[package]] name = "nostrdb" version = "0.5.1" -source = "git+https://github.com/damus-io/nostrdb-rs?rev=2111948b078b24a1659d0bd5d8570f370269c99b#2111948b078b24a1659d0bd5d8570f370269c99b" +source = "git+https://github.com/damus-io/nostrdb-rs?rev=ad3b345416d17ec75362fbfe82309c8196f5ad4b#ad3b345416d17ec75362fbfe82309c8196f5ad4b" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml @@ -30,7 +30,7 @@ indexmap = "2.6.0" log = "0.4.17" nostr = { version = "0.37.0", default-features = false, features = ["std", "nip49"] } mio = { version = "1.0.3", features = ["os-poll", "net"] } -nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "2111948b078b24a1659d0bd5d8570f370269c99b" } +nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "ad3b345416d17ec75362fbfe82309c8196f5ad4b" } #nostrdb = "0.5.2" notedeck = { path = "crates/notedeck" } notedeck_chrome = { path = "crates/notedeck_chrome" } diff --git a/crates/notedeck/src/unknowns.rs b/crates/notedeck/src/unknowns.rs @@ -6,7 +6,7 @@ use crate::{ use enostr::{Filter, NoteId, Pubkey}; use nostrdb::{BlockType, Mention, Ndb, Note, NoteKey, Transaction}; -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::time::{Duration, Instant}; use tracing::error; @@ -78,10 +78,12 @@ impl SingleUnkIdAction { } } +type RelayUrl = String; + /// Unknown Id searcher -#[derive(Default)] +#[derive(Default, Debug)] pub struct UnknownIds { - ids: HashSet<UnknownId>, + ids: HashMap<UnknownId, HashSet<RelayUrl>>, first_updated: Option<Instant>, last_updated: Option<Instant>, } @@ -108,20 +110,20 @@ impl UnknownIds { Instant::now() - last_updated >= Duration::from_secs(2) } - pub fn ids(&self) -> &HashSet<UnknownId> { - &self.ids + pub fn ids_iter(&self) -> impl ExactSizeIterator<Item = &UnknownId> { + self.ids.keys() } - pub fn ids_mut(&mut self) -> &mut HashSet<UnknownId> { + pub fn ids_mut(&mut self) -> &mut HashMap<UnknownId, HashSet<RelayUrl>> { &mut self.ids } pub fn clear(&mut self) { - self.ids = HashSet::default(); + self.ids = HashMap::default(); } pub fn filter(&self) -> Option<Vec<Filter>> { - let ids: Vec<&UnknownId> = self.ids.iter().collect(); + let ids: Vec<&UnknownId> = self.ids.keys().collect(); get_unknown_ids_filter(&ids) } @@ -170,14 +172,14 @@ impl UnknownIds { note_cache: &mut NoteCache, note: &Note, ) -> bool { - let before = unknown_ids.ids().len(); + let before = unknown_ids.ids_iter().len(); let key = note.key().expect("note key"); //let cached_note = note_cache.cached_note_or_insert(key, note).clone(); let cached_note = note_cache.cached_note_or_insert(key, note); if let Err(e) = get_unknown_note_ids(ndb, cached_note, txn, note, unknown_ids.ids_mut()) { error!("UnknownIds::update_from_note {e}"); } - let after = unknown_ids.ids().len(); + let after = unknown_ids.ids_iter().len(); if before != after { unknown_ids.mark_updated(); @@ -200,7 +202,7 @@ impl UnknownIds { return; } - self.ids.insert(UnknownId::Pubkey(*pubkey)); + self.ids.entry(UnknownId::Pubkey(*pubkey)).or_default(); self.mark_updated(); } @@ -210,12 +212,12 @@ impl UnknownIds { return; } - self.ids.insert(UnknownId::Id(*note_id)); + self.ids.entry(UnknownId::Id(*note_id)).or_default(); self.mark_updated(); } } -#[derive(Hash, Clone, Copy, PartialEq, Eq)] +#[derive(Hash, Clone, Copy, PartialEq, Eq, Debug)] pub enum UnknownId { Pubkey(Pubkey), Id(NoteId), @@ -250,14 +252,15 @@ pub fn get_unknown_note_ids<'a>( cached_note: &CachedNote, txn: &'a Transaction, note: &Note<'a>, - ids: &mut HashSet<UnknownId>, + ids: &mut HashMap<UnknownId, HashSet<RelayUrl>>, ) -> Result<()> { #[cfg(feature = "profiling")] puffin::profile_function!(); // the author pubkey if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))); + ids.entry(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))) + .or_default(); } // pull notes that notes are replying to @@ -265,14 +268,15 @@ pub fn get_unknown_note_ids<'a>( let note_reply = cached_note.reply.borrow(note.tags()); if let Some(root) = note_reply.root() { if ndb.get_note_by_id(txn, root.id).is_err() { - ids.insert(UnknownId::Id(NoteId::new(*root.id))); + ids.entry(UnknownId::Id(NoteId::new(*root.id))).or_default(); } } if !note_reply.is_reply_to_root() { if let Some(reply) = note_reply.reply() { if ndb.get_note_by_id(txn, reply.id).is_err() { - ids.insert(UnknownId::Id(NoteId::new(*reply.id))); + ids.entry(UnknownId::Id(NoteId::new(*reply.id))) + .or_default(); } } } @@ -287,36 +291,56 @@ pub fn get_unknown_note_ids<'a>( match block.as_mention().unwrap() { Mention::Pubkey(npub) => { if ndb.get_profile_by_pubkey(txn, npub.pubkey()).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*npub.pubkey()))); + ids.entry(UnknownId::Pubkey(Pubkey::new(*npub.pubkey()))) + .or_default(); } } Mention::Profile(nprofile) => { if ndb.get_profile_by_pubkey(txn, nprofile.pubkey()).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*nprofile.pubkey()))); + let id = UnknownId::Pubkey(Pubkey::new(*nprofile.pubkey())); + let relays = nprofile + .relays_iter() + .map(String::from) + .collect::<HashSet<RelayUrl>>(); + ids.entry(id).or_default().extend(relays); } } - Mention::Event(ev) => match ndb.get_note_by_id(txn, ev.id()) { - Err(_) => { - ids.insert(UnknownId::Id(NoteId::new(*ev.id()))); - if let Some(pk) = ev.pubkey() { - if ndb.get_profile_by_pubkey(txn, pk).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*pk))); + Mention::Event(ev) => { + let relays = ev + .relays_iter() + .map(String::from) + .collect::<HashSet<RelayUrl>>(); + match ndb.get_note_by_id(txn, ev.id()) { + Err(_) => { + ids.entry(UnknownId::Id(NoteId::new(*ev.id()))) + .or_default() + .extend(relays.clone()); + if let Some(pk) = ev.pubkey() { + if ndb.get_profile_by_pubkey(txn, pk).is_err() { + ids.entry(UnknownId::Pubkey(Pubkey::new(*pk))) + .or_default() + .extend(relays); + } } } - } - Ok(note) => { - if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))); + Ok(note) => { + if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { + ids.entry(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))) + .or_default() + .extend(relays); + } } } - }, + } Mention::Note(note) => match ndb.get_note_by_id(txn, note.id()) { Err(_) => { - ids.insert(UnknownId::Id(NoteId::new(*note.id()))); + ids.entry(UnknownId::Id(NoteId::new(*note.id()))) + .or_default(); } Ok(note) => { if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { - ids.insert(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))); + ids.entry(UnknownId::Pubkey(Pubkey::new(*note.pubkey()))) + .or_default(); } } }, diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs @@ -25,7 +25,7 @@ use nostrdb::{Ndb, Transaction}; use std::collections::HashMap; use std::path::Path; use std::time::Duration; -use tracing::{error, info, trace, warn}; +use tracing::{debug, error, info, trace, warn}; #[derive(Debug, Eq, PartialEq, Clone)] pub enum DamusState { @@ -158,10 +158,11 @@ fn try_process_event( } fn unknown_id_send(unknown_ids: &mut UnknownIds, pool: &mut RelayPool) { + debug!("unknown_id_send called on: {:?}", &unknown_ids); let filter = unknown_ids.filter().expect("filter"); info!( "Getting {} unknown ids from relays", - unknown_ids.ids().len() + unknown_ids.ids_iter().len() ); let msg = ClientMessage::req("unknownids".to_string(), filter); unknown_ids.clear(); diff --git a/crates/notedeck_columns/src/unknowns.rs b/crates/notedeck_columns/src/unknowns.rs @@ -10,11 +10,11 @@ pub fn update_from_columns( ndb: &Ndb, note_cache: &mut NoteCache, ) -> bool { - let before = unknown_ids.ids().len(); + let before = unknown_ids.ids_iter().len(); if let Err(e) = get_unknown_ids(txn, unknown_ids, timeline_cache, ndb, note_cache) { error!("UnknownIds::update {e}"); } - let after = unknown_ids.ids().len(); + let after = unknown_ids.ids_iter().len(); if before != after { unknown_ids.mark_updated();