Skip to content

Commit 8b0165d

Browse files
committed
Replace ManyChannelMonitor with chain::Watch
Rename ManyChannelMonitor to chain::Watch and move to chain/mod.rs, where chain-related interfaces live. Update the documentation for clarity and to conform to rustdoc formatting.
1 parent 40191e7 commit 8b0165d

File tree

10 files changed

+163
-142
lines changed

10 files changed

+163
-142
lines changed

ARCH.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ need to use are `ChannelManager` and `ChannelMonitor`. `ChannelManager` holds mu
66
channels, routes payments between them, and exposes a simple API to make and receive
77
payments. Individual `ChannelMonitor`s monitor the on-chain state of a channel, punish
88
counterparties if they misbehave, and force-close channels if they contain unresolved
9-
HTLCs which are near expiration. The `ManyChannelMonitor` API provides a way for you to
9+
HTLCs which are near expiration. The `chain::Watch` interface provides a way for you to
1010
receive `ChannelMonitorUpdate`s from `ChannelManager` and persist them to disk before the
1111
channel steps forward.
1212

@@ -45,9 +45,9 @@ At a high level, some of the common interfaces fit together as follows:
4545
| \ | | / ---------> | BroadcasterInterface |
4646
| \ | | / / | ------------------------
4747
| \ v v v / v ^
48-
| (as ------------------ ----------------------
49-
| ChannelMessageHandler)-> | ChannelManager | ----> | ManyChannelMonitor |
50-
v / ------------------ ----------------------
48+
| (as ------------------ ----------------
49+
| ChannelMessageHandler)-> | ChannelManager | ----> | chain::Watch |
50+
v / ------------------ ----------------
5151
--------------- / (as EventsProvider)
5252
| PeerManager |- \ /
5353
--------------- \ /

fuzz/src/chanmon_consistency.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use bitcoin::hashes::Hash as TraitImport;
2020
use bitcoin::hashes::sha256::Hash as Sha256;
2121
use bitcoin::hash_types::{BlockHash, WPubkeyHash};
2222

