@@ -1689,6 +1689,9 @@ pub(super) struct FundingScope {
1689
1689
funding_tx_confirmed_in: Option<BlockHash>,
1690
1690
funding_tx_confirmation_height: u32,
1691
1691
short_channel_id: Option<u64>,
1692
+
1693
+ /// The number of confirmation required before sending `channel_ready` or `splice_locked`.
1694
+ minimum_depth: Option<u32>,
1692
1695
}
1693
1696
1694
1697
impl Writeable for FundingScope {
@@ -1702,6 +1705,7 @@ impl Writeable for FundingScope {
1702
1705
(11, self.funding_tx_confirmed_in, option),
1703
1706
(13, self.funding_tx_confirmation_height, required),
1704
1707
(15, self.short_channel_id, option),
1708
+ (17, self.minimum_depth, option),
1705
1709
});
1706
1710
Ok(())
1707
1711
}
@@ -1717,6 +1721,7 @@ impl Readable for FundingScope {
1717
1721
let mut funding_tx_confirmed_in = None;
1718
1722
let mut funding_tx_confirmation_height = RequiredWrapper(None);
1719
1723
let mut short_channel_id = None;
1724
+ let mut minimum_depth = None;
1720
1725
1721
1726
read_tlv_fields!(reader, {
1722
1727
(1, value_to_self_msat, required),
@@ -1727,6 +1732,7 @@ impl Readable for FundingScope {
1727
1732
(11, funding_tx_confirmed_in, option),
1728
1733
(13, funding_tx_confirmation_height, required),
1729
1734
(15, short_channel_id, option),
1735
+ (17, minimum_depth, option),
1730
1736
});
1731
1737
1732
1738
Ok(Self {
@@ -1742,6 +1748,7 @@ impl Readable for FundingScope {
1742
1748
funding_tx_confirmed_in,
1743
1749
funding_tx_confirmation_height: funding_tx_confirmation_height.0.unwrap(),
1744
1750
short_channel_id,
1751
+ minimum_depth,
1745
1752
#[cfg(any(test, fuzzing))]
1746
1753
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
1747
1754
#[cfg(any(test, fuzzing))]
@@ -1847,6 +1854,10 @@ impl FundingScope {
1847
1854
pub fn get_short_channel_id(&self) -> Option<u64> {
1848
1855
self.short_channel_id
1849
1856
}
1857
+
1858
+ pub fn minimum_depth(&self) -> Option<u32> {
1859
+ self.minimum_depth
1860
+ }
1850
1861
}
1851
1862
1852
1863
/// 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 {
2035
2046
#[cfg(not(any(test, feature="_test_utils")))]
2036
2047
counterparty_max_accepted_htlcs: u16,
2037
2048
holder_max_accepted_htlcs: u16,
2038
- minimum_depth : Option<u32>,
2049
+ negotiated_minimum_depth : Option<u32>,
2039
2050
2040
2051
counterparty_forwarding_info: Option<CounterpartyForwardingInfo>,
2041
2052
@@ -2817,6 +2828,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2817
2828
funding_tx_confirmed_in: None,
2818
2829
funding_tx_confirmation_height: 0,
2819
2830
short_channel_id: None,
2831
+ minimum_depth,
2820
2832
};
2821
2833
let channel_context = ChannelContext {
2822
2834
user_id,
@@ -2891,7 +2903,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2891
2903
holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
2892
2904
counterparty_max_accepted_htlcs: open_channel_fields.max_accepted_htlcs,
2893
2905
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,
2895
2907
2896
2908
counterparty_forwarding_info: None,
2897
2909
@@ -3053,6 +3065,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3053
3065
funding_tx_confirmed_in: None,
3054
3066
funding_tx_confirmation_height: 0,
3055
3067
short_channel_id: None,
3068
+ minimum_depth: None, // Filled in in accept_channel
3056
3069
};
3057
3070
let channel_context = Self {
3058
3071
user_id,
@@ -3127,7 +3140,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3127
3140
holder_htlc_minimum_msat: if config.channel_handshake_config.our_htlc_minimum_msat == 0 { 1 } else { config.channel_handshake_config.our_htlc_minimum_msat },
3128
3141
counterparty_max_accepted_htlcs: 0,
3129
3142
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
3131
3144
3132
3145
counterparty_forwarding_info: None,
3133
3146
@@ -3313,10 +3326,6 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3313
3326
self.temporary_channel_id
3314
3327
}
3315
3328
3316
- pub fn minimum_depth(&self) -> Option<u32> {
3317
- self.minimum_depth
3318
- }
3319
-
3320
3329
/// Gets the "user_id" value passed into the construction of this channel. It has no special
3321
3330
/// meaning and exists only to allow users to have a persistent identifier of a channel.
3322
3331
pub fn get_user_id(&self) -> u128 {
@@ -3458,10 +3467,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3458
3467
self.counterparty_max_accepted_htlcs = common_fields.max_accepted_htlcs;
3459
3468
3460
3469
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);
3462
3471
} 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));
3464
3473
}
3474
+ self.negotiated_minimum_depth = funding.minimum_depth;
3465
3475
3466
3476
let counterparty_pubkeys = ChannelPublicKeys {
3467
3477
funding_pubkey: common_fields.funding_pubkey,
@@ -6761,7 +6771,7 @@ impl<SP: Deref> FundedChannel<SP> where
6761
6771
// the funding transaction confirmed before the monitor was persisted, or
6762
6772
// * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
6763
6773
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),
6765
6775
"Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
6766
6776
self.context.monitor_pending_channel_ready = false;
6767
6777
self.get_channel_ready(logger)
@@ -8010,7 +8020,7 @@ impl<SP: Deref> FundedChannel<SP> where
8010
8020
) {
8011
8021
// If we're not a 0conf channel, we'll be waiting on a monitor update with only
8012
8022
// 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);
8014
8024
return true;
8015
8025
}
8016
8026
if self.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER - 1 &&
@@ -8084,7 +8094,7 @@ impl<SP: Deref> FundedChannel<SP> where
8084
8094
// Called:
8085
8095
// * always when a new block/transactions are confirmed with the new height
8086
8096
// * 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) {
8088
8098
return None;
8089
8099
}
8090
8100
@@ -8093,7 +8103,7 @@ impl<SP: Deref> FundedChannel<SP> where
8093
8103
self.funding.funding_tx_confirmation_height = 0;
8094
8104
}
8095
8105
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 {
8097
8107
return None;
8098
8108
}
8099
8109
@@ -8219,9 +8229,9 @@ impl<SP: Deref> FundedChannel<SP> where
8219
8229
// If this is a coinbase transaction and not a 0-conf channel
8220
8230
// we should update our min_depth to 100 to handle coinbase maturity
8221
8231
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);
8225
8235
}
8226
8236
}
8227
8237
// 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
8322
8332
// to.
8323
8333
if funding_tx_confirmations == 0 && self.funding.funding_tx_confirmed_in.is_some() {
8324
8334
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);
8326
8336
return Err(ClosureReason::ProcessingError { err: err_reason });
8327
8337
}
8328
8338
} 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 {
9608
9618
// If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
9609
9619
// We can skip this if it is a zero-conf channel.
9610
9620
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);
9614
9624
}
9615
9625
9616
9626
debug_assert!(self.funding.funding_transaction.is_none());
@@ -9939,7 +9949,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9939
9949
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
9940
9950
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
9941
9951
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(),
9943
9953
to_self_delay: self.funding.get_holder_selected_contest_delay(),
9944
9954
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
9945
9955
funding_pubkey: keys.funding_pubkey,
@@ -10351,7 +10361,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
10351
10361
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
10352
10362
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
10353
10363
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(),
10355
10365
to_self_delay: self.funding.get_holder_selected_contest_delay(),
10356
10366
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
10357
10367
funding_pubkey: keys.funding_pubkey,
@@ -10719,7 +10729,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10719
10729
self.context.counterparty_max_accepted_htlcs.write(writer)?;
10720
10730
10721
10731
// 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)?;
10723
10733
10724
10734
match &self.context.counterparty_forwarding_info {
10725
10735
Some(info) => {
@@ -10794,7 +10804,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10794
10804
// here. On the read side, old versions will simply ignore the odd-type entries here,
10795
10805
// and new versions map the default values to None and allow the TLV entries here to
10796
10806
// override that.
10797
- (1, self.context .minimum_depth, option),
10807
+ (1, self.funding .minimum_depth, option),
10798
10808
(2, chan_type, option),
10799
10809
(3, self.funding.counterparty_selected_channel_reserve_satoshis, option),
10800
10810
(4, serialized_holder_selected_reserve, option),
@@ -10830,6 +10840,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10830
10840
(54, self.pending_funding, optional_vec), // Added in 0.2
10831
10841
(55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10832
10842
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
10843
+ (59, self.context.negotiated_minimum_depth, option), // Added in 0.2
10833
10844
});
10834
10845
10835
10846
Ok(())
@@ -11128,6 +11139,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11128
11139
let mut is_manual_broadcast = None;
11129
11140
11130
11141
let mut pending_funding = Some(Vec::new());
11142
+ let mut negotiated_minimum_depth: Option<u32> = None;
11131
11143
11132
11144
read_tlv_fields!(reader, {
11133
11145
(0, announcement_sigs, option),
@@ -11167,6 +11179,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11167
11179
(54, pending_funding, optional_vec), // Added in 0.2
11168
11180
(55, removed_htlc_failure_attribution_data, optional_vec),
11169
11181
(57, holding_cell_failure_attribution_data, optional_vec),
11182
+ (59, negotiated_minimum_depth, option), // Added in 0.2
11170
11183
});
11171
11184
11172
11185
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
11342
11355
funding_tx_confirmed_in,
11343
11356
funding_tx_confirmation_height,
11344
11357
short_channel_id,
11358
+ minimum_depth,
11345
11359
},
11346
11360
pending_funding: pending_funding.unwrap(),
11347
11361
context: ChannelContext {
@@ -11414,7 +11428,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11414
11428
counterparty_htlc_minimum_msat,
11415
11429
holder_htlc_minimum_msat,
11416
11430
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),
11418
11433
11419
11434
counterparty_forwarding_info,
11420
11435
0 commit comments