Skip to content

Commit 3ac384d

Browse files
committed
Add a message field to ClosureReason::HolderForceClosed
In d17e759 we added the ability for users to decide which message to send to peers when we force-close a channel. Here we pipe that message back out through the channel closure event via a new `message` field in `ClosureReason::HolderForceClosed`. This is nice to have but more importantly will be used in a coming commit to simplify the internal interface to the force-closure logic.
1 parent 4565398 commit 3ac384d

16 files changed

+260
-156
lines changed

lightning-persister/src/fs_store.rs

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -592,23 +592,19 @@ mod tests {
592592
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
593593
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
594594
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
595+
596+
let node_a_id = nodes[0].node.get_our_node_id();
597+
595598
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
596-
let error_message = "Channel force-closed";
599+
600+
let message = "Channel force-closed".to_owned();
597601
nodes[1]
598602
.node
599-
.force_close_broadcasting_latest_txn(
600-
&chan.2,
601-
&nodes[0].node.get_our_node_id(),
602-
error_message.to_string(),
603-
)
603+
.force_close_broadcasting_latest_txn(&chan.2, &node_a_id, message.clone())
604604
.unwrap();
605-
check_closed_event!(
606-
nodes[1],
607-
1,
608-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) },
609-
[nodes[0].node.get_our_node_id()],
610-
100000
611-
);
605+
let reason =
606+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
607+
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
612608
let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
613609

614610
// Set the store's directory to read-only, which should result in
@@ -640,23 +636,19 @@ mod tests {
640636
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
641637
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
642638
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
639+
640+
let node_a_id = nodes[0].node.get_our_node_id();
641+
643642
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
644-
let error_message = "Channel force-closed";
643+
644+
let message = "Channel force-closed".to_owned();
645645
nodes[1]
646646
.node
647-
.force_close_broadcasting_latest_txn(
648-
&chan.2,
649-
&nodes[0].node.get_our_node_id(),
650-
error_message.to_string(),
651-
)
647+
.force_close_broadcasting_latest_txn(&chan.2, &node_a_id, message.clone())
652648
.unwrap();
653-
check_closed_event!(
654-
nodes[1],
655-
1,
656-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) },
657-
[nodes[0].node.get_our_node_id()],
658-
100000
659-
);
649+
let reason =
650+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
651+
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
660652
let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap();
661653
let update_map = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap();
662654
let update_id = update_map.get(&added_monitors[0].1.channel_id()).unwrap();

lightning-persister/src/test_utils.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ pub(crate) fn do_test_store<K: KVStore + Sync>(store_0: &K, store_1: &K) {
137137
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
138138
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
139139

140+
let node_b_id = nodes[1].node.get_our_node_id();
141+
140142
// Check that the persisted channel data is empty before any channels are
141143
// open.
142144
let mut persisted_chan_data_0 =
@@ -178,22 +180,14 @@ pub(crate) fn do_test_store<K: KVStore + Sync>(store_0: &K, store_1: &K) {
178180

179181
// Force close because cooperative close doesn't result in any persisted
180182
// updates.
181-
let error_message = "Channel force-closed";
183+
let message = "Channel force-closed".to_owned();
184+
let chan_id = nodes[0].node.list_channels()[0].channel_id;
182185
nodes[0]
183186
.node
184-
.force_close_broadcasting_latest_txn(
185-
&nodes[0].node.list_channels()[0].channel_id,
186-
&nodes[1].node.get_our_node_id(),
187-
error_message.to_string(),
188-
)
187+
.force_close_broadcasting_latest_txn(&chan_id, &node_b_id, message.clone())
189188
.unwrap();
190-
check_closed_event!(
191-
nodes[0],
192-
1,
193-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) },
194-
[nodes[1].node.get_our_node_id()],
195-
100000
196-
);
189+
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
190+
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
197191
check_closed_broadcast!(nodes[0], true);
198192
check_added_monitors!(nodes[0], 1);
199193

