diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs index ea94cedd61a..20ef3f83eb2 100644 --- a/lightning/src/ln/channel.rs +++ b/lightning/src/ln/channel.rs @@ -31,8 +31,9 @@ use crate::ln::types::ChannelId; use crate::types::payment::{PaymentPreimage, PaymentHash}; use crate::types::features::{ChannelTypeFeatures, InitFeatures}; use crate::ln::interactivetxs::{ - get_output_weight, HandleTxCompleteResult, InteractiveTxConstructor, InteractiveTxConstructorArgs, - InteractiveTxSigningSession, InteractiveTxMessageSendResult, TX_COMMON_FIELDS_WEIGHT, + ConstructedTransaction, get_output_weight, HandleTxCompleteResult, InteractiveTxConstructor, + InteractiveTxConstructorArgs, InteractiveTxSigningSession, InteractiveTxMessageSendResult, + TX_COMMON_FIELDS_WEIGHT, }; use crate::ln::msgs; use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError}; @@ -9244,7 +9245,16 @@ impl Writeable for Channel where SP::Target: SignerProvider { self.context.channel_id.write(writer)?; { let mut channel_state = self.context.channel_state; - if matches!(channel_state, ChannelState::AwaitingChannelReady(_)|ChannelState::ChannelReady(_)) { + if matches!(channel_state, ChannelState::AwaitingChannelReady(_)|ChannelState::ChannelReady(_)) + { + channel_state.set_peer_disconnected(); + } else if self.interactive_tx_signing_session.is_some() { + if !matches!(channel_state, ChannelState::FundingNegotiated) { + debug_assert!(false, "V2 channels in pre-signing state should not be written"); + } + // This is a V2 session which has an active signing session + // TODO(dual_funding): When we allow contributing funds to dual-funded channels, + // we will need to handle persisting appropriate signing session state. channel_state.set_peer_disconnected(); } else { debug_assert!(false, "Pre-funded/shutdown channels should not be written"); @@ -9898,6 +9908,28 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch let mut next_holder_commitment_point_opt: Option = None; let mut is_manual_broadcast = None; + let interactive_tx_signing_session = if matches!(channel_state, ChannelState::FundingNegotiated) { + if let Some(ref funding_tx) = funding_transaction { + // TODO(dual_funding): When we allow contributing funds to dual-funded channels, + // we will need to handle persisting appropriate signing session state. + Some(InteractiveTxSigningSession { + unsigned_tx: ConstructedTransaction::default(), + counterparty_sent_tx_signatures: false, + holder_sends_tx_signatures_first: true, // TODO(dual_funding): Fixed to true as we currently don't contribute inputs. + received_commitment_signed: true, // We only enter the FundingNegotiated state once we have persisted the initial channel monitor. + holder_tx_signatures: Some(msgs::TxSignatures { + channel_id, + tx_hash: funding_tx.compute_txid(), + witnesses: vec![], // TODO(dual_funding): Fixed to true as we currently don't contribute inputs. + shared_input_signature: None, // TODO(splicing): Only relevant to splicing + }) + }) + } else { + debug_assert!(false, "Tried to read V2 channel with signing session but there is no funding transaction"); + None + } + } else { None }; + read_tlv_fields!(reader, { (0, announcement_sigs, option), (1, minimum_depth, option), @@ -10194,7 +10226,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch blocked_monitor_updates: blocked_monitor_updates.unwrap(), is_manual_broadcast: is_manual_broadcast.unwrap_or(false), }, - interactive_tx_signing_session: None, + interactive_tx_signing_session, }) } } diff --git a/lightning/src/ln/interactivetxs.rs b/lightning/src/ln/interactivetxs.rs index 02a2b19ec9d..b75b0f84c33 100644 --- a/lightning/src/ln/interactivetxs.rs +++ b/lightning/src/ln/interactivetxs.rs @@ -169,6 +169,22 @@ pub(crate) struct ConstructedTransaction { holder_sends_tx_signatures_first: bool, } +impl Default for ConstructedTransaction { + fn default() -> Self { + ConstructedTransaction { + holder_is_initiator: false, + inputs: vec![], + outputs: vec![], + local_inputs_value_satoshis: 0, + local_outputs_value_satoshis: 0, + remote_inputs_value_satoshis: 0, + remote_outputs_value_satoshis: 0, + lock_time: 0, + holder_sends_tx_signatures_first: true, + } + } +} + impl ConstructedTransaction { fn new(context: NegotiationContext) -> Self { let local_inputs_value_satoshis = context