@@ -906,6 +906,8 @@ pub(super) struct SignerResumeUpdates {
906
906
pub funding_signed: Option<msgs::FundingSigned>,
907
907
pub channel_ready: Option<msgs::ChannelReady>,
908
908
pub order: RAACommitmentOrder,
909
+ pub closing_signed: Option<msgs::ClosingSigned>,
910
+ pub signed_closing_tx: Option<Transaction>,
909
911
}
910
912
911
913
/// The return value of `channel_reestablish`
@@ -1268,6 +1270,9 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
1268
1270
/// [`msgs::FundingCreated`] or [`msgs::FundingSigned`] depending on if this channel is
1269
1271
/// outbound or inbound.
1270
1272
signer_pending_funding: bool,
1273
+ /// If we attempted to sign a cooperative close transaction but the signer wasn't ready, then this
1274
+ /// will be set to `true`.
1275
+ signer_pending_closing: bool,
1271
1276
1272
1277
// pending_update_fee is filled when sending and receiving update_fee.
1273
1278
//
@@ -1299,7 +1304,9 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
1299
1304
/// Max to_local and to_remote outputs in a remote-generated commitment transaction
1300
1305
counterparty_max_commitment_tx_output: Mutex<(u64, u64)>,
1301
1306
1302
- last_sent_closing_fee: Option<(u64, Signature)>, // (fee, holder_sig)
1307
+ // (fee_sats, skip_remote_output, fee_range, holder_sig)
1308
+ last_sent_closing_fee: Option<(u64, bool, ClosingSignedFeeRange, Option<Signature>)>,
1309
+ last_received_closing_sig: Option<Signature>,
1303
1310
target_closing_feerate_sats_per_kw: Option<u32>,
1304
1311
1305
1312
/// If our counterparty sent us a closing_signed while we were waiting for a `ChannelMonitor`
@@ -1736,6 +1743,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1736
1743
signer_pending_revoke_and_ack: false,
1737
1744
signer_pending_commitment_update: false,
1738
1745
signer_pending_funding: false,
1746
+ signer_pending_closing: false,
1739
1747
1740
1748
1741
1749
#[cfg(debug_assertions)]
@@ -1744,6 +1752,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1744
1752
counterparty_max_commitment_tx_output: Mutex::new((value_to_self_msat, (channel_value_satoshis * 1000 - msg_push_msat).saturating_sub(value_to_self_msat))),
1745
1753
1746
1754
last_sent_closing_fee: None,
1755
+ last_received_closing_sig: None,
1747
1756
pending_counterparty_closing_signed: None,
1748
1757
expecting_peer_commitment_signed: false,
1749
1758
closing_fee_limits: None,
@@ -1968,6 +1977,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1968
1977
signer_pending_revoke_and_ack: false,
1969
1978
signer_pending_commitment_update: false,
1970
1979
signer_pending_funding: false,
1980
+ signer_pending_closing: false,
1971
1981
1972
1982
// We'll add our counterparty's `funding_satoshis` to these max commitment output assertions
1973
1983
// when we receive `accept_channel2`.
@@ -1977,6 +1987,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1977
1987
counterparty_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
1978
1988
1979
1989
last_sent_closing_fee: None,
1990
+ last_received_closing_sig: None,
1980
1991
pending_counterparty_closing_signed: None,
1981
1992
expecting_peer_commitment_signed: false,
1982
1993
closing_fee_limits: None,
@@ -5490,19 +5501,44 @@ impl<SP: Deref> Channel<SP> where
5490
5501
commitment_update = None;
5491
5502
}
5492
5503
5493
- log_trace!(logger, "Signer unblocked with {} commitment_update, {} revoke_and_ack, {} funding_signed and {} channel_ready, with resend order {:?}",
5504
+ let (closing_signed, signed_closing_tx) = if self.context.signer_pending_closing {
5505
+ debug_assert!(self.context.last_sent_closing_fee.is_some());
5506
+ if let Some((fee, skip_remote_output, fee_range, holder_sig)) = self.context.last_sent_closing_fee.clone() {
5507
+ debug_assert!(holder_sig.is_none());
5508
+ log_trace!(logger, "Attempting to generate pending closing_signed...");
5509
+ let (closing_tx, fee) = self.build_closing_transaction(fee, skip_remote_output);
5510
+ let closing_signed = self.get_closing_signed_msg(&closing_tx, skip_remote_output,
5511
+ fee, fee_range.min_fee_satoshis, fee_range.max_fee_satoshis, logger);
5512
+ let signed_tx = if let (Some(ClosingSigned { signature, .. }), Some(counterparty_sig)) =
5513
+ (closing_signed.as_ref(), self.context.last_received_closing_sig) {
5514
+ let funding_redeemscript = self.context.get_funding_redeemscript();
5515
+ let sighash = closing_tx.trust().get_sighash_all(&funding_redeemscript, self.context.channel_value_satoshis);
5516
+ debug_assert!(self.context.secp_ctx.verify_ecdsa(&sighash, &counterparty_sig,
5517
+ &self.context.get_counterparty_pubkeys().funding_pubkey).is_ok());
5518
+ Some(self.build_signed_closing_transaction(&closing_tx, &counterparty_sig, signature))
5519
+ } else { None };
5520
+ (closing_signed, signed_tx)
5521
+ } else { (None, None) }
5522
+ } else { (None, None) };
5523
+
5524
+ log_trace!(logger, "Signer unblocked with {} commitment_update, {} revoke_and_ack, with resend order {:?}, {} funding_signed, {} channel_ready,
5525
+ {} closing_signed, and {} signed_closing_tx",
5494
5526
if commitment_update.is_some() { "a" } else { "no" },
5495
5527
if revoke_and_ack.is_some() { "a" } else { "no" },
5528
+ self.context.resend_order,
5496
5529
if funding_signed.is_some() { "a" } else { "no" },
5497
5530
if channel_ready.is_some() { "a" } else { "no" },
5498
- self.context.resend_order);
5531
+ if closing_signed.is_some() { "a" } else { "no" },
5532
+ if signed_closing_tx.is_some() { "a" } else { "no" });
5499
5533
5500
5534
SignerResumeUpdates {
5501
5535
commitment_update,
5502
5536
revoke_and_ack,
5503
5537
funding_signed,
5504
5538
channel_ready,
5505
5539
order: self.context.resend_order.clone(),
5540
+ closing_signed,
5541
+ signed_closing_tx,
5506
5542
}
5507
5543
}
5508
5544
@@ -5952,9 +5988,6 @@ impl<SP: Deref> Channel<SP> where
5952
5988
our_min_fee, our_max_fee, total_fee_satoshis);
5953
5989
5954
5990
let closing_signed = self.get_closing_signed_msg(&closing_tx, false, total_fee_satoshis, our_min_fee, our_max_fee, logger);
5955
- if closing_signed.is_none() {
5956
- return Err(ChannelError::close("Failed to get signature for closing transaction.".to_owned()));
5957
- }
5958
5991
Ok((closing_signed, None, None))
5959
5992
}
5960
5993
@@ -6108,33 +6141,36 @@ impl<SP: Deref> Channel<SP> where
6108
6141
) -> Option<msgs::ClosingSigned>
6109
6142
where L::Target: Logger
6110
6143
{
6111
- match &self.context.holder_signer {
6112
- ChannelSignerType::Ecdsa(ecdsa) => {
6113
- let fee_range = msgs::ClosingSignedFeeRange {
6114
- min_fee_satoshis,
6115
- max_fee_satoshis,
6116
- };
6117
- let sig = ecdsa.sign_closing_transaction(closing_tx, &self.context.secp_ctx).ok()?;
6118
-
6119
- self.context.last_sent_closing_fee = Some((fee_satoshis, sig.clone()));
6120
- Some(msgs::ClosingSigned {
6121
- channel_id: self.context.channel_id,
6122
- fee_satoshis,
6123
- signature: sig,
6124
- fee_range: Some(fee_range),
6125
- })
6126
- },
6144
+ let sig = match &self.context.holder_signer {
6145
+ ChannelSignerType::Ecdsa(ecdsa) => ecdsa.sign_closing_transaction(closing_tx, &self.context.secp_ctx).ok(),
6127
6146
// TODO (taproot|arik)
6128
6147
#[cfg(taproot)]
6129
6148
_ => todo!()
6149
+ };
6150
+ if sig.is_none() {
6151
+ log_trace!(logger, "Closing transaction signature unavailable, waiting on signer");
6152
+ self.context.signer_pending_closing = true;
6153
+ } else {
6154
+ self.context.signer_pending_closing = false;
6130
6155
}
6156
+ let fee_range = msgs::ClosingSignedFeeRange { min_fee_satoshis, max_fee_satoshis };
6157
+ self.context.last_sent_closing_fee = Some((fee_satoshis, skip_remote_output, fee_range.clone(), sig.clone()));
6158
+ sig.map(|signature| msgs::ClosingSigned {
6159
+ channel_id: self.context.channel_id,
6160
+ fee_satoshis,
6161
+ signature,
6162
+ fee_range: Some(fee_range),
6163
+ })
6131
6164
}
6132
6165
6133
6166
pub fn closing_signed<F: Deref, L: Deref>(
6134
6167
&mut self, fee_estimator: &LowerBoundedFeeEstimator<F>, msg: &msgs::ClosingSigned, logger: &L)
6135
6168
-> Result<(Option<msgs::ClosingSigned>, Option<Transaction>, Option<ShutdownResult>), ChannelError>
6136
6169
where F::Target: FeeEstimator, L::Target: Logger
6137
6170
{
6171
+ if self.is_shutdown_pending_signature() {
6172
+ return Err(ChannelError::Warn(String::from("Remote end sent us a closing_signed while fully shutdown and just waiting on the final closing signature")));
6173
+ }
6138
6174
if !self.context.channel_state.is_both_sides_shutdown() {
6139
6175
return Err(ChannelError::close("Remote end sent us a closing_signed before both sides provided a shutdown".to_owned()));
6140
6176
}
@@ -6190,7 +6226,7 @@ impl<SP: Deref> Channel<SP> where
6190
6226
};
6191
6227
6192
6228
assert!(self.context.shutdown_scriptpubkey.is_some());
6193
- if let Some((last_fee, sig)) = self.context.last_sent_closing_fee {
6229
+ if let Some((last_fee, _, _, Some( sig) )) = self.context.last_sent_closing_fee {
6194
6230
if last_fee == msg.fee_satoshis {
6195
6231
let shutdown_result = ShutdownResult {
6196
6232
closure_reason,
@@ -6223,9 +6259,6 @@ impl<SP: Deref> Channel<SP> where
6223
6259
};
6224
6260
6225
6261
let closing_signed = self.get_closing_signed_msg(&closing_tx, skip_remote_output, used_fee, our_min_fee, our_max_fee, logger);
6226
- if closing_signed.is_none() {
6227
- return Err(ChannelError::close("Failed to get signature for closing transaction.".to_owned()));
6228
- }
6229
6262
let (signed_tx, shutdown_result) = if $new_fee == msg.fee_satoshis {
6230
6263
let shutdown_result = ShutdownResult {
6231
6264
closure_reason,
@@ -6239,8 +6272,11 @@ impl<SP: Deref> Channel<SP> where
6239
6272
unbroadcasted_funding_tx: self.context.unbroadcasted_funding(),
6240
6273
channel_funding_txo: self.context.get_funding_txo(),
6241
6274
};
6242
- self.context.channel_state = ChannelState::ShutdownComplete;
6275
+ if closing_signed.is_some() {
6276
+ self.context.channel_state = ChannelState::ShutdownComplete;
6277
+ }
6243
6278
self.context.update_time_counter += 1;
6279
+ self.context.last_received_closing_sig = Some(msg.signature.clone());
6244
6280
let tx = closing_signed.as_ref().map(|ClosingSigned { signature, .. }|
6245
6281
self.build_signed_closing_transaction(&closing_tx, &msg.signature, signature));
6246
6282
(tx, Some(shutdown_result))
@@ -6278,7 +6314,7 @@ impl<SP: Deref> Channel<SP> where
6278
6314
} else {
6279
6315
// Old fee style negotiation. We don't bother to enforce whether they are complying
6280
6316
// with the "making progress" requirements, we just comply and hope for the best.
6281
- if let Some((last_fee, _)) = self.context.last_sent_closing_fee {
6317
+ if let Some((last_fee, _, _, _ )) = self.context.last_sent_closing_fee {
6282
6318
if msg.fee_satoshis > last_fee {
6283
6319
if msg.fee_satoshis < our_max_fee {
6284
6320
propose_fee!(msg.fee_satoshis);
@@ -6601,6 +6637,12 @@ impl<SP: Deref> Channel<SP> where
6601
6637
matches!(self.context.channel_state, ChannelState::ShutdownComplete)
6602
6638
}
6603
6639
6640
+ pub fn is_shutdown_pending_signature(&self) -> bool {
6641
+ matches!(self.context.channel_state, ChannelState::ChannelReady(_))
6642
+ && self.context.signer_pending_closing
6643
+ && self.context.last_received_closing_sig.is_some()
6644
+ }
6645
+
6604
6646
pub fn channel_update_status(&self) -> ChannelUpdateStatus {
6605
6647
self.context.channel_update_status
6606
6648
}
@@ -9466,6 +9508,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9466
9508
signer_pending_revoke_and_ack: false,
9467
9509
signer_pending_commitment_update: false,
9468
9510
signer_pending_funding: false,
9511
+ signer_pending_closing: false,
9469
9512
9470
9513
pending_update_fee,
9471
9514
holding_cell_update_fee,
@@ -9480,6 +9523,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9480
9523
counterparty_max_commitment_tx_output: Mutex::new((0, 0)),
9481
9524
9482
9525
last_sent_closing_fee: None,
9526
+ last_received_closing_sig: None,
9483
9527
pending_counterparty_closing_signed: None,
9484
9528
expecting_peer_commitment_signed: false,
9485
9529
closing_fee_limits: None,
0 commit comments