@@ -29,9 +29,9 @@ use bitcoin::locktime::absolute::LockTime;
29
29
use crate::ln::types::{ChannelId, PaymentPreimage, PaymentHash};
30
30
use crate::ln::features::{ChannelTypeFeatures, InitFeatures};
31
31
use crate::ln::interactivetxs::{
32
- AbortReason, estimate_input_weight, get_output_weight, HandleTxCompleteResult ,
33
- InteractiveTxConstructor, InteractiveTxMessageSend, InteractiveTxMessageSendResult ,
34
- OutputOwned, TX_COMMON_FIELDS_WEIGHT,
32
+ AbortReason, ConstructedTransaction, estimate_input_weight, get_output_weight ,
33
+ HandleTxCompleteResult, InteractiveTxConstructor, InteractiveTxMessageSend ,
34
+ InteractiveTxMessageSendResult, OutputOwned, SharedOwnedOutput , TX_COMMON_FIELDS_WEIGHT,
35
35
};
36
36
use crate::ln::msgs;
37
37
use crate::ln::msgs::DecodeError;
@@ -64,7 +64,6 @@ use crate::sync::Mutex;
64
64
use crate::sign::type_resolver::ChannelSignerType;
65
65
66
66
use super::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint};
67
- use super::interactivetxs::SharedOwnedOutput;
68
67
69
68
#[cfg(test)]
70
69
pub struct ChannelValueStat {
@@ -1463,7 +1462,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
1463
1462
script_pubkey: self.context().get_funding_redeemscript().to_p2wsh(),
1464
1463
};
1465
1464
funding_outputs.push(
1466
- if self.dual_funding_context_mut().their_funding_satoshis > 0 {
1465
+ if self.dual_funding_context_mut().their_funding_satoshis.unwrap_or(0) > 0 {
1467
1466
OutputOwned::Shared(SharedOwnedOutput::new(tx_out, self.dual_funding_context_mut().our_funding_satoshis))
1468
1467
} else {
1469
1468
OutputOwned::SharedControlFullyOwned(tx_out)
@@ -3822,7 +3821,7 @@ pub(super) struct DualFundingChannelContext {
3822
3821
/// The amount in satoshis we will be contributing to the channel.
3823
3822
pub our_funding_satoshis: u64,
3824
3823
/// The amount in satoshis our counterparty will be contributing to the channel.
3825
- pub their_funding_satoshis: u64,
3824
+ pub their_funding_satoshis: Option< u64> ,
3826
3825
/// The funding transaction locktime suggested by the initiator. If set by us, it is always set
3827
3826
/// to the current block height to align incentives against fee-sniping.
3828
3827
pub funding_tx_locktime: LockTime,
@@ -4613,6 +4612,102 @@ impl<SP: Deref> Channel<SP> where
4613
4612
Ok(())
4614
4613
}
4615
4614
4615
+ pub fn commitment_signed_initial_v2<L: Deref>(
4616
+ &mut self, msg: &msgs::CommitmentSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
4617
+ ) -> Result<ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, ChannelError>
4618
+ where L::Target: Logger
4619
+ {
4620
+ if !matches!(self.context.channel_state, ChannelState::FundingNegotiated) {
4621
+ return Err(ChannelError::Close(
4622
+ (
4623
+ "Received initial commitment_signed before funding transaction constructed!".to_owned(),
4624
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
4625
+ )));
4626
+ }
4627
+ if self.context.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
4628
+ self.context.cur_counterparty_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER ||
4629
+ self.context.holder_commitment_point.transaction_number() != INITIAL_COMMITMENT_NUMBER {
4630
+ panic!("Should not have advanced channel commitment tx numbers prior to funding_created");
4631
+ }
4632
+
4633
+ let funding_script = self.context.get_funding_redeemscript();
4634
+
4635
+ let counterparty_keys = self.context.build_remote_transaction_keys();
4636
+ let counterparty_initial_commitment_tx = self.context.build_commitment_transaction(self.context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
4637
+ let counterparty_trusted_tx = counterparty_initial_commitment_tx.trust();
4638
+ let counterparty_initial_bitcoin_tx = counterparty_trusted_tx.built_transaction();
4639
+
4640
+ log_trace!(logger, "Initial counterparty tx for channel {} is: txid {} tx {}",
4641
+ &self.context.channel_id(), counterparty_initial_bitcoin_tx.txid, encode::serialize_hex(&counterparty_initial_bitcoin_tx.transaction));
4642
+
4643
+ let holder_signer = self.context.build_holder_transaction_keys();
4644
+ let initial_commitment_tx = self.context.build_commitment_transaction(
4645
+ self.context.holder_commitment_point.transaction_number(), &holder_signer, true, false, logger
4646
+ ).tx;
4647
+ {
4648
+ let trusted_tx = initial_commitment_tx.trust();
4649
+ let initial_commitment_bitcoin_tx = trusted_tx.built_transaction();
4650
+ let sighash = initial_commitment_bitcoin_tx.get_sighash_all(&funding_script, self.context.channel_value_satoshis);
4651
+ // They sign our commitment transaction, allowing us to broadcast the tx if we wish.
4652
+ if self.context.secp_ctx.verify_ecdsa(&sighash, &msg.signature, &self.context.get_counterparty_pubkeys().funding_pubkey).is_err() {
4653
+ return Err(ChannelError::Close(
4654
+ (
4655
+ "Invalid funding_signed signature from peer".to_owned(),
4656
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
4657
+ )));
4658
+ }
4659
+ }
4660
+
4661
+ let holder_commitment_tx = HolderCommitmentTransaction::new(
4662
+ initial_commitment_tx,
4663
+ msg.signature,
4664
+ Vec::new(),
4665
+ &self.context.get_holder_pubkeys().funding_pubkey,
4666
+ self.context.counterparty_funding_pubkey()
4667
+ );
4668
+
4669
+ self.context.holder_signer.as_ref().validate_holder_commitment(&holder_commitment_tx, Vec::new())
4670
+ .map_err(|_| ChannelError::Close(
4671
+ (
4672
+ "Failed to validate our commitment".to_owned(),
4673
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
4674
+ )))?;
4675
+
4676
+ let funding_redeemscript = self.context.get_funding_redeemscript();
4677
+ let funding_txo = self.context.get_funding_txo().unwrap();
4678
+ let funding_txo_script = funding_redeemscript.to_p2wsh();
4679
+ let obscure_factor = get_commitment_transaction_number_obscure_factor(&self.context.get_holder_pubkeys().payment_point, &self.context.get_counterparty_pubkeys().payment_point, self.context.is_outbound());
4680
+ let shutdown_script = self.context.shutdown_scriptpubkey.clone().map(|script| script.into_inner());
4681
+ let mut monitor_signer = signer_provider.derive_channel_signer(self.context.channel_value_satoshis, self.context.channel_keys_id);
4682
+ monitor_signer.provide_channel_parameters(&self.context.channel_transaction_parameters);
4683
+ let channel_monitor = ChannelMonitor::new(self.context.secp_ctx.clone(), monitor_signer,
4684
+ shutdown_script, self.context.get_holder_selected_contest_delay(),
4685
+ &self.context.destination_script, (funding_txo, funding_txo_script),
4686
+ &self.context.channel_transaction_parameters,
4687
+ funding_redeemscript.clone(), self.context.channel_value_satoshis,
4688
+ obscure_factor,
4689
+ holder_commitment_tx, best_block, self.context.counterparty_node_id, self.context.channel_id());
4690
+
4691
+ channel_monitor.provide_initial_counterparty_commitment_tx(
4692
+ counterparty_initial_bitcoin_tx.txid, Vec::new(),
4693
+ self.context.cur_counterparty_commitment_transaction_number,
4694
+ self.context.counterparty_cur_commitment_point.unwrap(),
4695
+ counterparty_initial_commitment_tx.feerate_per_kw(),
4696
+ counterparty_initial_commitment_tx.to_broadcaster_value_sat(),
4697
+ counterparty_initial_commitment_tx.to_countersignatory_value_sat(), logger);
4698
+
4699
+ assert!(!self.context.channel_state.is_monitor_update_in_progress()); // We have no had any monitor(s) yet to fail update!
4700
+ self.context.holder_commitment_point.advance(&self.context.holder_signer, &self.context.secp_ctx, logger);
4701
+ self.context.cur_counterparty_commitment_transaction_number -= 1;
4702
+
4703
+ log_info!(logger, "Received initial commitment_signed from peer for channel {}", &self.context.channel_id());
4704
+
4705
+ let need_channel_ready = self.check_get_channel_ready(0, logger).is_some();
4706
+ self.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
4707
+
4708
+ Ok(channel_monitor)
4709
+ }
4710
+
4616
4711
pub fn commitment_signed<L: Deref>(&mut self, msg: &msgs::CommitmentSigned, logger: &L) -> Result<Option<ChannelMonitorUpdate>, ChannelError>
4617
4712
where L::Target: Logger
4618
4713
{
@@ -7848,7 +7943,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
7848
7943
&mut self, msg: &msgs::AcceptChannel, default_limits: &ChannelHandshakeLimits,
7849
7944
their_features: &InitFeatures
7850
7945
) -> Result<(), ChannelError> {
7851
- self.context.do_accept_channel_checks(default_limits, their_features, &msg.common_fields, msg.channel_reserve_satoshis)
7946
+ self.context.do_accept_channel_checks(
7947
+ default_limits, their_features, &msg.common_fields, msg.channel_reserve_satoshis)
7852
7948
}
7853
7949
7854
7950
/// Handles a funding_signed message from the remote end.
@@ -8300,7 +8396,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8300
8396
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8301
8397
dual_funding_context: DualFundingChannelContext {
8302
8398
our_funding_satoshis: funding_satoshis,
8303
- their_funding_satoshis: 0 ,
8399
+ their_funding_satoshis: None ,
8304
8400
funding_tx_locktime,
8305
8401
funding_feerate_sat_per_1000_weight,
8306
8402
our_funding_inputs: funding_inputs,
@@ -8370,6 +8466,27 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8370
8466
require_confirmed_inputs: None,
8371
8467
}
8372
8468
}
8469
+
8470
+ pub fn funding_tx_constructed<L: Deref>(
8471
+ mut self, transaction: ConstructedTransaction, logger: &L
8472
+ ) -> Result<(Channel<SP>, msgs::CommitmentSigned), (Self, ChannelError)>
8473
+ where
8474
+ L::Target: Logger
8475
+ {
8476
+ let res = get_initial_commitment_signed(&mut self.context, transaction, logger);
8477
+ let commitment_signed = match res {
8478
+ Ok(commitment_signed) => commitment_signed,
8479
+ Err(err) => return Err((self, err)),
8480
+ };
8481
+
8482
+ let channel = Channel {
8483
+ context: self.context,
8484
+ dual_funding_channel_context: Some(self.dual_funding_context),
8485
+ interactive_tx_constructor: self.interactive_tx_constructor,
8486
+ };
8487
+
8488
+ Ok((channel, commitment_signed))
8489
+ }
8373
8490
}
8374
8491
8375
8492
// A not-yet-funded inbound (from counterparty) channel using V2 channel establishment.
@@ -8456,7 +8573,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
8456
8573
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8457
8574
dual_funding_context: DualFundingChannelContext {
8458
8575
our_funding_satoshis: funding_satoshis,
8459
- their_funding_satoshis: msg.common_fields.funding_satoshis,
8576
+ their_funding_satoshis: Some( msg.common_fields.funding_satoshis) ,
8460
8577
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
8461
8578
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
8462
8579
our_funding_inputs: funding_inputs,
@@ -8535,6 +8652,27 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
8535
8652
pub fn get_accept_channel_v2_message(&self) -> msgs::AcceptChannelV2 {
8536
8653
self.generate_accept_channel_v2_message()
8537
8654
}
8655
+
8656
+ pub fn funding_tx_constructed<L: Deref>(
8657
+ mut self, transaction: ConstructedTransaction, logger: &L
8658
+ ) -> Result<(Channel<SP>, msgs::CommitmentSigned), (Self, ChannelError)>
8659
+ where
8660
+ L::Target: Logger
8661
+ {
8662
+ let res = get_initial_commitment_signed(&mut self.context, transaction, logger);
8663
+ let commitment_signed = match res {
8664
+ Ok(commitment_signed) => commitment_signed,
8665
+ Err(err) => return Err((self, err)),
8666
+ };
8667
+
8668
+ let channel = Channel {
8669
+ context: self.context,
8670
+ dual_funding_channel_context: Some(self.dual_funding_context),
8671
+ interactive_tx_constructor: self.interactive_tx_constructor,
8672
+ };
8673
+
8674
+ Ok((channel, commitment_signed))
8675
+ }
8538
8676
}
8539
8677
8540
8678
// Unfunded channel utilities
@@ -8562,6 +8700,84 @@ fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures)
8562
8700
ret
8563
8701
}
8564
8702
8703
+ fn get_initial_counterparty_commitment_signature<SP:Deref, L: Deref>(
8704
+ context: &mut ChannelContext<SP>, logger: &L
8705
+ ) -> Result<Signature, ChannelError>
8706
+ where
8707
+ SP::Target: SignerProvider,
8708
+ L::Target: Logger
8709
+ {
8710
+ let counterparty_keys = context.build_remote_transaction_keys();
8711
+ let counterparty_initial_commitment_tx = context.build_commitment_transaction(
8712
+ context.cur_counterparty_commitment_transaction_number, &counterparty_keys, false, false, logger).tx;
8713
+ match context.holder_signer {
8714
+ // TODO (taproot|arik): move match into calling method for Taproot
8715
+ ChannelSignerType::Ecdsa(ref ecdsa) => {
8716
+ Ok(ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &context.secp_ctx)
8717
+ .map_err(|_| ChannelError::Close(
8718
+ (
8719
+ "Failed to get signatures for new commitment_signed".to_owned(),
8720
+ ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
8721
+ )))?.0)
8722
+ },
8723
+ // TODO (taproot|arik)
8724
+ #[cfg(taproot)]
8725
+ _ => todo!(),
8726
+ }
8727
+ }
8728
+
8729
+ fn get_initial_commitment_signed<SP:Deref, L: Deref>(
8730
+ context: &mut ChannelContext<SP>, transaction: ConstructedTransaction, logger: &L
8731
+ ) -> Result<msgs::CommitmentSigned, ChannelError>
8732
+ where
8733
+ SP::Target: SignerProvider,
8734
+ L::Target: Logger
8735
+ {
8736
+ if !matches!(
8737
+ context.channel_state, ChannelState::NegotiatingFunding(flags)
8738
+ if flags == (NegotiatingFundingFlags::OUR_INIT_SENT | NegotiatingFundingFlags::THEIR_INIT_SENT)) {
8739
+ panic!("Tried to get a funding_created messsage at a time other than immediately after initial handshake completion (or tried to get funding_created twice)");
8740
+ }
8741
+ if context.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
8742
+ context.cur_counterparty_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER ||
8743
+ context.holder_commitment_point.transaction_number() != INITIAL_COMMITMENT_NUMBER {
8744
+ panic!("Should not have advanced channel commitment tx numbers prior to initial commitment_signed");
8745
+ }
8746
+
8747
+ let funding_redeemscript = context.get_funding_redeemscript().to_p2wsh();
8748
+ let funding_outpoint_index = transaction.outputs().enumerate().find_map(
8749
+ |(idx, output)| {
8750
+ if output.tx_out().script_pubkey == funding_redeemscript { Some(idx as u16) } else { None }
8751
+ }).expect("funding transaction contains funding output");
8752
+ let funding_txo = OutPoint { txid: transaction.txid(), index: funding_outpoint_index };
8753
+ context.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
8754
+ context.holder_signer.as_mut().provide_channel_parameters(&context.channel_transaction_parameters);
8755
+
8756
+ let signature = match get_initial_counterparty_commitment_signature(context, logger) {
8757
+ Ok(res) => res,
8758
+ Err(e) => {
8759
+ log_error!(logger, "Got bad signatures: {:?}!", e);
8760
+ context.channel_transaction_parameters.funding_outpoint = None;
8761
+ return Err(e);
8762
+ }
8763
+ };
8764
+
8765
+ if context.signer_pending_funding {
8766
+ log_trace!(logger, "Counterparty commitment signature ready for funding_created message: clearing signer_pending_funding");
8767
+ context.signer_pending_funding = false;
8768
+ }
8769
+
8770
+ log_info!(logger, "Generated commitment_signed for peer for channel {}", &context.channel_id());
8771
+
8772
+ Ok(msgs::CommitmentSigned {
8773
+ channel_id: context.channel_id,
8774
+ htlc_signatures: vec![],
8775
+ signature,
8776
+ #[cfg(taproot)]
8777
+ partial_signature_with_nonce: None,
8778
+ })
8779
+ }
8780
+
8565
8781
const SERIALIZATION_VERSION: u8 = 4;
8566
8782
const MIN_SERIALIZATION_VERSION: u8 = 3;
8567
8783
0 commit comments