Skip to content

Commit 4ee37a9

Browse files
committed
Handle sign_counterparty_commitment failing during outb 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 outbound channel funding, setting a new flag in `ChannelContext` which indicates we should retry sending the `funding_created` later. We don't yet add any ability to do that retry.
1 parent 65737c6 commit 4ee37a9

File tree

3 files changed

+39
-33
lines changed

3 files changed

+39
-33
lines changed

lightning/src/ln/channel.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,10 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
707707
/// This flag is set in such a case. Note that we don't need to persist this as we'll end up
708708
/// setting it again as a side-effect of [`Channel::channel_reestablish`].
709709
signer_pending_commitment_update: bool,
710+
/// Similar to [`Self::signer_pending_commitment_update`] but we're waiting to send either a
711+
/// [`msgs::FundingCreated`] or [`msgs::FundingSigned`] depending on if this channel is
712+
/// outbound or inbound.
713+
signer_pending_funding: bool,
710714

711715
// pending_update_fee is filled when sending and receiving update_fee.
712716
//
@@ -5722,6 +5726,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
57225726
monitor_pending_finalized_fulfills: Vec::new(),
57235727

57245728
signer_pending_commitment_update: false,
5729+
signer_pending_funding: false,
57255730

57265731
#[cfg(debug_assertions)]
57275732
holder_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
@@ -5802,15 +5807,14 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
58025807
})
58035808
}
58045809

5805-
/// If an Err is returned, it is a ChannelError::Close (for get_funding_created)
5806-
fn get_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
5810+
fn get_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ()> where L::Target: Logger {
58075811
let counterparty_keys = self.context.build_remote_transaction_keys();
58085812
let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
58095813
match &self.context.holder_signer {
58105814
// TODO (taproot|arik): move match into calling method for Taproot
58115815
ChannelSignerType::Ecdsa(ecdsa) => {
5812-
Ok(ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.context.secp_ctx)
5813-
.map_err(|_| ChannelError::Close("Failed to get signatures for new commitment_signed".to_owned()))?.0)
5816+
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), &self.context.secp_ctx)
5817+
.map(|(sig, _)| sig)
58145818
}
58155819
}
58165820
}
@@ -5823,7 +5827,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
58235827
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
58245828
/// If an Err is returned, it is a ChannelError::Close.
58255829
pub fn get_funding_created<L: Deref>(mut self, funding_transaction: Transaction, funding_txo: OutPoint, logger: &L)
5826-
-> Result<(Channel<SP>, msgs::FundingCreated), (Self, ChannelError)> where L::Target: Logger {
5830+
-> Result<(Channel<SP>, Option<msgs::FundingCreated>), (Self, ChannelError)> where L::Target: Logger {
58275831
if !self.context.is_outbound() {
58285832
panic!("Tried to create outbound funding_created message on an inbound channel!");
58295833
}
@@ -5839,15 +5843,6 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
58395843
self.context.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
58405844
self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters);
58415845

5842-
let signature = match self.get_funding_created_signature(logger) {
5843-
Ok(res) => res,
5844-
Err(e) => {
5845-
log_error!(logger, "Got bad signatures: {:?}!", e);
5846-
self.context.channel_transaction_parameters.funding_outpoint = None;
5847-
return Err((self, e));
5848-
}
5849-
};
5850-
58515846
let temporary_channel_id = self.context.channel_id;
58525847

58535848
// Now that we're past error-generating stuff, update our local state:
@@ -5865,20 +5860,27 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
58655860

58665861
self.context.funding_transaction = Some(funding_transaction);
58675862

5863+
let funding_created = if let Ok(signature) = self.get_funding_created_signature(logger) {
5864+
Some(msgs::FundingCreated {
5865+
temporary_channel_id,
5866+
funding_txid: funding_txo.txid,
5867+
funding_output_index: funding_txo.index,
5868+
signature,
5869+
#[cfg(taproot)]
5870+
partial_signature_with_nonce: None,
5871+
#[cfg(taproot)]
5872+
next_local_nonce: None,
5873+
})
5874+
} else {
5875+
self.context.signer_pending_funding = true;
5876+
None
5877+
};
5878+
58685879
let channel = Channel {
58695880
context: self.context,
58705881
};
58715882

5872-
Ok((channel, msgs::FundingCreated {
5873-
temporary_channel_id,
5874-
funding_txid: funding_txo.txid,
5875-
funding_output_index: funding_txo.index,
5876-
signature,
5877-
#[cfg(taproot)]
5878-
partial_signature_with_nonce: None,
5879-
#[cfg(taproot)]
5880-
next_local_nonce: None,
5881-
}))
5883+
Ok((channel, funding_created))
58825884
}
58835885

