@@ -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,
@@ -6761,7 +6771,7 @@ impl<SP: Deref> FundedChannel<SP> where
67616771 // the funding transaction confirmed before the monitor was persisted, or
67626772 // * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
67636773 let channel_ready = if self.context.monitor_pending_channel_ready {
6764- assert!(!self.funding.is_outbound() || self.context .minimum_depth == Some(0),
6774+ assert!(!self.funding.is_outbound() || self.funding .minimum_depth == Some(0),
67656775 "Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
67666776 self.context.monitor_pending_channel_ready = false;
67676777 self.get_channel_ready(logger)
@@ -8010,7 +8020,7 @@ impl<SP: Deref> FundedChannel<SP> where
80108020 ) {
80118021 // If we're not a 0conf channel, we'll be waiting on a monitor update with only
80128022 // AwaitingChannelReady set, though our peer could have sent their channel_ready.
8013- debug_assert!(self.context .minimum_depth.unwrap_or(1) > 0);
8023+ debug_assert!(self.funding .minimum_depth.unwrap_or(1) > 0);
80148024 return true;
80158025 }
80168026 if self.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER - 1 &&
@@ -8084,7 +8094,7 @@ impl<SP: Deref> FundedChannel<SP> where
80848094 // Called:
80858095 // * always when a new block/transactions are confirmed with the new height
80868096 // * when funding is signed with a height of 0
8087- if self.funding.funding_tx_confirmation_height == 0 && self.context .minimum_depth != Some(0) {
8097+ if self.funding.funding_tx_confirmation_height == 0 && self.funding .minimum_depth != Some(0) {
80888098 return None;
80898099 }
80908100
@@ -8093,7 +8103,7 @@ impl<SP: Deref> FundedChannel<SP> where
80938103 self.funding.funding_tx_confirmation_height = 0;
80948104 }
80958105
8096- if funding_tx_confirmations < self.context .minimum_depth.unwrap_or(0) as i64 {
8106+ if funding_tx_confirmations < self.funding .minimum_depth.unwrap_or(0) as i64 {
80978107 return None;
80988108 }
80998109
@@ -8219,9 +8229,9 @@ impl<SP: Deref> FundedChannel<SP> where
82198229 // If this is a coinbase transaction and not a 0-conf channel
82208230 // we should update our min_depth to 100 to handle coinbase maturity
82218231 if tx.is_coinbase() &&
8222- self.context .minimum_depth.unwrap_or(0) > 0 &&
8223- self.context .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
8224- self.context .minimum_depth = Some(COINBASE_MATURITY);
8232+ self.funding .minimum_depth.unwrap_or(0) > 0 &&
8233+ self.funding .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
8234+ self.funding .minimum_depth = Some(COINBASE_MATURITY);
82258235 }
82268236 }
82278237 // If we allow 1-conf funding, we may need to check for channel_ready here and
@@ -8322,7 +8332,7 @@ impl<SP: Deref> FundedChannel<SP> where
83228332 // to.
83238333 if funding_tx_confirmations == 0 && self.funding.funding_tx_confirmed_in.is_some() {
83248334 let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
8325- self.context .minimum_depth.unwrap(), funding_tx_confirmations);
8335+ self.funding .minimum_depth.unwrap(), funding_tx_confirmations);
83268336 return Err(ClosureReason::ProcessingError { err: err_reason });
83278337 }
83288338 } else if !self.funding.is_outbound() && self.funding.funding_tx_confirmed_in.is_none() &&
@@ -9608,9 +9618,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
96089618 // If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
96099619 // We can skip this if it is a zero-conf channel.
96109620 if funding_transaction.is_coinbase() &&
9611- self.context .minimum_depth.unwrap_or(0) > 0 &&
9612- self.context .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
9613- self.context .minimum_depth = Some(COINBASE_MATURITY);
9621+ self.funding .minimum_depth.unwrap_or(0) > 0 &&
9622+ self.funding .minimum_depth.unwrap_or(0) < COINBASE_MATURITY {
9623+ self.funding .minimum_depth = Some(COINBASE_MATURITY);
96149624 }
96159625
96169626 debug_assert!(self.funding.funding_transaction.is_none());
@@ -9939,7 +9949,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
99399949 dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
99409950 max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
99419951 htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
9942- minimum_depth: self.context .minimum_depth.unwrap(),
9952+ minimum_depth: self.funding .minimum_depth.unwrap(),
99439953 to_self_delay: self.funding.get_holder_selected_contest_delay(),
99449954 max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
99459955 funding_pubkey: keys.funding_pubkey,
@@ -10351,7 +10361,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1035110361 dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
1035210362 max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
1035310363 htlc_minimum_msat: self.context.holder_htlc_minimum_msat,
10354- minimum_depth: self.context .minimum_depth.unwrap(),
10364+ minimum_depth: self.funding .minimum_depth.unwrap(),
1035510365 to_self_delay: self.funding.get_holder_selected_contest_delay(),
1035610366 max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
1035710367 funding_pubkey: keys.funding_pubkey,
@@ -10719,7 +10729,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1071910729 self.context.counterparty_max_accepted_htlcs.write(writer)?;
1072010730
1072110731 // Note that this field is ignored by 0.0.99+ as the TLV Optional variant is used instead.
10722- self.context.minimum_depth .unwrap_or(0).write(writer)?;
10732+ self.context.negotiated_minimum_depth .unwrap_or(0).write(writer)?;
1072310733
1072410734 match &self.context.counterparty_forwarding_info {
1072510735 Some(info) => {
@@ -10794,7 +10804,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1079410804 // here. On the read side, old versions will simply ignore the odd-type entries here,
1079510805 // and new versions map the default values to None and allow the TLV entries here to
1079610806 // override that.
10797- (1, self.context .minimum_depth, option),
10807+ (1, self.funding .minimum_depth, option),
1079810808 (2, chan_type, option),
1079910809 (3, self.funding.counterparty_selected_channel_reserve_satoshis, option),
1080010810 (4, serialized_holder_selected_reserve, option),
@@ -10830,6 +10840,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1083010840 (54, self.pending_funding, optional_vec), // Added in 0.2
1083110841 (55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
1083210842 (57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
10843+ (59, self.context.negotiated_minimum_depth, option), // Added in 0.2
1083310844 });
1083410845
1083510846 Ok(())
@@ -11128,6 +11139,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1112811139 let mut is_manual_broadcast = None;
1112911140
1113011141 let mut pending_funding = Some(Vec::new());
11142+ let mut negotiated_minimum_depth: Option<u32> = None;
1113111143
1113211144 read_tlv_fields!(reader, {
1113311145 (0, announcement_sigs, option),
@@ -11167,6 +11179,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1116711179 (54, pending_funding, optional_vec), // Added in 0.2
1116811180 (55, removed_htlc_failure_attribution_data, optional_vec),
1116911181 (57, holding_cell_failure_attribution_data, optional_vec),
11182+ (59, negotiated_minimum_depth, option), // Added in 0.2
1117011183 });
1117111184
1117211185 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -11342,6 +11355,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1134211355 funding_tx_confirmed_in,
1134311356 funding_tx_confirmation_height,
1134411357 short_channel_id,
11358+ minimum_depth,
1134511359 },
1134611360 pending_funding: pending_funding.unwrap(),
1134711361 context: ChannelContext {
@@ -11414,7 +11428,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1141411428 counterparty_htlc_minimum_msat,
1141511429 holder_htlc_minimum_msat,
1141611430 counterparty_max_accepted_htlcs,
11417- minimum_depth,
11431+ // TODO: But what if minimum_depth (TLV 1) had been overridden with COINBASE_MATURITY?
11432+ negotiated_minimum_depth: negotiated_minimum_depth.or(minimum_depth),
1141811433
1141911434 counterparty_forwarding_info,
1142011435
0 commit comments