@@ -1400,7 +1400,10 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1400
1400
current_chain_height: u32,
1401
1401
outbound_scid_alias: u64,
1402
1402
temporary_channel_id: ChannelId,
1403
- channel_type: ChannelTypeFeatures,
1403
+ holder_selected_channel_reserve_satoshis: u64,
1404
+ channel_keys_id: [u8; 32],
1405
+ holder_signer: <SP::Target as SignerProvider>::EcdsaSigner,
1406
+ pubkeys: ChannelPublicKeys,
1404
1407
) -> Result<ChannelContext<SP>, APIError>
1405
1408
where
1406
1409
ES::Target: EntropySource,
@@ -1411,9 +1414,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1411
1414
let channel_value_satoshis = funding_satoshis;
1412
1415
1413
1416
let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay;
1414
- let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
1415
- let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
1416
- let pubkeys = holder_signer.pubkeys().clone();
1417
1417
1418
1418
if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
1419
1419
return Err(APIError::APIMisuseError{err: format!("funding_value must not exceed {}, it was {}", MAX_FUNDING_SATOSHIS_NO_WUMBO, channel_value_satoshis)});
@@ -1428,13 +1428,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1428
1428
if holder_selected_contest_delay < BREAKDOWN_TIMEOUT {
1429
1429
return Err(APIError::APIMisuseError {err: format!("Configured with an unreasonable our_to_self_delay ({}) putting user funds at risks", holder_selected_contest_delay)});
1430
1430
}
1431
- let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(channel_value_satoshis, config);
1432
- if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
1433
- // Protocol level safety check in place, although it should never happen because
1434
- // of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
1435
- return Err(APIError::APIMisuseError { err: format!("Holder selected channel reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
1436
- }
1437
1431
1432
+ let channel_type = get_initial_channel_type(&config, their_features);
1438
1433
debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
1439
1434
1440
1435
let (commitment_conf_target, anchor_outputs_value_msat) = if channel_type.supports_anchors_zero_fee_htlc_tx() {
@@ -1490,6 +1485,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1490
1485
channel_state: ChannelState::OurInitSent as u32,
1491
1486
announcement_sigs_state: AnnouncementSigsState::NotSent,
1492
1487
secp_ctx,
1488
+ // We'll add our counterparty's `funding_satoshis` when we receive `accept_channel2`.
1493
1489
channel_value_satoshis,
1494
1490
1495
1491
latest_monitor_update_id: 0,
@@ -1523,6 +1519,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1523
1519
signer_pending_commitment_update: false,
1524
1520
signer_pending_funding: false,
1525
1521
1522
+ // We'll add our counterparty's `funding_satoshis` to these max commitment output assertions
1523
+ // when we receive `accept_channel2`.
1526
1524
#[cfg(debug_assertions)]
1527
1525
holder_max_commitment_tx_output: Mutex::new((channel_value_satoshis * 1000 - push_msat, push_msat)),
1528
1526
#[cfg(debug_assertions)]
@@ -1543,6 +1541,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1543
1541
counterparty_dust_limit_satoshis: 0,
1544
1542
holder_dust_limit_satoshis: MIN_CHAN_DUST_LIMIT_SATOSHIS,
1545
1543
counterparty_max_htlc_value_in_flight_msat: 0,
1544
+ // We'll adjust this to include our counterparty's `funding_satoshis` when we
1545
+ // receive `accept_channel2`.
1546
1546
holder_max_htlc_value_in_flight_msat: get_holder_max_htlc_value_in_flight_msat(channel_value_satoshis, &config.channel_handshake_config),
1547
1547
counterparty_selected_channel_reserve_satoshis: None, // Filled in in accept_channel
1548
1548
holder_selected_channel_reserve_satoshis,
@@ -6623,7 +6623,17 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6623
6623
F::Target: FeeEstimator
6624
6624
{
6625
6625
let temporary_channel_id = temporary_channel_id.unwrap_or_else(|| ChannelId::temporary_from_entropy_source(entropy_source));
6626
- let channel_type = Self::get_initial_channel_type(&config, their_features);
6626
+
6627
+ let holder_selected_channel_reserve_satoshis = get_holder_selected_channel_reserve_satoshis(channel_value_satoshis, config);
6628
+ if holder_selected_channel_reserve_satoshis < MIN_CHAN_DUST_LIMIT_SATOSHIS {
6629
+ // Protocol level safety check in place, although it should never happen because
6630
+ // of `MIN_THEIR_CHAN_RESERVE_SATOSHIS`
6631
+ return Err(APIError::APIMisuseError { err: format!("Holder selected channel reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
6632
+ }
6633
+
6634
+ let channel_keys_id = signer_provider.generate_channel_keys_id(false, channel_value_satoshis, user_id);
6635
+ let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
6636
+ let pubkeys = holder_signer.pubkeys().clone();
6627
6637
6628
6638
let chan = Self {
6629
6639
context: ChannelContext::new_for_outbound_channel(
@@ -6639,7 +6649,10 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6639
6649
current_chain_height,
6640
6650
outbound_scid_alias,
6641
6651
temporary_channel_id,
6642
- channel_type,
6652
+ holder_selected_channel_reserve_satoshis,
6653
+ channel_keys_id,
6654
+ holder_signer,
6655
+ pubkeys,
6643
6656
)?,
6644
6657
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
6645
6658
};
@@ -6703,29 +6716,6 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
6703
6716
Ok((channel, funding_created))
6704
6717
}
6705
6718
6706
- fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
6707
- // The default channel type (ie the first one we try) depends on whether the channel is
6708
- // public - if it is, we just go with `only_static_remotekey` as it's the only option
6709
- // available. If it's private, we first try `scid_privacy` as it provides better privacy
6710
- // with no other changes, and fall back to `only_static_remotekey`.
6711
- let mut ret = ChannelTypeFeatures::only_static_remote_key();
6712
- if !config.channel_handshake_config.announced_channel &&
6713
- config.channel_handshake_config.negotiate_scid_privacy &&
6714
- their_features.supports_scid_privacy() {
6715
- ret.set_scid_privacy_required();
6716
- }
6717
-
6718
- // Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
6719
- // set it now. If they don't understand it, we'll fall back to our default of
6720
- // `only_static_remotekey`.
6721
- if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
6722
- their_features.supports_anchors_zero_fee_htlc_tx() {
6723
- ret.set_anchors_zero_fee_htlc_tx_required();
6724
- }
6725
-
6726
- ret
6727
- }
6728
-
6729
6719
/// If we receive an error message, it may only be a rejection of the channel type we tried,
6730
6720
/// not of our ability to open any channel at all. Thus, on error, we should first call this
6731
6721
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
@@ -7179,6 +7169,114 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
7179
7169
}
7180
7170
}
7181
7171
7172
+ // A not-yet-funded outbound (from holder) channel using V2 channel establishment.
7173
+ pub(super) struct OutboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
7174
+ pub context: ChannelContext<SP>,
7175
+ pub unfunded_context: UnfundedChannelContext,
7176
+ #[cfg(dual_funding)]
7177
+ pub dual_funding_context: DualFundingChannelContext,
7178
+ }
7179
+
7180
+ #[cfg(dual_funding)]
7181
+ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
7182
+ pub fn new<ES: Deref, F: Deref>(
7183
+ fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
7184
+ counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
7185
+ user_id: u128, config: &UserConfig, current_chain_height: u32, outbound_scid_alias: u64,
7186
+ funding_confirmation_target: ConfirmationTarget,
7187
+ ) -> Result<OutboundV2Channel<SP>, APIError>
7188
+ where ES::Target: EntropySource,
7189
+ F::Target: FeeEstimator,
7190
+ {
7191
+ let channel_keys_id = signer_provider.generate_channel_keys_id(false, funding_satoshis, user_id);
7192
+ let holder_signer = signer_provider.derive_channel_signer(funding_satoshis, channel_keys_id);
7193
+ let pubkeys = holder_signer.pubkeys().clone();
7194
+
7195
+ let temporary_channel_id = ChannelId::temporary_v2_from_revocation_basepoint(&pubkeys.revocation_basepoint);
7196
+
7197
+ let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
7198
+ funding_satoshis, MIN_CHAN_DUST_LIMIT_SATOSHIS);
7199
+
7200
+ let funding_feerate_sat_per_1000_weight = fee_estimator.bounded_sat_per_1000_weight(funding_confirmation_target);
7201
+ let funding_tx_locktime = current_chain_height;
7202
+
7203
+ let chan = Self {
7204
+ context: ChannelContext::new_for_outbound_channel(
7205
+ fee_estimator,
7206
+ entropy_source,
7207
+ signer_provider,
7208
+ counterparty_node_id,
7209
+ their_features,
7210
+ funding_satoshis,
7211
+ 0,
7212
+ user_id,
7213
+ config,
7214
+ current_chain_height,
7215
+ outbound_scid_alias,
7216
+ temporary_channel_id,
7217
+ holder_selected_channel_reserve_satoshis,
7218
+ channel_keys_id,
7219
+ holder_signer,
7220
+ pubkeys,
7221
+ )?,
7222
+ unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
7223
+ dual_funding_context: DualFundingChannelContext {
7224
+ our_funding_satoshis: funding_satoshis,
7225
+ their_funding_satoshis: 0,
7226
+ funding_tx_locktime,
7227
+ funding_feerate_sat_per_1000_weight,
7228
+ }
7229
+ };
7230
+ Ok(chan)
7231
+ }
7232
+
7233
+ pub fn get_open_channel_v2(&self, chain_hash: ChainHash) -> msgs::OpenChannelV2 {
7234
+ if self.context.channel_state != ChannelState::OurInitSent as u32 {
7235
+ panic!("Cannot generate an open_channel2 after we've moved forward");
7236
+ }
7237
+
7238
+ if self.context.cur_holder_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
7239
+ panic!("Tried to send an open_channel2 for a channel that has already advanced");
7240
+ }
7241
+
7242
+ let first_per_commitment_point = self.context.holder_signer.as_ref()
7243
+ .get_per_commitment_point(self.context.cur_holder_commitment_transaction_number,
7244
+ &self.context.secp_ctx);
7245
+ let second_per_commitment_point = self.context.holder_signer.as_ref()
7246
+ .get_per_commitment_point(self.context.cur_holder_commitment_transaction_number - 1,
7247
+ &self.context.secp_ctx);
7248
+ let keys = self.context.get_holder_pubkeys();
7249
+
7250
+ msgs::OpenChannelV2 {
7251
+ chain_hash,
7252
+ temporary_channel_id: self.context.temporary_channel_id.unwrap(),
7253
+ funding_satoshis: self.context.channel_value_satoshis,
7254
+ dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
7255
+ max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
7256
+ htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
7257
+ funding_feerate_sat_per_1000_weight: self.context.feerate_per_kw,
7258
+ commitment_feerate_sat_per_1000_weight: self.context.feerate_per_kw,
7259
+ to_self_delay: self.context.get_holder_selected_contest_delay(),
7260
+ max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
7261
+ funding_pubkey: keys.funding_pubkey,
7262
+ revocation_basepoint: keys.revocation_basepoint.to_public_key(),
7263
+ payment_basepoint: keys.payment_point,
7264
+ delayed_payment_basepoint: keys.delayed_payment_basepoint.to_public_key(),
7265
+ htlc_basepoint: keys.htlc_basepoint.to_public_key(),
7266
+ first_per_commitment_point,
7267
+ second_per_commitment_point,
7268
+ channel_flags: if self.context.config.announced_channel {1} else {0},
7269
+ shutdown_scriptpubkey: Some(match &self.context.shutdown_scriptpubkey {
7270
+ Some(script) => script.clone().into_inner(),
7271
+ None => Builder::new().into_script(),
7272
+ }),
7273
+ channel_type: Some(self.context.channel_type.clone()),
7274
+ locktime: self.dual_funding_context.funding_tx_locktime,
7275
+ require_confirmed_inputs: None,
7276
+ }
7277
+ }
7278
+ }
7279
+
7182
7280
// A not-yet-funded inbound (from counterparty) channel using V2 channel establishment.
7183
7281
#[cfg(dual_funding)]
7184
7282
pub(super) struct InboundV2Channel<SP: Deref> where SP::Target: SignerProvider {
@@ -7332,6 +7430,31 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
7332
7430
}
7333
7431
}
7334
7432
7433
+ // Unfunded channel utilities
7434
+
7435
+ fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
7436
+ // The default channel type (ie the first one we try) depends on whether the channel is
7437
+ // public - if it is, we just go with `only_static_remotekey` as it's the only option
7438
+ // available. If it's private, we first try `scid_privacy` as it provides better privacy
7439
+ // with no other changes, and fall back to `only_static_remotekey`.
7440
+ let mut ret = ChannelTypeFeatures::only_static_remote_key();
7441
+ if !config.channel_handshake_config.announced_channel &&
7442
+ config.channel_handshake_config.negotiate_scid_privacy &&
7443
+ their_features.supports_scid_privacy() {
7444
+ ret.set_scid_privacy_required();
7445
+ }
7446
+
7447
+ // Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
7448
+ // set it now. If they don't understand it, we'll fall back to our default of
7449
+ // `only_static_remotekey`.
7450
+ if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
7451
+ their_features.supports_anchors_zero_fee_htlc_tx() {
7452
+ ret.set_anchors_zero_fee_htlc_tx_required();
7453
+ }
7454
+
7455
+ ret
7456
+ }
7457
+
7335
7458
const SERIALIZATION_VERSION: u8 = 3;
7336
7459
const MIN_SERIALIZATION_VERSION: u8 = 3;
7337
7460
0 commit comments