mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-30 00:41:42 +00:00
Enhance DbPersonRelay::get_best_relays() with a score
This commit is contained in:
parent
303ad437fc
commit
b1cb090c31
@ -1,6 +1,6 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::globals::GLOBALS;
|
use crate::globals::GLOBALS;
|
||||||
use nostr_types::{PublicKeyHex, Url};
|
use nostr_types::{PublicKeyHex, Unixtime, Url};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
@ -332,32 +332,91 @@ impl DbPersonRelay {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub async fn get_best_relays(pubkey: PublicKeyHex) -> Result<Vec<Url>, Error> {
|
/// This returns the best relays for the person along with a score, in order of score
|
||||||
// This is the ranking we are using. There might be reasons
|
pub async fn get_best_relays(pubkey: PublicKeyHex) -> Result<Vec<(Url, u64)>, Error> {
|
||||||
// for ranking differently:
|
let sql = "SELECT person, relay, last_suggested_nip23, last_suggested_kind3, \
|
||||||
// nip23 > kind3 > nip05 > kind2 > fetched > bytag
|
last_suggested_nip05, last_fetched, last_suggested_kind2, \
|
||||||
|
last_suggested_bytag \
|
||||||
|
FROM person_relay WHERE person=?";
|
||||||
|
|
||||||
let sql = "SELECT relay FROM person_relay WHERE person=? \
|
let ranked_relays: Result<Vec<(Url, u64)>, Error> = spawn_blocking(move || {
|
||||||
ORDER BY last_suggested_nip23 DESC, last_suggested_kind3 DESC, \
|
|
||||||
last_suggested_nip05 DESC, last_suggested_kind2 DESC, \
|
|
||||||
last_fetched DESC, last_suggested_bytag DESC";
|
|
||||||
|
|
||||||
let relays: Result<Vec<Url>, Error> = spawn_blocking(move || {
|
|
||||||
let maybe_db = GLOBALS.db.blocking_lock();
|
let maybe_db = GLOBALS.db.blocking_lock();
|
||||||
let db = maybe_db.as_ref().unwrap();
|
let db = maybe_db.as_ref().unwrap();
|
||||||
let mut stmt = db.prepare(sql)?;
|
let mut stmt = db.prepare(sql)?;
|
||||||
stmt.raw_bind_parameter(1, &pubkey.0)?;
|
stmt.raw_bind_parameter(1, &pubkey.0)?;
|
||||||
let mut rows = stmt.raw_query();
|
let mut rows = stmt.raw_query();
|
||||||
let mut relays: Vec<Url> = Vec::new();
|
|
||||||
|
let mut dbprs: Vec<DbPersonRelay> = Vec::new();
|
||||||
while let Some(row) = rows.next()? {
|
while let Some(row) = rows.next()? {
|
||||||
let s: String = row.get(0)?;
|
let dbpr = DbPersonRelay {
|
||||||
relays.push(Url::new(&s));
|
person: row.get(0)?,
|
||||||
|
relay: row.get(1)?,
|
||||||
|
last_fetched: row.get(2)?,
|
||||||
|
last_suggested_kind2: row.get(3)?,
|
||||||
|
last_suggested_kind3: row.get(4)?,
|
||||||
|
last_suggested_nip23: row.get(5)?,
|
||||||
|
last_suggested_nip05: row.get(6)?,
|
||||||
|
last_suggested_bytag: row.get(7)?,
|
||||||
|
};
|
||||||
|
dbprs.push(dbpr);
|
||||||
}
|
}
|
||||||
Ok(relays)
|
|
||||||
|
Ok(DbPersonRelay::rank(dbprs))
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
relays
|
ranked_relays
|
||||||
|
}
|
||||||
|
|
||||||
|
// This ranks the relays
|
||||||
|
pub fn rank(mut dbprs: Vec<DbPersonRelay>) -> Vec<(Url, u64)> {
|
||||||
|
// This is the ranking we are using. There might be reasons
|
||||||
|
// for ranking differently:
|
||||||
|
// nip23 (score=10) > kind3 (score=8) > nip05 (score=6) > fetched (score=4)
|
||||||
|
// > kind2 (score=2) > bytag (score=1)
|
||||||
|
|
||||||
|
let now = Unixtime::now().unwrap().0 as u64;
|
||||||
|
let mut output: Vec<(Url, u64)> = Vec::new();
|
||||||
|
|
||||||
|
let scorefn = |when: u64, fade_period: u64, base: u64| -> u64 {
|
||||||
|
let dur = now.saturating_sub(when); // seconds since
|
||||||
|
let periods = (dur / fade_period) + 1; // minimum one period
|
||||||
|
base / periods
|
||||||
|
};
|
||||||
|
|
||||||
|
for dbpr in dbprs.drain(..) {
|
||||||
|
let mut score = 0;
|
||||||
|
// nip23 is an author-signed explicit claim of using this relay
|
||||||
|
if let Some(when) = dbpr.last_suggested_nip23 {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 30, 15);
|
||||||
|
}
|
||||||
|
// kind3 is a temporary (not NIPped) author-signed explicit claim of using this relay
|
||||||
|
if let Some(when) = dbpr.last_suggested_kind3 {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 30, 15);
|
||||||
|
}
|
||||||
|
// kind2 is an author-signed recommended relay list
|
||||||
|
if let Some(when) = dbpr.last_suggested_kind2 {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 30, 10);
|
||||||
|
}
|
||||||
|
// nip05 is an unsigned dns claim of using this relay
|
||||||
|
if let Some(when) = dbpr.last_suggested_nip05 {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 15, 6);
|
||||||
|
}
|
||||||
|
// last_fetched is gossip verified happened-to-work-before
|
||||||
|
if let Some(when) = dbpr.last_fetched {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 3, 6);
|
||||||
|
}
|
||||||
|
// last_suggested_bytag is an anybody-signed suggestion
|
||||||
|
if let Some(when) = dbpr.last_suggested_bytag {
|
||||||
|
score += scorefn(when, 60 * 60 * 24 * 2, 1);
|
||||||
|
}
|
||||||
|
tracing::debug!("person relay score {} = {}", &dbpr.relay, score);
|
||||||
|
output.push((Url::new(&dbpr.relay), score));
|
||||||
|
}
|
||||||
|
|
||||||
|
output.sort_by(|(_, score1), (_, score2)| score2.cmp(score1));
|
||||||
|
|
||||||
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1045,12 +1045,12 @@ impl Overlord {
|
|||||||
|
|
||||||
// Sort the people into the relays we will find their metadata at
|
// Sort the people into the relays we will find their metadata at
|
||||||
for pubkey in &pubkeys {
|
for pubkey in &pubkeys {
|
||||||
for relay in DbPersonRelay::get_best_relays(pubkey.to_owned())
|
for relayscore in DbPersonRelay::get_best_relays(pubkey.to_owned())
|
||||||
.await?
|
.await?
|
||||||
.drain(..)
|
.drain(..)
|
||||||
.take(num_relays_per_person as usize)
|
.take(num_relays_per_person as usize)
|
||||||
{
|
{
|
||||||
map.entry(relay)
|
map.entry(relayscore.0)
|
||||||
.and_modify(|e| e.push(pubkey.to_owned()))
|
.and_modify(|e| e.push(pubkey.to_owned()))
|
||||||
.or_insert_with(|| vec![pubkey.to_owned()]);
|
.or_insert_with(|| vec![pubkey.to_owned()]);
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ impl People {
|
|||||||
let maybeurl = relays.get(0);
|
let maybeurl = relays.get(0);
|
||||||
p_tags.push(Tag::Pubkey {
|
p_tags.push(Tag::Pubkey {
|
||||||
pubkey: pubkey.clone(),
|
pubkey: pubkey.clone(),
|
||||||
recommended_relay_url: maybeurl.cloned(),
|
recommended_relay_url: maybeurl.map(|(u, _)| u).cloned(),
|
||||||
petname: None,
|
petname: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user