Skip to content

Commit 99e4db3

Browse files
TheBlueMattwaterson
authored andcommitted
Handle sign_counterparty_commitment failing during inb funding
If sign_counterparty_commitment fails (i.e. because the signer is temporarily disconnected), this really indicates that we should retry the message sending which required the signature later, rather than force-closing the channel (which probably won't even work if the signer is missing). Here we add initial handling of sign_counterparty_commitment failing during inbound channel funding, setting a flag in `ChannelContext` which indicates we should retry sending the `funding_signed` later. We don't yet add any ability to do that retry.
1 parent fe19cfc commit 99e4db3

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed

lightning/src/ln/channel.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6633,7 +6633,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
66336633
self.generate_accept_channel_message()
66346634
}
66356635

6636-
fn funding_created_signature<L: Deref>(&mut self, sig: &Signature, logger: &L) -> Result<(CommitmentTransaction, CommitmentTransaction, Signature), ChannelError> where L::Target: Logger {
6636+
fn funding_created_signature<L: Deref>(&mut self, sig: &Signature, logger: &L) -> Result<(CommitmentTransaction, CommitmentTransaction, Option<Signature>), ChannelError> where L::Target: Logger {
66376637
let funding_script = self.context.get_funding_redeemscript();
66386638

66396639
let keys = self.context.build_holder_transaction_keys(self.context.cur_holder_commitment_transaction_number);
@@ -6662,7 +6662,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
66626662
// TODO (arik): move match into calling method for Taproot
66636663
ChannelSignerType::Ecdsa(ecdsa) => {
66646664
let counterparty_signature = ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.context.secp_ctx)
6665-
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0;
6665+
.map(|(sig, _)| sig).ok();
66666666

66676667
// We sign "counterparty" commitment transaction, allowing them to broadcast the tx if they wish.
66686668
Ok((counterparty_initial_commitment_tx, initial_commitment_tx, counterparty_signature))
@@ -6672,7 +6672,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
66726672

66736673
pub fn funding_created<L: Deref>(
66746674
mut self, msg: &msgs::FundingCreated, best_block: BestBlock, signer_provider: &SP, logger: &L
6675-
) -> Result<(Channel<SP>, msgs::FundingSigned, ChannelMonitor<<SP::Target as SignerProvider>::Signer>), (Self, ChannelError)>
6675+
) -> Result<(Channel<SP>, Option<msgs::FundingSigned>, ChannelMonitor<<SP::Target as SignerProvider>::Signer>), (Self, ChannelError)>
66766676
where
66776677
L::Target: Logger
66786678
{
@@ -6697,7 +6697,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
66976697
// funding_created_signature may fail.
66986698
self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters);
66996699

6700-
let (counterparty_initial_commitment_tx, initial_commitment_tx, signature) = match self.funding_created_signature(&msg.signature, logger) {
6700+
let (counterparty_initial_commitment_tx, initial_commitment_tx, sig_opt) = match self.funding_created_signature(&msg.signature, logger) {
67016701
Ok(res) => res,
67026702
Err(ChannelError::Close(e)) => {
67036703
self.context.channel_transaction_parameters.funding_outpoint = None;
@@ -6761,12 +6761,19 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
67616761
let need_channel_ready = channel.check_get_channel_ready(0).is_some();
67626762
channel.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
67636763

6764-
Ok((channel, msgs::FundingSigned {
6765-
channel_id,
6766-
signature,
6767-
#[cfg(taproot)]
6768-
partial_signature_with_nonce: None,
6769-
}, channel_monitor))
6764+
let funding_signed = if let Some(signature) = sig_opt {
6765+
Some(msgs::FundingSigned {
6766+
channel_id,
6767+
signature,
6768+
#[cfg(taproot)]
6769+
partial_signature_with_nonce: None,
6770+
})
6771+
} else {
6772+
channel.context.signer_pending_funding = true;
6773+
None
6774+
};
6775+
6776+
Ok((channel, funding_signed, channel_monitor))
67706777
}
67716778
}
67726779

@@ -7854,7 +7861,7 @@ mod tests {
78547861
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
78557862

78567863
// Node B --> Node A: funding signed
7857-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7864+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
78587865

78597866
// Put some inbound and outbound HTLCs in A's channel.
78607867
let htlc_amount_msat = 11_092_000; // put an amount below A's effective dust limit but above B's.
@@ -7981,7 +7988,7 @@ mod tests {
79817988
let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
79827989

79837990
// Node B --> Node A: funding signed
7984-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7991+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
79857992

79867993
// Now disconnect the two nodes and check that the commitment point in
79877994
// Node B's channel_reestablish message is sane.
@@ -8169,7 +8176,7 @@ mod tests {
81698176
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
81708177

81718178
// Node B --> Node A: funding signed
8172-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
8179+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
81738180

81748181
// Make sure that receiving a channel update will update the Channel as expected.
81758182
let update = ChannelUpdate {
@@ -9242,7 +9249,7 @@ mod tests {
92429249
// Receive funding_signed, but the channel will be configured to hold sending channel_ready and
92439250
// broadcasting the funding transaction until the batch is ready.
92449251
let _ = node_a_chan.funding_signed(
9245-
&funding_signed_msg,
9252+
&funding_signed_msg.unwrap(),
92469253
best_block,
92479254
&&keys_provider,
92489255
&&logger,

lightning/src/ln/channelmanager.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6026,7 +6026,7 @@ where
60266026

60276027
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
60286028
let peer_state = &mut *peer_state_lock;
6029-
let (chan, funding_msg, monitor) =
6029+
let (chan, funding_msg_opt, monitor) =
60306030
match peer_state.channel_by_id.remove(&msg.temporary_channel_id) {
60316031
Some(ChannelPhase::UnfundedInboundV1(inbound_chan)) => {
60326032
match inbound_chan.funding_created(msg, best_block, &self.signer_provider, &self.logger) {
@@ -6049,17 +6049,20 @@ where
60496049
None => return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.temporary_channel_id))
60506050
};
60516051

6052-
match peer_state.channel_by_id.entry(funding_msg.channel_id) {
6052+
match peer_state.channel_by_id.entry(chan.context.channel_id()) {
60536053
hash_map::Entry::Occupied(_) => {
6054-
Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
6054+
Err(MsgHandleErrInternal::send_err_msg_no_close(
6055+
"Already had channel with the new channel_id".to_owned(),
6056+
chan.context.channel_id()
6057+
))
60556058
},
60566059
hash_map::Entry::Vacant(e) => {
60576060
let mut id_to_peer_lock = self.id_to_peer.lock().unwrap();
60586061
match id_to_peer_lock.entry(chan.context.channel_id()) {
60596062
hash_map::Entry::Occupied(_) => {
60606063
return Err(MsgHandleErrInternal::send_err_msg_no_close(
60616064
"The funding_created message had the same funding_txid as an existing channel - funding is not possible".to_owned(),
6062-
funding_msg.channel_id))
6065+
chan.context.channel_id()))
60636066
},
60646067
hash_map::Entry::Vacant(i_e) => {
60656068
let monitor_res = self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);
@@ -6071,10 +6074,12 @@ where
60716074
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
60726075
// accepted payment from yet. We do, however, need to wait to send our channel_ready
60736076
// until we have persisted our monitor.
6074-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
6075-
node_id: counterparty_node_id.clone(),
6076-
msg: funding_msg,
6077-
});
6077+
if let Some(msg) = funding_msg_opt {
6078+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
6079+
node_id: counterparty_node_id.clone(),
6080+
msg,
6081+
});
6082+
}
60786083

60796084
if let ChannelPhase::Funded(chan) = e.insert(ChannelPhase::Funded(chan)) {
60806085
handle_new_monitor_update!(self, persist_state, peer_state_lock, peer_state,
@@ -6085,9 +6090,13 @@ where
60856090
Ok(())
60866091
} else {
60876092
log_error!(self.logger, "Persisting initial ChannelMonitor failed, implying the funding outpoint was duplicated");
6093+
let channel_id = match funding_msg_opt {
6094+
Some(msg) => msg.channel_id,
6095+
None => chan.context.channel_id(),
6096+
};
60886097
return Err(MsgHandleErrInternal::send_err_msg_no_close(
60896098
"The funding_created message had the same funding_txid as an existing channel - funding is not possible".to_owned(),
6090-
funding_msg.channel_id));
6099+
channel_id));
60916100
}
60926101
}
60936102
}

0 commit comments

Comments
 (0)