Skip to content

Commit bb5ef8e

Browse files
committed
Don't close a funded channel on splice failure
If splicing fails, the previous funding is still usable. Send a tx_abort message if the channel was already successfully funded, thus aborting the negotiation. Otherwise, close the channel as this means the failure occurred during v2 channel establishment.
1 parent 05d2a8e commit bb5ef8e

File tree

3 files changed

+65
-29
lines changed

3 files changed

+65
-29
lines changed

lightning/src/ln/channel.rs

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,16 @@ impl ChannelError {
10091009
pub(super) fn close(err: String) -> Self {
10101010
ChannelError::Close((err.clone(), ClosureReason::ProcessingError { err }))
10111011
}
1012+
1013+
pub(super) fn message(&self) -> &str {
1014+
match self {
1015+
&ChannelError::Ignore(ref e) => &e,
1016+
&ChannelError::Warn(ref e) => &e,
1017+
&ChannelError::WarnAndDisconnect(ref e) => &e,
1018+
&ChannelError::Close((ref e, _)) => &e,
1019+
&ChannelError::SendError(ref e) => &e,
1020+
}
1021+
}
10121022
}
10131023

10141024
pub(super) struct WithChannelContext<'a, L: Deref>
@@ -1774,7 +1784,7 @@ where
17741784

17751785
pub fn funding_tx_constructed<L: Deref>(
17761786
&mut self, logger: &L,
1777-
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
1787+
) -> Result<(msgs::CommitmentSigned, Option<Event>), msgs::TxAbort>
17781788
where
17791789
L::Target: Logger,
17801790
{
@@ -1829,14 +1839,17 @@ where
18291839
}
18301840
}
18311841

1832-
return Err(ChannelError::Warn(
1833-
"Got a tx_complete message in an invalid state".to_owned(),
1834-
));
1842+
return Err(msgs::TxAbort {
1843+
channel_id: chan.context.channel_id(),
1844+
data: "Got a tx_complete message in an invalid state".to_owned().into_bytes(),
1845+
});
18351846
},
18361847
_ => {
1837-
return Err(ChannelError::Warn(
1838-
"Got a tx_complete message in an invalid phase".to_owned(),
1839-
))
1848+
debug_assert!(false);
1849+
return Err(msgs::TxAbort {
1850+
channel_id: self.context().channel_id(),
1851+
data: "Got a tx_complete message in an invalid phase".to_owned().into_bytes(),
1852+
});
18401853
},
18411854
}
18421855
}
@@ -5476,7 +5489,7 @@ where
54765489
fn funding_tx_constructed<L: Deref>(
54775490
&mut self, funding: &mut FundingScope, signing_session: &mut InteractiveTxSigningSession,
54785491
is_splice: bool, holder_commitment_transaction_number: u64, logger: &L
5479-
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
5492+
) -> Result<(msgs::CommitmentSigned, Option<Event>), msgs::TxAbort>
54805493
where
54815494
L::Target: Logger
54825495
{
@@ -5485,19 +5498,21 @@ where
54855498
for (idx, outp) in signing_session.unsigned_tx().outputs().enumerate() {
54865499
if outp.script_pubkey() == &expected_spk && outp.value() == funding.get_value_satoshis() {
54875500
if output_index.is_some() {
5488-
let msg = "Multiple outputs matched the expected script and value";
5489-
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5490-
return Err(ChannelError::Close((msg.to_owned(), reason)));
5501+
return Err(msgs::TxAbort {
5502+
channel_id: self.channel_id(),
5503+
data: "Multiple outputs matched the expected script and value".to_owned().into_bytes(),
5504+
});
54915505
}
54925506
output_index = Some(idx as u16);
54935507
}
54945508
}
54955509
let outpoint = if let Some(output_index) = output_index {
54965510
OutPoint { txid: signing_session.unsigned_tx().compute_txid(), index: output_index }
54975511
} else {
5498-
let msg = "No output matched the funding script_pubkey";
5499-
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5500-
return Err(ChannelError::Close((msg.to_owned(), reason)));
5512+
return Err(msgs::TxAbort {
5513+
channel_id: self.channel_id(),
5514+
data: "No output matched the funding script_pubkey".to_owned().into_bytes(),
5515+
});
55015516
};
55025517
funding
55035518
.channel_transaction_parameters.funding_outpoint = Some(outpoint);
@@ -5507,12 +5522,11 @@ where
55075522
holder_commitment_transaction_number,
55085523
self.cur_counterparty_commitment_transaction_number,
55095524
);
5510-
let message = "TODO Forced error, incomplete implementation".to_owned();
55115525
// TODO(splicing) Forced error, as the use case is not complete
5512-
return Err(ChannelError::Close((
5513-
message.clone(),
5514-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false), message }
5515-
)));
5526+
return Err(msgs::TxAbort {
5527+
channel_id: self.channel_id(),
5528+
data: "Splicing not yet supported".to_owned().into_bytes(),
5529+
});
55165530
} else {
55175531
self.assert_no_commitment_advancement(holder_commitment_transaction_number, "initial commitment_signed");
55185532
}
@@ -5522,7 +5536,10 @@ where
55225536
Ok(commitment_signed) => commitment_signed,
55235537
Err(e) => {
55245538
funding.channel_transaction_parameters.funding_outpoint = None;
5525-
return Err(e)
5539+
return Err(msgs::TxAbort {
5540+
channel_id: self.channel_id(),
5541+
data: e.message().to_owned().into_bytes(),
5542+
});
55265543
},
55275544
};
55285545

