Skip to content

Commit f122a7d

Browse files
committed
Breakup CooperativeClosure into Local/Remote initiated
1 parent 5bf58f0 commit f122a7d

File tree

7 files changed

+106
-53
lines changed

7 files changed

+106
-53
lines changed

lightning/src/events/mod.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,15 @@ pub enum ClosureReason {
184184
HolderForceClosed,
185185
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
186186
/// the cooperative close transaction. Note the shutdown may have been initiated by us.
187-
//TODO: split between CounterpartyInitiated/LocallyInitiated
187+
// Can be removed once we disallow downgrading to 0.0.121
188188
CooperativeClosure,
189+
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
190+
/// the cooperative close transaction. This indicates that the shutdown was initiated by our
191+
/// counterparty.
192+
CounterpartyInitiatedCooperativeClosure,
193+
/// The channel was closed after negotiating a cooperative close and we've now broadcasted
194+
/// the cooperative close transaction. This indicates that the shutdown was initiated by us.
195+
LocallyInitiatedCooperativeClosure,
189196
/// A commitment transaction was confirmed on chain, closing the channel. Most likely this
190197
/// commitment transaction came from our counterparty, but it may also have come from
191198
/// a copy of our own `ChannelMonitor`.
@@ -231,6 +238,8 @@ impl core::fmt::Display for ClosureReason {
231238
},
232239
ClosureReason::HolderForceClosed => f.write_str("user manually force-closed the channel"),
233240
ClosureReason::CooperativeClosure => f.write_str("the channel was cooperatively closed"),
241+
ClosureReason::CounterpartyInitiatedCooperativeClosure => f.write_str("the channel was cooperatively closed by our peer"),
242+
ClosureReason::LocallyInitiatedCooperativeClosure => f.write_str("the channel was cooperatively closed by us"),
234243
ClosureReason::CommitmentTxConfirmed => f.write_str("commitment or closing transaction was confirmed on chain."),
235244
ClosureReason::FundingTimedOut => write!(f, "funding transaction failed to confirm within {} blocks", FUNDING_CONF_DEADLINE_BLOCKS),
236245
ClosureReason::ProcessingError { err } => {
@@ -255,7 +264,9 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
255264
(10, DisconnectedPeer) => {},
256265
(12, OutdatedChannelManager) => {},
257266
(13, CounterpartyCoopClosedUnfundedChannel) => {},
258-
(15, FundingBatchClosure) => {}
267+
(15, FundingBatchClosure) => {},
268+
(17, CounterpartyInitiatedCooperativeClosure) => {},
269+
(19, LocallyInitiatedCooperativeClosure) => {},
259270
);
260271

261272
/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].

lightning/src/ln/chanmon_update_fail_tests.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1955,8 +1955,8 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
19551955

19561956
send_payment(&nodes[0], &[&nodes[1]], 8000000);
19571957
close_channel(&nodes[0], &nodes[1], &channel_id, funding_tx, true);
1958-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1959-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
1958+
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1959+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
19601960
}
19611961

19621962
#[test]
@@ -2634,8 +2634,8 @@ fn test_temporary_error_during_shutdown() {
26342634
assert_eq!(txn_a, txn_b);
26352635
assert_eq!(txn_a.len(), 1);
26362636
check_spends!(txn_a[0], funding_tx);
2637-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
2638-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
2637+
check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
2638+
check_closed_event!(nodes[0], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
26392639
}
26402640

26412641
#[test]

lightning/src/ln/channel.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,9 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
12561256
// We track whether we already emitted a `ChannelReady` event.
12571257
channel_ready_event_emitted: bool,
12581258

1259+
/// Some if we initiated to shut down the channel.
1260+
local_initiated_shutdown: Option<()>,
1261+
12591262
/// The unique identifier used to re-derive the private key material for the channel through
12601263
/// [`SignerProvider::derive_channel_signer`].
12611264
channel_keys_id: [u8; 32],
@@ -4959,11 +4962,17 @@ impl<SP: Deref> Channel<SP> where
49594962
}
49604963
}
49614964