lightning/src/chain/chainmonitor.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,12 +1458,13 @@ mod tests {
14581458

14591459
// Test that monitors with pending_claims are persisted on every block.
14601460
// Now, close channel_2 i.e. b/w node-0 and node-2 to create pending_claim in node[0].
1461+
let message = "Channel force-closed".to_owned();
14611462
nodes[0]
14621463
.node
1463-
.force_close_broadcasting_latest_txn(&channel_2, &node_c_id, "closed".to_string())
1464+
.force_close_broadcasting_latest_txn(&channel_2, &node_c_id, message.clone())
14641465
.unwrap();
14651466
let closure_reason =
1466-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
1467+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
14671468
check_closed_event!(&nodes[0], 1, closure_reason, false, [node_c_id], 1000000);
14681469
check_closed_broadcast(&nodes[0], 1, true);
14691470
let close_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);

lightning/src/chain/channelmonitor.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3551,7 +3551,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35513551
F::Target: FeeEstimator,
35523552
L::Target: Logger,
35533553
{
3554-
let (claimable_outpoints, _) = self.generate_claimable_outpoints_and_watch_outputs(ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) });
3554+
let reason = ClosureReason::HolderForceClosed {
3555+
broadcasted_latest_txn: Some(true),
3556+
message: "ChannelMonitor-initiated commitment transaction broadcast".to_owned(),
3557+
};
3558+
let (claimable_outpoints, _) = self.generate_claimable_outpoints_and_watch_outputs(reason);
35553559
let conf_target = self.closure_conf_target();
35563560
self.onchain_tx_handler.update_claims_view_from_requests(
35573561
claimable_outpoints, self.best_block.height, self.best_block.height, broadcaster,

lightning/src/events/mod.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,11 @@ pub enum ClosureReason {
318318
/// [`UntrustedString`]: crate::util::string::UntrustedString
319319
peer_msg: UntrustedString,
320320
},
321-
/// Closure generated from [`ChannelManager::force_close_channel`], called by the user.
321+
/// Closure generated from [`ChannelManager::force_close_broadcasting_latest_txn`] or
322+
/// [`ChannelManager::force_close_all_channels_broadcasting_latest_txn`], called by the user.
322323
///
323-
/// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel.
324+
/// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn
325+
/// [`ChannelManager::force_close_all_channels_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_all_channels_broadcasting_latest_txn
324326
HolderForceClosed {
325327
/// Whether or not the latest transaction was broadcasted when the channel was force
326328
/// closed.
@@ -335,6 +337,14 @@ pub enum ClosureReason {
335337
/// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn.
336338
/// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn.
337339
broadcasted_latest_txn: Option<bool>,
340+
/// The error message provided to [`ChannelManager::force_close_broadcasting_latest_txn`] or
341+
/// [`ChannelManager::force_close_all_channels_broadcasting_latest_txn`].
342+
///
343+
/// This will be the empty string for objects generated or written by LDK 0.1 and earlier.
344+
///
345+
/// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn
346+
/// [`ChannelManager::force_close_all_channels_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_all_channels_broadcasting_latest_txn
347+
message: String,
338348
},
339349
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
340350
/// the cooperative close transaction. Note the shutdown may have been initiated by us.
@@ -419,12 +429,13 @@ impl core::fmt::Display for ClosureReason {
419429
ClosureReason::CounterpartyForceClosed { peer_msg } => {
420430
f.write_fmt(format_args!("counterparty force-closed with message: {}", peer_msg))
421431
},
422-
ClosureReason::HolderForceClosed { broadcasted_latest_txn } => {
423-
f.write_str("user force-closed the channel")?;
432+
ClosureReason::HolderForceClosed { broadcasted_latest_txn, message } => {
433+
f.write_str("user force-closed the channel with the message \"")?;
434+
f.write_str(message)?;
424435
if let Some(brodcasted) = broadcasted_latest_txn {
425436
write!(
426437
f,
427-
" and {} the latest transaction",
438+
"\" and {} the latest transaction",
428439
if *brodcasted { "broadcasted" } else { "elected not to broadcast" }
429440
)
430441
} else {
@@ -482,7 +493,10 @@ impl core::fmt::Display for ClosureReason {
482493
impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
483494
(0, CounterpartyForceClosed) => { (1, peer_msg, required) },
484495
(1, FundingTimedOut) => {},
485-
(2, HolderForceClosed) => { (1, broadcasted_latest_txn, option) },
496+
(2, HolderForceClosed) => {
497+
(1, broadcasted_latest_txn, option),
498+
(3, message, (default_value, String::new())),
499+
},
486500
(6, CommitmentTxConfirmed) => {},
487501
(4, LegacyCooperativeClosure) => {},
488502
(8, ProcessingError) => { (1, err, required) },

lightning/src/ln/async_signer_tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,17 +1011,18 @@ fn do_test_async_holder_signatures(anchors: bool, remote_commitment: bool) {
10111011
// Route an HTLC and set the signer as unavailable.
10121012
let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
10131013
route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
1014-
let error_message = "Channel force-closed";
10151014

10161015
if remote_commitment {
1016+
let message = "Channel force-closed".to_owned();
10171017
// Make the counterparty broadcast its latest commitment.
10181018
nodes[1]
10191019
.node
1020-
.force_close_broadcasting_latest_txn(&chan_id, &node_a_id, error_message.to_string())
1020+
.force_close_broadcasting_latest_txn(&chan_id, &node_a_id, message.clone())
10211021
.unwrap();
10221022
check_added_monitors(&nodes[1], 1);
10231023
check_closed_broadcast(&nodes[1], 1, true);
1024-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
1024+
let reason =
1025+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
10251026
check_closed_event(&nodes[1], 1, reason, false, &[node_a_id], 100_000);
10261027
} else {
10271028
nodes[0].disable_channel_signer_op(&node_b_id, &chan_id, SignerOp::SignHolderCommitment);

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -261,16 +261,19 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
261261
}
262262

263263
// ...and make sure we can force-close a frozen channel
264-
let err_msg = "Channel force-closed".to_owned();
265-
nodes[0].node.force_close_broadcasting_latest_txn(&channel_id, &node_b_id, err_msg).unwrap();
264+
let message = "Channel force-closed".to_owned();
265+
let reason = ClosureReason::HolderForceClosed {
266+
broadcasted_latest_txn: Some(true),
267+
message: message.clone(),
268+
};
269+
nodes[0].node.force_close_broadcasting_latest_txn(&channel_id, &node_b_id, message).unwrap();
266270
check_added_monitors!(nodes[0], 1);
267271
check_closed_broadcast!(nodes[0], true);
268272

269273
// TODO: Once we hit the chain with the failure transaction we should check that we get a
270274
// PaymentPathFailed event
271275

272276
assert_eq!(nodes[0].node.list_channels().len(), 0);
273-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
274277
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
275278
}
276279

@@ -3757,27 +3760,30 @@ fn do_test_durable_preimages_on_closed_channel(
37573760
let _ = get_revoke_commit_msgs!(nodes[1], node_c_id);
37583761

37593762
let mon_bc = get_monitor!(nodes[1], chan_id_bc).encode();
3760-
let err_msg = "Channel force-closed".to_owned();
37613763

37623764
if close_chans_before_reload {
37633765
if !close_only_a {
37643766
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
3767+
let message = "Channel force-closed".to_owned();
37653768
nodes[1]
37663769
.node
3767-
.force_close_broadcasting_latest_txn(&chan_id_bc, &node_c_id, err_msg.clone())
3770+
.force_close_broadcasting_latest_txn(&chan_id_bc, &node_c_id, message.clone())
37683771
.unwrap();
37693772
check_closed_broadcast(&nodes[1], 1, true);
3770-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
3773+
let reason =
3774+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
37713775
check_closed_event(&nodes[1], 1, reason, false, &[node_c_id], 100000);
37723776
}
37733777

37743778
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
3779+
let message = "Channel force-closed".to_owned();
37753780
nodes[1]
37763781
.node
3777-
.force_close_broadcasting_latest_txn(&chan_id_ab, &node_a_id, err_msg)
3782+
.force_close_broadcasting_latest_txn(&chan_id_ab, &node_a_id, message.clone())
37783783
.unwrap();
37793784
check_closed_broadcast(&nodes[1], 1, true);
3780-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
3785+
let reason =
3786+
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
37813787
check_closed_event(&nodes[1], 1, reason, false, &[node_a_id], 100000);
37823788
}
37833789

@@ -3799,8 +3805,11 @@ fn do_test_durable_preimages_on_closed_channel(
37993805
}
38003806

38013807
let err_msg = "Channel force-closed".to_owned();
3808+
let reason = ClosureReason::HolderForceClosed {
3809+
broadcasted_latest_txn: Some(true),
3810+
message: err_msg.clone(),
3811+
};
38023812
nodes[0].node.force_close_broadcasting_latest_txn(&chan_id_ab, &node_b_id, err_msg).unwrap();
3803-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
38043813
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 100000);
38053814
let as_closing_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
38063815
assert_eq!(as_closing_tx.len(), 1);
@@ -3964,10 +3973,13 @@ fn do_test_reload_mon_update_completion_actions(close_during_reload: bool) {
39643973
if close_during_reload {
39653974
// Test that we still free the B<->C channel if the A<->B channel closed while we reloaded
39663975
// (as learned about during the on-reload block connection).
3976+
let reason = ClosureReason::HolderForceClosed {
3977+
broadcasted_latest_txn: Some(true),
3978+
message: msg.clone(),
3979+
};
39673980
nodes[0].node.force_close_broadcasting_latest_txn(&chan_id_ab, &node_b_id, msg).unwrap();
39683981
check_added_monitors!(nodes[0], 1);
39693982
check_closed_broadcast!(nodes[0], true);
3970-
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
39713983
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 100_000);
39723984
let as_closing_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
39733985
mine_transaction_without_consistency_checks(&nodes[1], &as_closing_tx[0]);
@@ -4292,12 +4304,13 @@ fn test_claim_to_closed_channel_blocks_forwarded_preimage_removal() {
42924304
let (payment_preimage, payment_hash, ..) =
42934305
route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
42944306

4307+
let message = "Channel force-closed".to_owned();
42954308
nodes[0]
42964309
.node
4297-
.force_close_broadcasting_latest_txn(&chan_a.2, &node_b_id, String::new())
4310+
.force_close_broadcasting_latest_txn(&chan_a.2, &node_b_id, message.clone())
42984311
.unwrap();
42994312
check_added_monitors!(nodes[0], 1);
4300-
let a_reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
4313+
let a_reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
43014314
check_closed_event!(nodes[0], 1, a_reason, [node_b_id], 1000000);
43024315
check_closed_broadcast!(nodes[0], true);
43034316

@@ -4367,12 +4380,13 @@ fn test_claim_to_closed_channel_blocks_claimed_event() {
43674380

43684381
let (payment_preimage, payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
43694382

4383+
let message = "Channel force-closed".to_owned();
43704384
nodes[0]
43714385
.node
4372-
.force_close_broadcasting_latest_txn(&chan_a.2, &node_b_id, String::new())
4386+
.force_close_broadcasting_latest_txn(&chan_a.2, &node_b_id, message.clone())
43734387
.unwrap();
43744388
check_added_monitors!(nodes[0], 1);
4375-
let a_reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) };
4389+
let a_reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
43764390
check_closed_event!(nodes[0], 1, a_reason, [node_b_id], 1000000);
43774391
check_closed_broadcast!(nodes[0], true);
43784392

0 commit comments

Comments
 (0)