Skip to content

Commit a7df823

Browse files
committed
Introduce FundingTransactionReadyForSignatures event
The `FundingTransactionReadyForSignatures` event requests witnesses from the client for their contributed inputs to an interactively constructed transaction. The client calls `ChannelManager::funding_transaction_signed` to provide the witnesses to LDK. The `handle_channel_resumption` method handles resumption from both a channel re-establish and a monitor update. When the corresponding monitor update for the commitment_signed message completes, we will push the event here. We can thus only ever provide holder signatures after a monitor update has completed. We can also get rid of the reestablish code involved with `monitor_pending_tx_signatures` and remove that field too.
1 parent f4e40f0 commit a7df823

File tree

4 files changed

+266
-86
lines changed

4 files changed

+266
-86
lines changed

lightning/src/events/mod.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,52 @@ pub enum Event {
16921692
/// [`ChannelManager::send_static_invoice`]: crate::ln::channelmanager::ChannelManager::send_static_invoice
16931693
reply_path: Responder,
16941694
},
1695+
/// Indicates that a channel funding transaction constructed interactively is ready to be
1696+
/// signed. This event will only be triggered if at least one input was contributed.
1697+
///
1698+
/// The transaction contains all inputs and outputs provided by both parties including the
1699+
/// channel's funding output and a change output if applicable.
1700+
///
1701+
/// No part of the transaction should be changed before signing as the content of the transaction
1702+
/// has already been negotiated with the counterparty.
1703+
///
1704+
/// Each signature MUST use the `SIGHASH_ALL` flag to avoid invalidation of the initial commitment and
1705+
/// hence possible loss of funds.
1706+
///
1707+
/// After signing, call [`ChannelManager::funding_transaction_signed`] with the (partially) signed
1708+
/// funding transaction.
1709+
///
1710+
/// Generated in [`ChannelManager`] message handling.
1711+
///
1712+
/// # Failure Behavior and Persistence
1713+
/// This event will eventually be replayed after failures-to-handle (i.e., the event handler
1714+
/// returning `Err(ReplayEvent ())`), but will only be regenerated as needed after restarts.
1715+
///
1716+
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
1717+
/// [`ChannelManager::funding_transaction_signed`]: crate::ln::channelmanager::ChannelManager::funding_transaction_signed
1718+
FundingTransactionReadyForSigning {
1719+
/// The `channel_id` of the channel which you'll need to pass back into
1720+
/// [`ChannelManager::funding_transaction_signed`].
1721+
///
1722+
/// [`ChannelManager::funding_transaction_signed`]: crate::ln::channelmanager::ChannelManager::funding_transaction_signed
1723+
channel_id: ChannelId,
1724+
/// The counterparty's `node_id`, which you'll need to pass back into
1725+
/// [`ChannelManager::funding_transaction_signed`].
1726+
///
1727+
/// [`ChannelManager::funding_transaction_signed`]: crate::ln::channelmanager::ChannelManager::funding_transaction_signed
1728+
counterparty_node_id: PublicKey,
1729+
/// The `user_channel_id` value passed in for outbound channels, or for inbound channels if
1730+
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
1731+
/// `user_channel_id` will be randomized for inbound channels.
1732+
///
1733+
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
1734+
user_channel_id: u128,
1735+
/// The unsigned transaction to be signed and passed back to
1736+
/// [`ChannelManager::funding_transaction_signed`].
1737+
///
1738+
/// [`ChannelManager::funding_transaction_signed`]: crate::ln::channelmanager::ChannelManager::funding_transaction_signed
1739+
unsigned_transaction: Transaction,
1740+
},
16951741
}
16961742