58845886
fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
@@ -6371,6 +6373,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
63716373
monitor_pending_finalized_fulfills: Vec::new(),
63726374

63736375
signer_pending_commitment_update: false,
6376+
signer_pending_funding: false,
63746377

63756378
#[cfg(debug_assertions)]
63766379
holder_max_commitment_tx_output: Mutex::new((msg.push_msat, msg.funding_satoshis * 1000 - msg.push_msat)),
@@ -7459,6 +7462,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
74597462
monitor_pending_finalized_fulfills: monitor_pending_finalized_fulfills.unwrap(),
74607463

74617464
signer_pending_commitment_update: false,
7465+
signer_pending_funding: false,
74627466

74637467
pending_update_fee,
74647468
holding_cell_update_fee,
@@ -7730,7 +7734,7 @@ mod tests {
77307734
}]};
77317735
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
77327736
let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap();
7733-
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
7737+
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
77347738

77357739
// Node B --> Node A: funding signed
77367740
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
@@ -7857,7 +7861,7 @@ mod tests {
78577861
}]};
78587862
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
78597863
let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap();
7860-
let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
7864+
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();
78617865

78627866
// Node B --> Node A: funding signed
78637867
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
@@ -8045,7 +8049,7 @@ mod tests {
80458049
}]};
80468050
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
80478051
let (mut node_a_chan, funding_created_msg) = node_a_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap();
8048-
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
8052+
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg.unwrap(), best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
80498053

80508054
// Node B --> Node A: funding signed
80518055
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,7 +3468,7 @@ where
34683468

34693469
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
34703470
let peer_state = &mut *peer_state_lock;
3471-
let (chan, msg) = match peer_state.outbound_v1_channel_by_id.remove(&temporary_channel_id) {
3471+
let (chan, msg_opt) = match peer_state.outbound_v1_channel_by_id.remove(&temporary_channel_id) {
34723472
Some(chan) => {
34733473
let funding_txo = find_funding_output(&chan, &funding_transaction)?;
34743474

@@ -3502,10 +3502,12 @@ where
35023502
},
35033503
};
35043504

3505-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
3506-
node_id: chan.context.get_counterparty_node_id(),
3507-
msg,
3508-
});
3505+
if let Some(msg) = msg_opt {
3506+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendFundingCreated {
3507+
node_id: chan.context.get_counterparty_node_id(),
3508+
msg,
3509+
});
3510+
}
35093511
match peer_state.channel_by_id.entry(chan.context.channel_id()) {
35103512
hash_map::Entry::Occupied(_) => {
35113513
panic!("Generated duplicate funding txid?");

lightning/src/ln/functional_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8936,7 +8936,7 @@ fn test_duplicate_chan_id() {
89368936
as_chan.get_funding_created(tx.clone(), funding_outpoint, &&logger).map_err(|_| ()).unwrap()
89378937
};
89388938
check_added_monitors!(nodes[0], 0);
8939-
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
8939+
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created.unwrap());
89408940
// At this point we'll look up if the channel_id is present and immediately fail the channel
89418941
// without trying to persist the `ChannelMonitor`.
89428942
check_added_monitors!(nodes[1], 0);

0 commit comments

Comments
 (0)