@@ -58,9 +58,8 @@ use crate::ln::channelmanager::{
58
58
#[cfg(splicing)]
59
59
use crate::ln::interactivetxs::{calculate_change_output_value, AbortReason};
60
60
use crate::ln::interactivetxs::{
61
- get_output_weight, HandleTxCompleteResult, InteractiveTxConstructor,
62
- InteractiveTxConstructorArgs, InteractiveTxMessageSendResult, InteractiveTxSigningSession,
63
- SharedOwnedInput, SharedOwnedOutput, TX_COMMON_FIELDS_WEIGHT,
61
+ get_output_weight, InteractiveTxConstructor, InteractiveTxConstructorArgs,
62
+ InteractiveTxSigningSession, SharedOwnedInput, SharedOwnedOutput, TX_COMMON_FIELDS_WEIGHT,
64
63
};
65
64
use crate::ln::msgs;
66
65
use crate::ln::msgs::{ClosingSigned, ClosingSignedFeeRange, DecodeError, OnionErrorPacket};
@@ -1728,6 +1727,15 @@ where
1728
1727
}
1729
1728
}
1730
1729
1730
+ pub fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
1731
+ match &mut self.phase {
1732
+ ChannelPhase::UnfundedV2(chan) => chan.interactive_tx_constructor.as_mut(),
1733
+ #[cfg(splicing)]
1734
+ ChannelPhase::Funded(chan) => chan.interactive_tx_constructor_mut(),
1735
+ _ => None,
1736
+ }
1737
+ }
1738
+
1731
1739
#[rustfmt::skip]
1732
1740
pub fn funding_signed<L: Deref>(
1733
1741
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
@@ -1761,16 +1769,71 @@ where
1761
1769
}
1762
1770
1763
1771
pub fn funding_tx_constructed<L: Deref>(
1764
- &mut self, signing_session: InteractiveTxSigningSession, logger: &L,
1772
+ &mut self, logger: &L,
1765
1773
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
1766
1774
where
1767
1775
L::Target: Logger,
1768
1776
{
1769
- if let ChannelPhase::UnfundedV2(chan) = &mut self.phase {
1770
- let logger = WithChannelContext::from(logger, &chan.context, None);
1771
- chan.funding_tx_constructed(signing_session, &&logger)
1772
- } else {
1773
- Err(ChannelError::Warn("Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()))
1777
+ let logger = WithChannelContext::from(logger, self.context(), None);
1778
+ match &mut self.phase {
1779
+ ChannelPhase::UnfundedV2(chan) => {
1780
+ let mut signing_session = chan
1781
+ .interactive_tx_constructor
1782
+ .take()
1783
+ .expect("PendingV2Channel::interactive_tx_constructor should be set")
1784
+ .into_signing_session();
1785
+ let (commitment_signed, event) = chan.context.funding_tx_constructed(
1786
+ &mut chan.funding,
1787
+ &mut signing_session,
1788
+ false,
1789
+ chan.unfunded_context.transaction_number(),
1790
+ &&logger,
1791
+ )?;
1792
+
1793
+ chan.interactive_tx_signing_session = Some(signing_session);
1794
+
1795
+ return Ok((commitment_signed, event));
1796
+ },
1797
+ #[cfg(splicing)]
1798
+ ChannelPhase::Funded(chan) => {
1799
+ if let Some(pending_splice) = chan.pending_splice.as_mut() {
1800
+ if let Some(funding_negotiation) = pending_splice.funding_negotiation.take() {
1801
+ if let FundingNegotiation::Pending(
1802
+ mut funding,
1803
+ interactive_tx_constructor,
1804
+ ) = funding_negotiation
1805
+ {
1806
+ let mut signing_session =
1807
+ interactive_tx_constructor.into_signing_session();
1808
+ let (commitment_signed, event) = chan.context.funding_tx_constructed(
1809
+ &mut funding,
1810
+ &mut signing_session,
1811
+ true,
1812
+ chan.holder_commitment_point.transaction_number(),
1813
+ &&logger,
1814
+ )?;
1815
+
1816
+ chan.interactive_tx_signing_session = Some(signing_session);
1817
+ pending_splice.funding_negotiation =
1818
+ Some(FundingNegotiation::AwaitingSignatures(funding));
1819
+
1820
+ return Ok((commitment_signed, event));
1821
+ } else {
1822
+ // Replace the taken state
1823
+ pending_splice.funding_negotiation = Some(funding_negotiation);
1824
+ }
1825
+ }
1826
+ }
1827
+
1828
+ return Err(ChannelError::Warn(
1829
+ "Got a transaction negotiation message in an invalid state".to_owned(),
1830
+ ));
1831
+ },
1832
+ _ => {
1833
+ return Err(ChannelError::Warn(
1834
+ "Got a transaction negotiation message in an invalid phase".to_owned(),
1835
+ ))
1836
+ },
1774
1837
}
1775
1838
}
1776
1839
@@ -2771,170 +2834,6 @@ where
2771
2834
}
2772
2835
}
2773
2836
2774
- impl<SP: Deref> PendingV2Channel<SP>
2775
- where
2776
- SP::Target: SignerProvider,
2777
- {
2778
- pub fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
2779
- InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor {
2780
- Some(ref mut tx_constructor) => tx_constructor
2781
- .handle_tx_add_input(msg)
2782
- .map_err(|reason| reason.into_tx_abort_msg(self.context.channel_id())),
2783
- None => Err(msgs::TxAbort {
2784
- channel_id: self.context.channel_id(),
2785
- data: b"No interactive transaction negotiation in progress".to_vec(),
2786
- }),
2787
- })
2788
- }
2789
-
2790
- pub fn tx_add_output(&mut self, msg: &msgs::TxAddOutput) -> InteractiveTxMessageSendResult {
2791
- InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor {
2792
- Some(ref mut tx_constructor) => tx_constructor
2793
- .handle_tx_add_output(msg)
2794
- .map_err(|reason| reason.into_tx_abort_msg(self.context.channel_id())),
2795
- None => Err(msgs::TxAbort {
2796
- channel_id: self.context.channel_id(),
2797
- data: b"No interactive transaction negotiation in progress".to_vec(),
2798
- }),
2799
- })
2800
- }
2801
-
2802
- pub fn tx_remove_input(&mut self, msg: &msgs::TxRemoveInput) -> InteractiveTxMessageSendResult {
2803
- InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor {
2804
- Some(ref mut tx_constructor) => tx_constructor
2805
- .handle_tx_remove_input(msg)
2806
- .map_err(|reason| reason.into_tx_abort_msg(self.context.channel_id())),
2807
- None => Err(msgs::TxAbort {
2808
- channel_id: self.context.channel_id(),
2809
- data: b"No interactive transaction negotiation in progress".to_vec(),
2810
- }),
2811
- })
2812
- }
2813
-
2814
- pub fn tx_remove_output(
2815
- &mut self, msg: &msgs::TxRemoveOutput,
2816
- ) -> InteractiveTxMessageSendResult {
2817
- InteractiveTxMessageSendResult(match &mut self.interactive_tx_constructor {
2818
- Some(ref mut tx_constructor) => tx_constructor
2819
- .handle_tx_remove_output(msg)
2820
- .map_err(|reason| reason.into_tx_abort_msg(self.context.channel_id())),
2821
- None => Err(msgs::TxAbort {
2822
- channel_id: self.context.channel_id(),
2823
- data: b"No interactive transaction negotiation in progress".to_vec(),
2824
- }),
2825
- })
2826
- }
2827
-
2828
- pub fn tx_complete(&mut self, msg: &msgs::TxComplete) -> HandleTxCompleteResult {
2829
- let tx_constructor = match &mut self.interactive_tx_constructor {
2830
- Some(ref mut tx_constructor) => tx_constructor,
2831
- None => {
2832
- let tx_abort = msgs::TxAbort {
2833
- channel_id: msg.channel_id,
2834
- data: b"No interactive transaction negotiation in progress".to_vec(),
2835
- };
2836
- return HandleTxCompleteResult(Err(tx_abort));
2837
- },
2838
- };
2839
-
2840
- let tx_complete = match tx_constructor.handle_tx_complete(msg) {
2841
- Ok(tx_complete) => tx_complete,
2842
- Err(reason) => {
2843
- return HandleTxCompleteResult(Err(reason.into_tx_abort_msg(msg.channel_id)))
2844
- },
2845
- };
2846
-
2847
- HandleTxCompleteResult(Ok(tx_complete))
2848
- }
2849
-
2850
- #[rustfmt::skip]
2851
- pub fn funding_tx_constructed<L: Deref>(
2852
- &mut self, mut signing_session: InteractiveTxSigningSession, logger: &L
2853
- ) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
2854
- where
2855
- L::Target: Logger
2856
- {
2857
- let transaction_number = self.unfunded_context.transaction_number();
2858
-
2859
- let mut output_index = None;
2860
- let expected_spk = self.funding.get_funding_redeemscript().to_p2wsh();
2861
- for (idx, outp) in signing_session.unsigned_tx().outputs().enumerate() {
2862
- if outp.script_pubkey() == &expected_spk && outp.value() == self.funding.get_value_satoshis() {
2863
- if output_index.is_some() {
2864
- let msg = "Multiple outputs matched the expected script and value";
2865
- let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2866
- return Err(ChannelError::Close((msg.to_owned(), reason)));
2867
- }
2868
- output_index = Some(idx as u16);
2869
- }
2870
- }
2871
- let outpoint = if let Some(output_index) = output_index {
2872
- OutPoint { txid: signing_session.unsigned_tx().compute_txid(), index: output_index }
2873
- } else {
2874
- let msg = "No output matched the funding script_pubkey";
2875
- let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2876
- return Err(ChannelError::Close((msg.to_owned(), reason)));
2877
- };
2878
- self.funding.channel_transaction_parameters.funding_outpoint = Some(outpoint);
2879
-
2880
- self.context.assert_no_commitment_advancement(transaction_number, "initial commitment_signed");
2881
- let commitment_signed = self.context.get_initial_commitment_signed(&self.funding, logger);
2882
- let commitment_signed = match commitment_signed {
2883
- Ok(commitment_signed) => commitment_signed,
2884
- Err(e) => {
2885
- self.funding.channel_transaction_parameters.funding_outpoint = None;
2886
- return Err(e)
2887
- },
2888
- };
2889
-
2890
- let funding_ready_for_sig_event = if signing_session.local_inputs_count() == 0 {
2891
- debug_assert_eq!(self.funding_negotiation_context.our_funding_contribution_satoshis, 0);
2892
- if signing_session.provide_holder_witnesses(self.context.channel_id, Vec::new()).is_err() {
2893
- debug_assert!(
2894
- false,
2895
- "Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
2896
- );
2897
- let msg = "V2 channel rejected due to sender error";
2898
- let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2899
- return Err(ChannelError::Close((msg.to_owned(), reason)));
2900
- }
2901
- None
2902
- } else {
2903
- // TODO(dual_funding): Send event for signing if we've contributed funds.
2904
- // Inform the user that SIGHASH_ALL must be used for all signatures when contributing
2905
- // inputs/signatures.
2906
- // Also warn the user that we don't do anything to prevent the counterparty from
2907
- // providing non-standard witnesses which will prevent the funding transaction from
2908
- // confirming. This warning must appear in doc comments wherever the user is contributing
2909
- // funds, whether they are initiator or acceptor.
2910
- //
2911
- // The following warning can be used when the APIs allowing contributing inputs become available:
2912
- // <div class="warning">
2913
- // WARNING: LDK makes no attempt to prevent the counterparty from using non-standard inputs which
2914
- // will prevent the funding transaction from being relayed on the bitcoin network and hence being
2915
- // confirmed.
2916
- // </div>
2917
- debug_assert!(
2918
- false,
2919
- "We don't support users providing inputs but somehow we had more than zero inputs",
2920
- );
2921
- let msg = "V2 channel rejected due to sender error";
2922
- let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
2923
- return Err(ChannelError::Close((msg.to_owned(), reason)));
2924
- };
2925
-
2926
- let mut channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
2927
- channel_state.set_interactive_signing();
2928
- self.context.channel_state = channel_state;
2929
-
2930
- // Clear the interactive transaction constructor
2931
- self.interactive_tx_constructor.take();
2932
- self.interactive_tx_signing_session = Some(signing_session);
2933
-
2934
- Ok((commitment_signed, funding_ready_for_sig_event))
2935
- }
2936
- }
2937
-
2938
2837
impl<SP: Deref> ChannelContext<SP>
2939
2838
where
2940
2839
SP::Target: SignerProvider,
@@ -5418,6 +5317,97 @@ where
5418
5317
Ok(())
5419
5318
}
5420
5319
5320
+ #[rustfmt::skip]
5321
+ fn funding_tx_constructed<L: Deref>(
5322
+ &mut self, funding: &mut FundingScope, signing_session: &mut InteractiveTxSigningSession,
5323
+ is_splice: bool, holder_commitment_transaction_number: u64, logger: &L
5324
+ ) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
5325
+ where
5326
+ L::Target: Logger
5327
+ {
5328
+ let mut output_index = None;
5329
+ let expected_spk = funding.get_funding_redeemscript().to_p2wsh();
5330
+ for (idx, outp) in signing_session.unsigned_tx().outputs().enumerate() {
5331
+ if outp.script_pubkey() == &expected_spk && outp.value() == funding.get_value_satoshis() {
5332
+ if output_index.is_some() {
5333
+ let msg = "Multiple outputs matched the expected script and value";
5334
+ let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5335
+ return Err(ChannelError::Close((msg.to_owned(), reason)));
5336
+ }
5337
+ output_index = Some(idx as u16);
5338
+ }
5339
+ }
5340
+ let outpoint = if let Some(output_index) = output_index {
5341
+ OutPoint { txid: signing_session.unsigned_tx().compute_txid(), index: output_index }
5342
+ } else {
5343
+ let msg = "No output matched the funding script_pubkey";
5344
+ let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5345
+ return Err(ChannelError::Close((msg.to_owned(), reason)));
5346
+ };
5347
+ funding
5348
+ .channel_transaction_parameters.funding_outpoint = Some(outpoint);
5349
+
5350
+ if is_splice {
5351
+ let message = "TODO Forced error, incomplete implementation".to_owned();
5352
+ // TODO(splicing) Forced error, as the use case is not complete
5353
+ return Err(ChannelError::Close((
5354
+ message.clone(),
5355
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false), message }
5356
+ )));
5357
+ }
5358
+
5359
+ self.assert_no_commitment_advancement(holder_commitment_transaction_number, "initial commitment_signed");
5360
+ let commitment_signed = self.get_initial_commitment_signed(&funding, logger);
5361
+ let commitment_signed = match commitment_signed {
5362
+ Ok(commitment_signed) => commitment_signed,
5363
+ Err(e) => {
5364
+ funding.channel_transaction_parameters.funding_outpoint = None;
5365
+ return Err(e)
5366
+ },
5367
+ };
5368
+
5369
+ let funding_ready_for_sig_event = if signing_session.local_inputs_count() == 0 {
5370
+ if signing_session.provide_holder_witnesses(self.channel_id, Vec::new()).is_err() {
5371
+ debug_assert!(
5372
+ false,
5373
+ "Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
5374
+ );
5375
+ let msg = "V2 channel rejected due to sender error";
5376
+ let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5377
+ return Err(ChannelError::Close((msg.to_owned(), reason)));
5378
+ }
5379
+ None
5380
+ } else {
5381
+ // TODO(dual_funding): Send event for signing if we've contributed funds.
5382
+ // Inform the user that SIGHASH_ALL must be used for all signatures when contributing
5383
+ // inputs/signatures.
5384
+ // Also warn the user that we don't do anything to prevent the counterparty from
5385
+ // providing non-standard witnesses which will prevent the funding transaction from
5386
+ // confirming. This warning must appear in doc comments wherever the user is contributing
5387
+ // funds, whether they are initiator or acceptor.
5388
+ //
5389
+ // The following warning can be used when the APIs allowing contributing inputs become available:
5390
+ // <div class="warning">
5391
+ // WARNING: LDK makes no attempt to prevent the counterparty from using non-standard inputs which
5392
+ // will prevent the funding transaction from being relayed on the bitcoin network and hence being
5393
+ // confirmed.
5394
+ // </div>
5395
+ debug_assert!(
5396
+ false,
5397
+ "We don't support users providing inputs but somehow we had more than zero inputs",
5398
+ );
5399
+ let msg = "V2 channel rejected due to sender error";
5400
+ let reason = ClosureReason::ProcessingError { err: msg.to_owned() };
5401
+ return Err(ChannelError::Close((msg.to_owned(), reason)));
5402
+ };
5403
+
5404
+ let mut channel_state = ChannelState::FundingNegotiated(FundingNegotiatedFlags::new());
5405
+ channel_state.set_interactive_signing();
5406
+ self.channel_state = channel_state;
5407
+
5408
+ Ok((commitment_signed, funding_ready_for_sig_event))
5409
+ }
5410
+
5421
5411
/// Asserts that the commitment tx numbers have not advanced from their initial number.
5422
5412
#[rustfmt::skip]
5423
5413
fn assert_no_commitment_advancement(&self, holder_commitment_transaction_number: u64, msg_name: &str) {
@@ -6033,6 +6023,22 @@ where
6033
6023
self.context.force_shutdown(&self.funding, closure_reason)
6034
6024
}
6035
6025
6026
+ #[cfg(splicing)]
6027
+ fn interactive_tx_constructor_mut(&mut self) -> Option<&mut InteractiveTxConstructor> {
6028
+ self.pending_splice
6029
+ .as_mut()
6030
+ .and_then(|pending_splice| pending_splice.funding_negotiation.as_mut())
6031
+ .and_then(|funding_negotiation| {
6032
+ if let FundingNegotiation::Pending(_, interactive_tx_constructor) =
6033
+ funding_negotiation
6034
+ {
6035
+ Some(interactive_tx_constructor)
6036
+ } else {
6037
+ None
6038
+ }
6039
+ })
6040
+ }
6041
+
6036
6042
#[rustfmt::skip]
6037
6043
fn check_remote_fee<F: Deref, L: Deref>(
6038
6044
channel_type: &ChannelTypeFeatures, fee_estimator: &LowerBoundedFeeEstimator<F>,
0 commit comments