Skip to content

Commit 382c71c

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 addc49d commit 382c71c

File tree

4 files changed

+6
-158
lines changed

4 files changed

+6
-158
lines changed

lightning/src/chain/chaininterface.rs

Lines changed: 1 addition & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44
//! Includes traits for monitoring and receiving notifications of new blocks and block
55
//! disconnections, transaction broadcasting, and feerate information requests.
66
7-
use bitcoin::blockdata::block::{Block, BlockHeader};
7+
use bitcoin::blockdata::block::BlockHeader;
88
use bitcoin::blockdata::transaction::Transaction;
99
use bitcoin::blockdata::script::Script;
1010
use bitcoin::hash_types::Txid;
1111

12-
use std::sync::{Mutex, Arc};
1312
use std::collections::HashSet;
14-
use std::ops::Deref;
15-
use std::marker::PhantomData;
16-
use std::ptr;
1713

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

lightning/src/ln/channelmanager.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,10 +706,6 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
706706
///
707707
/// Users need to notify the new ChannelManager when a new block is connected or
708708
/// disconnected using its `block_connected` and `block_disconnected` methods.
709-
/// However, rather than calling these methods directly, the user should register
710-
/// the ChannelManager as a listener to the BlockNotifier and call the BlockNotifier's
711-
/// `block_(dis)connected` methods, which will notify all registered listeners in one
712-
/// go.
713709
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 {
714710
let secp_ctx = Secp256k1::new();
715711

lightning/src/ln/functional_test_utils.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use chain;
55
use chain::Watch;
6-
use chain::chaininterface;
6+
use chain::chaininterface::ChainListener;
77
use chain::transaction::OutPoint;
88
use ln::channelmanager::{ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure};
99
use ln::channelmonitor::ChannelMonitor;
@@ -75,7 +75,6 @@ pub fn connect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, depth: u32, he
7575

7676
pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block, height: u32) {
7777
use chain::WatchEventProvider;
78-
use chain::chaininterface::ChainListener;
7978

8079
let watch_events = node.chain_monitor.chain_monitor.release_pending_watch_events();
8180
process_chain_watch_events(&watch_events);
@@ -98,7 +97,8 @@ pub fn connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: &Block,
9897
fn process_chain_watch_events(_events: &Vec<chain::WatchEvent>) {}
9998

10099
pub fn disconnect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, header: &BlockHeader, height: u32) {
101-
node.block_notifier.block_disconnected(header, height)
100+
node.chain_monitor.chain_monitor.block_disconnected(header, height);
101+
node.node.block_disconnected(header, height);
102102
}
103103

104104
pub struct TestChanMonCfg {
@@ -119,7 +119,6 @@ pub struct NodeCfg<'a> {
119119
}
120120

121121
pub struct Node<'a, 'b: 'a, 'c: 'b> {
122-
pub block_notifier: chaininterface::BlockNotifierRef<'a>,
123122
pub chain_source: &'c test_utils::TestChainSource,
124123
pub tx_broadcaster: &'c test_utils::TestBroadcaster,
125124
pub chain_monitor: &'b test_utils::TestChainMonitor<'c>,
@@ -1141,11 +1140,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
11411140
let payment_count = Rc::new(RefCell::new(0));
11421141

11431142
for i in 0..node_count {
1144-
let block_notifier = chaininterface::BlockNotifier::new();
1145-
block_notifier.register_listener(&cfgs[i].chain_monitor.chain_monitor as &chaininterface::ChainListener);
1146-
block_notifier.register_listener(&chan_mgrs[i] as &chaininterface::ChainListener);
11471143
let net_graph_msg_handler = NetGraphMsgHandler::new(None, cfgs[i].logger);
1148-
nodes.push(Node{ chain_source: cfgs[i].chain_source, block_notifier,
1144+
nodes.push(Node{ chain_source: cfgs[i].chain_source,
11491145
tx_broadcaster: cfgs[i].tx_broadcaster, chain_monitor: &cfgs[i].chain_monitor,
11501146
keys_manager: &cfgs[i].keys_manager, node: &chan_mgrs[i], net_graph_msg_handler,
11511147
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
@@ -5,7 +5,7 @@
55
use chain::Watch;
66
use chain::transaction::OutPoint;
77
use chain::keysinterface::{ChannelKeys, KeysInterface, SpendableOutputDescriptor};
8-
use chain::chaininterface::{ChainListener, BlockNotifier};
8+
use chain::chaininterface::ChainListener;
99
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
1010
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, PaymentSecret, PaymentSendFailure, BREAKDOWN_TIMEOUT};
1111
use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
@@ -4302,7 +4302,6 @@ fn test_no_txn_manager_serialize_deserialize() {
43024302

43034303
assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
43044304
nodes[0].node = &nodes_0_deserialized;
4305-
nodes[0].block_notifier.register_listener(nodes[0].node);
43064305
assert_eq!(nodes[0].node.list_channels().len(), 1);
43074306
check_added_monitors!(nodes[0], 1);
43084307

@@ -4425,7 +4424,6 @@ fn test_manager_serialize_deserialize_events() {
44254424
};
44264425

44274426
// Make sure the channel is functioning as though the de/serialization never happened
4428-
nodes[0].block_notifier.register_listener(nodes[0].node);
44294427
assert_eq!(nodes[0].node.list_channels().len(), 1);
44304428
check_added_monitors!(nodes[0], 1);
44314429

@@ -7554,10 +7552,6 @@ fn test_data_loss_protect() {
75547552
nodes[0].chain_monitor = &monitor;
75557553
nodes[0].chain_source = &chain_source;
75567554

7557-
nodes[0].block_notifier = BlockNotifier::new();
7558-
nodes[0].block_notifier.register_listener(&nodes[0].chain_monitor.chain_monitor);
7559-
nodes[0].block_notifier.register_listener(nodes[0].node);
7560-
75617555
check_added_monitors!(nodes[0], 1);
75627556

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

0 commit comments

Comments
 (0)