Skip to content

Commit 4bf6747

Browse files
committed
Remove BlockNotifier
BlockNotifier is a convenience for handing blocks to listeners. However, it requires that each listener conforms to the ChainListener interface. Additionally, there are only two listeners, ChannelManager and ChainMonitor, the latter of which may not be used when monitoring channels remotely. Remove BlockNotifier since it doesn't provide much value and constrains each listener to a specific interface.
1 parent 2080e95 commit 4bf6747

File tree

4 files changed

+6
-160
lines changed

4 files changed

+6
-160
lines changed

lightning/src/chain/chaininterface.rs

Lines changed: 1 addition & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,12 @@
1313
//! Includes traits for monitoring and receiving notifications of new blocks and block
1414
//! disconnections, transaction broadcasting, and feerate information requests.
1515
16-
use bitcoin::blockdata::block::{Block, BlockHeader};
16+
use bitcoin::blockdata::block::BlockHeader;
1717
use bitcoin::blockdata::transaction::Transaction;
1818
use bitcoin::blockdata::script::Script;
1919
use bitcoin::hash_types::Txid;
2020

21-
use std::sync::{Mutex, Arc};
2221
use std::collections::HashSet;
23-
use std::ops::Deref;
24-
use std::marker::PhantomData;
25-
use std::ptr;
2622

