Skip to content

Commit d205d8d

Browse files
committed
Use channel ID over funding outpoint to track monitors in ChainMonitor
Once dual funding/splicing is supported, channels will no longer maintain their original funding outpoint. Ideally, we identify `ChannelMonitor`s with a stable identifier, such as the channel ID, which is fixed throughout the channel's lifetime. This commit replaces the use of funding outpoints as the key to the monitor index with the channel ID. Note that this is strictly done to the in-memory state; it does not change how we track monitors within their persisted state, they are still keyed by their funding outpoint there. Addressing that is left for follow-up work.
1 parent 569f906 commit d205d8d

14 files changed

+389
-390
lines changed

fuzz/src/chanmon_consistency.rs

+49-42
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ struct LatestMonitorState {
173173
/// A set of (monitor id, serialized `ChannelMonitor`)s which we're currently "persisting",
174174
/// from LDK's perspective.
175175
pending_monitors: Vec<(u64, Vec<u8>)>,
176+
funding_txo: OutPoint,
176177
}
177178

178179
struct TestChainMonitor {
@@ -189,7 +190,7 @@ struct TestChainMonitor {
189190
Arc<TestPersister>,
190191
>,
191192
>,
192-
pub latest_monitors: Mutex<HashMap<OutPoint, LatestMonitorState>>,
193+
pub latest_monitors: Mutex<HashMap<ChannelId, LatestMonitorState>>,
193194
}
194195
impl TestChainMonitor {
195196
pub fn new(
@@ -213,35 +214,37 @@ impl TestChainMonitor {
213214
}
214215
impl chain::Watch<TestChannelSigner> for TestChainMonitor {
215216
fn watch_channel(
216-
&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
217+
&self, channel_id: ChannelId, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
217218
) -> Result<chain::ChannelMonitorUpdateStatus, ()> {
218219
let mut ser = VecWriter(Vec::new());
219220
monitor.write(&mut ser).unwrap();
220221
let monitor_id = monitor.get_latest_update_id();
221-
let res = self.chain_monitor.watch_channel(funding_txo, monitor);
222+
let funding_txo = monitor.get_funding_txo().0;
223+
let res = self.chain_monitor.watch_channel(channel_id, monitor);
222224
let state = match res {
223225
Ok(chain::ChannelMonitorUpdateStatus::Completed) => LatestMonitorState {
224226
persisted_monitor_id: monitor_id,
225227
persisted_monitor: ser.0,
226228
pending_monitors: Vec::new(),
229+
funding_txo,
227230
},
228231
Ok(chain::ChannelMonitorUpdateStatus::InProgress) => {
229232
panic!("The test currently doesn't test initial-persistence via the async pipeline")
230233
},
231234
Ok(chain::ChannelMonitorUpdateStatus::UnrecoverableError) => panic!(),
232235
Err(()) => panic!(),
233236
};
234-
if self.latest_monitors.lock().unwrap().insert(funding_txo, state).is_some() {
237+
if self.latest_monitors.lock().unwrap().insert(channel_id, state).is_some() {
235238
panic!("Already had monitor pre-watch_channel");
236239
}
237240
res
238241
}
239242

240243
fn update_channel(
241-
&self, funding_txo: OutPoint, update: &channelmonitor::ChannelMonitorUpdate,
244+
&self, channel_id: ChannelId, update: &channelmonitor::ChannelMonitorUpdate,
242245
) -> chain::ChannelMonitorUpdateStatus {
243246
let mut map_lock = self.latest_monitors.lock().unwrap();
244-
let map_entry = map_lock.get_mut(&funding_txo).expect("Didn't have monitor on update call");
247+
let map_entry = map_lock.get_mut(&channel_id).expect("Didn't have monitor on update call");
245248
let latest_monitor_data = map_entry
246249
.pending_monitors
247250
.last()
@@ -265,7 +268,7 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
265268
.unwrap();
266269
let mut ser = VecWriter(Vec::new());
267270
deserialized_monitor.write(&mut ser).unwrap();
268-
let res = self.chain_monitor.update_channel(funding_txo, update);
271+
let res = self.chain_monitor.update_channel(channel_id, update);
269272
match res {
270273
chain::ChannelMonitorUpdateStatus::Completed => {
271274
map_entry.persisted_monitor_id = update.update_id;
@@ -711,9 +714,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
711714

712715
let mut monitors = new_hash_map();
713716
let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
714-
for (outpoint, mut prev_state) in old_monitors.drain() {
717+
for (channel_id, mut prev_state) in old_monitors.drain() {
715718
monitors.insert(
716-
outpoint,
719+
prev_state.funding_txo,
717720
<(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
718721
&mut Cursor::new(&prev_state.persisted_monitor),
719722
(&*$keys_manager, &*$keys_manager),
@@ -725,7 +728,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
725728
// considering them discarded. LDK should replay these for us as they're stored in
726729
// the `ChannelManager`.
727730
prev_state.pending_monitors.clear();
728-
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, prev_state);
731+
chain_monitor.latest_monitors.lock().unwrap().insert(channel_id, prev_state);
729732
}
730733
let mut monitor_refs = new_hash_map();
731734
for (outpoint, monitor) in monitors.iter() {
@@ -752,9 +755,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
752755
.1,
753756
chain_monitor.clone(),
754757
);
755-
for (funding_txo, mon) in monitors.drain() {
758+
for (_, mon) in monitors.drain() {
756759
assert_eq!(
757-
chain_monitor.chain_monitor.watch_channel(funding_txo, mon),
760+
chain_monitor.chain_monitor.watch_channel(mon.channel_id(), mon),
758761
Ok(ChannelMonitorUpdateStatus::Completed)
759762
);
760763
}
@@ -825,7 +828,6 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
825828
};
826829

827830
$source.handle_accept_channel($dest.get_our_node_id(), &accept_channel);
828-
let funding_output;
829831
{
830832
let mut events = $source.get_and_clear_pending_events();
831833
assert_eq!(events.len(), 1);
@@ -845,7 +847,6 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
845847
script_pubkey: output_script,
846848
}],
847849
};
848-
funding_output = OutPoint { txid: tx.compute_txid(), index: 0 };
849850
$source
850851
.funding_transaction_generated(
851852
temporary_channel_id,
@@ -890,13 +891,19 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
890891
$source.handle_funding_signed($dest.get_our_node_id(), &funding_signed);
891892
let events = $source.get_and_clear_pending_events();
892893
assert_eq!(events.len(), 1);
893-
if let events::Event::ChannelPending { ref counterparty_node_id, .. } = events[0] {
894+
let channel_id = if let events::Event::ChannelPending {
895+
ref counterparty_node_id,
896+
ref channel_id,
897+
..
898+
} = events[0]
899+
{
894900
assert_eq!(counterparty_node_id, &$dest.get_our_node_id());
901+
channel_id.clone()
895902
} else {
896903
panic!("Wrong event type");
897-
}
904+
};
898905

899-
funding_output
906+
channel_id
900907
}};
901908
}
902909

@@ -963,8 +970,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
963970

964971
let mut nodes = [node_a, node_b, node_c];
965972

966-
let chan_1_funding = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
967-
let chan_2_funding = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
973+
let chan_1_id = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
974+
let chan_2_id = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
968975

969976
for node in nodes.iter() {
970977
confirm_txn!(node);
@@ -1363,14 +1370,14 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
13631370
}
13641371
};
13651372

1366-
let complete_all_monitor_updates = |monitor: &Arc<TestChainMonitor>, chan_funding| {
1367-
if let Some(state) = monitor.latest_monitors.lock().unwrap().get_mut(chan_funding) {
1373+
let complete_all_monitor_updates = |monitor: &Arc<TestChainMonitor>, chan_id| {
1374+
if let Some(state) = monitor.latest_monitors.lock().unwrap().get_mut(chan_id) {
13681375
assert!(
13691376
state.pending_monitors.windows(2).all(|pair| pair[0].0 < pair[1].0),
13701377
"updates should be sorted by id"
13711378
);
13721379
for (id, data) in state.pending_monitors.drain(..) {
1373-
monitor.chain_monitor.channel_monitor_updated(*chan_funding, id).unwrap();
1380+
monitor.chain_monitor.channel_monitor_updated(*chan_id, id).unwrap();
13741381
if id > state.persisted_monitor_id {
13751382
state.persisted_monitor_id = id;
13761383
state.persisted_monitor = data;
@@ -1410,10 +1417,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
14101417
ChannelMonitorUpdateStatus::Completed
14111418
},
14121419

1413-
0x08 => complete_all_monitor_updates(&monitor_a, &chan_1_funding),
1414-
0x09 => complete_all_monitor_updates(&monitor_b, &chan_1_funding),
1415-
0x0a => complete_all_monitor_updates(&monitor_b, &chan_2_funding),
1416-
0x0b => complete_all_monitor_updates(&monitor_c, &chan_2_funding),
1420+
0x08 => complete_all_monitor_updates(&monitor_a, &chan_1_id),
1421+
0x09 => complete_all_monitor_updates(&monitor_b, &chan_1_id),
1422+
0x0a => complete_all_monitor_updates(&monitor_b, &chan_2_id),
1423+
0x0b => complete_all_monitor_updates(&monitor_c, &chan_2_id),
14171424

14181425
0x0c => {
14191426
if !chan_a_disconnected {
@@ -1683,21 +1690,21 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
16831690
nodes[2].maybe_update_chan_fees();
16841691
},
16851692

1686-
0xf0 => complete_monitor_update(&monitor_a, &chan_1_funding, &complete_first),
1687-
0xf1 => complete_monitor_update(&monitor_a, &chan_1_funding, &complete_second),
1688-
0xf2 => complete_monitor_update(&monitor_a, &chan_1_funding, &Vec::pop),
1693+
0xf0 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_first),
1694+
0xf1 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_second),
1695+
0xf2 => complete_monitor_update(&monitor_a, &chan_1_id, &Vec::pop),
16891696

1690-
0xf4 => complete_monitor_update(&monitor_b, &chan_1_funding, &complete_first),
1691-
0xf5 => complete_monitor_update(&monitor_b, &chan_1_funding, &complete_second),
1692-
0xf6 => complete_monitor_update(&monitor_b, &chan_1_funding, &Vec::pop),
1697+
0xf4 => complete_monitor_update(&monitor_b, &chan_1_id, &complete_first),
1698+
0xf5 => complete_monitor_update(&monitor_b, &chan_1_id, &complete_second),
1699+
0xf6 => complete_monitor_update(&monitor_b, &chan_1_id, &Vec::pop),
16931700

1694-
0xf8 => complete_monitor_update(&monitor_b, &chan_2_funding, &complete_first),
1695-
0xf9 => complete_monitor_update(&monitor_b, &chan_2_funding, &complete_second),
1696-
0xfa => complete_monitor_update(&monitor_b, &chan_2_funding, &Vec::pop),
1701+
0xf8 => complete_monitor_update(&monitor_b, &chan_2_id, &complete_first),
1702+
0xf9 => complete_monitor_update(&monitor_b, &chan_2_id, &complete_second),
1703+
0xfa => complete_monitor_update(&monitor_b, &chan_2_id, &Vec::pop),
16971704

1698-
0xfc => complete_monitor_update(&monitor_c, &chan_2_funding, &complete_first),
1699-
0xfd => complete_monitor_update(&monitor_c, &chan_2_funding, &complete_second),
1700-
0xfe => complete_monitor_update(&monitor_c, &chan_2_funding, &Vec::pop),
1705+
0xfc => complete_monitor_update(&monitor_c, &chan_2_id, &complete_first),
1706+
0xfd => complete_monitor_update(&monitor_c, &chan_2_id, &complete_second),
1707+
0xfe => complete_monitor_update(&monitor_c, &chan_2_id, &Vec::pop),
17011708

17021709
0xff => {
17031710
// Test that no channel is in a stuck state where neither party can send funds even
@@ -1711,10 +1718,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
17111718
*monitor_c.persister.update_ret.lock().unwrap() =
17121719
ChannelMonitorUpdateStatus::Completed;
17131720

1714-
complete_all_monitor_updates(&monitor_a, &chan_1_funding);
1715-
complete_all_monitor_updates(&monitor_b, &chan_1_funding);
1716-
complete_all_monitor_updates(&monitor_b, &chan_2_funding);
1717-
complete_all_monitor_updates(&monitor_c, &chan_2_funding);
1721+
complete_all_monitor_updates(&monitor_a, &chan_1_id);
1722+
complete_all_monitor_updates(&monitor_b, &chan_1_id);
1723+
complete_all_monitor_updates(&monitor_b, &chan_2_id);
1724+
complete_all_monitor_updates(&monitor_c, &chan_2_id);
17181725

17191726
// Next, make sure peers are all connected to each other
17201727
if chan_a_disconnected {

lightning-block-sync/src/init.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ where
125125
///
126126
/// // Allow the chain monitor to watch any channels.
127127
/// let monitor = monitor_listener.0;
128-
/// chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);
128+
/// chain_monitor.watch_channel(monitor.channel_id(), monitor);
129129
///
130130
/// // Create an SPV client to notify the chain monitor and channel manager of block events.
131131
/// let chain_poller = poll::ChainPoller::new(block_source, Network::Bitcoin);

0 commit comments

Comments
 (0)