16971743
impl Writeable for Event {
@@ -2134,6 +2180,11 @@ impl Writeable for Event {
21342180
47u8.write(writer)?;
21352181
// Never write StaticInvoiceRequested events as buffered onion messages aren't serialized.
21362182
},
2183+
&Event::FundingTransactionReadyForSigning { .. } => {
2184+
49u8.write(writer)?;
2185+
// We never write out FundingTransactionReadyForSigning events as they will be regenerated when
2186+
// necessary.
2187+
},
21372188
// Note that, going forward, all new events must only write data inside of
21382189
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
21392190
// data via `write_tlv_fields`.
@@ -2716,6 +2767,8 @@ impl MaybeReadable for Event {
27162767
// Note that we do not write a length-prefixed TLV for StaticInvoiceRequested events.
27172768
#[cfg(async_payments)]
27182769
47u8 => Ok(None),
2770+
// Note that we do not write a length-prefixed TLV for FundingTransactionReadyForSigning events.
2771+
49u8 => Ok(None),
27192772
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
27202773
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
27212774
// reads.

lightning/src/ln/channel.rs

Lines changed: 56 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use bitcoin::constants::ChainHash;
1414
use bitcoin::script::{Builder, Script, ScriptBuf, WScriptHash};
1515
use bitcoin::sighash::EcdsaSighashType;
1616
use bitcoin::transaction::{Transaction, TxIn, TxOut};
17-
use bitcoin::Weight;
17+
use bitcoin::{Weight, Witness};
1818

1919
use bitcoin::hash_types::{BlockHash, Txid};
2020
use bitcoin::hashes::sha256::Hash as Sha256;
@@ -24,9 +24,9 @@ use bitcoin::hashes::Hash;
2424
use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
2525
use bitcoin::secp256k1::{ecdsa::Signature, Secp256k1};
2626
use bitcoin::secp256k1::{PublicKey, SecretKey};
27-
use bitcoin::{secp256k1, sighash};
2827
#[cfg(splicing)]
29-
use bitcoin::{Sequence, Witness};
28+
use bitcoin::Sequence;
29+
use bitcoin::{secp256k1, sighash};
3030

3131
use crate::chain::chaininterface::{
3232
fee_for_weight, ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator,
@@ -2549,7 +2549,6 @@ where
25492549
monitor_pending_failures: Vec<(HTLCSource, PaymentHash, HTLCFailReason)>,
25502550
monitor_pending_finalized_fulfills: Vec<(HTLCSource, Option<AttributionData>)>,
25512551
monitor_pending_update_adds: Vec<msgs::UpdateAddHTLC>,
2552-
monitor_pending_tx_signatures: Option<msgs::TxSignatures>,
25532552

25542553
/// If we went to send a revoke_and_ack but our signer was unable to give us a signature,
25552554
/// we should retry at some point in the future when the signer indicates it may have a
@@ -3269,7 +3268,6 @@ where
32693268
monitor_pending_failures: Vec::new(),
32703269
monitor_pending_finalized_fulfills: Vec::new(),
32713270
monitor_pending_update_adds: Vec::new(),
3272-
monitor_pending_tx_signatures: None,
32733271

32743272
signer_pending_revoke_and_ack: false,
32753273
signer_pending_commitment_update: false,
@@ -3508,7 +3506,6 @@ where
35083506
monitor_pending_failures: Vec::new(),
35093507
monitor_pending_finalized_fulfills: Vec::new(),
35103508
monitor_pending_update_adds: Vec::new(),
3511-
monitor_pending_tx_signatures: None,
35123509

35133510
signer_pending_revoke_and_ack: false,
35143511
signer_pending_commitment_update: false,
@@ -5544,16 +5541,6 @@ where
55445541
};
55455542

55465543
let funding_ready_for_sig_event = if signing_session.local_inputs_count() == 0 {
5547-
if signing_session.provide_holder_witnesses(self.channel_id, Vec::new()).is_err() {
5548-
debug_assert!(
5549-
false,
5550-
"Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
5551-
);
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-
});
5556-
}
55575544
None
55585545
} else {
55595546
// TODO(dual_funding): Send event for signing if we've contributed funds.
@@ -6979,12 +6966,8 @@ where
69796966

69806967
self.monitor_updating_paused(false, false, false, Vec::new(), Vec::new(), Vec::new());
69816968

6982-
if let Some(tx_signatures) = self.interactive_tx_signing_session.as_mut().and_then(
6983-
|session| session.received_commitment_signed()
6984-
) {
6985-
// We're up first for submitting our tx_signatures, but our monitor has not persisted yet
6986-
// so they'll be sent as soon as that's done.
6987-
self.context.monitor_pending_tx_signatures = Some(tx_signatures);
6969+
if let Some(session) = &mut self.interactive_tx_signing_session {
6970+
session.received_commitment_signed();
69886971
}
69896972

69906973
Ok(channel_monitor)
@@ -7072,13 +7055,11 @@ where
70727055
channel_id: Some(self.context.channel_id()),
70737056
};
70747057

7075-
let tx_signatures = self
7076-
.interactive_tx_signing_session
7058+
self.interactive_tx_signing_session
70777059
.as_mut()
70787060
.expect("Signing session must exist for negotiated pending splice")
70797061
.received_commitment_signed();
70807062
self.monitor_updating_paused(false, false, false, Vec::new(), Vec::new(), Vec::new());
7081-
self.context.monitor_pending_tx_signatures = tx_signatures;
70827063

70837064
Ok(self.push_ret_blockable_mon_update(monitor_update))
70847065
}
@@ -7988,10 +7969,39 @@ where
79887969
}
79897970
}
79907971

