@@ -1689,6 +1689,9 @@ pub(super) struct FundingScope {
16891689 funding_tx_confirmed_in: Option<BlockHash>,
16901690 funding_tx_confirmation_height: u32,
16911691 short_channel_id: Option<u64>,
1692+
1693+ /// The number of confirmation required before sending `channel_ready` or `splice_locked`.
1694+ minimum_depth: Option<u32>,
16921695}
16931696
16941697impl Writeable for FundingScope {
@@ -1702,6 +1705,7 @@ impl Writeable for FundingScope {
17021705 (11, self.funding_tx_confirmed_in, option),
17031706 (13, self.funding_tx_confirmation_height, required),
17041707 (15, self.short_channel_id, option),
1708+ (17, self.minimum_depth, option),
17051709 });
17061710 Ok(())
17071711 }
@@ -1717,6 +1721,7 @@ impl Readable for FundingScope {
17171721 let mut funding_tx_confirmed_in = None;
17181722 let mut funding_tx_confirmation_height = RequiredWrapper(None);
17191723 let mut short_channel_id = None;
1724+ let mut minimum_depth = None;
17201725
17211726 read_tlv_fields!(reader, {
17221727 (1, value_to_self_msat, required),
@@ -1727,6 +1732,7 @@ impl Readable for FundingScope {
17271732 (11, funding_tx_confirmed_in, option),
17281733 (13, funding_tx_confirmation_height, required),
17291734 (15, short_channel_id, option),
1735+ (17, minimum_depth, option),
17301736 });
17311737
17321738 Ok(Self {
@@ -1742,6 +1748,7 @@ impl Readable for FundingScope {
17421748 funding_tx_confirmed_in,
17431749 funding_tx_confirmation_height: funding_tx_confirmation_height.0.unwrap(),
17441750 short_channel_id,
1751+ minimum_depth,
17451752 #[cfg(any(test, fuzzing))]
17461753 next_local_commitment_tx_fee_info_cached: Mutex::new(None),
17471754 #[cfg(any(test, fuzzing))]
@@ -1847,6 +1854,10 @@ impl FundingScope {
18471854 pub fn get_short_channel_id(&self) -> Option<u64> {
18481855 self.short_channel_id
18491856 }
1857+
1858+ pub fn minimum_depth(&self) -> Option<u32> {
1859+ self.minimum_depth
1860+ }
18501861}
18511862
18521863/// Info about a pending splice, used in the pre-splice channel
@@ -2035,7 +2046,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
20352046 #[cfg(not(any(test, feature="_test_utils")))]
20362047 counterparty_max_accepted_htlcs: u16,
20372048 holder_max_accepted_htlcs: u16,
2038- minimum_depth : Option<u32>,
2049+ negotiated_minimum_depth : Option<u32>,
20392050
20402051 counterparty_forwarding_info: Option<CounterpartyForwardingInfo>,
20412052
@@ -2817,6 +2828,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
28172828 funding_tx_confirmed_in: None,
28182829 funding_tx_confirmation_height: 0,
28192830 short_channel_id: None,
2831+ minimum_depth,
28202832 };
28212833 let channel_context = ChannelContext {
28222834 user_id,
@@ -2891,7 +2903,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
28912903 holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
28922904 counterparty_max_accepted_htlcs: open_channel_fields.max_accepted_htlcs,
28932905 holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, max_htlcs(&channel_type)),
2894- minimum_depth,
2906+ negotiated_minimum_depth: minimum_depth,
28952907
28962908 counterparty_forwarding_info: None,
28972909
@@ -3053,6 +3065,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
30533065 funding_tx_confirmed_in: None,
30543066 funding_tx_confirmation_height: 0,
30553067 short_channel_id: None,
3068+ minimum_depth: None, // Filled in in accept_channel
30563069 };
30573070 let channel_context = Self {
30583071 user_id,
@@ -3127,7 +3140,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
31273140 holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
31283141 counterparty_max_accepted_htlcs: 0,
31293142 holder_max_accepted_htlcs: cmp::min(config.channel_handshake_config.our_max_accepted_htlcs, max_htlcs(&channel_type)),
3130- minimum_depth : None, // Filled in in accept_channel
3143+ negotiated_minimum_depth : None, // Filled in in accept_channel
31313144
31323145 counterparty_forwarding_info: None,
31333146
@@ -3313,10 +3326,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
33133326 self.temporary_channel_id
33143327 }
33153328
3316- pub fn minimum_depth(&self) -> Option<u32> {
3317- self.minimum_depth
3318- }
3319-
33203329 /// Gets the "user_id" value passed into the construction of this channel. It has no special
33213330 /// meaning and exists only to allow users to have a persistent identifier of a channel.
33223331 pub fn get_user_id(&self) -> u128 {
@@ -3458,10 +3467,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
34583467 self.counterparty_max_accepted_htlcs = common_fields.max_accepted_htlcs;
34593468
34603469 if peer_limits.trust_own_funding_0conf {
3461- self .minimum_depth = Some(common_fields.minimum_depth);
3470+ funding .minimum_depth = Some(common_fields.minimum_depth);
34623471 } else {
3463- self .minimum_depth = Some(cmp::max(1, common_fields.minimum_depth));
3472+ funding .minimum_depth = Some(cmp::max(1, common_fields.minimum_depth));
34643473 }
3474+ self.negotiated_minimum_depth = funding.minimum_depth;
34653475
34663476 let counterparty_pubkeys = ChannelPublicKeys {
34673477 funding_pubkey: common_fields.funding_pubkey,
@@ -6864,7 +6874,7 @@ impl<SP: Deref> FundedChannel<SP> where
68646874 // the funding transaction confirmed before the monitor was persisted, or
68656875 // * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
68666876 let channel_ready = if self.context.monitor_pending_channel_ready {
6867- assert!(!self.funding.is_outbound() || self.context .minimum_depth == Some(0),
6877+ assert!(!self.funding.is_outbound() || self.funding .minimum_depth == Some(0),
68686878 "Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
68696879 self.context.monitor_pending_channel_ready = false;
68706880 self.get_channel_ready(logger)
@@ -8113,7 +8123,7 @@ impl<SP: Deref> FundedChannel<SP> where
81138123 ) {
81148124 // If we're not a 0conf channel, we'll be waiting on a monitor update with only
81158125 // AwaitingChannelReady set, though our peer could have sent their channel_ready.
8116- debug_assert!(self.context .minimum_depth.unwrap_or(1) > 0);
8126+ debug_assert!(self.funding .minimum_depth.unwrap_or(1) > 0);
81178127 return true;
81188128 }
81198129 if self.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER - 1 &&
@@ -8187,7 +8197,7 @@ impl<SP: Deref> FundedChannel<SP> where
81878197 // Called:
81888198 // * always when a new block/transactions are confirmed with the new height
81898199 // * when funding is signed with a height of 0
8190- if self.funding.funding_tx_confirmation_height == 0 && self.context .minimum_depth != Some(0) {
8200+ if self.funding.funding_tx_confirmation_height == 0 && self.funding .minimum_depth != Some(0) {
81918201 return None;
81928202 }
81938203
@@ -8196,7 +8206,7 @@ impl<SP: Deref> FundedChannel<SP> where
81968206 self.funding.funding_tx_confirmation_height = 0;
81978207 }
81988208
8199- if funding_tx_confirmations < self.context .minimum_depth.unwrap_or(0) as i64 {
8209+ if funding_tx_confirmations < self.funding .minimum_depth.unwrap_or(0) as i64 {
82008210 return None;
82018211 }
82028212
@@ -8340,9 +8350,9 @@ impl<SP: Deref> FundedChannel<SP> where
83408350 // If this is a coinbase transaction and not a 0-conf channel
83418351 // we should update our min_depth to 100 to handle coinbase maturity
83428352 if funding_tx.is_coinbase() &&
8343- self.context .minimum_depth.unwrap_or(0) > 0 &&
8344- self.context .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
8345- self.context .minimum_depth = Some(COINBASE_MATURITY);
8353+ self.funding .minimum_depth.unwrap_or(0) > 0 &&
8354+ self.funding .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
8355+ self.funding .minimum_depth = Some(COINBASE_MATURITY);
83468356 }
83478357
83488358 // If we allow 1-conf funding, we may need to check for channel_ready here and
@@ -8436,7 +8446,7 @@ impl<SP: Deref> FundedChannel<SP> where
84368446 // to.
84378447 if funding_tx_confirmations == 0 && self.funding.funding_tx_confirmed_in.is_some() {
84388448 let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
8439- self.context .minimum_depth.unwrap(), funding_tx_confirmations);
8449+ self.funding .minimum_depth.unwrap(), funding_tx_confirmations);
84408450 return Err(ClosureReason::ProcessingError { err: err_reason });
84418451 }
84428452 } else if !self.funding.is_outbound() && self.funding.funding_tx_confirmed_in.is_none() &&
@@ -9637,9 +9647,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
96379647 // If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
96389648 // We can skip this if it is a zero-conf channel.
96399649 if funding_transaction.is_coinbase() &&
9640- self.context .minimum_depth.unwrap_or(0) > 0 &&
9641- self.context .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
9642- self.context .minimum_depth = Some(COINBASE_MATURITY);
9650+ self.funding .minimum_depth.unwrap_or(0) > 0 &&
9651+ self.funding .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
9652+ self.funding .minimum_depth = Some(COINBASE_MATURITY);
96439653 }
96449654
96459655 debug_assert!(self.funding.funding_transaction.is_none());
@@ -9968,7 +9978,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
99689978 dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
99699979 max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
99709980 htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
9971- minimum_depth: self.context .minimum_depth.unwrap(),
9981+ minimum_depth: self.funding .minimum_depth.unwrap(),
99729982 to_self_delay: self.funding.get_holder_selected_contest_delay(),
99739983 max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
99749984 funding_pubkey: keys.funding_pubkey,
@@ -10380,7 +10390,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1038010390 dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
1038110391 max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
1038210392 htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
10383- minimum_depth: self.context .minimum_depth.unwrap(),
10393+ minimum_depth: self.funding .minimum_depth.unwrap(),
1038410394 to_self_delay: self.funding.get_holder_selected_contest_delay(),
1038510395 max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
1038610396 funding_pubkey: keys.funding_pubkey,
@@ -10748,7 +10758,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1074810758 self.context.counterparty_max_accepted_htlcs.write(writer)?;
1074910759
1075010760 // Note that this field is ignored by 0.0.99+ as the TLV Optional variant is used instead.
10751- self.context.minimum_depth .unwrap_or(0).write(writer)?;
10761+ self.context.negotiated_minimum_depth .unwrap_or(0).write(writer)?;
1075210762
1075310763 match &self.context.counterparty_forwarding_info {
1075410764 Some(info) => {
@@ -10823,7 +10833,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1082310833 // here. On the read side, old versions will simply ignore the odd-type entries here,
1082410834 // and new versions map the default values to None and allow the TLV entries here to
1082510835 // override that.
10826- (1, self.context .minimum_depth, option),
10836+ (1, self.funding .minimum_depth, option),
1082710837 (2, chan_type, option),
1082810838 (3, self.funding.counterparty_selected_channel_reserve_satoshis, option),
1082910839 (4, serialized_holder_selected_reserve, option),
@@ -10859,6 +10869,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1085910869 (54, self.pending_funding, optional_vec), // Added in 0.2
1086010870 (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
1086110871 (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
10872+ (59, self.context.negotiated_minimum_depth, option), // Added in 0.2
1086210873 });
1086310874
1086410875 Ok(())
@@ -11157,6 +11168,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1115711168 let mut is_manual_broadcast = None;
1115811169
1115911170 let mut pending_funding = Some(Vec::new());
11171+ let mut negotiated_minimum_depth: Option<u32> = None;
1116011172
1116111173 read_tlv_fields!(reader, {
1116211174 (0, announcement_sigs, option),
@@ -11196,6 +11208,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1119611208 (54, pending_funding, optional_vec), // Added in 0.2
1119711209 (55, removed_htlc_failure_attribution_data, optional_vec),
1119811210 (57, holding_cell_failure_attribution_data, optional_vec),
11211+ (59, negotiated_minimum_depth, option), // Added in 0.2
1119911212 });
1120011213
1120111214 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -11371,6 +11384,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1137111384 funding_tx_confirmed_in,
1137211385 funding_tx_confirmation_height,
1137311386 short_channel_id,
11387+ minimum_depth,
1137411388 },
1137511389 pending_funding: pending_funding.unwrap(),
1137611390 context: ChannelContext {
@@ -11443,7 +11457,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1144311457 counterparty_htlc_minimum_msat,
1144411458 holder_htlc_minimum_msat,
1144511459 counterparty_max_accepted_htlcs,
11446- minimum_depth,
11460+ // TODO: But what if minimum_depth (TLV 1) had been overridden with COINBASE_MATURITY?
11461+ negotiated_minimum_depth: negotiated_minimum_depth.or(minimum_depth),
1144711462
1144811463 counterparty_forwarding_info,
1144911464
0 commit comments