Skip to content

Commit 738ccfb

Browse files
committed
Use ClosureReason::ProcessingError not HolderForceClosed on err
`ClosureReason::HolderForceClosed` says explicitly in its docs "Closure generated from `ChannelManager...`, called by the user." However, we were using it extensively when we fail a channel due to errors handling messages or generating our own responses. Here, we convert these cases to the catch-all `ClosureReason::ProcessingError` which exists to communicate errors including a string that describes what happened. This should substantially improve debug-ability in closure cases by avoiding having to pull up logs.
1 parent 54255c5 commit 738ccfb

File tree

2 files changed

+56
-71
lines changed

2 files changed

+56
-71
lines changed

lightning/src/ln/channel.rs

Lines changed: 40 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,23 +2937,19 @@ where
29372937
for (idx, outp) in signing_session.unsigned_tx().outputs().enumerate() {
29382938
if outp.script_pubkey() == &expected_spk && outp.value() == self.funding.get_value_satoshis() {
29392939
if output_index.is_some() {
2940-
return Err(ChannelError::Close(
2941-
(
2942-
"Multiple outputs matched the expected script and value".to_owned(),
2943-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2944-
)));
2940+
let msg = "Multiple outputs matched the expected script and value";
2941+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2942+
return Err(ChannelError::Close((msg.to_owned(), reason)));
29452943
}
29462944
output_index = Some(idx as u16);
29472945
}
29482946
}
29492947
let outpoint = if let Some(output_index) = output_index {
29502948
OutPoint { txid: signing_session.unsigned_tx().compute_txid(), index: output_index }
29512949
} else {
2952-
return Err(ChannelError::Close(
2953-
(
2954-
"No output matched the funding script_pubkey".to_owned(),
2955-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2956-
)));
2950+
let msg = "No output matched the funding script_pubkey";
2951+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2952+
return Err(ChannelError::Close((msg.to_owned(), reason)));
29572953
};
29582954
self.funding.channel_transaction_parameters.funding_outpoint = Some(outpoint);
29592955

@@ -2974,10 +2970,9 @@ where
29742970
false,
29752971
"Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
29762972
);
2977-
return Err(ChannelError::Close((
2978-
"V2 channel rejected due to sender error".into(),
2979-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
2980-
)));
2973+
let msg = "V2 channel rejected due to sender error";
2974+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2975+
return Err(ChannelError::Close((msg.to_owned(), reason)));
29812976
}
29822977
None
29832978
} else {
@@ -2999,10 +2994,9 @@ where
29992994
false,
30002995
"We don't support users providing inputs but somehow we had more than zero inputs",
30012996
);
3002-
return Err(ChannelError::Close((
3003-
"V2 channel rejected due to sender error".into(),
3004-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
3005-
)));
2997+
let msg = "V2 channel rejected due to sender error";
2998+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2999+
return Err(ChannelError::Close((msg.to_owned(), reason)));
30063000
};
30073001

30083002
let mut channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
@@ -5556,11 +5550,11 @@ where
55565550
let channel_parameters = &funding.channel_transaction_parameters;
55575551
ecdsa.sign_counterparty_commitment(channel_parameters, &counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
55585552
.map(|(signature, _)| signature)
5559-
.map_err(|_| ChannelError::Close(
5560-
(
5561-
"Failed to get signatures for new commitment_signed".to_owned(),
5562-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
5563-
)))
5553+
.map_err(|()| {
5554+
let msg = "Failed to get signatures for new commitment_signed";
5555+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5556+
ChannelError::Close((msg.to_owned(), reason))
5557+
})
55645558
},
55655559
// TODO (taproot|arik)
55665560
#[cfg(taproot)]
@@ -5581,10 +5575,10 @@ where
55815575
if flags == (NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT)
55825576
) {
55835577
debug_assert!(false);
5584-
return Err(ChannelError::Close(("Tried to get an initial commitment_signed messsage at a time other than \
5585-
immediately after initial handshake completion (or tried to get funding_created twice)".to_string(),
5586-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true) }
5587-
)));
5578+
let msg = "Tried to get an initial commitment_signed messsage at a time other than \
5579+
immediately after initial handshake completion (or tried to get funding_created twice)";
5580+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5581+
return Err(ChannelError::Close((msg.to_owned(), reason)));
55885582
}
55895583

