Skip to content

Commit 5b7690a

Browse files
committed
add functionality for BlockNotifier to unregister a previously registered listener, in order to no longer receive events
1 parent fc03ab1 commit 5b7690a

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

lightning/src/chain/chaininterface.rs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,21 @@ impl<'a, CL: Deref<Target = ChainListener + 'a> + 'a> BlockNotifier<'a, CL> {
252252
}
253253

254254
/// Register the given listener to receive events.
255-
// TODO: unregister
256255
pub fn register_listener(&self, listener: CL) {
257256
let mut vec = self.listeners.lock().unwrap();
258257
vec.push(listener);
259258
}
260259

260+
/// Unregister the given listener to no longer
261+
/// receive events.
262+
///
263+
/// If the same listener is registered multiple times, unregistering
264+
/// will remove ALL occurrences of that listener.
265+
pub fn unregister_listener(&self, listener: CL) {
266+
let mut vec = self.listeners.lock().unwrap();
267+
vec.retain(|item| !std::ptr::eq(&(**item) as *const _, &(*listener) as *const _));
268+
}
269+
261270
/// Notify listeners that a block was connected given a full, unfiltered block.
262271
///
263272
/// Handles re-scanning the block and calling block_connected again if listeners register new
@@ -376,3 +385,58 @@ impl ChainWatchInterfaceUtil {
376385
watched.does_match_tx(tx)
377386
}
378387
}
388+
389+
#[cfg(test)]
390+
mod tests {
391+
use ln::functional_test_utils::{create_node_cfgs};
392+
use super::{BlockNotifier, ChainListener};
393+
394+
#[test]
395+
fn register_listener_test() {
396+
let node_cfgs = create_node_cfgs(1);
397+
let block_notifier: BlockNotifier<&dyn ChainListener> = BlockNotifier::new(node_cfgs[0].chain_monitor.clone());
398+
let listener = &node_cfgs[0].chan_monitor.simple_monitor as &ChainListener;
399+
block_notifier.register_listener(listener);
400+
let vec = block_notifier.listeners.lock().unwrap();
401+
assert_eq!(vec.len(), 1);
402+
let item = vec.first().clone().unwrap();
403+
assert!(std::ptr::eq(&(**item) as *const _, &(*listener) as *const _));
404+
}
405+
406+
#[test]
407+
fn unregister_single_listener_test() {
408+
let node_cfgs = create_node_cfgs(2);
409+
let block_notifier: BlockNotifier<&dyn ChainListener> = BlockNotifier::new(node_cfgs[0].chain_monitor.clone());
410+
let listener1 = &node_cfgs[0].chan_monitor.simple_monitor as &ChainListener;
411+
let listener2 = &node_cfgs[1].chan_monitor.simple_monitor as &ChainListener;
412+
block_notifier.register_listener(listener1);
413+
block_notifier.register_listener(listener2);
414+
let vec = block_notifier.listeners.lock().unwrap();
415+
assert_eq!(vec.len(), 2);
416+
drop(vec);
417+
block_notifier.unregister_listener(listener1);
418+
let vec = block_notifier.listeners.lock().unwrap();
419+
assert_eq!(vec.len(), 1);
420+
let item = vec.first().clone().unwrap();
421+
assert!(std::ptr::eq(&(**item) as *const _, &(*listener2) as *const _));
422+
}
423+
424+
#[test]
425+
fn unregister_multiple_of_the_same_listeners_test() {
426+
let node_cfgs = create_node_cfgs(2);
427+
let block_notifier: BlockNotifier<&dyn ChainListener> = BlockNotifier::new(node_cfgs[0].chain_monitor.clone());
428+
let listener1 = &node_cfgs[0].chan_monitor.simple_monitor as &ChainListener;
429+
let listener2 = &node_cfgs[1].chan_monitor.simple_monitor as &ChainListener;
430+
block_notifier.register_listener(listener1);
431+
block_notifier.register_listener(listener1);
432+
block_notifier.register_listener(listener2);
433+
let vec = block_notifier.listeners.lock().unwrap();
434+
assert_eq!(vec.len(), 3);
435+
drop(vec);
436+
block_notifier.unregister_listener(listener1);
437+
let vec = block_notifier.listeners.lock().unwrap();
438+
assert_eq!(vec.len(), 1);
439+
let item = vec.first().clone().unwrap();
440+
assert!(std::ptr::eq(&(**item) as *const _, &(*listener2) as *const _));
441+
}
442+
}

lightning/src/ln/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ mod onion_utils;
2727
mod wire;
2828

2929
#[cfg(test)]
30-
#[macro_use] mod functional_test_utils;
30+
#[macro_use]
31+
pub(crate) mod functional_test_utils;
3132
#[cfg(test)]
3233
mod functional_tests;
3334
#[cfg(test)]

0 commit comments

Comments
 (0)