4965+
let closure_reason = if self.initiated_shutdown() {
4966+
ClosureReason::LocallyInitiatedCooperativeClosure
4967+
} else {
4968+
ClosureReason::CounterpartyInitiatedCooperativeClosure
4969+
};
4970+
49624971
assert!(self.context.shutdown_scriptpubkey.is_some());
49634972
if let Some((last_fee, sig)) = self.context.last_sent_closing_fee {
49644973
if last_fee == msg.fee_satoshis {
49654974
let shutdown_result = ShutdownResult {
4966-
closure_reason: ClosureReason::CooperativeClosure,
4975+
closure_reason,
49674976
monitor_update: None,
49684977
dropped_outbound_htlcs: Vec::new(),
49694978
unbroadcasted_batch_funding_txid: self.context.unbroadcasted_batch_funding_txid(),
@@ -4998,7 +5007,7 @@ impl<SP: Deref> Channel<SP> where
49985007
.map_err(|_| ChannelError::Close("External signer refused to sign closing transaction".to_owned()))?;
49995008
let (signed_tx, shutdown_result) = if $new_fee == msg.fee_satoshis {
50005009
let shutdown_result = ShutdownResult {
5001-
closure_reason: ClosureReason::CooperativeClosure,
5010+
closure_reason,
50025011
monitor_update: None,
50035012
dropped_outbound_htlcs: Vec::new(),
50045013
unbroadcasted_batch_funding_txid: self.context.unbroadcasted_batch_funding_txid(),
@@ -5263,6 +5272,11 @@ impl<SP: Deref> Channel<SP> where
52635272
self.context.channel_state.is_local_shutdown_sent()
52645273
}
52655274

5275+
/// Returns true if we either initiated to shut down the channel.
5276+
pub fn initiated_shutdown(&self) -> bool {
5277+
self.context.local_initiated_shutdown.is_some()
5278+
}
5279+
52665280
/// Returns true if this channel is fully shut down. True here implies that no further actions
52675281
/// may/will be taken on this channel, and thus this object should be freed. Any future changes
52685282
/// will be handled appropriately by the chain monitor.
@@ -6177,6 +6191,7 @@ impl<SP: Deref> Channel<SP> where
61776191
// From here on out, we may not fail!
61786192
self.context.target_closing_feerate_sats_per_kw = target_feerate_sats_per_kw;
61796193
self.context.channel_state.set_local_shutdown_sent();
6194+
self.context.local_initiated_shutdown = Some(());
61806195
self.context.update_time_counter += 1;
61816196

61826197
let monitor_update = if update_shutdown_script {
@@ -6437,6 +6452,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
64376452
channel_keys_id,
64386453

64396454
blocked_monitor_updates: Vec::new(),
6455+
local_initiated_shutdown: None,
64406456
},
64416457
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
64426458
})
@@ -7237,6 +7253,8 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
72377253
channel_type,
72387254
channel_keys_id,
72397255

7256+
local_initiated_shutdown: None,
7257+
72407258
blocked_monitor_updates: Vec::new(),
72417259
},
72427260
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
@@ -7811,6 +7829,7 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
78117829
(39, pending_outbound_blinding_points, optional_vec),
78127830
(41, holding_cell_blinding_points, optional_vec),
78137831
(43, malformed_htlcs, optional_vec), // Added in 0.0.119
7832+
(45, self.context.local_initiated_shutdown, option), // Added in 0.0.122
78147833
});
78157834

78167835
Ok(())
@@ -8098,6 +8117,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
80988117

80998118
let mut is_batch_funding: Option<()> = None;
81008119

8120+
let mut local_initiated_shutdown: Option<()> = None;
8121+
81018122
let mut pending_outbound_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
81028123
let mut holding_cell_blinding_points_opt: Option<Vec<Option<PublicKey>>> = None;
81038124

@@ -8132,6 +8153,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
81328153
(39, pending_outbound_blinding_points_opt, optional_vec),
81338154
(41, holding_cell_blinding_points_opt, optional_vec),
81348155
(43, malformed_htlcs, optional_vec), // Added in 0.0.119
8156+
(45, local_initiated_shutdown, option),
81358157
});
81368158

81378159
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
@@ -8362,6 +8384,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
83628384
channel_type: channel_type.unwrap(),
83638385
channel_keys_id,
83648386