55905584
let signature = match self.get_initial_counterparty_commitment_signature(funding, logger) {
@@ -6713,11 +6707,9 @@ where
67136707
if !self.context.channel_state.is_interactive_signing()
67146708
|| self.context.channel_state.is_their_tx_signatures_sent()
67156709
{
6716-
return Err(ChannelError::Close(
6717-
(
6718-
"Received initial commitment_signed before funding transaction constructed or after peer's tx_signatures received!".to_owned(),
6719-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
6720-
)));
6710+
let msg = "Received initial commitment_signed before funding transaction constructed or after peer's tx_signatures received!";
6711+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
6712+
return Err(ChannelError::Close((msg.to_owned(), reason)));
67216713
}
67226714

67236715
let holder_commitment_point = &mut self.holder_commitment_point.clone();
@@ -7652,22 +7644,18 @@ where
76527644

76537645
if let Some(ref mut signing_session) = self.interactive_tx_signing_session {
76547646
if msg.tx_hash != signing_session.unsigned_tx().compute_txid() {
7655-
return Err(ChannelError::Close(
7656-
(
7657-
"The txid for the transaction does not match".to_string(),
7658-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
7659-
)));
7647+
let msg = "The txid for the transaction does not match";
7648+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
7649+
return Err(ChannelError::Close((msg.to_owned(), reason)));
76607650
}
76617651

76627652
// We need to close the channel if our peer hasn't sent their commitment signed already.
76637653
// Technically we'd wait on having an initial monitor persisted, so we shouldn't be broadcasting
76647654
// the transaction, but this may risk losing funds for a manual broadcast if we continue.
76657655
if !signing_session.has_received_commitment_signed() {
7666-
return Err(ChannelError::Close(
7667-
(
7668-
"Received tx_signatures before initial commitment_signed".to_string(),
7669-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
7670-
)));
7656+
let msg = "Received tx_signatures before initial commitment_signed";
7657+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
7658+
return Err(ChannelError::Close((msg.to_owned(), reason)));
76717659
}
76727660

76737661
if msg.witnesses.len() != signing_session.remote_inputs_count() {
@@ -7678,11 +7666,9 @@ where
76787666

76797667
for witness in &msg.witnesses {
76807668
if witness.is_empty() {
7681-
return Err(ChannelError::Close(
7682-
(
7683-
"Unexpected empty witness in tx_signatures received".to_string(),
7684-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
7685-
)));
7669+
let msg = "Unexpected empty witness in tx_signatures received";
7670+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
7671+
return Err(ChannelError::Close((msg.to_owned(), reason)));
76867672
}
76877673

76887674
// TODO(dual_funding): Check all sigs are SIGHASH_ALL.
@@ -7718,10 +7704,9 @@ where
77187704
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
77197705
Ok((funding_tx_opt, holder_tx_signatures_opt))
77207706
} else {
7721-
Err(ChannelError::Close((
7722-
"Unexpected tx_signatures. No funding transaction awaiting signatures".to_string(),
7723-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
7724-
)))
7707+
let msg = "Unexpected tx_signatures. No funding transaction awaiting signatures";
7708+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
7709+
return Err(ChannelError::Close((msg.to_owned(), reason)));
77257710
}
77267711
}
77277712

@@ -12056,10 +12041,10 @@ where
1205612041
outputs_to_contribute: Vec::new(),
1205712042
expected_remote_shared_funding_output: Some((funding.get_funding_redeemscript().to_p2wsh(), funding.get_value_satoshis())),
1205812043
}
12059-
).map_err(|_| ChannelError::Close((
12060-
"V2 channel rejected due to sender error".into(),
12061-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
12062-
)))?);
12044+
).map_err(|err| {
12045+
let reason = ClosureReason::ProcessingError { err: err.to_string() };
12046+
ChannelError::Close((err.to_string(), reason))
12047+
})?);
1206312048

1206412049
let unfunded_context = UnfundedChannelContext {
1206512050
unfunded_channel_age_ticks: 0,

lightning/src/ln/channelmanager.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9026,11 +9026,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
90269026
let (msg_send_event_opt, signing_session_opt) = match chan_entry.get_mut().as_unfunded_v2_mut() {
90279027
Some(chan) => chan.tx_complete(msg)
90289028
.into_msg_send_event_or_signing_session(counterparty_node_id),
9029-
None => try_channel_entry!(self, peer_state, Err(ChannelError::Close(
9030-
(
9031-
"Got a tx_complete message with no interactive transaction construction expected or in-progress".into(),
9032-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
9033-
))), chan_entry)
9029+
None => {
9030+
let msg = "Got a tx_complete message with no interactive transaction construction expected or in-progress";
9031+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
9032+
let err = ChannelError::Close((msg.to_owned(), reason));
9033+
try_channel_entry!(self, peer_state, Err(err), chan_entry)
9034+
},
90349035
};
90359036
if let Some(msg_send_event) = msg_send_event_opt {
90369037
peer_state.pending_msg_events.push(msg_send_event);
@@ -9098,11 +9099,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
90989099
}
90999100
}
91009101
},
9101-
None => try_channel_entry!(self, peer_state, Err(ChannelError::Close(
9102-
(
9103-
"Got an unexpected tx_signatures message".into(),
9104-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
9105-
))), chan_entry)
9102+
None => {
9103+
let msg = "Got an unexpected tx_signatures message";
9104+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
9105+
let err = ChannelError::Close((msg.to_owned(), reason));
9106+
try_channel_entry!(self, peer_state, Err(err), chan_entry)
9107+
},
91069108
}
91079109
Ok(())
91089110
},
@@ -9588,12 +9590,10 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
95889590
} else {
95899591
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
95909592
log_error!(logger, "Persisting initial ChannelMonitor failed, implying the channel ID was duplicated");
9591-
try_channel_entry!(self, peer_state, Err(ChannelError::Close(
9592-
(
9593-
"Channel ID was a duplicate".to_owned(),
9594-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
9595-
)
9596-
)), chan_entry)
9593+
let msg = "Channel ID was a duplicate";
9594+
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
9595+
let err = ChannelError::Close((msg.to_owned(), reason));
9596+
try_channel_entry!(self, peer_state, Err(err), chan_entry)
95979597
}
95989598
} else if let Some(monitor_update) = monitor_update_opt {
95999599
handle_new_monitor_update!(self, funding_txo.unwrap(), monitor_update, peer_state_lock,

0 commit comments

Comments
 (0)