7972+
pub fn funding_transaction_signed(
7973+
&mut self, witnesses: Vec<Witness>,
7974+
) -> Result<Option<msgs::TxSignatures>, APIError> {
7975+
let (funding_tx_opt, tx_signatures_opt) = self
7976+
.interactive_tx_signing_session
7977+
.as_mut()
7978+
.ok_or_else(|| APIError::APIMisuseError {
7979+
err: format!(
7980+
"Channel {} not expecting funding signatures",
7981+
self.context.channel_id
7982+
),
7983+
})
7984+
.and_then(|signing_session| {
7985+
signing_session
7986+
.provide_holder_witnesses(self.context.channel_id, witnesses)
7987+
.map_err(|err| APIError::APIMisuseError { err })
7988+
})?;
7989+
7990+
if tx_signatures_opt.is_some() {
7991+
self.context.channel_state.set_our_tx_signatures_ready();
7992+
}
7993+
7994+
if funding_tx_opt.is_some() {
7995+
self.funding.funding_transaction = funding_tx_opt;
7996+
self.context.channel_state =
7997+
ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
7998+
}
7999+
8000+
Ok(tx_signatures_opt)
8001+
}
8002+
79918003
#[rustfmt::skip]
7992-
pub fn tx_signatures<L: Deref>(&mut self, msg: &msgs::TxSignatures, logger: &L) -> Result<(Option<Transaction>, Option<msgs::TxSignatures>), ChannelError>
7993-
where L::Target: Logger
7994-
{
8004+
pub fn tx_signatures(&mut self, msg: &msgs::TxSignatures) -> Result<(Option<Transaction>, Option<msgs::TxSignatures>), ChannelError> {
79958005
if !self.context.channel_state.is_interactive_signing()
79968006
|| self.context.channel_state.is_their_tx_signatures_sent()
79978007
{
@@ -8014,23 +8024,12 @@ where
80148024
return Err(ChannelError::Close((msg.to_owned(), reason)));
80158025
}
80168026

8017-
if msg.witnesses.len() != signing_session.remote_inputs_count() {
8018-
return Err(ChannelError::Warn(
8019-
"Witness count did not match contributed input count".to_string()
8020-
));
8021-
}
8022-
80238027
for witness in &msg.witnesses {
80248028
if witness.is_empty() {
80258029
let msg = "Unexpected empty witness in tx_signatures received";
80268030
let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
80278031
return Err(ChannelError::Close((msg.to_owned(), reason)));
80288032
}
8029-
8030-
// TODO(dual_funding): Check all sigs are SIGHASH_ALL.
8031-
8032-
// TODO(dual_funding): I don't see how we're going to be able to ensure witness-standardness
8033-
// for spending. Doesn't seem to be anything in rust-bitcoin.
80348033
}
80358034

80368035
let (holder_tx_signatures_opt, funding_tx_opt) = signing_session.received_tx_signatures(msg.clone())
@@ -8039,24 +8038,23 @@ where
80398038
// Set `THEIR_TX_SIGNATURES_SENT` flag after all potential errors.
80408039
self.context.channel_state.set_their_tx_signatures_sent();
80418040

8041+
// Note that `holder_tx_signatures_opt` will be `None` if we sent `tx_signatures` first or if the
8042+
// user still needs to provide tx_signatures and we are sending second.
8043+
if holder_tx_signatures_opt.is_some() {
8044+
self.context.channel_state.set_our_tx_signatures_ready();
8045+
}
8046+
80428047
if funding_tx_opt.is_some() {
80438048
// We have a finalized funding transaction, so we can set the funding transaction.
80448049
self.funding.funding_transaction = funding_tx_opt.clone();
8050+
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
80458051
}
80468052

8047-
// Note that `holder_tx_signatures_opt` will be `None` if we sent `tx_signatures` first, so this
8048-
// case checks if there is a monitor persist in progress when we need to respond with our `tx_signatures`
8049-
// and sets it as pending.
8050-
if holder_tx_signatures_opt.is_some() && self.is_awaiting_initial_mon_persist() {
8051-
log_debug!(logger, "Not sending tx_signatures: a monitor update is in progress. Setting monitor_pending_tx_signatures.");
8052-
self.context.monitor_pending_tx_signatures = holder_tx_signatures_opt;
8053-
return Ok((None, None));
8054-
}
8055-
8056-
if holder_tx_signatures_opt.is_some() {
8057-
self.context.channel_state.set_our_tx_signatures_ready();
8053+
if holder_tx_signatures_opt.is_none() {
8054+
return Ok((funding_tx_opt, None));
80588055
}
80598056

8057+
// TODO(splicing): Transition back to `ChannelReady` and not `AwaitingChannelReady`
80608058
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
80618059
Ok((funding_tx_opt, holder_tx_signatures_opt))
80628060
} else {
@@ -8309,25 +8307,14 @@ where
83098307
mem::swap(&mut finalized_claimed_htlcs, &mut self.context.monitor_pending_finalized_fulfills);
83108308
let mut pending_update_adds = Vec::new();
83118309
mem::swap(&mut pending_update_adds, &mut self.context.monitor_pending_update_adds);
8312-
// For channels established with V2 establishment we won't send a `tx_signatures` when we're in
8313-
// MonitorUpdateInProgress (and we assume the user will never directly broadcast the funding
8314-
// transaction and waits for us to do it).
8315-
let tx_signatures = self.context.monitor_pending_tx_signatures.take();
8316-
if tx_signatures.is_some() {
8317-
if self.context.channel_state.is_their_tx_signatures_sent() {
8318-
self.context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
8319-
} else {
8320-
self.context.channel_state.set_our_tx_signatures_ready();
8321-
}
8322-
}
83238310

83248311
if self.context.channel_state.is_peer_disconnected() {
83258312
self.context.monitor_pending_revoke_and_ack = false;
83268313
self.context.monitor_pending_commitment_signed = false;
83278314
return MonitorRestoreUpdates {
83288315
raa: None, commitment_update: None, order: RAACommitmentOrder::RevokeAndACKFirst,
83298316
accepted_htlcs, failed_htlcs, finalized_claimed_htlcs, pending_update_adds,
8330-
funding_broadcastable, channel_ready, announcement_sigs, tx_signatures
8317+
funding_broadcastable, channel_ready, announcement_sigs, tx_signatures: None
83318318
};
83328319
}
83338320

@@ -8357,7 +8344,7 @@ where
83578344
match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"});
83588345
MonitorRestoreUpdates {
83598346
raa, commitment_update, order, accepted_htlcs, failed_htlcs, finalized_claimed_htlcs,
8360-
pending_update_adds, funding_broadcastable, channel_ready, announcement_sigs, tx_signatures
8347+
pending_update_adds, funding_broadcastable, channel_ready, announcement_sigs, tx_signatures: None
83618348
}
83628349
}
83638350

@@ -8834,7 +8821,6 @@ where
88348821
update_fee: None,
88358822
})
88368823
} else { None };
8837-
// TODO(dual_funding): For async signing support we need to hold back `tx_signatures` until the `commitment_signed` is ready.
88388824
let tx_signatures = if (
88398825
// if it has not received tx_signatures for that funding transaction AND
88408826
// if it has already received commitment_signed AND it should sign first, as specified in the tx_signatures requirements:
@@ -8843,14 +8829,8 @@ where
88438829
// else if it has already received tx_signatures for that funding transaction:
88448830
// MUST send its tx_signatures for that funding transaction.
88458831
) || self.context.channel_state.is_their_tx_signatures_sent() {
8846-
if self.context.channel_state.is_monitor_update_in_progress() {
8847-
// The `monitor_pending_tx_signatures` field should have already been set in `commitment_signed_initial_v2`
8848-
// if we were up first for signing and had a monitor update in progress, but check again just in case.
8849-
debug_assert!(self.context.monitor_pending_tx_signatures.is_some(), "monitor_pending_tx_signatures should already be set");
8850-
log_debug!(logger, "Not sending tx_signatures: a monitor update is in progress. Setting monitor_pending_tx_signatures.");
8851-
if self.context.monitor_pending_tx_signatures.is_none() {
8852-
self.context.monitor_pending_tx_signatures = session.holder_tx_signatures().clone();
8853-
}
8832+
if session.holder_tx_signatures().is_none() {
8833+
log_debug!(logger, "Not sending tx_signatures: a monitor update is in progress.");
88548834
None
88558835
} else {
88568836
// If `holder_tx_signatures` is `None` here, the `tx_signatures` message will be sent
@@ -11792,6 +11772,10 @@ where
1179211772
// CHANNEL_ANNOUNCEMENT_PROPAGATION_DELAY confirmations.
1179311773
self.context.historical_scids.drain(0..end)
1179411774
}
11775+
11776+
pub fn set_our_tx_signatures_ready(&mut self) {
11777+
self.context.channel_state.set_our_tx_signatures_ready();
11778+
}
1179511779
}
1179611780

1179711781
/// A not-yet-funded outbound (from holder) channel using V1 channel establishment.
@@ -13956,7 +13940,6 @@ where
1395613940
monitor_pending_failures,
1395713941
monitor_pending_finalized_fulfills: monitor_pending_finalized_fulfills.unwrap(),
1395813942
monitor_pending_update_adds: monitor_pending_update_adds.unwrap_or_default(),
13959-
monitor_pending_tx_signatures: None,
1396013943

1396113944
signer_pending_revoke_and_ack: false,
1396213945
signer_pending_commitment_update: false,

0 commit comments

Comments
 (0)