8387+
local_initiated_shutdown,
8388+
83658389
blocked_monitor_updates: blocked_monitor_updates.unwrap(),
83668390
}
83678391
})

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11856,8 +11856,8 @@ mod tests {
1185611856
}
1185711857
let (_nodes_1_update, _none) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
1185811858

11859-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 1000000);
11860-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 1000000);
11859+
check_closed_event!(nodes[0], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 1000000);
11860+
check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 1000000);
1186111861
}
1186211862

1186311863
fn check_not_connected_to_peer_error<T>(res_err: Result<T, APIError>, expected_public_key: PublicKey) {

lightning/src/ln/functional_tests.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ fn test_update_fee_with_fundee_update_add_htlc() {
871871
send_payment(&nodes[1], &vec!(&nodes[0])[..], 800000);
872872
send_payment(&nodes[0], &vec!(&nodes[1])[..], 800000);
873873
close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true);
874-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
875-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
874+
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
875+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
876876
}
877877

878878
#[test]
@@ -985,8 +985,8 @@ fn test_update_fee() {
985985
assert_eq!(get_feerate!(nodes[0], nodes[1], channel_id), feerate + 30);
986986
assert_eq!(get_feerate!(nodes[1], nodes[0], channel_id), feerate + 30);
987987
close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true);
988-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
989-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
988+
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
989+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
990990
}
991991

992992
#[test]
@@ -1104,17 +1104,17 @@ fn fake_network_test() {
11041104

11051105
// Close down the channels...
11061106
close_channel(&nodes[0], &nodes[1], &chan_1.2, chan_1.3, true);
1107-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1108-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
1107+
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1108+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
11091109
close_channel(&nodes[1], &nodes[2], &chan_2.2, chan_2.3, false);
1110-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[2].node.get_our_node_id()], 100000);
1111-
check_closed_event!(nodes[2], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1110+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[2].node.get_our_node_id()], 100000);
1111+
check_closed_event!(nodes[2], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
11121112
close_channel(&nodes[2], &nodes[3], &chan_3.2, chan_3.3, true);
1113-
check_closed_event!(nodes[2], 1, ClosureReason::CooperativeClosure, [nodes[3].node.get_our_node_id()], 100000);
1114-
check_closed_event!(nodes[3], 1, ClosureReason::CooperativeClosure, [nodes[2].node.get_our_node_id()], 100000);
1113+
check_closed_event!(nodes[2], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[3].node.get_our_node_id()], 100000);
1114+
check_closed_event!(nodes[3], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[2].node.get_our_node_id()], 100000);
11151115
close_channel(&nodes[1], &nodes[3], &chan_4.2, chan_4.3, false);
1116-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[3].node.get_our_node_id()], 100000);
1117-
check_closed_event!(nodes[3], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1116+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[3].node.get_our_node_id()], 100000);
1117+
check_closed_event!(nodes[3], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
11181118
}
11191119

11201120
#[test]
@@ -5619,15 +5619,15 @@ fn test_static_output_closing_tx() {
56195619
let closing_tx = close_channel(&nodes[0], &nodes[1], &chan.2, chan.3, true).2;
56205620

56215621
mine_transaction(&nodes[0], &closing_tx);
5622-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
5622+
check_closed_event!(nodes[0], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
56235623
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
56245624

56255625
let spend_txn = check_spendable_outputs!(nodes[0], node_cfgs[0].keys_manager);
56265626
assert_eq!(spend_txn.len(), 1);
56275627
check_spends!(spend_txn[0], closing_tx);
56285628

56295629
mine_transaction(&nodes[1], &closing_tx);
5630-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
5630+
check_closed_event!(nodes[1], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
56315631
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
56325632

56335633
let spend_txn = check_spendable_outputs!(nodes[1], node_cfgs[1].keys_manager);

lightning/src/ln/monitor_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ fn do_chanmon_claim_value_coop_close(anchors: bool) {
257257
spendable_outputs_b
258258
);
259259

260-
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 1000000);
261-
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 1000000);
260+
check_closed_event!(nodes[0], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 1000000);
261+
check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 1000000);
262262
}
263263

264264
#[test]

0 commit comments

Comments
 (0)