@@ -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,
@@ -6864,7 +6874,7 @@ impl<SP: Deref> FundedChannel<SP> where
6864
6874
// the funding transaction confirmed before the monitor was persisted, or
6865
6875
// * a 0-conf channel and intended to send the channel_ready before any broadcast at all.
6866
6876
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),
6868
6878
"Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
6869
6879
self.context.monitor_pending_channel_ready = false;
6870
6880
self.get_channel_ready(logger)
@@ -8113,7 +8123,7 @@ impl<SP: Deref> FundedChannel<SP> where
8113
8123
) {
8114
8124
// If we're not a 0conf channel, we'll be waiting on a monitor update with only
8115
8125
// 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);
8117
8127
return true;
8118
8128
}
8119
8129
if self.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER - 1 &&
@@ -8187,7 +8197,7 @@ impl<SP: Deref> FundedChannel<SP> where
8187
8197
// Called:
8188
8198
// * always when a new block/transactions are confirmed with the new height
8189
8199
// * 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) {
8191
8201
return None;
8192
8202
}
8193
8203
@@ -8196,7 +8206,7 @@ impl<SP: Deref> FundedChannel<SP> where
8196
8206
self.funding.funding_tx_confirmation_height = 0;
8197
8207
}
8198
8208
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 {
8200
8210
return None;
8201
8211
}
8202
8212
@@ -8340,9 +8350,9 @@ impl<SP: Deref> FundedChannel<SP> where
8340
8350
// If this is a coinbase transaction and not a 0-conf channel
8341
8351
// we should update our min_depth to 100 to handle coinbase maturity
8342
8352
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);
8346
8356
}
8347
8357
8348
8358
// 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
8436
8446
// to.
8437
8447
if funding_tx_confirmations == 0 && self.funding.funding_tx_confirmed_in.is_some() {
8438
8448
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);
8440
8450
return Err(ClosureReason::ProcessingError { err: err_reason });
8441
8451
}
8442
8452
} 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 {
9637
9647
// If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
9638
9648
// We can skip this if it is a zero-conf channel.
9639
9649
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);
9643
9653
}
9644
9654
9645
9655
debug_assert!(self.funding.funding_transaction.is_none());
@@ -9968,7 +9978,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
9968
9978
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
9969
9979
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
9970
9980
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(),
9972
9982
to_self_delay: self.funding.get_holder_selected_contest_delay(),
9973
9983
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
9974
9984
funding_pubkey: keys.funding_pubkey,
@@ -10380,7 +10390,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
10380
10390
dust_limit_satoshis: self.context.holder_dust_limit_satoshis,
10381
10391
max_htlc_value_in_flight_msat: self.context.holder_max_htlc_value_in_flight_msat,
10382
10392
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(),
10384
10394
to_self_delay: self.funding.get_holder_selected_contest_delay(),
10385
10395
max_accepted_htlcs: self.context.holder_max_accepted_htlcs,
10386
10396
funding_pubkey: keys.funding_pubkey,
@@ -10748,7 +10758,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10748
10758
self.context.counterparty_max_accepted_htlcs.write(writer)?;
10749
10759
10750
10760
// 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)?;
10752
10762
10753
10763
match &self.context.counterparty_forwarding_info {
10754
10764
Some(info) => {
@@ -10823,7 +10833,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10823
10833
// here. On the read side, old versions will simply ignore the odd-type entries here,
10824
10834
// and new versions map the default values to None and allow the TLV entries here to
10825
10835
// override that.
10826
- (1, self.context .minimum_depth, option),
10836
+ (1, self.funding .minimum_depth, option),
10827
10837
(2, chan_type, option),
10828
10838
(3, self.funding.counterparty_selected_channel_reserve_satoshis, option),
10829
10839
(4, serialized_holder_selected_reserve, option),
@@ -10859,6 +10869,7 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10859
10869
(54, self.pending_funding, optional_vec), // Added in 0.2
10860
10870
(55, removed_htlc_failure_attribution_data, optional_vec), // Added in 0.2
10861
10871
(57, holding_cell_failure_attribution_data, optional_vec), // Added in 0.2
10872
+ (59, self.context.negotiated_minimum_depth, option), // Added in 0.2
10862
10873
});
10863
10874
10864
10875
Ok(())
@@ -11157,6 +11168,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11157
11168
let mut is_manual_broadcast = None;
11158
11169
11159
11170
let mut pending_funding = Some(Vec::new());
11171
+ let mut negotiated_minimum_depth: Option<u32> = None;
11160
11172
11161
11173
read_tlv_fields!(reader, {
11162
11174
(0, announcement_sigs, option),
@@ -11196,6 +11208,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11196
11208
(54, pending_funding, optional_vec), // Added in 0.2
11197
11209
(55, removed_htlc_failure_attribution_data, optional_vec),
11198
11210
(57, holding_cell_failure_attribution_data, optional_vec),
11211
+ (59, negotiated_minimum_depth, option), // Added in 0.2
11199
11212
});
11200
11213
11201
11214
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
11371
11384
funding_tx_confirmed_in,
11372
11385
funding_tx_confirmation_height,
11373
11386
short_channel_id,
11387
+ minimum_depth,
11374
11388
},
11375
11389
pending_funding: pending_funding.unwrap(),
11376
11390
context: ChannelContext {
@@ -11443,7 +11457,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11443
11457
counterparty_htlc_minimum_msat,
11444
11458
holder_htlc_minimum_msat,
11445
11459
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),
11447
11462
11448
11463
counterparty_forwarding_info,
11449
11464
0 commit comments