浏览代码

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 月之前
父节点
当前提交
b753fee336
共有 2 个文件被更改,包括 94 次插入22 次删除
  1. 80 0
      crates/relayer/src/relayer.rs
  2. 14 22
      crates/relayer/src/subscription/manager.rs

+ 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()));