Skip to content

Commit 008ba95

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 3d2b4de commit 008ba95

File tree

14 files changed

+379
-380
lines changed

14 files changed

+379
-380
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ struct LatestMonitorState {
182182
/// A set of (monitor id, serialized `ChannelMonitor`)s which we're currently "persisting",
183183
/// from LDK's perspective.
184184
pending_monitors: Vec<(u64, Vec<u8>)>,
185+
funding_txo: OutPoint,
185186
}
186187

187188
struct TestChainMonitor {
@@ -198,7 +199,7 @@ struct TestChainMonitor {
198199
Arc<TestPersister>,
199200
>,
200201
>,
201-
pub latest_monitors: Mutex<HashMap<OutPoint, LatestMonitorState>>,
202+
pub latest_monitors: Mutex<HashMap<ChannelId, LatestMonitorState>>,
202203
}
203204
impl TestChainMonitor {
204205
pub fn new(
@@ -222,35 +223,37 @@ impl TestChainMonitor {
222223
}
223224
impl chain::Watch<TestChannelSigner> for TestChainMonitor {
224225
fn watch_channel(
225-
&self, funding_txo: OutPoint, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
226+
&self, channel_id: ChannelId, monitor: channelmonitor::ChannelMonitor<TestChannelSigner>,
226227
) -> Result<chain::ChannelMonitorUpdateStatus, ()> {
227228
let mut ser = VecWriter(Vec::new());
228229
monitor.write(&mut ser).unwrap();
229230
let monitor_id = monitor.get_latest_update_id();
230-
let res = self.chain_monitor.watch_channel(funding_txo, monitor);
231+
let funding_txo = monitor.get_funding_txo().0;
232+
let res = self.chain_monitor.watch_channel(channel_id, monitor);
231233
let state = match res {
232234
Ok(chain::ChannelMonitorUpdateStatus::Completed) => LatestMonitorState {
233235
persisted_monitor_id: monitor_id,
234236
persisted_monitor: ser.0,
235237
pending_monitors: Vec::new(),
238+
funding_txo,
236239
},
237240
Ok(chain::ChannelMonitorUpdateStatus::InProgress) => {
238241
panic!("The test currently doesn't test initial-persistence via the async pipeline")
239242
},
240243
Ok(chain::ChannelMonitorUpdateStatus::UnrecoverableError) => panic!(),
241244
Err(()) => panic!(),
242245
};
243-
if self.latest_monitors.lock().unwrap().insert(funding_txo, state).is_some() {
246+
if self.latest_monitors.lock().unwrap().insert(channel_id, state).is_some() {
244247
panic!("Already had monitor pre-watch_channel");
245248
}
246249
res
247250
}
248251

249252
fn update_channel(
250-
&self, funding_txo: OutPoint, update: &channelmonitor::ChannelMonitorUpdate,
253+
&self, channel_id: ChannelId, update: &channelmonitor::ChannelMonitorUpdate,
251254
) -> chain::ChannelMonitorUpdateStatus {
252255
let mut map_lock = self.latest_monitors.lock().unwrap();
253-
let map_entry = map_lock.get_mut(&funding_txo).expect("Didn't have monitor on update call");
256+
let map_entry = map_lock.get_mut(&channel_id).expect("Didn't have monitor on update call");
254257
let latest_monitor_data = map_entry
255258
.pending_monitors
256259
.last()
@@ -274,7 +277,7 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
274277
.unwrap();
275278
let mut ser = VecWriter(Vec::new());
276279
deserialized_monitor.write(&mut ser).unwrap();
277-
let res = self.chain_monitor.update_channel(funding_txo, update);
280+
let res = self.chain_monitor.update_channel(channel_id, update);
278281
match res {
279282
chain::ChannelMonitorUpdateStatus::Completed => {
280283
map_entry.persisted_monitor_id = update.update_id;
@@ -722,9 +725,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
722725

723726
let mut monitors = new_hash_map();
724727
let mut old_monitors = $old_monitors.latest_monitors.lock().unwrap();
725-
for (outpoint, mut prev_state) in old_monitors.drain() {
728+
for (channel_id, mut prev_state) in old_monitors.drain() {
726729
monitors.insert(
727-
outpoint,
730+
prev_state.funding_txo,
728731
<(BlockHash, ChannelMonitor<TestChannelSigner>)>::read(
729732
&mut Cursor::new(&prev_state.persisted_monitor),
730733
(&*$keys_manager, &*$keys_manager),
@@ -736,7 +739,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
736739
// considering them discarded. LDK should replay these for us as they're stored in
737740
// the `ChannelManager`.
738741
prev_state.pending_monitors.clear();
739-
chain_monitor.latest_monitors.lock().unwrap().insert(outpoint, prev_state);
742+
chain_monitor.latest_monitors.lock().unwrap().insert(channel_id, prev_state);
740743
}
741744
let mut monitor_refs = new_hash_map();
742745
for (outpoint, monitor) in monitors.iter() {
@@ -763,9 +766,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
763766
.1,
764767
chain_monitor.clone(),
765768
);
766-
for (funding_txo, mon) in monitors.drain() {
769+
for (_, mon) in monitors.drain() {
767770
assert_eq!(
768-
chain_monitor.chain_monitor.watch_channel(funding_txo, mon),
771+
chain_monitor.chain_monitor.watch_channel(mon.channel_id(), mon),
769772
Ok(ChannelMonitorUpdateStatus::Completed)
770773
);
771774
}
@@ -836,7 +839,6 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
836839
};
837840

838841
$source.handle_accept_channel($dest.get_our_node_id(), &accept_channel);
839-
let funding_output;
840842
{
841843
let mut events = $source.get_and_clear_pending_events();
842844
assert_eq!(events.len(), 1);
@@ -856,7 +858,6 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
856858
script_pubkey: output_script,
857859
}],
858860
};
859-
funding_output = OutPoint { txid: tx.compute_txid(), index: 0 };
860861
$source
861862
.funding_transaction_generated(
862863
temporary_channel_id,
@@ -901,13 +902,19 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
901902
$source.handle_funding_signed($dest.get_our_node_id(), &funding_signed);
902903
let events = $source.get_and_clear_pending_events();
903904
assert_eq!(events.len(), 1);
904-
if let events::Event::ChannelPending { ref counterparty_node_id, .. } = events[0] {
905+
let channel_id = if let events::Event::ChannelPending {
906+
ref counterparty_node_id,
907+
ref channel_id,
908+
..
909+
} = events[0]
910+
{
905911
assert_eq!(counterparty_node_id, &$dest.get_our_node_id());
912+
channel_id.clone()
906913
} else {
907914
panic!("Wrong event type");
908-
}
915+
};
909916

910-
funding_output
917+
channel_id
911918
}};
912919
}
913920

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

975982
let mut nodes = [node_a, node_b, node_c];
976983

977-
let chan_1_funding = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
978-
let chan_2_funding = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
984+
let chan_1_id = make_channel!(nodes[0], nodes[1], keys_manager_b, 0);
985+
let chan_2_id = make_channel!(nodes[1], nodes[2], keys_manager_c, 1);
979986

980987
for node in nodes.iter() {
981988
confirm_txn!(node);
@@ -1374,14 +1381,14 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
13741381
}
13751382
};
13761383

1377-
let complete_all_monitor_updates = |monitor: &Arc<TestChainMonitor>, chan_funding| {
1378-
if let Some(state) = monitor.latest_monitors.lock().unwrap().get_mut(chan_funding) {
1384+
let complete_all_monitor_updates = |monitor: &Arc<TestChainMonitor>, chan_id| {
1385+
if let Some(state) = monitor.latest_monitors.lock().unwrap().get_mut(chan_id) {
13791386
assert!(
13801387
state.pending_monitors.windows(2).all(|pair| pair[0].0 < pair[1].0),
13811388
"updates should be sorted by id"
13821389
);
13831390
for (id, data) in state.pending_monitors.drain(..) {
1384-
monitor.chain_monitor.channel_monitor_updated(*chan_funding, id).unwrap();
1391+
monitor.chain_monitor.channel_monitor_updated(*chan_id, id).unwrap();
13851392
if id > state.persisted_monitor_id {
13861393
state.persisted_monitor_id = id;
13871394
state.persisted_monitor = data;
@@ -1421,10 +1428,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
14211428
ChannelMonitorUpdateStatus::Completed
14221429
},
14231430

1424-
0x08 => complete_all_monitor_updates(&monitor_a, &chan_1_funding),
1425-
0x09 => complete_all_monitor_updates(&monitor_b, &chan_1_funding),
1426-
0x0a => complete_all_monitor_updates(&monitor_b, &chan_2_funding),
1427-
0x0b => complete_all_monitor_updates(&monitor_c, &chan_2_funding),
1431+
0x08 => complete_all_monitor_updates(&monitor_a, &chan_1_id),
1432+
0x09 => complete_all_monitor_updates(&monitor_b, &chan_1_id),
1433+
0x0a => complete_all_monitor_updates(&monitor_b, &chan_2_id),
1434+
0x0b => complete_all_monitor_updates(&monitor_c, &chan_2_id),
14281435

14291436
0x0c => {
14301437
if !chan_a_disconnected {
@@ -1694,21 +1701,21 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
16941701
nodes[2].maybe_update_chan_fees();
16951702
},
16961703

1697-
0xf0 => complete_monitor_update(&monitor_a, &chan_1_funding, &complete_first),
1698-
0xf1 => complete_monitor_update(&monitor_a, &chan_1_funding, &complete_second),
1699-
0xf2 => complete_monitor_update(&monitor_a, &chan_1_funding, &Vec::pop),
1704+
0xf0 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_first),
1705+
0xf1 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_second),
1706+
0xf2 => complete_monitor_update(&monitor_a, &chan_1_id, &Vec::pop),
17001707

1701-
0xf4 => complete_monitor_update(&monitor_b, &chan_1_funding, &complete_first),
1702-
0xf5 => complete_monitor_update(&monitor_b, &chan_1_funding, &complete_second),
1703-
0xf6 => complete_monitor_update(&monitor_b, &chan_1_funding, &Vec::pop),
1708+
0xf4 => complete_monitor_update(&monitor_b, &chan_1_id, &complete_first),
1709+
0xf5 => complete_monitor_update(&monitor_b, &chan_1_id, &complete_second),
1710+
0xf6 => complete_monitor_update(&monitor_b, &chan_1_id, &Vec::pop),
17041711

1705-
0xf8 => complete_monitor_update(&monitor_b, &chan_2_funding, &complete_first),
1706-
0xf9 => complete_monitor_update(&monitor_b, &chan_2_funding, &complete_second),
1707-
0xfa => complete_monitor_update(&monitor_b, &chan_2_funding, &Vec::pop),
1712+
0xf8 => complete_monitor_update(&monitor_b, &chan_2_id, &complete_first),
1713+
0xf9 => complete_monitor_update(&monitor_b, &chan_2_id, &complete_second),
1714+
0xfa => complete_monitor_update(&monitor_b, &chan_2_id, &Vec::pop),
17081715

1709-
0xfc => complete_monitor_update(&monitor_c, &chan_2_funding, &complete_first),
1710-
0xfd => complete_monitor_update(&monitor_c, &chan_2_funding, &complete_second),
1711-
0xfe => complete_monitor_update(&monitor_c, &chan_2_funding, &Vec::pop),
1716+
0xfc => complete_monitor_update(&monitor_c, &chan_2_id, &complete_first),
1717+
0xfd => complete_monitor_update(&monitor_c, &chan_2_id, &complete_second),
1718+
0xfe => complete_monitor_update(&monitor_c, &chan_2_id, &Vec::pop),
17121719

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

1725-
complete_all_monitor_updates(&monitor_a, &chan_1_funding);
1726-
complete_all_monitor_updates(&monitor_b, &chan_1_funding);
1727-
complete_all_monitor_updates(&monitor_b, &chan_2_funding);
1728-
complete_all_monitor_updates(&monitor_c, &chan_2_funding);
1732+
complete_all_monitor_updates(&monitor_a, &chan_1_id);
1733+
complete_all_monitor_updates(&monitor_b, &chan_1_id);
1734+
complete_all_monitor_updates(&monitor_b, &chan_2_id);
1735+
complete_all_monitor_updates(&monitor_c, &chan_2_id);
17291736

17301737
// Next, make sure peers are all connected to each other
17311738
if chan_a_disconnected {

lightning-block-sync/src/init.rs

Lines changed: 1 addition & 1 deletion
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)