subscription.rs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. use nostr_rs_types::types::{Event, Filter, Tag};
  2. #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord, Hash)]
  3. pub struct Subscription {
  4. author: Option<Vec<u8>>,
  5. ref_public_key: Option<Vec<u8>>,
  6. ref_id: Option<Vec<u8>>,
  7. id: Option<Vec<u8>>,
  8. kind: Option<u32>,
  9. }
  10. impl Subscription {
  11. #[inline]
  12. pub fn from_filters(filters: &[Filter]) -> Vec<Subscription> {
  13. let mut subs = vec![];
  14. filters.iter().for_each(|filter| {
  15. let authors: Vec<Option<Vec<u8>>> = if filter.authors.is_empty() {
  16. vec![None]
  17. } else {
  18. filter
  19. .authors
  20. .iter()
  21. .map(|author| Some(author.to_vec()))
  22. .collect()
  23. };
  24. let ref_public_keys = if filter.references_to_public_key.is_empty() {
  25. vec![None]
  26. } else {
  27. filter
  28. .references_to_public_key
  29. .iter()
  30. .map(|public_key| Some((*public_key).to_vec()))
  31. .collect()
  32. };
  33. let ref_ids = if filter.references_to_event.is_empty() {
  34. vec![None]
  35. } else {
  36. filter
  37. .references_to_event
  38. .iter()
  39. .map(|id| Some((*id).to_vec()))
  40. .collect()
  41. };
  42. let kind = if filter.kinds.is_empty() {
  43. vec![None]
  44. } else {
  45. filter
  46. .kinds
  47. .iter()
  48. .map(|kind| Some((*kind).into()))
  49. .collect()
  50. };
  51. let ids = if filter.ids.is_empty() {
  52. vec![None]
  53. } else {
  54. filter.ids.iter().map(|id| Some((*id).to_vec())).collect()
  55. };
  56. for author in authors.iter() {
  57. for id in ids.iter() {
  58. for ref_public_key in ref_public_keys.iter() {
  59. for ref_id in ref_ids.iter() {
  60. for kind in kind.iter() {
  61. subs.push(Subscription {
  62. id: id.clone(),
  63. ref_public_key: ref_public_key.clone(),
  64. author: author.clone(),
  65. ref_id: ref_id.clone(),
  66. kind: *kind,
  67. });
  68. }
  69. }
  70. }
  71. }
  72. }
  73. });
  74. subs
  75. }
  76. #[inline]
  77. pub fn from_event(event: &Event) -> Vec<Subscription> {
  78. let kind = event.kind().into();
  79. let public_keys = vec![None, Some(event.author().as_ref().to_vec())];
  80. let id = vec![None, Some(event.id.as_ref().to_vec())];
  81. let kind = [None, Some(kind)];
  82. let mut ref_public_keys = vec![None];
  83. let mut ref_ids = vec![None];
  84. event.tags().iter().for_each(|tag| match tag {
  85. Tag::Event(x) => {
  86. ref_ids.push(Some(x.id.as_ref().to_vec()));
  87. }
  88. Tag::PubKey(x) => {
  89. ref_public_keys.push(Some(x.id.as_ref().to_vec()));
  90. }
  91. _ => {}
  92. });
  93. let mut subs = vec![];
  94. for ref_public_key in ref_public_keys.iter() {
  95. for ref_id in ref_ids.iter() {
  96. for public_key in public_keys.iter() {
  97. for id in id.iter() {
  98. for kind in kind.iter() {
  99. subs.push(Subscription {
  100. ref_id: ref_id.clone(),
  101. ref_public_key: ref_public_key.clone(),
  102. author: public_key.clone(),
  103. id: id.clone(),
  104. kind: *kind,
  105. });
  106. }
  107. }
  108. }
  109. }
  110. }
  111. subs
  112. }
  113. }
  114. #[cfg(test)]
  115. mod test {
  116. use super::*;
  117. use nostr_rs_types::{types::Addr, Request};
  118. #[test]
  119. fn test_no_listen_to_all() {
  120. let request: Request = serde_json::from_str("[\"REQ\",\"6440d5279e350\",{\"authors\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"since\":1681967101},{\"#p\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[1,3,6,7,9735],\"since\":1681967101},{\"#p\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[4]},{\"authors\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[4]},{\"#e\":[\"2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a\",\"a5e3369c43daf2675ecbce18831e5f4e07db0d4dde0ef4f5698e645e4c46eed1\"],\"kinds\":[1,6,7,9735]}]").expect("valid");
  121. let mut subscriptions =
  122. Subscription::from_filters(&request.as_request().expect("req").filters);
  123. subscriptions.sort();
  124. assert!(subscriptions
  125. .binary_search(&Subscription::default())
  126. .is_err())
  127. }
  128. #[test]
  129. fn from_filters() {
  130. let request: Request = serde_json::from_str("[\"REQ\",\"1298169700973717\",{\"authors\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"since\":1681939304},{\"#p\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[1,3,6,7,9735],\"since\":1681939304},{\"#p\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[4]},{\"authors\":[\"39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb\"],\"kinds\":[4]},{\"#e\":[\"2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a\",\"a5e3369c43daf2675ecbce18831e5f4e07db0d4dde0ef4f5698e645e4c46eed1\"],\"kinds\":[1,6,7,9735]}]").expect("valid object");
  131. let mut subscriptions =
  132. Subscription::from_filters(&request.as_request().expect("req").filters);
  133. subscriptions.sort();
  134. assert!(subscriptions
  135. .binary_search(&Subscription::default())
  136. .is_err())
  137. }
  138. #[test]
  139. fn from_event() {
  140. let new_event: Request = serde_json::from_str(r#"["EVENT", {"kind":1,"content":"Pong","tags":[["e","9508850d7ddc8ef58c8b392236c49d472dc23fa11f4e73eb5475dfb099ddff42","","root"],["e","2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a","","reply"],["p","39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],["p","ee7202ad91459e013bfef263c59e47deb0163a5e7651b026673765488bfaf102"]],"created_at":1681938616,"pubkey":"a42007e33cfa25673b26f46f39df039aa6003258a68dc88f1f1e0447607aedb3","id":"e862fe23daf52ab09b36a37fa91ca3743e0c323e630e8627891212ca147c2da9","sig":"9036150a6c8a32933cffcc42aec4d2109a22e9f10d1c3860c0435a925e6386babb7df5c95fcf68c8ed6a9726a1f07225af663d0b068eb555014130aad21674fc","meta":{"revision":0,"created":1681939266488,"version":0},"$loki":108}]"#).expect("value");
  141. let mut subscriptions = Subscription::from_event(&new_event.as_event().expect("event"));
  142. subscriptions.sort();
  143. let pk: Addr = "39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"
  144. .try_into()
  145. .expect("id");
  146. let id: Addr = "e862fe23daf52ab09b36a37fa91ca3743e0c323e630e8627891212ca147c2da9"
  147. .try_into()
  148. .expect("id");
  149. let ref_id: Addr = "2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a"
  150. .try_into()
  151. .expect("id");
  152. let author: Addr = "a42007e33cfa25673b26f46f39df039aa6003258a68dc88f1f1e0447607aedb3"
  153. .try_into()
  154. .expect("id");
  155. let expected = vec![
  156. Subscription {
  157. ref_public_key: Some(pk.as_ref().to_vec()),
  158. ..Subscription::default()
  159. },
  160. Subscription {
  161. id: Some(id.as_ref().to_vec()),
  162. ref_public_key: Some(pk.as_ref().to_vec()),
  163. ..Subscription::default()
  164. },
  165. Subscription {
  166. id: Some(id.as_ref().to_vec()),
  167. ref_id: Some(ref_id.as_ref().to_vec()),
  168. ref_public_key: Some(pk.as_ref().to_vec()),
  169. ..Subscription::default()
  170. },
  171. Subscription {
  172. author: Some(author.as_ref().to_vec()),
  173. kind: Some(1),
  174. ..Subscription::default()
  175. },
  176. Subscription {
  177. author: Some(author.as_ref().to_vec()),
  178. ..Subscription::default()
  179. },
  180. Subscription {
  181. id: Some(id.as_ref().to_vec()),
  182. ref_id: Some(ref_id.as_ref().to_vec()),
  183. author: Some(author.as_ref().to_vec()),
  184. ..Subscription::default()
  185. },
  186. ];
  187. assert_eq!(subscriptions.len(), 72);
  188. expected.iter().enumerate().for_each(|(i, sub)| {
  189. assert!(
  190. subscriptions.binary_search(sub).is_ok(),
  191. "{} -> {:?}",
  192. i,
  193. sub
  194. );
  195. });
  196. assert!(subscriptions
  197. .binary_search(&Subscription::default())
  198. .is_ok());
  199. }
  200. }