23+
use lightning::chain;
2324
use lightning::chain::transaction::OutPoint;
2425
use lightning::chain::chaininterface::{BroadcasterInterface, ChainListener, ConfirmationTarget, FeeEstimator};
2526
use lightning::chain::keysinterface::{KeysInterface, InMemoryChannelKeys};
@@ -95,21 +96,21 @@ impl TestChannelMonitor {
9596
}
9697
}
9798
}
98-
impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
99+
impl chain::Watch for TestChannelMonitor {
99100
type Keys = EnforcingChannelKeys;
100101

101-
fn add_monitor(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
102+
fn watch_channel(&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<EnforcingChannelKeys>) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
102103
let mut ser = VecWriter(Vec::new());
103104
monitor.write_for_disk(&mut ser).unwrap();
104105
if let Some(_) = self.latest_monitors.lock().unwrap().insert(funding_txo, (monitor.get_latest_update_id(), ser.0)) {
105-
panic!("Already had monitor pre-add_monitor");
106+
panic!("Already had monitor pre-watch_channel");
106107
}
107108
self.should_update_manager.store(true, atomic::Ordering::Relaxed);
108-
assert!(self.simple_monitor.add_monitor(funding_txo, monitor).is_ok());
109+
assert!(self.simple_monitor.watch_channel(funding_txo, monitor).is_ok());
109110
self.update_ret.lock().unwrap().clone()
110111
}
111112

112-
fn update_monitor(&self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
113+
fn update_channel(&self, funding_txo: OutPoint, update: channelmonitor::ChannelMonitorUpdate) -> Result<(), channelmonitor::ChannelMonitorUpdateErr> {
113114
let mut map_lock = self.latest_monitors.lock().unwrap();
114115
let mut map_entry = match map_lock.entry(funding_txo) {
115116
hash_map::Entry::Occupied(entry) => entry,
@@ -125,8 +126,8 @@ impl channelmonitor::ManyChannelMonitor for TestChannelMonitor {
125126
self.update_ret.lock().unwrap().clone()
126127
}
127128

128-
fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate> {
129-
return self.simple_monitor.get_and_clear_pending_htlcs_updated();
129+
fn release_pending_htlc_updates(&self) -> Vec<HTLCUpdate> {
130+
return self.simple_monitor.release_pending_htlc_updates();
130131
}
131132
}
132133

@@ -204,7 +205,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
204205
macro_rules! reload_node {
205206
($ser: expr, $node_id: expr, $old_monitors: expr) => { {
206207
let logger: Arc<dyn Logger> = Arc::new(test_logger::TestLogger::new($node_id.to_string(), out.clone()));
207-
let monitor = Arc::new(TestChannelMonitor::new(broadcast.clone(), logger.clone(), fee_est.clone()));
208+
let chain_monitor = Arc::new(TestChannelMonitor::new(broadcast.clone(), logger.clone(), fee_est.clone()));
208209

209210
let keys_manager = Arc::new(KeyProvider { node_id: $node_id, session_id: atomic::AtomicU8::new(0), channel_id: atomic::AtomicU8::new(0) });
210211
let mut config = UserConfig::default();
@@ -216,7 +217,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
216217
let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
217218
for (outpoint, (update_id, monitor_ser)) in old_monitors.drain() {
218219
monitors.insert(outpoint, <(BlockHash, ChannelMonitor<EnforcingChannelKeys>)>::read(&mut Cursor::new(&monitor_ser)).expect("Failed to read monitor").1);
219-
monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
220+
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, (update_id, monitor_ser));
220221
}
221222
let mut monitor_refs = HashMap::new();
222223
for (outpoint, monitor) in monitors.iter_mut() {
@@ -226,14 +227,14 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
226227
let read_args = ChannelManagerReadArgs {
227228
keys_manager,
228229
fee_estimator: fee_est.clone(),
229-
monitor: monitor.clone(),
230+
chain_monitor: chain_monitor.clone(),
230231
tx_broadcaster: broadcast.clone(),
231232
logger,
232233
default_config: config,
233234
channel_monitors: &mut monitor_refs,
234235
};
235236

236-
(<(BlockHash, ChannelManager<EnforcingChannelKeys, Arc<TestChannelMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, monitor)
237+
(<(BlockHash, ChannelManager<EnforcingChannelKeys, Arc<TestChannelMonitor>, Arc<TestBroadcaster>, Arc<KeyProvider>, Arc<FuzzEstimator>, Arc<dyn Logger>>)>::read(&mut Cursor::new(&$ser.0), read_args).expect("Failed to read manager").1, chain_monitor)
237238
} }
238239
}
239240

lightning/src/chain/mod.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use bitcoin::blockdata::script::Script;
44
use bitcoin::blockdata::transaction::TxOut;
55
use bitcoin::hash_types::{BlockHash, Txid};
66

7+
use chain::keysinterface::ChannelKeys;
78
use chain::transaction::OutPoint;
9+
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, HTLCUpdate};
810

911
pub mod chaininterface;
1012
pub mod transaction;
@@ -32,6 +34,51 @@ pub enum AccessError {
3234
UnknownTx,
3335
}
3436

37+
/// The `Watch` trait defines behavior for watching on-chain activity pertaining to channels as
38+
/// blocks are connected and disconnected.
39+
///
40+
/// Each channel is associated with a [`ChannelMonitor`]. Implementations are responsible for
41+
/// maintaining a set of monitors and updating them accordingly as channel state changes and HTLCs
42+
/// are resolved on chain. See method documentation for specific requirements.
43+
///
44+
/// TODO: Add documentation about persisting monitors.
45+
///
46+
/// If an implementation maintains multiple instances of a channel's monitor (e.g., by using a
47+
/// watchtower), then it must ensure that updates are applied across all instances. Otherwise, it
48+
/// could result in a revoked transaction being broadcast, allowing the counterparty to claim all
49+
/// funds in the channel.
50+
///
51+
/// [`ChannelMonitor`]: ../ln/channelmonitor/struct.ChannelMonitor.html
52+
pub trait Watch: Send + Sync {
53+
/// Keys needed by monitors for creating and signing transactions.
54+
type Keys: ChannelKeys;
55+
56+
/// Watches a channel identified by `funding_txo` using `monitor`.
57+
///
58+
/// Implementations are responsible for watching the chain for the funding transaction along
59+
/// with spends of its output and any outputs returned by [`get_outputs_to_watch`]. In practice,
60+
/// this means calling [`block_connected`] and [`block_disconnected`] on the monitor and
61+
/// including all such transactions that meet this criteria.
62+
///
63+
/// [`get_outputs_to_watch`]: ../ln/channelmonitor/struct.ChannelMonitor.html#method.get_outputs_to_watch
64+
/// [`block_connected`]: ../ln/channelmonitor/struct.ChannelMonitor.html#method.block_connected
65+
/// [`block_disconnected`]: ../ln/channelmonitor/struct.ChannelMonitor.html#method.block_disconnected
66+
fn watch_channel(&self, funding_txo: OutPoint, monitor: ChannelMonitor<Self::Keys>) -> Result<(), ChannelMonitorUpdateErr>;
67+
68+
/// Updates a channel identified by `funding_txo` by applying `update` to its monitor.
69+
///
70+
/// Implementations must call [`update_monitor`] with the given update. See
71+
/// [`ChannelMonitorUpdateErr`] for invariants around returning an error.
72+
///
73+
/// [`update_monitor`]: ../ln/channelmonitor/struct.ChannelMonitor.html#method.update_monitor
74+
/// [`ChannelMonitorUpdateErr`]: ../ln/channelmonitor/enum.ChannelMonitorUpdateErr.html
75+
fn update_channel(&self, funding_txo: OutPoint, update: ChannelMonitorUpdate) -> Result<(), ChannelMonitorUpdateErr>;
76+
77+
/// Returns any HTLCs resolved on chain since the last call. Subsequent calls must only return
78+
/// newly resolved HTLCs.
79+
fn release_pending_htlc_updates(&self) -> Vec<HTLCUpdate>;
80+
}
81+
3582
/// An interface for providing [`WatchEvent`]s.
3683
///
3784
/// [`WatchEvent`]: enum.WatchEvent.html

0 commit comments

Comments
 (0)