2723
/// An interface to send a transaction to the Bitcoin network.
2824
pub trait BroadcasterInterface: Sync + Send {
@@ -161,139 +157,3 @@ impl ChainWatchedUtil {
161157
false
162158
}
163159
}
164-
165-
/// BlockNotifierArc is useful when you need a BlockNotifier that points to ChainListeners with
166-
/// static lifetimes, e.g. when you're using lightning-net-tokio (since tokio::spawn requires
167-
/// parameters with static lifetimes). Other times you can afford a reference, which is more
168-
/// efficient, in which case BlockNotifierRef is a more appropriate type. Defining these type
169-
/// aliases prevents issues such as overly long function definitions.
170-
pub type BlockNotifierArc = Arc<BlockNotifier<'static, Arc<ChainListener>>>;
171-
172-
/// BlockNotifierRef is useful when you want a BlockNotifier that points to ChainListeners
173-
/// with nonstatic lifetimes. This is useful for when static lifetimes are not needed. Nonstatic
174-
/// lifetimes are more efficient but less flexible, and should be used by default unless static
175-
/// lifetimes are required, e.g. when you're using lightning-net-tokio (since tokio::spawn
176-
/// requires parameters with static lifetimes), in which case BlockNotifierArc is a more
177-
/// appropriate type. Defining these type aliases for common usages prevents issues such as
178-
/// overly long function definitions.
179-
pub type BlockNotifierRef<'a> = BlockNotifier<'a, &'a ChainListener>;
180-
181-
/// Utility for notifying listeners when blocks are connected or disconnected.
182-
///
183-
/// Rather than using a plain BlockNotifier, it is preferable to use either a BlockNotifierArc
184-
/// or a BlockNotifierRef for conciseness. See their documentation for more details, but essentially
185-
/// you should default to using a BlockNotifierRef, and use a BlockNotifierArc instead when you
186-
/// require ChainListeners with static lifetimes, such as when you're using lightning-net-tokio.
187-
pub struct BlockNotifier<'a, CL: Deref + 'a>
188-
where CL::Target: ChainListener + 'a {
189-
listeners: Mutex<Vec<CL>>,
190-
phantom: PhantomData<&'a ()>,
191-
}
192-
193-
impl<'a, CL: Deref + 'a> BlockNotifier<'a, CL>
194-
where CL::Target: ChainListener + 'a {
195-
/// Constructs a new BlockNotifier without any listeners.
196-
pub fn new() -> BlockNotifier<'a, CL> {
197-
BlockNotifier {
198-
listeners: Mutex::new(Vec::new()),
199-
phantom: PhantomData,
200-
}
201-
}
202-
203-
/// Register the given listener to receive events.
204-
pub fn register_listener(&self, listener: CL) {
205-
let mut vec = self.listeners.lock().unwrap();
206-
vec.push(listener);
207-
}
208-
/// Unregister the given listener to no longer
209-
/// receive events.
210-
///
211-
/// If the same listener is registered multiple times, unregistering
212-
/// will remove ALL occurrences of that listener. Comparison is done using
213-
/// the pointer returned by the Deref trait implementation.
214-
pub fn unregister_listener(&self, listener: CL) {
215-
let mut vec = self.listeners.lock().unwrap();
216-
// item is a ref to an abstract thing that dereferences to a ChainListener,
217-
// so dereference it twice to get the ChainListener itself
218-
vec.retain(|item | !ptr::eq(&(**item), &(*listener)));
219-
}
220-
221-
/// Notify listeners that a block was connected.
222-
pub fn block_connected(&self, block: &Block, height: u32) {
223-
let txdata: Vec<_> = block.txdata.iter().enumerate().collect();
224-
let listeners = self.listeners.lock().unwrap();
225-
for listener in listeners.iter() {
226-
listener.block_connected(&block.header, &txdata, height);
227-
}
228-
}
229-
230-
/// Notify listeners that a block was disconnected.
231-
pub fn block_disconnected(&self, header: &BlockHeader, disconnected_height: u32) {
232-
let listeners = self.listeners.lock().unwrap();
233-
for listener in listeners.iter() {
234-
listener.block_disconnected(&header, disconnected_height);
235-
}
236-
}
237-
}
238-
239-
#[cfg(test)]
240-
mod tests {
241-
use bitcoin::blockdata::block::BlockHeader;
242-
use bitcoin::blockdata::transaction::Transaction;
243-
use super::{BlockNotifier, ChainListener};
244-
use std::ptr;
245-
246-
struct TestChainListener(u8);
247-
248-
impl ChainListener for TestChainListener {
249-
fn block_connected(&self, _header: &BlockHeader, _txdata: &[(usize, &Transaction)], _height: u32) {}
250-
fn block_disconnected(&self, _header: &BlockHeader, _disconnected_height: u32) {}
251-
}
252-
253-
#[test]
254-
fn register_listener_test() {
255-
let block_notifier = BlockNotifier::new();
256-
assert_eq!(block_notifier.listeners.lock().unwrap().len(), 0);
257-
let listener = &TestChainListener(0);
258-
block_notifier.register_listener(listener as &ChainListener);
259-
let vec = block_notifier.listeners.lock().unwrap();
260-
assert_eq!(vec.len(), 1);
261-
let item = vec.first().unwrap();
262-
assert!(ptr::eq(&(**item), listener));
263-
}
264-
265-
#[test]
266-
fn unregister_single_listener_test() {
267-
let block_notifier = BlockNotifier::new();
268-
let listener1 = &TestChainListener(1);
269-
let listener2 = &TestChainListener(2);
270-
block_notifier.register_listener(listener1 as &ChainListener);
271-
block_notifier.register_listener(listener2 as &ChainListener);
272-
let vec = block_notifier.listeners.lock().unwrap();
273-
assert_eq!(vec.len(), 2);
274-
drop(vec);
275-
block_notifier.unregister_listener(listener1);
276-
let vec = block_notifier.listeners.lock().unwrap();
277-
assert_eq!(vec.len(), 1);
278-
let item = vec.first().unwrap();
279-
assert!(ptr::eq(&(**item), listener2));
280-
}
281-
282-
#[test]
283-
fn unregister_multiple_of_the_same_listeners_test() {
284-
let block_notifier = BlockNotifier::new();
285-
let listener1 = &TestChainListener(1);
286-
let listener2 = &TestChainListener(2);
287-
block_notifier.register_listener(listener1 as &ChainListener);
288-
block_notifier.register_listener(listener1 as &ChainListener);
289-
block_notifier.register_listener(listener2 as &ChainListener);
290-
let vec = block_notifier.listeners.lock().unwrap();
291-
assert_eq!(vec.len(), 3);
292-
drop(vec);
293-
block_notifier.unregister_listener(listener1);
294-
let vec = block_notifier.listeners.lock().unwrap();
295-
assert_eq!(vec.len(), 1);
296-
let item = vec.first().unwrap();
297-
assert!(ptr::eq(&(**item), listener2));
298-
}
299-
}

