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

This commit is contained in:
Ken Sedgwick
2025-02-04 16:19:40 -08:00
parent f0588a7f6b
commit 482313f883
5 changed files with 64 additions and 39 deletions

2
Cargo.lock generated
View File

@@ -2728,7 +2728,7 @@ dependencies = [
[[package]] [[package]]
name = "nostrdb" name = "nostrdb"
version = "0.5.1" 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 = [ dependencies = [
"bindgen", "bindgen",
"cc", "cc",

View File

@@ -30,7 +30,7 @@ indexmap = "2.6.0"
log = "0.4.17" log = "0.4.17"
nostr = { version = "0.37.0", default-features = false, features = ["std", "nip49"] } nostr = { version = "0.37.0", default-features = false, features = ["std", "nip49"] }
mio = { version = "1.0.3", features = ["os-poll", "net"] } 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" #nostrdb = "0.5.2"
notedeck = { path = "crates/notedeck" } notedeck = { path = "crates/notedeck" }
notedeck_chrome = { path = "crates/notedeck_chrome" } notedeck_chrome = { path = "crates/notedeck_chrome" }

View File

@@ -6,7 +6,7 @@ use crate::{
use enostr::{Filter, NoteId, Pubkey}; use enostr::{Filter, NoteId, Pubkey};
use nostrdb::{BlockType, Mention, Ndb, Note, NoteKey, Transaction}; use nostrdb::{BlockType, Mention, Ndb, Note, NoteKey, Transaction};
use std::collections::HashSet; use std::collections::{HashMap, HashSet};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tracing::error; use tracing::error;
@@ -78,10 +78,12 @@ impl SingleUnkIdAction {
} }
} }
type RelayUrl = String;
/// Unknown Id searcher /// Unknown Id searcher
#[derive(Default)] #[derive(Default, Debug)]
pub struct UnknownIds { pub struct UnknownIds {
ids: HashSet<UnknownId>, ids: HashMap<UnknownId, HashSet<RelayUrl>>,
first_updated: Option<Instant>, first_updated: Option<Instant>,
last_updated: Option<Instant>, last_updated: Option<Instant>,
} }
@@ -108,20 +110,20 @@ impl UnknownIds {
Instant::now() - last_updated >= Duration::from_secs(2) Instant::now() - last_updated >= Duration::from_secs(2)
} }
pub fn ids(&self) -> &HashSet<UnknownId> { pub fn ids_iter(&self) -> impl ExactSizeIterator<Item = &UnknownId> {
&self.ids 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 &mut self.ids
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.ids = HashSet::default(); self.ids = HashMap::default();
} }
pub fn filter(&self) -> Option<Vec<Filter>> { 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) get_unknown_ids_filter(&ids)
} }
@@ -170,14 +172,14 @@ impl UnknownIds {
note_cache: &mut NoteCache, note_cache: &mut NoteCache,
note: &Note, note: &Note,
) -> bool { ) -> bool {
let before = unknown_ids.ids().len(); let before = unknown_ids.ids_iter().len();
let key = note.key().expect("note key"); 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).clone();
let cached_note = note_cache.cached_note_or_insert(key, note); 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()) { if let Err(e) = get_unknown_note_ids(ndb, cached_note, txn, note, unknown_ids.ids_mut()) {
error!("UnknownIds::update_from_note {e}"); error!("UnknownIds::update_from_note {e}");
} }
let after = unknown_ids.ids().len(); let after = unknown_ids.ids_iter().len();
if before != after { if before != after {
unknown_ids.mark_updated(); unknown_ids.mark_updated();
@@ -200,7 +202,7 @@ impl UnknownIds {
return; return;
} }
self.ids.insert(UnknownId::Pubkey(*pubkey)); self.ids.entry(UnknownId::Pubkey(*pubkey)).or_default();
self.mark_updated(); self.mark_updated();
} }
@@ -210,12 +212,12 @@ impl UnknownIds {
return; return;
} }
self.ids.insert(UnknownId::Id(*note_id)); self.ids.entry(UnknownId::Id(*note_id)).or_default();
self.mark_updated(); self.mark_updated();
} }
} }
#[derive(Hash, Clone, Copy, PartialEq, Eq)] #[derive(Hash, Clone, Copy, PartialEq, Eq, Debug)]
pub enum UnknownId { pub enum UnknownId {
Pubkey(Pubkey), Pubkey(Pubkey),
Id(NoteId), Id(NoteId),
@@ -250,14 +252,15 @@ pub fn get_unknown_note_ids<'a>(
cached_note: &CachedNote, cached_note: &CachedNote,
txn: &'a Transaction, txn: &'a Transaction,
note: &Note<'a>, note: &Note<'a>,
ids: &mut HashSet<UnknownId>, ids: &mut HashMap<UnknownId, HashSet<RelayUrl>>,
) -> Result<()> { ) -> Result<()> {
#[cfg(feature = "profiling")] #[cfg(feature = "profiling")]
puffin::profile_function!(); puffin::profile_function!();
// the author pubkey // the author pubkey
if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { 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 // 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()); let note_reply = cached_note.reply.borrow(note.tags());
if let Some(root) = note_reply.root() { if let Some(root) = note_reply.root() {
if ndb.get_note_by_id(txn, root.id).is_err() { 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 !note_reply.is_reply_to_root() {
if let Some(reply) = note_reply.reply() { if let Some(reply) = note_reply.reply() {
if ndb.get_note_by_id(txn, reply.id).is_err() { 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() { match block.as_mention().unwrap() {
Mention::Pubkey(npub) => { Mention::Pubkey(npub) => {
if ndb.get_profile_by_pubkey(txn, npub.pubkey()).is_err() { 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) => { Mention::Profile(nprofile) => {
if ndb.get_profile_by_pubkey(txn, nprofile.pubkey()).is_err() { 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()) { Mention::Event(ev) => {
Err(_) => { let relays = ev
ids.insert(UnknownId::Id(NoteId::new(*ev.id()))); .relays_iter()
if let Some(pk) = ev.pubkey() { .map(String::from)
if ndb.get_profile_by_pubkey(txn, pk).is_err() { .collect::<HashSet<RelayUrl>>();
ids.insert(UnknownId::Pubkey(Pubkey::new(*pk))); 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.entry(UnknownId::Pubkey(Pubkey::new(*note.pubkey())))
.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())));
}
}
},
Mention::Note(note) => match ndb.get_note_by_id(txn, note.id()) { Mention::Note(note) => match ndb.get_note_by_id(txn, note.id()) {
Err(_) => { Err(_) => {
ids.insert(UnknownId::Id(NoteId::new(*note.id()))); ids.entry(UnknownId::Id(NoteId::new(*note.id())))
.or_default();
} }
Ok(note) => { Ok(note) => {
if ndb.get_profile_by_pubkey(txn, note.pubkey()).is_err() { 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();
} }
} }
}, },

View File

@@ -25,7 +25,7 @@ use nostrdb::{Ndb, Transaction};
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;
use std::time::Duration; use std::time::Duration;
use tracing::{error, info, trace, warn}; use tracing::{debug, error, info, trace, warn};
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub enum DamusState { pub enum DamusState {
@@ -158,10 +158,11 @@ fn try_process_event(
} }
fn unknown_id_send(unknown_ids: &mut UnknownIds, pool: &mut RelayPool) { 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"); let filter = unknown_ids.filter().expect("filter");
info!( info!(
"Getting {} unknown ids from relays", "Getting {} unknown ids from relays",
unknown_ids.ids().len() unknown_ids.ids_iter().len()
); );
let msg = ClientMessage::req("unknownids".to_string(), filter); let msg = ClientMessage::req("unknownids".to_string(), filter);
unknown_ids.clear(); unknown_ids.clear();

View File

@@ -10,11 +10,11 @@ pub fn update_from_columns(
ndb: &Ndb, ndb: &Ndb,
note_cache: &mut NoteCache, note_cache: &mut NoteCache,
) -> bool { ) -> 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) { if let Err(e) = get_unknown_ids(txn, unknown_ids, timeline_cache, ndb, note_cache) {
error!("UnknownIds::update {e}"); error!("UnknownIds::update {e}");
} }
let after = unknown_ids.ids().len(); let after = unknown_ids.ids_iter().len();
if before != after { if before != after {
unknown_ids.mark_updated(); unknown_ids.mark_updated();