relay.rs (4975B)
1 use crate::{bindings, NoteKey, Transaction}; 2 use tracing::error; 3 4 #[derive(Debug)] 5 pub struct NoteRelaysIter<'a> { 6 _txn: &'a Transaction, 7 iter: bindings::ndb_note_relay_iterator, 8 } 9 10 #[derive(Debug)] 11 pub enum NoteRelays<'a> { 12 Empty, 13 Active(NoteRelaysIter<'a>), 14 } 15 16 impl<'a> NoteRelays<'a> { 17 pub fn empty() -> Self { 18 Self::Empty 19 } 20 21 pub fn new(txn: &'a Transaction, note_key: NoteKey) -> Self { 22 Self::Active(NoteRelaysIter::new(txn, note_key)) 23 } 24 } 25 26 impl<'a> NoteRelaysIter<'a> { 27 pub fn as_mut_ptr(&mut self) -> *mut bindings::ndb_note_relay_iterator { 28 &mut self.iter 29 } 30 31 pub fn new(txn: &'a Transaction, note_key: NoteKey) -> Self { 32 let note_key = note_key.as_u64(); 33 let mut val = Self { 34 _txn: txn, 35 iter: empty_iterator(), 36 }; 37 38 let ok = unsafe { 39 bindings::ndb_note_relay_iterate_start(txn.as_mut_ptr(), val.as_mut_ptr(), note_key) 40 }; 41 42 if ok == 0 { 43 // NOTE (jb55): this should never happen, no need to burden the api. let's log just in case? 44 error!("error starting note relay iterator? {}", note_key); 45 } 46 47 val 48 } 49 } 50 51 fn empty_iterator() -> bindings::ndb_note_relay_iterator { 52 bindings::ndb_note_relay_iterator { 53 txn: std::ptr::null_mut(), 54 note_key: 0, 55 cursor_op: 0, 56 mdb_cur: std::ptr::null_mut(), 57 } 58 } 59 60 impl<'a> Iterator for NoteRelays<'a> { 61 type Item = &'a str; 62 63 fn next(&mut self) -> Option<Self::Item> { 64 let iter = match self { 65 Self::Empty => { 66 return None; 67 } 68 Self::Active(iter) => iter, 69 }; 70 71 let relay = unsafe { bindings::ndb_note_relay_iterate_next(iter.as_mut_ptr()) }; 72 if relay.is_null() { 73 return None; 74 } 75 76 let relay = unsafe { 77 let byte_slice = std::slice::from_raw_parts(relay as *const u8, libc::strlen(relay)); 78 std::str::from_utf8_unchecked(byte_slice) 79 }; 80 81 Some(relay) 82 } 83 } 84 85 impl Drop for NoteRelays<'_> { 86 fn drop(&mut self) { 87 let iter = match self { 88 Self::Empty => { 89 return; 90 } 91 Self::Active(iter) => iter, 92 }; 93 94 unsafe { 95 bindings::ndb_note_relay_iterate_close(iter.as_mut_ptr()); 96 } 97 } 98 } 99 100 #[cfg(test)] 101 mod tests { 102 use super::*; 103 use crate::{config::Config, test_util, IngestMetadata, Ndb}; 104 use tokio::time::{self, sleep, Duration}; 105 106 #[test] 107 fn process_event_relays_works() { 108 let db = "target/testdbs/relays_work"; 109 test_util::cleanup_db(&db); 110 111 { 112 let ndb = Ndb::new(db, &Config::new()).expect("ndb"); 113 let eva = r#"["EVENT","s",{"id": "702555e52e82cc24ad517ba78c21879f6e47a7c0692b9b20df147916ae8731a3","pubkey": "32bf915904bfde2d136ba45dde32c88f4aca863783999faea2e847a8fafd2f15","created_at": 1702675561,"kind": 1,"tags": [],"content": "hello, world","sig": "2275c5f5417abfd644b7bc74f0388d70feb5d08b6f90fa18655dda5c95d013bfbc5258ea77c05b7e40e0ee51d8a2efa931dc7a0ec1db4c0a94519762c6625675"}]"#; 114 ndb.process_event_with(eva, IngestMetadata::new().client(false).relay("a")) 115 .expect("process ok"); 116 let evb = r#"["EVENT","s",{"id": "702555e52e82cc24ad517ba78c21879f6e47a7c0692b9b20df147916ae8731a3","pubkey": "32bf915904bfde2d136ba45dde32c88f4aca863783999faea2e847a8fafd2f15","created_at": 1702675561,"kind": 1,"tags": [],"content": "hello, world","sig": "2275c5f5417abfd644b7bc74f0388d70feb5d08b6f90fa18655dda5c95d013bfbc5258ea77c05b7e40e0ee51d8a2efa931dc7a0ec1db4c0a94519762c6625675"}]"#; 117 ndb.process_event_with(evb, IngestMetadata::new().client(false).relay("b")) 118 .expect("process ok"); 119 let evc = r#"["EVENT","s",{"id": "702555e52e82cc24ad517ba78c21879f6e47a7c0692b9b20df147916ae8731a3","pubkey": "32bf915904bfde2d136ba45dde32c88f4aca863783999faea2e847a8fafd2f15","created_at": 1702675561,"kind": 1,"tags": [],"content": "hello, world","sig": "2275c5f5417abfd644b7bc74f0388d70feb5d08b6f90fa18655dda5c95d013bfbc5258ea77c05b7e40e0ee51d8a2efa931dc7a0ec1db4c0a94519762c6625675"}]"#; 120 ndb.process_event_with(evc, IngestMetadata::new().client(false).relay("c")) 121 .expect("process ok"); 122 } 123 124 { 125 let ndb = Ndb::new(db, &Config::new()).expect("ndb"); 126 let id = 127 hex::decode("702555e52e82cc24ad517ba78c21879f6e47a7c0692b9b20df147916ae8731a3") 128 .expect("hex id"); 129 let mut txn = Transaction::new(&ndb).expect("txn"); 130 let id_bytes: [u8; 32] = id.try_into().expect("id bytes"); 131 let note = ndb.get_note_by_id(&txn, &id_bytes).expect("note"); 132 133 let relays: Vec<&str> = note.relays(&txn).collect(); 134 assert_eq!(relays, vec!["a", "b", "c"]); 135 136 assert_eq!(note.kind(), 1); 137 } 138 } 139 }