lightning/src/ln/channelmanager.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,6 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
717717
///
718718
/// Users need to notify the new ChannelManager when a new block is connected or
719719
/// disconnected using its `block_connected` and `block_disconnected` methods.
720-
/// However, rather than calling these methods directly, the user should register
721-
/// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's
722-
/// `block_(dis)connected` methods, which will notify all registered listeners in one
723-
/// go.
724720
pub fn new(network: Network, fee_est: F, chain_monitor: M, tx_broadcaster: T, logger: L, keys_manager: K, config: UserConfig, current_blockchain_height: usize) -> Self {
725721
let secp_ctx = Secp256k1::new();
726722

lightning/src/ln/functional_test_utils.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
use chain;
1414
use chain::Watch;
15-
use chain::chaininterface;
15+
use chain::chaininterface::ChainListener;
1616
use chain::transaction::OutPoint;
1717
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
1818
use ln::channelmonitor::ChannelMonitor;
@@ -84,7 +84,6 @@ pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32, he
8484

8585
pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, height: u32) {
8686
use chain::WatchEventProvider;
87-
use chain::chaininterface::ChainListener;
8887

8988
let watch_events = node.chain_monitor.chain_monitor.release_pending_watch_events();
9089
process_chain_watch_events(&watch_events);
@@ -107,7 +106,8 @@ pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block,
107106
fn process_chain_watch_events(_events: &Vec<chain::WatchEvent>) {}
108107

109108
pub fn disconnect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, header: &BlockHeader, height: u32) {
110-
node.block_notifier.block_disconnected(header, height)
109+
node.chain_monitor.chain_monitor.block_disconnected(header, height);
110+
node.node.block_disconnected(header, height);
111111
}
112112

113113
pub struct TestChanMonCfg {
@@ -128,7 +128,6 @@ pub struct NodeCfg<'a> {
128128
}
129129

130130
pub struct Node<'a, 'b: 'a, 'c: 'b> {
131-
pub block_notifier: chaininterface::BlockNotifierRef<'a>,
132131
pub chain_source: &'c test_utils::TestChainSource,
133132
pub tx_broadcaster: &'c test_utils::TestBroadcaster,
134133
pub chain_monitor: &'b test_utils::TestChainMonitor<'c>,
@@ -1150,11 +1149,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
11501149
let payment_count = Rc::new(RefCell::new(0));
11511150

11521151
for i in 0..node_count {
1153-
let block_notifier = chaininterface::BlockNotifier::new();
1154-
block_notifier.register_listener(&cfgs[i].chain_monitor.chain_monitor as &chaininterface::ChainListener);
1155-
block_notifier.register_listener(&chan_mgrs[i] as &chaininterface::ChainListener);
11561152
let net_graph_msg_handler = NetGraphMsgHandler::new(None, cfgs[i].logger);
1157-
nodes.push(Node{ chain_source: cfgs[i].chain_source, block_notifier,
1153+
nodes.push(Node{ chain_source: cfgs[i].chain_source,
11581154
tx_broadcaster: cfgs[i].tx_broadcaster, chain_monitor: &cfgs[i].chain_monitor,
11591155
keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
11601156
node_seed: cfgs[i].node_seed, network_chan_count: chan_count.clone(),

lightning/src/ln/functional_tests.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use chain::Watch;
1515
use chain::transaction::OutPoint;
1616
use chain::keysinterface::{ChannelKeys, KeysInterface, SpendableOutputDescriptor};
17-
use chain::chaininterface::{ChainListener, BlockNotifier};
17+
use chain::chaininterface::ChainListener;
1818
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
1919
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure, BREAKDOWN_TIMEOUT};
2020
use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
@@ -4353,7 +4353,6 @@ fn test_no_txn_manager_serialize_deserialize() {
43534353

43544354
assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
43554355
nodes[0].node = &nodes_0_deserialized;
4356-
nodes[0].block_notifier.register_listener(nodes[0].node);
43574356
assert_eq!(nodes[0].node.list_channels().len(), 1);
43584357
check_added_monitors!(nodes[0], 1);
43594358

@@ -4476,7 +4475,6 @@ fn test_manager_serialize_deserialize_events() {
44764475
};
44774476

44784477
// Make sure the channel is functioning as though the de/serialization never happened
4479-
nodes[0].block_notifier.register_listener(nodes[0].node);
44804478
assert_eq!(nodes[0].node.list_channels().len(), 1);
44814479
check_added_monitors!(nodes[0], 1);
44824480

@@ -7941,10 +7939,6 @@ fn test_data_loss_protect() {
79417939
nodes[0].chain_monitor = &monitor;
79427940
nodes[0].chain_source = &chain_source;
79437941

7944-
nodes[0].block_notifier = BlockNotifier::new();
7945-
nodes[0].block_notifier.register_listener(&nodes[0].chain_monitor.chain_monitor);
7946-
nodes[0].block_notifier.register_listener(nodes[0].node);
7947-
79487942
check_added_monitors!(nodes[0], 1);
79497943

79507944
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });

0 commit comments

Comments
 (0)