nostr: fix profile loading over the relay
Profiles never loaded when scanning a bare npub (username/avatar stayed blank) even though the relay stores and serves the kind-0 fine. Two causes: fetch_profile_blocking ran on a throwaway current-thread runtime that can't drive the relay connections (which live on the service runtime, behind the custom Nym mixnet transport), and it only dialed nprofile hints, never the user's own default relays. Run the fetch on the service runtime via a stored Handle, and always dial the default relay set (incl relay.goblin.st).
This commit is contained in:
+28
-9
@@ -73,6 +73,11 @@ pub struct NostrService {
|
||||
|
||||
/// SDK client, present while the service loop runs.
|
||||
client: RwLock<Option<Client>>,
|
||||
/// Handle to the service's tokio runtime. One-shot fetches (e.g. profile
|
||||
/// lookups) from worker threads MUST run here, not on a throwaway runtime:
|
||||
/// the relay connections (incl. the custom Nym mixnet transport) are driven
|
||||
/// by this runtime, and a foreign runtime can't reach them.
|
||||
rt_handle: RwLock<Option<tokio::runtime::Handle>>,
|
||||
/// Service thread started flag.
|
||||
started: AtomicBool,
|
||||
/// Shutdown request flag.
|
||||
@@ -124,6 +129,7 @@ impl NostrService {
|
||||
store: Arc::new(store),
|
||||
nostr_dir,
|
||||
client: RwLock::new(None),
|
||||
rt_handle: RwLock::new(None),
|
||||
started: AtomicBool::new(false),
|
||||
shutdown: AtomicBool::new(false),
|
||||
connected: AtomicBool::new(false),
|
||||
@@ -185,15 +191,25 @@ impl NostrService {
|
||||
let client = self.client.read().clone()?;
|
||||
let pk = PublicKey::from_hex(hex).ok()?;
|
||||
let hints: Vec<String> = hints.to_vec();
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.ok()?;
|
||||
rt.block_on(async {
|
||||
// Dial the target's own relays so their kind-0 is reachable even when
|
||||
// it isn't mirrored to any relay we already hold.
|
||||
if !hints.is_empty() {
|
||||
connect_relays(&client, &hints).await;
|
||||
// Run on the SERVICE runtime — the relay connections (and the custom Nym
|
||||
// mixnet transport) live there. A throwaway current-thread runtime can't
|
||||
// drive them, which is why bare-npub profile lookups silently returned
|
||||
// nothing even though the relay serves the kind-0 fine.
|
||||
let handle = self.rt_handle.read().clone()?;
|
||||
let own_relays = self.relays();
|
||||
handle.block_on(async {
|
||||
// Dial the target's own relays (hints) AND our own relay set so the
|
||||
// kind-0 is reachable whether it lives on their relays or ours (most
|
||||
// Goblin users share relay.goblin.st). Without this, a bare-npub scan
|
||||
// only queried whatever happened to be connected and often saw nothing.
|
||||
let mut dial: Vec<String> = hints.clone();
|
||||
for r in &own_relays {
|
||||
if !dial.contains(r) {
|
||||
dial.push(r.clone());
|
||||
}
|
||||
}
|
||||
if !dial.is_empty() {
|
||||
connect_relays(&client, &dial).await;
|
||||
}
|
||||
let filter = Filter::new().kind(Kind::Metadata).author(pk).limit(1);
|
||||
let events = client
|
||||
@@ -660,6 +676,9 @@ impl NostrService {
|
||||
|
||||
/// Main service loop: connect, publish identity, catch up, listen.
|
||||
async fn run_service(svc: Arc<NostrService>, wallet: Wallet) {
|
||||
// Publish the service runtime handle so worker-thread one-shots (profile
|
||||
// lookups) can run their fetches here, where the relay I/O actually lives.
|
||||
*svc.rt_handle.write() = Some(tokio::runtime::Handle::current());
|
||||
let relays = svc.relays();
|
||||
info!(
|
||||
"nostr: starting service for {} with relays {:?}",
|
||||
|
||||
Reference in New Issue
Block a user