~gheartsfield/nostr-rs-relay-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
3 2

[PATCH nostr-rs-relay 1/2] Implement NIP15

Details
Message ID
<20220530220300.96429-1-hi@semisol.dev>
DKIM signature
missing
Download raw message
Patch: +16 -5
NIP15 sends an EOSE notice to clients after all stored events are sent
to allow loading indicators and other use cases.
---
 src/db.rs   |  6 ++++++
 src/info.rs |  2 +-
 src/main.rs | 13 +++++++++----
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/db.rs b/src/db.rs
index cbc0172..a4fabc6 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -575,6 +575,12 @@ pub async fn db_query(
                    })
                    .ok();
            }
            query_tx
                .blocking_send(QueryResult {
                    sub_id: sub.get_id(),
                    event: "EOSE".to_string(),
                })
                .ok();
            debug!(
                "query completed ({} rows) in {:?}",
                row_count,
diff --git a/src/info.rs b/src/info.rs
index d1d8d7e..143d5d9 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -35,7 +35,7 @@ impl From<config::Info> for RelayInfo {
            description: i.description,
            pubkey: i.pubkey,
            contact: i.contact,
            supported_nips: Some(vec![1, 2, 11]),
            supported_nips: Some(vec![1, 2, 11, 15]),
            software: Some("https://git.sr.ht/~gheartsfield/nostr-rs-relay".to_owned()),
            version: CARGO_PKG_VERSION.map(|x| x.to_owned()),
        }
diff --git a/src/main.rs b/src/main.rs
index 449937c..34f0043 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -424,11 +424,16 @@ async fn nostr_server(
            },
            Some(query_result) = query_rx.recv() => {
                // database informed us of a query result we asked for
                client_received_event_count += 1;
                // send a result
                let subesc = query_result.sub_id.replace("\"", "");
                let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
                ws_stream.send(Message::Text(send_str)).await.ok();
                if query_result.event == "EOSE" {
                    let send_str = format!("[\"EOSE\",\"{}\"]", subesc);
                    ws_stream.send(Message::Text(send_str)).await.ok();
                } else {
                    client_received_event_count += 1;
                    // send a result
                    let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
                    ws_stream.send(Message::Text(send_str)).await.ok();
                }
            },
            // TODO: consider logging the LaggedRecv error
            Ok(global_event) = bcast_rx.recv() => {
-- 
2.32.0 (Apple Git-132)

[PATCH nostr-rs-relay 2/2] Implement NIP16

Details
Message ID
<20220530220300.96429-2-hi@semisol.dev>
In-Reply-To
<20220530220300.96429-1-hi@semisol.dev> (view parent)
DKIM signature
missing
Download raw message
Patch: +43 -45
NIP16 introduces a replaceable and ephemeral event range:
[10000..20000) for replaceable and [20000..30000) for
ephemeral.
---
 src/db.rs   | 86 ++++++++++++++++++++++++++---------------------------
 src/info.rs |  2 +-
 2 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/src/db.rs b/src/db.rs
index a4fabc6..8fd5f07 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -207,30 +207,41 @@ pub async fn db_writer(
            }
            // TODO: cache recent list of authors to remove a DB call.
            let start = Instant::now();
            match write_event(&mut pool.get()?, &event) {
                Ok(updated) => {
                    if updated == 0 {
                        trace!("ignoring duplicate event");
                    } else {
                        info!(
                            "persisted event {:?} from {:?} in {:?}",
                            event.get_event_id_prefix(),
                            event.get_author_prefix(),
                            start.elapsed()
                        );
                        event_write = true;
                        // send this out to all clients
                        bcast_tx.send(event.clone()).ok();
            if event.kind >= 20000 && event.kind < 30000 {
                info!(
                    "published ephemeral event {:?} from {:?} in {:?}",
                    event.get_event_id_prefix(),
                    event.get_author_prefix(),
                    start.elapsed()
                );
                bcast_tx.send(event.clone()).ok();
                event_write = true
            } else {
                match write_event(&mut pool.get()?, &event) {
                    Ok(updated) => {
                        if updated == 0 {
                            trace!("ignoring duplicate event");
                        } else {
                            info!(
                                "persisted event {:?} from {:?} in {:?}",
                                event.get_event_id_prefix(),
                                event.get_author_prefix(),
                                start.elapsed()
                            );
                            event_write = true;
                            // send this out to all clients
                            bcast_tx.send(event.clone()).ok();
                        }
                    }
                    Err(err) => {
                        warn!("event insert failed: {:?}", err);
                        notice_tx
                            .try_send(
                                "relay experienced an error trying to publish the latest event"
                                    .to_owned(),
                            )
                            .ok();
                    }
                }
                Err(err) => {
                    warn!("event insert failed: {:?}", err);
                    notice_tx
                        .try_send(
                            "relay experienced an error trying to publish the latest event"
                                .to_owned(),
                        )
                        .ok();
                }
            }

@@ -302,32 +313,19 @@ pub fn write_event(conn: &mut PooledConnection, e: &Event) -> Result<usize> {
            }
        }
    }
    // if this event is for a metadata update, hide every other kind=0
    // event from the same author that was issued earlier than this.
    if e.kind == 0 {
        let update_count = tx.execute(
            "UPDATE event SET hidden=TRUE WHERE id!=? AND kind=0 AND author=? AND created_at <= ? and hidden!=TRUE",
            params![ev_id, hex::decode(&e.pubkey).ok(), e.created_at],
        )?;
        if update_count > 0 {
            info!(
                "hid {} older metadata events for author {:?}",
                update_count,
                e.get_author_prefix()
            );
        }
    }
    // if this event is for a contact update, hide every other kind=3
    // event from the same author that was issued earlier than this.
    if e.kind == 3 {
    // if this event is replaceable update, hide every other replaceable
    // event with the same kind from the same author that was issued
    // earlier than this.
    if e.kind == 0 || e.kind == 3 || (e.kind >= 10000 && e.kind < 20000) {
        let update_count = tx.execute(
            "UPDATE event SET hidden=TRUE WHERE id!=? AND kind=3 AND author=? AND created_at <= ? and hidden!=TRUE",
            params![ev_id, hex::decode(&e.pubkey).ok(), e.created_at],
            "UPDATE event SET hidden=TRUE WHERE id!=? AND kind=? AND author=? AND created_at <= ? and hidden!=TRUE",
            params![ev_id, e.kind, hex::decode(&e.pubkey).ok(), e.created_at],
        )?;
        if update_count > 0 {
            info!(
                "hid {} older contact events for author {:?}",
                "hid {} older replaceable kind {} events for author {:?}",
                update_count,
                e.kind,
                e.get_author_prefix()
            );
        }
diff --git a/src/info.rs b/src/info.rs
index 143d5d9..1af7f9e 100644
--- a/src/info.rs
+++ b/src/info.rs
@@ -35,7 +35,7 @@ impl From<config::Info> for RelayInfo {
            description: i.description,
            pubkey: i.pubkey,
            contact: i.contact,
            supported_nips: Some(vec![1, 2, 11, 15]),
            supported_nips: Some(vec![1, 2, 11, 15, 16]),
            software: Some("https://git.sr.ht/~gheartsfield/nostr-rs-relay".to_owned()),
            version: CARGO_PKG_VERSION.map(|x| x.to_owned()),
        }
-- 
2.32.0 (Apple Git-132)
William Casarin <jb55@jb55.com>
Details
Message ID
<20220531151237.g2tjh3zptc72hoef@cross.lan>
In-Reply-To
<20220530220300.96429-1-hi@semisol.dev> (view parent)
DKIM signature
missing
Download raw message
On Tue, May 31, 2022 at 01:02:59AM +0300, Semisol wrote:
>NIP15 sends an EOSE notice to clients after all stored events are sent
>to allow loading indicators and other use cases.
>---
> src/db.rs   |  6 ++++++
> src/info.rs |  2 +-
> src/main.rs | 13 +++++++++----
> 3 files changed, 16 insertions(+), 5 deletions(-)
>
>diff --git a/src/db.rs b/src/db.rs
>index cbc0172..a4fabc6 100644
>--- a/src/db.rs
>+++ b/src/db.rs
>@@ -575,6 +575,12 @@ pub async fn db_query(
>                     })
>                     .ok();
>             }
>+            query_tx
>+                .blocking_send(QueryResult {
>+                    sub_id: sub.get_id(),
>+                    event: "EOSE".to_string(),
>+                })
>+                .ok();
>             debug!(
>                 "query completed ({} rows) in {:?}",
>                 row_count,
>diff --git a/src/info.rs b/src/info.rs
>index d1d8d7e..143d5d9 100644
>--- a/src/info.rs
>+++ b/src/info.rs
>@@ -35,7 +35,7 @@ impl From<config::Info> for RelayInfo {
>             description: i.description,
>             pubkey: i.pubkey,
>             contact: i.contact,
>-            supported_nips: Some(vec![1, 2, 11]),
>+            supported_nips: Some(vec![1, 2, 11, 15]),
>             software: Some("https://git.sr.ht/~gheartsfield/nostr-rs-relay".to_owned()),
>             version: CARGO_PKG_VERSION.map(|x| x.to_owned()),
>         }
>diff --git a/src/main.rs b/src/main.rs
>index 449937c..34f0043 100644
>--- a/src/main.rs
>+++ b/src/main.rs
>@@ -424,11 +424,16 @@ async fn nostr_server(
>             },
>             Some(query_result) = query_rx.recv() => {
>                 // database informed us of a query result we asked for
>-                client_received_event_count += 1;
>-                // send a result
>                 let subesc = query_result.sub_id.replace("\"", "");
>-                let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
>-                ws_stream.send(Message::Text(send_str)).await.ok();
>+                if query_result.event == "EOSE" {

I guess this works, although it seems a bit hacky. I had an initial
implementation that looked more like this:

	 /// Serialized event associated with a specific subscription request.
	 #[derive(PartialEq, Debug, Clone)]
	-pub struct QueryResult {
	+pub enum QueryResult {
	+    /// An event result
	+    EventResult(EventQueryResult),
	+    /// An end-of-stored-events result
	+    EoseResult,
	+}
	+
	+
	+pub enum EventQueryResult {
	     /// Subscription identifier
	     pub sub_id: String,
	     /// Serialized event

but that touches more code. I'm ok with this implementation if Greg is.

>+                    let send_str = format!("[\"EOSE\",\"{}\"]", subesc);
>+                    ws_stream.send(Message::Text(send_str)).await.ok();
>+                } else {
>+                    client_received_event_count += 1;
>+                    // send a result
>+                    let send_str = format!("[\"EVENT\",\"{}\",{}]", subesc, &query_result.event);
>+                    ws_stream.send(Message::Text(send_str)).await.ok();
>+                }
>             },
>             // TODO: consider logging the LaggedRecv error
>             Ok(global_event) = bcast_rx.recv() => {
>-- 
>2.32.0 (Apple Git-132)
>
Details
Message ID
<CKE2QPEBJQMO.1Y1UOQS54URPT@Semisol>
In-Reply-To
<20220531151237.g2tjh3zptc72hoef@cross.lan> (view parent)
DKIM signature
missing
Download raw message
Yeah. It is a bit hacky but it works :)
Reply to thread Export thread (mbox)