@@ -1556,21 +1556,40 @@ impl<SP: Deref> Channel<SP> where
15561556 L::Target: Logger
15571557 {
15581558 let phase = core::mem::replace(&mut self.phase, ChannelPhase::Undefined);
1559- let result = if let ChannelPhase::UnfundedV2(chan) = phase {
1560- let logger = WithChannelContext::from(logger, &chan.context, None);
1561- match chan.funding_tx_constructed(signing_session, &&logger) {
1562- Ok((chan, commitment_signed, event)) => {
1563- self.phase = ChannelPhase::Funded(chan);
1564- Ok((commitment_signed, event))
1565- },
1566- Err((chan, e)) => {
1567- self.phase = ChannelPhase::UnfundedV2(chan);
1568- Err(e)
1569- },
1559+ let result = match phase {
1560+ ChannelPhase::UnfundedV2(chan) => {
1561+ let logger = WithChannelContext::from(logger, &chan.context, None);
1562+ match chan.funding_tx_constructed(signing_session, &&logger) {
1563+ Ok((chan, commitment_signed, event)) => {
1564+ self.phase = ChannelPhase::Funded(chan);
1565+ Ok((commitment_signed, event))
1566+ },
1567+ Err((chan, e)) => {
1568+ // revert
1569+ self.phase = ChannelPhase::UnfundedV2(chan);
1570+ Err(e)
1571+ },
1572+ }
1573+ }
1574+ #[cfg(splicing)]
1575+ ChannelPhase::RefundingV2(chan) => {
1576+ let logger = WithChannelContext::from(logger, &chan.pre_funded.context, None);
1577+ match chan.funding_tx_constructed(signing_session, &&logger) {
1578+ Ok((signing_session, holder_commitment_point, commitment_signed, event)) => {
1579+ let _res = self.phase_from_splice_to_funded(signing_session, holder_commitment_point)?;
1580+ Ok((commitment_signed, event))
1581+ },
1582+ Err((chan, e)) => {
1583+ // revert
1584+ self.phase = ChannelPhase::RefundingV2(chan);
1585+ Err(e)
1586+ },
1587+ }
1588+ }
1589+ _ => {
1590+ self.phase = phase;
1591+ Err(ChannelError::Warn("Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()))
15701592 }
1571- } else {
1572- self.phase = phase;
1573- Err(ChannelError::Warn("Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()))
15741593 };
15751594
15761595 debug_assert!(!matches!(self.phase, ChannelPhase::Undefined));
@@ -1580,11 +1599,10 @@ impl<SP: Deref> Channel<SP> where
15801599 /// Transition the channel from Funded to SplicingChannel.
15811600 /// Done in one go, as the existing ('pre') channel is put in the new channel (alongside a new one).
15821601 #[cfg(splicing)]
1583- fn phase_to_splice(&mut self, post_funding: FundingScope, dual_funding_context: DualFundingChannelContext, pending_splice_post: PendingSplicePost) -> Result<(), ChannelError>
1584- {
1602+ fn phase_from_funded_to_splice(&mut self, post_funding: FundingScope, dual_funding_context: DualFundingChannelContext, unfunded_context: UnfundedChannelContext, pending_splice_post: PendingSplicePost) -> Result<(), ChannelError> {
15851603 let phase = core::mem::replace(&mut self.phase, ChannelPhase::Undefined);
15861604 let result = if let ChannelPhase::Funded(prev_chan) = phase {
1587- self.phase = ChannelPhase::RefundingV2(SplicingChannel::new(prev_chan, post_funding, dual_funding_context, pending_splice_post));
1605+ self.phase = ChannelPhase::RefundingV2(SplicingChannel::new(prev_chan, post_funding, dual_funding_context, unfunded_context, pending_splice_post));
15881606 Ok(())
15891607 } else {
15901608 // revert phase
@@ -1595,6 +1613,29 @@ impl<SP: Deref> Channel<SP> where
15951613 result
15961614 }
15971615
1616+ /// Transition the channel from SplicingChannel to Funded, after negotiating new funded.
1617+ #[cfg(splicing)]
1618+ fn phase_from_splice_to_funded(&mut self, signing_session: InteractiveTxSigningSession, holder_commitment_point: HolderCommitmentPoint) -> Result<(), ChannelError> {
1619+ let phase = core::mem::replace(&mut self.phase, ChannelPhase::Undefined);
1620+ let result = if let ChannelPhase::RefundingV2(chan) = phase {
1621+ self.phase = ChannelPhase::Funded(FundedChannel {
1622+ funding: chan.post_funding,
1623+ context: chan.pre_funded.context,
1624+ interactive_tx_signing_session: Some(signing_session),
1625+ holder_commitment_point,
1626+ pending_splice_pre: None,
1627+ pending_splice_post: None,
1628+ });
1629+ Ok(())
1630+ } else {
1631+ // revert phase
1632+ self.phase = phase;
1633+ Err(ChannelError::Warn("Cannot transition away from splicing, not in splicing phase".to_owned()))
1634+ };
1635+ debug_assert!(!matches!(self.phase, ChannelPhase::Undefined));
1636+ result
1637+ }
1638+
15981639 #[cfg(splicing)]
15991640 pub fn splice_init<ES: Deref, L: Deref>(
16001641 &mut self, msg: &msgs::SpliceInit, our_funding_contribution: i64,
@@ -1606,10 +1647,10 @@ impl<SP: Deref> Channel<SP> where
16061647 {
16071648 // Explicit check for Funded, not as_funded; RefundingV2 not allowed
16081649 if let ChannelPhase::Funded(prev_chan) = &mut self.phase {
1609- let (pending_splice_post, post_funding, dual_funding_context) =
1650+ let (pending_splice_post, post_funding, dual_funding_context, unfunded_context ) =
16101651 prev_chan.splice_init(msg, our_funding_contribution)?;
16111652
1612- let _res = self.phase_to_splice (post_funding, dual_funding_context, pending_splice_post)?;
1653+ let _res = self.phase_from_funded_to_splice (post_funding, dual_funding_context, unfunded_context , pending_splice_post)?;
16131654
16141655 if let ChannelPhase::RefundingV2(chan) = &mut self.phase {
16151656 let splice_ack_msg = chan.splice_init(msg, our_funding_contribution, signer_provider, entropy_source, our_node_id, logger)?;
@@ -1633,10 +1674,10 @@ impl<SP: Deref> Channel<SP> where
16331674 {
16341675 // Explicit check for Funded, not as_funded; RefundingV2 not allowed
16351676 if let ChannelPhase::Funded(prev_chan) = &mut self.phase {
1636- let (pending_splice_post, post_funding, dual_funding_context, our_funding_contribution) =
1677+ let (pending_splice_post, post_funding, dual_funding_context, unfunded_context, our_funding_contribution) =
16371678 prev_chan.splice_ack(msg)?;
16381679
1639- let _res = self.phase_to_splice (post_funding, dual_funding_context, pending_splice_post)?;
1680+ let _res = self.phase_from_funded_to_splice (post_funding, dual_funding_context, unfunded_context , pending_splice_post)?;
16401681
16411682 if let ChannelPhase::RefundingV2(chan) = &mut self.phase {
16421683 let tx_msg_opt = chan.splice_ack(msg, our_funding_contribution, signer_provider, entropy_source, our_node_id, logger)?;
@@ -1709,9 +1750,9 @@ pub(super) struct SplicingChannel<SP: Deref> where SP::Target: SignerProvider {
17091750 /// TODO: replace it with its fields; done with trait?
17101751 pub pre_funded: FundedChannel<SP>,
17111752
1712- // Fields for PendingV2Channel follow, except ChannelContext
1753+ // Fields from PendingV2Channel follow, except ChannelContext, which is reused from above
17131754 pub post_funding: FundingScope,
1714- // pub unfunded_context: Option< UnfundedChannelContext> ,
1755+ pub unfunded_context: UnfundedChannelContext,
17151756 /// Used when negotiating the splice transaction
17161757 pub dual_funding_context: DualFundingChannelContext,
17171758 /// The current interactive transaction construction session under negotiation.
@@ -1724,18 +1765,18 @@ pub(super) struct SplicingChannel<SP: Deref> where SP::Target: SignerProvider {
17241765
17251766#[cfg(splicing)]
17261767impl<SP: Deref> SplicingChannel<SP> where SP::Target: SignerProvider {
1727- fn new(pre_funded: FundedChannel<SP>, post_funding: FundingScope, dual_funding_context: DualFundingChannelContext, pending_splice_post: PendingSplicePost) -> Self {
1768+ fn new(pre_funded: FundedChannel<SP>, post_funding: FundingScope, dual_funding_context: DualFundingChannelContext, unfunded_context: UnfundedChannelContext, pending_splice_post: PendingSplicePost) -> Self {
17281769 Self {
17291770 pre_funded,
17301771 post_funding,
17311772 dual_funding_context,
1773+ unfunded_context,
17321774 interactive_tx_constructor: None,
17331775 pending_splice_post,
17341776 }
17351777 }
17361778
17371779 /// Handle splice_init
1738- #[cfg(splicing)]
17391780 pub fn splice_init<ES: Deref, L: Deref>(
17401781 &mut self, _msg: &msgs::SpliceInit, our_funding_contribution: i64,
17411782 signer_provider: &SP, entropy_source: &ES, holder_node_id: &PublicKey, logger: &L,
@@ -1757,7 +1798,6 @@ impl<SP: Deref> SplicingChannel<SP> where SP::Target: SignerProvider {
17571798 }
17581799
17591800 /// Handle splice_ack
1760- #[cfg(splicing)]
17611801 pub fn splice_ack<ES: Deref, L: Deref>(
17621802 &mut self, msg: &msgs::SpliceAck, our_funding_contribution: i64,
17631803 signer_provider: &SP, entropy_source: &ES, holder_node_id: &PublicKey, logger: &L,
@@ -1793,7 +1833,6 @@ impl<SP: Deref> SplicingChannel<SP> where SP::Target: SignerProvider {
17931833 }
17941834
17951835 /// Splice process starting; update state, log, etc.
1796- #[cfg(splicing)]
17971836 pub(crate) fn splice_start<L: Deref>(&mut self, is_outgoing: bool, logger: &L) where L::Target: Logger {
17981837 // Set state, by this point splice_init/splice_ack handshake is complete
17991838 // TODO(splicing)
@@ -1966,15 +2005,100 @@ impl<SP: Deref> SplicingChannel<SP> where SP::Target: SignerProvider {
19662005 HandleTxCompleteResult(Ok(tx_complete))
19672006 }
19682007
1969- // TODO implement and use
1970- // pub fn funding_tx_constructed<L: Deref>(
1971- // self, signing_session: InteractiveTxSigningSession, logger: &L
1972- // ) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError> where L::Target: Logger {
1973- // match self.post_pending.funding_tx_constructed(signing_session, logger) {
1974- // Ok((_chan, msg, event)) => Ok((msg, event)),
1975- // Err((_chan, err)) => Err(err),
1976- // }
1977- // }
2008+ /// Copied from PendingV2Channel::funding_tx_constructed
2009+ /// TODO avoid code duplication with traits
2010+ fn funding_tx_constructed<L: Deref>(
2011+ mut self, mut signing_session: InteractiveTxSigningSession, logger: &L
2012+ ) -> Result<(InteractiveTxSigningSession, HolderCommitmentPoint, msgs::CommitmentSigned, Option<Event>), (SplicingChannel<SP>, ChannelError)>
2013+ where
2014+ L::Target: Logger
2015+ {
2016+ let our_funding_satoshis = self.dual_funding_context.our_funding_satoshis;
2017+ let transaction_number = self.unfunded_context.transaction_number();
2018+
2019+ let mut output_index = None;
2020+ let expected_spk = self.pre_funded.context.get_funding_redeemscript().to_p2wsh();
2021+ for (idx, outp) in signing_session.unsigned_tx.outputs().enumerate() {
2022+ if outp.script_pubkey() == &expected_spk && outp.value() == self.post_funding.get_value_satoshis() {
2023+ if output_index.is_some() {
2024+ return Err(ChannelError::Close((
2025+ "Multiple outputs matched the expected script and value".to_owned(),
2026+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2027+ ))).map_err(|e| (self, e));
2028+ }
2029+ output_index = Some(idx as u16);
2030+ }
2031+ }
2032+ let outpoint = if let Some(output_index) = output_index {
2033+ OutPoint { txid: signing_session.unsigned_tx.compute_txid(), index: output_index }
2034+ } else {
2035+ return Err(ChannelError::Close((
2036+ "No output matched the funding script_pubkey".to_owned(),
2037+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2038+ ))).map_err(|e| (self, e));
2039+ };
2040+ self.pre_funded.context.channel_transaction_parameters.funding_outpoint = Some(outpoint);
2041+ self.pre_funded.context.holder_signer.as_mut().provide_channel_parameters(&self.pre_funded.context.channel_transaction_parameters);
2042+
2043+ self.pre_funded.context.assert_no_commitment_advancement(transaction_number, "initial commitment_signed");
2044+ let commitment_signed = self.pre_funded.context.get_initial_commitment_signed(&self.post_funding, logger);
2045+ let commitment_signed = match commitment_signed {
2046+ Ok(commitment_signed) => {
2047+ // TODO: funding tx should be in FundingContext
2048+ self.pre_funded.context.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
2049+ commitment_signed
2050+ },
2051+ Err(err) => {
2052+ self.pre_funded.context.channel_transaction_parameters.funding_outpoint = None;
2053+ return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
2054+ .map_err(|e| (self, e));
2055+ },
2056+ };
2057+
2058+ let funding_ready_for_sig_event = None;
2059+ if signing_session.local_inputs_count() == 0 {
2060+ debug_assert_eq!(our_funding_satoshis, 0);
2061+ if signing_session.provide_holder_witnesses(self.pre_funded.context.channel_id, Vec::new()).is_err() {
2062+ debug_assert!(
2063+ false,
2064+ "Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
2065+ );
2066+ }
2067+ } else {
2068+ // TODO(dual_funding): Send event for signing if we've contributed funds.
2069+ // Inform the user that SIGHASH_ALL must be used for all signatures when contributing
2070+ // inputs/signatures.
2071+ // Also warn the user that we don't do anything to prevent the counterparty from
2072+ // providing non-standard witnesses which will prevent the funding transaction from
2073+ // confirming. This warning must appear in doc comments wherever the user is contributing
2074+ // funds, whether they are initiator or acceptor.
2075+ //
2076+ // The following warning can be used when the APIs allowing contributing inputs become available:
2077+ // <div class="warning">
2078+ // WARNING: LDK makes no attempt to prevent the counterparty from using non-standard inputs which
2079+ // will prevent the funding transaction from being relayed on the bitcoin network and hence being
2080+ // confirmed.
2081+ // </div>
2082+ }
2083+
2084+ self.pre_funded.context.channel_state = ChannelState::FundingNegotiated;
2085+
2086+ // Clear the interactive transaction constructor
2087+ self.interactive_tx_constructor.take();
2088+
2089+ match self.unfunded_context.holder_commitment_point {
2090+ Some(holder_commitment_point) => {
2091+ Ok((signing_session, holder_commitment_point, commitment_signed, funding_ready_for_sig_event))
2092+ },
2093+ None => {
2094+ let err = ChannelError::close(format!(
2095+ "Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
2096+ self.pre_funded.context.channel_id(),
2097+ ));
2098+ Err((self, err))
2099+ },
2100+ }
2101+ }
19782102}
19792103
19802104/// Contains all state common to unfunded inbound/outbound channels.
@@ -9181,7 +9305,7 @@ impl<SP: Deref> FundedChannel<SP> where
91819305 #[cfg(splicing)]
91829306 fn splice_init(
91839307 &mut self, msg: &msgs::SpliceInit, our_funding_contribution: i64,
9184- ) -> Result<(PendingSplicePost, FundingScope, DualFundingChannelContext), ChannelError>
9308+ ) -> Result<(PendingSplicePost, FundingScope, DualFundingChannelContext, UnfundedChannelContext ), ChannelError>
91859309 {
91869310 let _res = self.splice_init_checks(msg)?;
91879311
@@ -9229,12 +9353,12 @@ impl<SP: Deref> FundedChannel<SP> where
92299353 funding_feerate_sat_per_1000_weight: msg.funding_feerate_per_kw,
92309354 our_funding_inputs: Vec::new(),
92319355 };
9232- // let unfunded_context = UnfundedChannelContext {
9233- // unfunded_channel_age_ticks: 0,
9234- // holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
9235- // };
9356+ let unfunded_context = UnfundedChannelContext {
9357+ unfunded_channel_age_ticks: 0,
9358+ holder_commitment_point: HolderCommitmentPoint::new(&self. context.holder_signer, &self. context.secp_ctx),
9359+ };
92369360
9237- Ok((pending_splice_post, post_funding, dual_funding_context))
9361+ Ok((pending_splice_post, post_funding, dual_funding_context, unfunded_context ))
92389362 }
92399363
92409364 /// Checks during handling splice_ack
@@ -9252,7 +9376,7 @@ impl<SP: Deref> FundedChannel<SP> where
92529376 #[cfg(splicing)]
92539377 fn splice_ack(
92549378 &mut self, msg: &msgs::SpliceAck,
9255- ) -> Result<(PendingSplicePost, FundingScope, DualFundingChannelContext, i64), ChannelError>
9379+ ) -> Result<(PendingSplicePost, FundingScope, DualFundingChannelContext, UnfundedChannelContext, i64), ChannelError>
92569380 {
92579381 let pending_splice = self.splice_ack_checks()?;
92589382
@@ -9300,12 +9424,12 @@ impl<SP: Deref> FundedChannel<SP> where
93009424 funding_feerate_sat_per_1000_weight: pending_splice.funding_feerate_per_kw,
93019425 our_funding_inputs: pending_splice.our_funding_inputs.clone(),
93029426 };
9303- // let unfunded_context = UnfundedChannelContext {
9304- // unfunded_channel_age_ticks: 0,
9305- // holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
9306- // };
9427+ let unfunded_context = UnfundedChannelContext {
9428+ unfunded_channel_age_ticks: 0,
9429+ holder_commitment_point: HolderCommitmentPoint::new(&self. context.holder_signer, &self. context.secp_ctx),
9430+ };
93079431
9308- Ok((pending_splice_post, post_funding, dual_funding_context, pending_splice.our_funding_contribution))
9432+ Ok((pending_splice_post, post_funding, dual_funding_context, unfunded_context, pending_splice.our_funding_contribution))
93099433 }
93109434
93119435 // Send stuff to our remote peers:
0 commit comments