Skip to content

Commit ec9ac9b

Browse files
committed
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 4ee37a9 commit ec9ac9b

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

lightning/src/ln/channel.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6521,7 +6521,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
65216521
self.generate_accept_channel_message()
65226522
}
65236523

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

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

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

65616561
pub fn funding_created<L: Deref>(
65626562
mut self, msg: &msgs::FundingCreated, best_block: BestBlock, signer_provider: &SP, logger: &L
6563-
) -> Result<(Channel<SP>, msgs::FundingSigned, ChannelMonitor<<SP::Target as SignerProvider>::Signer>), (Self, ChannelError)>
6563+
) -> Result<(Channel<SP>, Option<msgs::FundingSigned>, ChannelMonitor<<SP::Target as SignerProvider>::Signer>), (Self, ChannelError)>
65646564
where
65656565
L::Target: Logger
65666566
{
@@ -6585,7 +6585,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
65856585
// funding_created_signature may fail.
65866586
self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters);
65876587

6588-
let (counterparty_initial_commitment_tx, initial_commitment_tx, signature) = match self.funding_created_signature(&msg.signature, logger) {
6588+
let (counterparty_initial_commitment_tx, initial_commitment_tx, sig_opt) = match self.funding_created_signature(&msg.signature, logger) {
65896589
Ok(res) => res,
65906590
Err(ChannelError::Close(e)) => {
65916591
self.context.channel_transaction_parameters.funding_outpoint = None;
@@ -6649,12 +6649,19 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
66496649
let need_channel_ready = channel.check_get_channel_ready(0).is_some();
66506650
channel.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
66516651

6652-
Ok((channel, msgs::FundingSigned {
6653-
channel_id,
6654-
signature,
6655-
#[cfg(taproot)]
6656-
partial_signature_with_nonce: None,
6657-
}, channel_monitor))
6652+
let funding_signed = if let Some(signature) = sig_opt {
6653+
Some(msgs::FundingSigned {
6654+
channel_id,
6655+
signature,
6656+
#[cfg(taproot)]
6657+
partial_signature_with_nonce: None,
6658+
})
6659+
} else {
6660+
channel.context.signer_pending_funding = true;
6661+
None
6662+
};
6663+
6664+
Ok((channel, funding_signed, channel_monitor))
66586665
}
66596666
}
66606667

@@ -7737,7 +7744,7 @@ mod tests {
77377744
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
77387745

77397746
// Node B --> Node A: funding signed
7740-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7747+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
77417748

77427749
// Put some inbound and outbound HTLCs in A's channel.
77437750
let htlc_amount_msat = 11_092_000; // put an amount below A's effective dust limit but above B's.
@@ -7864,7 +7871,7 @@ mod tests {
78647871
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();
78657872

78667873
// Node B --> Node A: funding signed
7867-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7874+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
78687875

78697876
// Now disconnect the two nodes and check that the commitment point in
78707877
// Node B's channel_reestablish message is sane.
@@ -8052,7 +8059,7 @@ mod tests {
80528059
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
80538060

80548061
// Node B --> Node A: funding signed
8055-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
8062+
let _ = node_a_chan.funding_signed(&funding_signed_msg.unwrap(), best_block, &&keys_provider, &&logger).unwrap();
80568063

80578064
// Make sure that receiving a channel update will update the Channel as expected.
80588065
let update = ChannelUpdate {

lightning/src/ln/channelmanager.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5626,7 +5626,7 @@ where
56265626

56275627
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
56285628
let peer_state = &mut *peer_state_lock;
5629-
let (chan, funding_msg, monitor) =
5629+
let (chan, funding_msg_opt, monitor) =
56305630
match peer_state.inbound_v1_channel_by_id.remove(&msg.temporary_channel_id) {
56315631
Some(inbound_chan) => {
56325632
match inbound_chan.funding_created(msg, best_block, &self.signer_provider, &self.logger) {
@@ -5646,16 +5646,19 @@ where
56465646
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))
56475647
};
56485648

5649-
match peer_state.channel_by_id.entry(funding_msg.channel_id) {
5649+
match peer_state.channel_by_id.entry(chan.context.channel_id()) {
56505650
hash_map::Entry::Occupied(_) => {
5651-
Err(MsgHandleErrInternal::send_err_msg_no_close("Already had channel with the new channel_id".to_owned(), funding_msg.channel_id))
5651+
Err(MsgHandleErrInternal::send_err_msg_no_close(
5652+
"Already had channel with the new channel_id".to_owned(),
5653+
chan.context.channel_id()
5654+
))
56525655
},
56535656
hash_map::Entry::Vacant(e) => {
56545657
match self.id_to_peer.lock().unwrap().entry(chan.context.channel_id()) {
56555658
hash_map::Entry::Occupied(_) => {
56565659
return Err(MsgHandleErrInternal::send_err_msg_no_close(
56575660
"The funding_created message had the same funding_txid as an existing channel - funding is not possible".to_owned(),
5658-
funding_msg.channel_id))
5661+
chan.context.channel_id()))
56595662
},
56605663
hash_map::Entry::Vacant(i_e) => {
56615664
i_e.insert(chan.context.get_counterparty_node_id());
@@ -5666,11 +5669,13 @@ where
56665669
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
56675670
// accepted payment from yet. We do, however, need to wait to send our channel_ready
56685671
// until we have persisted our monitor.
5669-
let new_channel_id = funding_msg.channel_id;
5670-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
5671-
node_id: counterparty_node_id.clone(),
5672-
msg: funding_msg,
5673-
});
5672+
let new_channel_id = chan.context.channel_id();
5673+
if let Some(msg) = funding_msg_opt {
5674+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingSigned {
5675+
node_id: counterparty_node_id.clone(),
5676+
msg,
5677+
});
5678+
}
56745679

56755680
let monitor_res = self.chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor);
56765681

0 commit comments

Comments
 (0)