@@ -1621,7 +1621,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1621
1621
current_chain_height: u32,
1622
1622
outbound_scid_alias: u64,
1623
1623
temporary_channel_id: Option<ChannelId>,
1624
- channel_type: ChannelTypeFeatures,
1624
+ holder_selected_channel_reserve_satoshis: u64,
1625
+ channel_keys_id: [u8; 32],
1626
+ holder_signer: <SP::Target as SignerProvider>::EcdsaSigner,
1627
+ pubkeys: ChannelPublicKeys,
1625
1628
) -> Result<ChannelContext<SP>, APIError>
1626
1629
where
1627
1630
ES::Target: EntropySource,
@@ -1632,9 +1635,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1632
1635
let channel_value_satoshis = funding_satoshis;
1633
1636
1634
1637
let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay;
1635
- let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
1636
- let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
1637
- let pubkeys = holder_signer.pubkeys().clone();
1638
1638
1639
1639
if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
1640
1640
return Err(APIError::APIMisuseError{err: format!("funding_value must not exceed {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, channel_value_satoshis)});
@@ -1649,13 +1649,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1649
1649
if holder_selected_contest_delay < BREAKDOWN_TIMEOUT {
1650
1650
return Err(APIError::APIMisuseError {err: format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks", holder_selected_contest_delay)});
1651
1651
}
1652
- let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(channel_value_satoshis, config);
1653
- if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
1654
- // Protocol level safety check in place, although it should never happen because
1655
- // of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
1656
- return Err(APIError::APIMisuseError { err: format!("Holder selected channel reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
1657
- }
1658
1652
1653
+ let channel_type = get_initial_channel_type(&config, their_features);
1659
1654
debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
1660
1655
1661
1656
let (commitment_conf_target, anchor_outputs_value_msat) = if channel_type.supports_anchors_zero_fee_htlc_tx() {
@@ -1712,6 +1707,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1712
1707
channel_state: ChannelState::NegotiatingFunding(NegotiatingFundingFlags::OUR_INIT_SENT),
1713
1708
announcement_sigs_state: AnnouncementSigsState::NotSent,
1714
1709
secp_ctx,
1710
+ // We'll add our counterparty's `funding_satoshis` when we receive `accept_channel2`.
1715
1711
channel_value_satoshis,
1716
1712
1717
1713
latest_monitor_update_id: 0,
@@ -1745,6 +1741,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1745
1741
signer_pending_commitment_update: false,
1746
1742
signer_pending_funding: false,
1747
1743
1744
+ // We'll add our counterparty's `funding_satoshis` to these max commitment output assertions
1745
+ // when we receive `accept_channel2`.
1748
1746
#[cfg(debug_assertions)]
1749
1747
holder_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
1750
1748
#[cfg(debug_assertions)]
@@ -1765,6 +1763,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1765
1763
counterparty_dust_limit_satoshis: 0,
1766
1764
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
1767
1765
counterparty_max_htlc_value_in_flight_msat: 0,
1766
+ // We'll adjust this to include our counterparty's `funding_satoshis` when we
1767
+ // receive `accept_channel2`.
1768
1768
holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis, &config.channel_handshake_config),
1769
1769
counterparty_selected_channel_reserve_satoshis: None, // Filled in in accept_channel
1770
1770
holder_selected_channel_reserve_satoshis,
@@ -3094,6 +3094,7 @@ pub(crate) fn get_legacy_default_holder_selected_channel_reserve_satoshis(channe
3094
3094
///
3095
3095
/// This is used both for outbound and inbound channels and has lower bound
3096
3096
/// of `dust_limit_satoshis`.
3097
+ #[cfg(dual_funding)]
3097
3098
fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satoshis: u64) -> u64 {
3098
3099
let channel_reserve_proportional_millionths = 10_000; // Fixed at 1% in spec.
3099
3100
let calculated_reserve =
@@ -6833,7 +6834,17 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6833
6834
where ES::Target: EntropySource,
6834
6835
F::Target: FeeEstimator
6835
6836
{
6836
- let channel_type = Self::get_initial_channel_type(&config, their_features);
6837
+ let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(channel_value_satoshis, config);
6838
+ if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
6839
+ // Protocol level safety check in place, although it should never happen because
6840
+ // of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
6841
+ return Err(APIError::APIMisuseError { err: format!("Holder selected channel reserve below \
6842
+ implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
6843
+ }
6844
+
6845
+ let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
6846
+ let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
6847
+ let pubkeys = holder_signer.pubkeys().clone();
6837
6848
6838
6849
let chan = Self {
6839
6850
context: ChannelContext::new_for_outbound_channel(
@@ -6849,7 +6860,10 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6849
6860
current_chain_height,
6850
6861
outbound_scid_alias,
6851
6862
temporary_channel_id,
6852
- channel_type,
6863
+ holder_selected_channel_reserve_satoshis,
6864
+ channel_keys_id,
6865
+ holder_signer,
6866
+ pubkeys,
6853
6867
)?,
6854
6868
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
6855
6869
};
@@ -6947,29 +6961,6 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6947
6961
Ok(funding_created)
6948
6962
}
6949
6963
6950
- fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
6951
- // The default channel type (ie the first one we try) depends on whether the channel is
6952
- // public - if it is, we just go with `only_static_remotekey` as it's the only option
6953
- // available. If it's private, we first try `scid_privacy` as it provides better privacy
6954
- // with no other changes, and fall back to `only_static_remotekey`.
6955
- let mut ret = ChannelTypeFeatures::only_static_remote_key();
6956
- if !config.channel_handshake_config.announced_channel &&
6957
- config.channel_handshake_config.negotiate_scid_privacy &&
6958
- their_features.supports_scid_privacy() {
6959
- ret.set_scid_privacy_required();
6960
- }
6961
-
6962
- // Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
6963
- // set it now. If they don't understand it, we'll fall back to our default of
6964
- // `only_static_remotekey`.
6965
- if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
6966
- their_features.supports_anchors_zero_fee_htlc_tx() {
6967
- ret.set_anchors_zero_fee_htlc_tx_required();
6968
- }
6969
-
6970
- ret
6971
- }
6972
-
6973
6964
/// If we receive an error message, it may only be a rejection of the channel type we tried,
6974
6965
/// not of our ability to open any channel at all. Thus, on error, we should first call this
6975
6966
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
@@ -7603,6 +7594,115 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
7603
7594
}
7604
7595
}
7605
7596
7597
+ // A not-yet-funded outbound (from holder) channel using V2 channel establishment.
7598
+ #[cfg(dual_funding)]
7599
+ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
7600
+ pub context: ChannelContext<SP>,
7601
+ pub unfunded_context: UnfundedChannelContext,
7602
+ #[cfg(dual_funding)]
7603
+ pub dual_funding_context: DualFundingChannelContext,
7604
+ }
7605
+
7606
+ #[cfg(dual_funding)]
7607
+ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
7608
+ pub fn new<ES: Deref, F: Deref>(
7609
+ fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
7610
+ counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
7611
+ user_id: u128, config: &UserConfig, current_chain_height: u32, outbound_scid_alias: u64,
7612
+ funding_confirmation_target: ConfirmationTarget,
7613
+ ) -> Result<OutboundV2Channel<SP>, APIError>
7614
+ where ES::Target: EntropySource,
7615
+ F::Target: FeeEstimator,
7616
+ {
7617
+ let channel_keys_id = signer_provider.generate_channel_keys_id(false, funding_satoshis, user_id);
7618
+ let holder_signer = signer_provider.derive_channel_signer(funding_satoshis, channel_keys_id);
7619
+ let pubkeys = holder_signer.pubkeys().clone();
7620
+
7621
+ let temporary_channel_id = Some(ChannelId::temporary_v2_from_revocation_basepoint(&pubkeys.revocation_basepoint));
7622
+
7623
+ let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
7624
+ funding_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
7625
+
7626
+ let funding_feerate_sat_per_1000_weight = fee_estimator.bounded_sat_per_1000_weight(funding_confirmation_target);
7627
+ let funding_tx_locktime = current_chain_height;
7628
+
7629
+ let chan = Self {
7630
+ context: ChannelContext::new_for_outbound_channel(
7631
+ fee_estimator,
7632
+ entropy_source,
7633
+ signer_provider,
7634
+ counterparty_node_id,
7635
+ their_features,
7636
+ funding_satoshis,
7637
+ 0,
7638
+ user_id,
7639
+ config,
7640
+ current_chain_height,
7641
+ outbound_scid_alias,
7642
+ temporary_channel_id,
7643
+ holder_selected_channel_reserve_satoshis,
7644
+ channel_keys_id,
7645
+ holder_signer,
7646
+ pubkeys,
7647
+ )?,
7648
+ unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
7649
+ dual_funding_context: DualFundingChannelContext {
7650
+ our_funding_satoshis: funding_satoshis,
7651
+ their_funding_satoshis: 0,
7652
+ funding_tx_locktime,
7653
+ funding_feerate_sat_per_1000_weight,
7654
+ }
7655
+ };
7656
+ Ok(chan)
7657
+ }
7658
+
7659
+ pub fn get_open_channel_v2(&self, chain_hash: ChainHash) -> msgs::OpenChannelV2 {
7660
+ if self.context.have_received_message() {
7661
+ panic!("Cannot generate an open_channel2 after we've moved forward");
7662
+ }
7663
+
7664
+ if self.context.cur_holder_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
7665
+ panic!("Tried to send an open_channel2 for a channel that has already advanced");
7666
+ }
7667
+
7668
+ let first_per_commitment_point = self.context.holder_signer.as_ref()
7669
+ .get_per_commitment_point(self.context.cur_holder_commitment_transaction_number,
7670
+ &self.context.secp_ctx);
7671
+ let second_per_commitment_point = self.context.holder_signer.as_ref()
7672
+ .get_per_commitment_point(self.context.cur_holder_commitment_transaction_number - 1,
7673
+ &self.context.secp_ctx);
7674
+ let keys = self.context.get_holder_pubkeys();
7675
+
7676
+ msgs::OpenChannelV2 {
7677
+ chain_hash,
7678
+ temporary_channel_id: self.context.temporary_channel_id.unwrap(),
7679
+ funding_satoshis: self.context.channel_value_satoshis,
7680
+ dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
7681
+ max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
7682
+ htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
7683
+ funding_feerate_sat_per_1000_weight: self.context.feerate_per_kw,
7684
+ commitment_feerate_sat_per_1000_weight: self.context.feerate_per_kw,
7685
+ to_self_delay: self.context.get_holder_selected_contest_delay(),
7686
+ max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
7687
+ funding_pubkey: keys.funding_pubkey,
7688
+ revocation_basepoint: keys.revocation_basepoint.to_public_key(),
7689
+ payment_basepoint: keys.payment_point,
7690
+ delayed_payment_basepoint: keys.delayed_payment_basepoint.to_public_key(),
7691
+ htlc_basepoint: keys.htlc_basepoint.to_public_key(),
7692
+ first_per_commitment_point,
7693
+ second_per_commitment_point,
7694
+ channel_flags: if self.context.config.announced_channel {1} else {0},
7695
+ shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
7696
+ Some(script) => script.clone().into_inner(),
7697
+ None => Builder::new().into_script(),
7698
+ }),
7699
+ channel_type: Some(self.context.channel_type.clone()),
7700
+ locktime: self.dual_funding_context.funding_tx_locktime,
7701
+ require_confirmed_inputs: None,
7702
+ }
7703
+ }
7704
+ }
7705
+
7606
7706
// A not-yet-funded inbound (from counterparty) channel using V2 channel establishment.
7607
7707
#[cfg(dual_funding)]
7608
7708
pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
@@ -7762,6 +7862,31 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
7762
7862
}
7763
7863
}
7764
7864
7865
+ // Unfunded channel utilities
7866
+
7867
+ fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
7868
+ // The default channel type (ie the first one we try) depends on whether the channel is
7869
+ // public - if it is, we just go with `only_static_remotekey` as it's the only option
7870
+ // available. If it's private, we first try `scid_privacy` as it provides better privacy
7871
+ // with no other changes, and fall back to `only_static_remotekey`.
7872
+ let mut ret = ChannelTypeFeatures::only_static_remote_key();
7873
+ if !config.channel_handshake_config.announced_channel &&
7874
+ config.channel_handshake_config.negotiate_scid_privacy &&
7875
+ their_features.supports_scid_privacy() {
7876
+ ret.set_scid_privacy_required();
7877
+ }
7878
+
7879
+ // Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
7880
+ // set it now. If they don't understand it, we'll fall back to our default of
7881
+ // `only_static_remotekey`.
7882
+ if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
7883
+ their_features.supports_anchors_zero_fee_htlc_tx() {
7884
+ ret.set_anchors_zero_fee_htlc_tx_required();
7885
+ }
7886
+
7887
+ ret
7888
+ }
7889
+
7765
7890
const SERIALIZATION_VERSION: u8 = 3;
7766
7891
const MIN_SERIALIZATION_VERSION: u8 = 3;
7767
7892
0 commit comments