@@ -5532,9 +5549,10 @@ where
55325549
false,
55335550
"Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
55345551
);
5535-
let msg = "V2 channel rejected due to sender error";
5536-
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5537-
return Err(ChannelError::Close((msg.to_owned(), reason)));
5552+
return Err(msgs::TxAbort {
5553+
channel_id: self.channel_id(),
5554+
data: "V2 channel rejected due to sender error".to_owned().into_bytes(),
5555+
});
55385556
}
55395557
None
55405558
} else {
@@ -5556,9 +5574,10 @@ where
55565574
false,
55575575
"We don't support users providing inputs but somehow we had more than zero inputs",
55585576
);
5559-
let msg = "V2 channel rejected due to sender error";
5560-
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5561-
return Err(ChannelError::Close((msg.to_owned(), reason)));
5577+
return Err(msgs::TxAbort {
5578+
channel_id: self.channel_id(),
5579+
data: "V2 channel rejected due to sender error".to_owned().into_bytes(),
5580+
});
55625581
};
55635582

55645583
let mut channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());

lightning/src/ln/channelmanager.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9730,10 +9730,27 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
97309730
peer_state.pending_msg_events.push(msg_send_event);
97319731
};
97329732
if negotiation_complete {
9733-
let (commitment_signed, funding_ready_for_sig_event_opt) = chan_entry
9733+
let (commitment_signed, funding_ready_for_sig_event_opt) = match chan_entry
97349734
.get_mut()
97359735
.funding_tx_constructed(&self.logger)
9736-
.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
9736+
{
9737+
Ok((commitment_signed, event)) => (commitment_signed, event),
9738+
Err(tx_abort) => {
9739+
if chan_entry.get().is_funded() {
9740+
peer_state.pending_msg_events.push(MessageSendEvent::SendTxAbort {
9741+
node_id: counterparty_node_id,
9742+
msg: tx_abort,
9743+
});
9744+
return Ok(());
9745+
} else {
9746+
let msg = String::from_utf8(tx_abort.data)
9747+
.expect("tx_abort data should contain valid UTF-8");
9748+
let reason = ClosureReason::ProcessingError { err: msg.clone() };
9749+
let err = ChannelError::Close((msg, reason));
9750+
try_channel_entry!(self, peer_state, Err(err), chan_entry)
9751+
}
9752+
},
9753+
};
97379754
if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
97389755
let mut pending_events = self.pending_events.lock().unwrap();
97399756
pending_events.push_back((funding_ready_for_sig_event, None));

lightning/src/ln/splicing_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ fn test_v1_splice_in() {
270270
_ => panic!("Unexpected event {:?}", events[0]),
271271
}
272272
match events[1] {
273-
MessageSendEvent::HandleError { .. } => {},
273+
MessageSendEvent::SendTxAbort { .. } => {},
274274
_ => panic!("Unexpected event {:?}", events[1]),
275275
}
276276

0 commit comments

Comments
 (0)