Pārlūkot izejas kodu

Fixed bug with key prefix in subscription manager

The offset for key prefix was incorrect generating partial matches but not full
matches of keys.

The bug was fixed while working on another branch and tests has been added
Cesar Rodas 2 mēneši atpakaļ
vecāks
revīzija
b753fee336

+ 80 - 0
crates/relayer/src/relayer.rs

@@ -475,6 +475,86 @@ mod test {
     }
 
     #[tokio::test]
+    async fn server_listener_real_time_single_argument() {
+        let request: Request = serde_json::from_value(json!(
+            [
+                "REQ",
+                "1298169700973717",
+                {
+                    "authors": ["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
+                    "since":1681939304
+                },
+                {
+                    "#p":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
+                    "since":1681939304
+                },
+                {
+                    "#p":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
+                },
+                {
+                    "authors":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
+                },
+                {
+                    "#e":[
+                        "2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a",
+                        "a5e3369c43daf2675ecbce18831e5f4e07db0d4dde0ef4f5698e645e4c46eed1"
+                    ],
+                }
+        ]))
+        .expect("valid object");
+        let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
+        let (connection, mut recv) = Connection::new_local_connection();
+
+        assert_eq!(relayer.total_subscribers(), 0);
+        let _ = relayer
+            .process_request_from_client(&connection, request)
+            .await;
+
+        assert_eq!(relayer.total_subscribers(), 5);
+
+        // eod
+        assert!(recv
+            .try_recv()
+            .expect("valid")
+            .as_end_of_stored_events()
+            .is_some());
+
+        // It is empty
+        assert!(recv.try_recv().is_err());
+
+        relayer
+            .process_request_from_client(&connection, get_note())
+            .await
+            .expect("process event");
+
+        sleep(Duration::from_millis(100)).await;
+
+        // It is not empty
+        let msg = recv.try_recv();
+        assert!(msg.is_ok());
+        assert_eq!(
+            msg.expect("is ok")
+                .as_event()
+                .expect("valid")
+                .subscription_id
+                .to_string(),
+            "1298169700973717".to_owned()
+        );
+
+        // it must be deliverd at most once
+        assert!(recv.try_recv().is_err());
+        assert_eq!(relayer.total_subscribers(), 5);
+
+        // when client is dropped, the subscription is removed
+        // automatically
+        drop(connection);
+
+        sleep(Duration::from_millis(10)).await;
+
+        assert_eq!(relayer.total_subscribers(), 0);
+    }
+
+    #[tokio::test]
     async fn server_listener_real_time() {
         let request: Request = serde_json::from_value(json!(
             [

+ 14 - 22
crates/relayer/src/subscription/manager.rs

@@ -16,7 +16,7 @@ use tokio::sync::{mpsc::Sender, RwLock};
 
 type SubIdx = (Key, ConnectionId, SubscriptionId);
 
-pub const MIN_PREFIX_MATCH_LEN: usize = 4;
+pub const MIN_PREFIX_MATCH_LEN: usize = 2;
 
 /// Subscription for a connection
 ///
@@ -110,41 +110,33 @@ impl SubscriptionManager {
         let author = event.author().as_ref().to_vec();
         let id = event.id.as_ref().to_vec();
 
-        let len = author.len();
-        for i in min_prefix_match_len..len - min_prefix_match_len {
-            subscriptions.push(Key::Author(author[..len - i].to_vec(), None));
-            subscriptions.push(Key::Author(author[..len - i].to_vec(), Some(event.kind())));
+        for i in min_prefix_match_len..=author.len() {
+            subscriptions.push(Key::Author(author[..i].to_vec(), None));
+            subscriptions.push(Key::Author(author[..i].to_vec(), Some(event.kind())));
         }
 
         for t in event.tags() {
             match t {
                 nostr_rs_types::types::Tag::Event(ref_event) => {
-                    let len = ref_event.id.len();
-                    for i in min_prefix_match_len..ref_event.id.len() - min_prefix_match_len {
-                        subscriptions.push(Key::RefId(ref_event.id[..len - i].to_vec(), None));
-                        subscriptions.push(Key::RefId(
-                            ref_event.id[..len - i].to_vec(),
-                            Some(event.kind()),
-                        ));
+                    for i in min_prefix_match_len..=ref_event.id.len() {
+                        subscriptions.push(Key::RefId(ref_event.id[..i].to_vec(), None));
+                        subscriptions
+                            .push(Key::RefId(ref_event.id[..i].to_vec(), Some(event.kind())));
                     }
                 }
                 nostr_rs_types::types::Tag::PubKey(ref_pub_key) => {
-                    let len = ref_pub_key.id.len();
-                    for i in min_prefix_match_len..len - min_prefix_match_len {
-                        subscriptions.push(Key::RefId(ref_pub_key.id[..len - i].to_vec(), None));
-                        subscriptions.push(Key::RefId(
-                            ref_pub_key.id[..len - i].to_vec(),
-                            Some(event.kind()),
-                        ));
+                    for i in min_prefix_match_len..=ref_pub_key.id.len() {
+                        subscriptions.push(Key::RefId(ref_pub_key.id[..i].to_vec(), None));
+                        subscriptions
+                            .push(Key::RefId(ref_pub_key.id[..i].to_vec(), Some(event.kind())));
                     }
                 }
                 _ => {}
             }
         }
 
-        let len = id.len();
-        for i in min_prefix_match_len..len - min_prefix_match_len {
-            subscriptions.push(Key::Id(id[..len - i].to_vec()));
+        for i in min_prefix_match_len..=id.len() {
+            subscriptions.push(Key::Id(id[..i].to_vec()));
         }
 
         subscriptions.push(Key::Kind(event.kind()));