mod.rs (6532B)
1 mod broadcast; 2 mod compaction; 3 mod coordinator; 4 mod identity; 5 mod limits; 6 pub mod message; 7 mod multicast; 8 mod outbox; 9 pub mod pool; 10 mod queue; 11 pub mod subs_debug; 12 mod subscription; 13 mod transparent; 14 mod websocket; 15 16 pub use broadcast::{BroadcastCache, BroadcastRelay}; 17 pub use identity::{ 18 NormRelayUrl, OutboxSubId, RelayId, RelayReqId, RelayReqStatus, RelayType, RelayUrlPkgs, 19 }; 20 pub use limits::{ 21 RelayCoordinatorLimits, RelayLimitations, SubPass, SubPassGuardian, SubPassRevocation, 22 }; 23 pub use multicast::{MulticastRelay, MulticastRelayCache}; 24 use nostrdb::Filter; 25 pub use outbox::{OutboxPool, OutboxSession, OutboxSessionHandler}; 26 pub use queue::QueuedTasks; 27 pub use subscription::{ 28 FullModificationTask, ModifyFiltersTask, ModifyRelaysTask, ModifyTask, OutboxSubscriptions, 29 OutboxTask, SubscribeTask, 30 }; 31 pub use websocket::{WebsocketConn, WebsocketRelay}; 32 33 #[cfg(test)] 34 pub mod test_utils; 35 36 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 37 pub enum RelayStatus { 38 Connected, 39 Connecting, 40 Disconnected, 41 } 42 43 enum UnownedRelay<'a> { 44 Websocket(&'a mut WebsocketRelay), 45 Multicast(&'a mut MulticastRelay), 46 } 47 48 /// RawEventData is the event raw data from a relay 49 pub struct RawEventData<'a> { 50 pub url: &'a str, 51 pub event_json: &'a str, 52 pub relay_type: RelayImplType, 53 } 54 55 /// RelayImplType identifies whether an event came from a websocket or multicast relay. 56 pub enum RelayImplType { 57 Websocket, 58 Multicast, 59 } 60 61 pub enum RelayTask { 62 Unsubscribe, 63 Subscribe, 64 } 65 66 pub struct FilterMetadata { 67 filter_json_size: usize, 68 last_seen: Option<u64>, 69 } 70 71 pub struct MetadataFilters { 72 filters: Vec<Filter>, 73 meta: Vec<FilterMetadata>, 74 } 75 76 impl MetadataFilters { 77 pub fn new(filters: Vec<Filter>) -> Self { 78 let meta = filters 79 .iter() 80 .map(|f| FilterMetadata { 81 filter_json_size: f.json().ok().map(|j| j.len()).unwrap_or(0), 82 last_seen: None, 83 }) 84 .collect(); 85 Self { filters, meta } 86 } 87 88 pub fn json_size_sum(&self) -> usize { 89 self.meta.iter().map(|f| f.filter_json_size).sum() 90 } 91 92 pub fn since_optimize(&mut self) { 93 for (filter, meta) in self.filters.iter_mut().zip(self.meta.iter()) { 94 let Some(last_seen) = meta.last_seen else { 95 continue; 96 }; 97 98 *filter = filter.clone().since_mut(last_seen); 99 } 100 } 101 102 pub fn get_filters(&self) -> &Vec<Filter> { 103 &self.filters 104 } 105 106 #[allow(dead_code)] 107 pub fn iter(&self) -> MetadataFiltersIter<'_> { 108 MetadataFiltersIter { 109 filters: self.filters.iter(), 110 meta: self.meta.iter(), 111 } 112 } 113 114 pub fn iter_mut(&mut self) -> MetadataFiltersIterMut<'_> { 115 MetadataFiltersIterMut { 116 filters: self.filters.iter_mut(), 117 meta: self.meta.iter_mut(), 118 } 119 } 120 121 #[allow(dead_code)] 122 pub fn is_empty(&self) -> bool { 123 self.filters.iter().all(|f| f.num_elements() == 0) 124 } 125 } 126 127 #[allow(dead_code)] 128 pub struct MetadataFiltersIter<'a> { 129 filters: std::slice::Iter<'a, Filter>, 130 meta: std::slice::Iter<'a, FilterMetadata>, 131 } 132 133 impl<'a> Iterator for MetadataFiltersIter<'a> { 134 type Item = (&'a Filter, &'a FilterMetadata); 135 136 fn next(&mut self) -> Option<Self::Item> { 137 Some((self.filters.next()?, self.meta.next()?)) 138 } 139 } 140 141 pub struct MetadataFiltersIterMut<'a> { 142 filters: std::slice::IterMut<'a, Filter>, 143 meta: std::slice::IterMut<'a, FilterMetadata>, 144 } 145 146 impl<'a> Iterator for MetadataFiltersIterMut<'a> { 147 type Item = (&'a mut Filter, &'a mut FilterMetadata); 148 149 fn next(&mut self) -> Option<Self::Item> { 150 Some((self.filters.next()?, self.meta.next()?)) 151 } 152 } 153 154 #[cfg(test)] 155 mod tests { 156 use super::*; 157 158 fn filter_has_since(filter: &Filter, expected: u64) -> bool { 159 let json = filter.json().expect("filter json"); 160 json.contains(&format!("\"since\":{}", expected)) 161 } 162 163 #[test] 164 fn since_optimize_applies_last_seen_to_filter() { 165 let filter = Filter::new().kinds(vec![1]).build(); 166 let mut metadata_filters = MetadataFilters::new(vec![filter]); 167 168 // Initially no since 169 let json_before = metadata_filters.get_filters()[0] 170 .json() 171 .expect("filter json"); 172 assert!( 173 !json_before.contains("\"since\""), 174 "filter should not have since initially" 175 ); 176 177 // Set last_seen on metadata 178 metadata_filters.meta[0].last_seen = Some(12345); 179 180 // Call since_optimize 181 metadata_filters.since_optimize(); 182 183 // Now filter should have since 184 assert!( 185 filter_has_since(&metadata_filters.get_filters()[0], 12345), 186 "filter should have since:12345 after optimization" 187 ); 188 } 189 190 #[test] 191 fn since_optimize_skips_filters_without_last_seen() { 192 let filter1 = Filter::new().kinds(vec![1]).build(); 193 let filter2 = Filter::new().kinds(vec![2]).build(); 194 let mut metadata_filters = MetadataFilters::new(vec![filter1, filter2]); 195 196 // Only set last_seen on first filter 197 metadata_filters.meta[0].last_seen = Some(99999); 198 199 metadata_filters.since_optimize(); 200 201 // First filter should have since 202 assert!( 203 filter_has_since(&metadata_filters.get_filters()[0], 99999), 204 "first filter should have since" 205 ); 206 207 // Second filter should NOT have since 208 let json_second = metadata_filters.get_filters()[1] 209 .json() 210 .expect("filter json"); 211 assert!( 212 !json_second.contains("\"since\""), 213 "second filter should not have since" 214 ); 215 } 216 217 #[test] 218 fn since_optimize_overwrites_existing_since() { 219 // Create filter with initial since value 220 let filter = Filter::new().kinds(vec![1]).since(100).build(); 221 let mut metadata_filters = MetadataFilters::new(vec![filter]); 222 223 // Verify initial since 224 assert!( 225 filter_has_since(&metadata_filters.get_filters()[0], 100), 226 "filter should have initial since:100" 227 ); 228 229 // Set different last_seen 230 metadata_filters.meta[0].last_seen = Some(200); 231 metadata_filters.since_optimize(); 232 233 // Since should be updated to new value 234 assert!( 235 filter_has_since(&metadata_filters.get_filters()[0], 200), 236 "filter should have updated since:200" 237 ); 238 } 239 }