Skip to content

Commit 772ca7a

Browse files
committed
Expand the fields exposed to users in ChannelDetails
This adds four new fields in `ChannelDetails`: 1. holder_selected_ and counterparty_selected_channel_reserve_delay are useful to determine what amount of the channel is unavailable for payments. 2. confirmations_required is useful when awaiting funding confirmation to determine how long you will need to wait. 3. to_self_delay is useful to determine how long it will take to receive funds after a force-close. Fixes #983.
1 parent 90cbdc1 commit 772ca7a

File tree

5 files changed

+106
-8
lines changed

5 files changed

+106
-8
lines changed

fuzz/src/router.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
214214
channel_value_satoshis: slice_to_be64(get_slice!(8)),
215215
user_id: 0,
216216
inbound_capacity_msat: 0,
217+
counterparty_selected_channel_reserve_satoshis: None,
218+
holder_selected_channel_reserve_satoshis: 0,
219+
confirmations_required: None, to_self_delay: None,
217220
is_outbound: true,
218221
is_funding_locked: true,
219222
is_usable: true,

lightning/src/ln/channel.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,8 +1784,22 @@ impl<Signer: Sign> Channel<Signer> {
17841784
/// corner case properly.
17851785
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
17861786
// Note that we have to handle overflow due to the above case.
1787-
(cmp::max(self.channel_value_satoshis as i64 * 1000 - self.value_to_self_msat as i64 - self.get_inbound_pending_htlc_stats().1 as i64, 0) as u64,
1788-
cmp::max(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64)
1787+
(
1788+
cmp::max(self.channel_value_satoshis as i64 * 1000
1789+
- self.value_to_self_msat as i64
1790+
- self.get_inbound_pending_htlc_stats().1 as i64
1791+
- Self::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis) as i64 * 1000,
1792+
0) as u64,
1793+
cmp::max(self.value_to_self_msat as i64
1794+
- self.get_outbound_pending_htlc_stats().1 as i64
1795+
- self.counterparty_selected_channel_reserve_satoshis.unwrap_or(0) as i64 * 1000,
1796+
0) as u64
1797+
)
1798+
}
1799+
1800+
pub fn get_holder_counterparty_selected_channel_reserve_satoshis(&self) -> (u64, Option<u64>) {
1801+
(Self::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis),
1802+
self.counterparty_selected_channel_reserve_satoshis)
17891803
}
17901804

17911805
// Get the fee cost of a commitment tx with a given number of HTLC outputs.
@@ -3338,6 +3352,10 @@ impl<Signer: Sign> Channel<Signer> {
33383352
self.channel_id
33393353
}
33403354

3355+
pub fn minimum_depth(&self) -> Option<u32> {
3356+
self.minimum_depth
3357+
}
3358+
33413359
/// Gets the "user_id" value passed into the construction of this channel. It has no special
33423360
/// meaning and exists only to allow users to have a persistent identifier of a channel.
33433361
pub fn get_user_id(&self) -> u64 {
@@ -3365,7 +3383,7 @@ impl<Signer: Sign> Channel<Signer> {
33653383
&self.channel_transaction_parameters.holder_pubkeys
33663384
}
33673385

3368-
fn get_counterparty_selected_contest_delay(&self) -> Option<u16> {
3386+
pub fn get_counterparty_selected_contest_delay(&self) -> Option<u16> {
33693387
self.channel_transaction_parameters.counterparty_parameters
33703388
.as_ref().map(|params| params.selected_contest_delay)
33713389
}

lightning/src/ln/channelmanager.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,25 +656,74 @@ pub struct ChannelDetails {
656656
pub counterparty_features: InitFeatures,
657657
/// The value, in satoshis, of this channel as appears in the funding output
658658
pub channel_value_satoshis: u64,
659+
/// The value, in satoshis, which must always be held in the channel for us. This value ensures
660+
/// that if we broadcast a revoked state, our counterparty can punish us by claiming at least
661+
/// this value on chain.
662+
///
663+
/// This value is not included in [`outbound_capacity_msat`] as it can never be spent.
664+
///
665+
/// This value will be `None` for outbound channels until the counterparty accepts the channel.
666+
///
667+
/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
668+
pub counterparty_selected_channel_reserve_satoshis: Option<u64>,
669+
/// The value, in satoshis, which must always be held in the channel for our counterparty. This
670+
/// value ensures that if our counterparty broadcasts a revoked state, we can punish them by
671+
/// claiming at least this value on chain.
672+
///
673+
/// This value is not included in [`inbound_capacity_msat`] as it can never be spent.
674+
///
675+
/// [`inbound_capacity_msat`]: ChannelDetails::inbound_capacity_msat
676+
pub holder_selected_channel_reserve_satoshis: u64,
659677
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
660678
pub user_id: u64,
661679
/// The available outbound capacity for sending HTLCs to the remote peer. This does not include
662680
/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
663681
/// available for inclusion in new outbound HTLCs). This further does not include any pending
664682
/// outgoing HTLCs which are awaiting some other resolution to be sent.
683+
///
684+
/// This value is not exact. Due to various in-flight changes, feerate changes, and our
685+
/// conflict-avoidance policy, exactly this amount is not likely to be spendable. However, we
686+
/// should be able to spend nearly this amount.
665687
pub outbound_capacity_msat: u64,
666688
/// The available inbound capacity for the remote peer to send HTLCs to us. This does not
667689
/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
668690
/// available for inclusion in new inbound HTLCs).
669691
/// Note that there are some corner cases not fully handled here, so the actual available
670692
/// inbound capacity may be slightly higher than this.
693+
///
694+
/// This value is not exact. Due to various in-flight changes, feerate changes, and our
695+
/// counterparty's conflict-avoidance policy, exactly this amount is not likely to be spendable.
696+
/// However, our counterparty should be able to spend nearly this amount.
671697
pub inbound_capacity_msat: u64,
698+
/// The number of required confirmations on the funding transaction before the funding will be
699+
/// considered "locked". This number is selected by the channel fundee (ie us if
700+
/// [`is_outbound`] is *not* set), and can be selected for inbound channels with
701+
/// [`ChannelHandshakeConfig::minimum_depth`] or limited for outbound channels with
702+
/// [`ChannelHandshakeLimits::max_minimum_depth`].
703+
///
704+
/// This value will be `None` for outbound channels until the counterparty accepts the channel.
705+
///
706+
/// [`is_outbound`]: ChannelDetails::is_outbound
707+
/// [`ChannelHandshakeConfig::minimum_depth`]: crate::util::config::ChannelHandshakeConfig::minimum_depth
708+
/// [`ChannelHandshakeLimits::max_minimum_depth`]: crate::util::config::ChannelHandshakeLimits::max_minimum_depth
709+
pub confirmations_required: Option<u32>,
710+
/// The number of blocks (after our commitment transaction confirms) which we will need to wait
711+
/// until we can claim our funds after we force-close the channel. During this time our
712+
/// counterparty is allowed to punish us if we broadcasted a stale state. If our counterparty
713+
/// force-closes the channel and broadcasts a commitment transaction we do not have to wait any
714+
/// time to claim our non-HTLC-encumbered funds.
715+
///
716+
/// This value will be `None` for outbound channels until the counterparty accepts the channel.
717+
pub to_self_delay: Option<u16>,
672718
/// True if the channel was initiated (and thus funded) by us.
673719
pub is_outbound: bool,
674720
/// True if the channel is confirmed, funding_locked messages have been exchanged, and the
675721
/// channel is not currently being shut down. `funding_locked` message exchange implies the
676722
/// required confirmation count has been reached (and we were connected to the peer at some
677-
/// point after the funding transaction received enough confirmations).
723+
/// point after the funding transaction received enough confirmations). The required
724+
/// confirmation count is provided in [`confirmations_required`].
725+
///
726+
/// [`confirmations_required`]: ChannelDetails::confirmations_required
678727
pub is_funding_locked: bool,
679728
/// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
680729
/// the peer is connected, and (c) the channel is not currently negotiating a shutdown.
@@ -1146,16 +1195,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
11461195
res.reserve(channel_state.by_id.len());
11471196
for (channel_id, channel) in channel_state.by_id.iter().filter(f) {
11481197
let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
1198+
let (holder_selected_channel_reserve_satoshis, counterparty_selected_channel_reserve_satoshis) =
1199+
channel.get_holder_counterparty_selected_channel_reserve_satoshis();
11491200
res.push(ChannelDetails {
11501201
channel_id: (*channel_id).clone(),
11511202
funding_txo: channel.get_funding_txo(),
11521203
short_channel_id: channel.get_short_channel_id(),
11531204
remote_network_id: channel.get_counterparty_node_id(),
11541205
counterparty_features: InitFeatures::empty(),
11551206
channel_value_satoshis: channel.get_value_satoshis(),
1207+
counterparty_selected_channel_reserve_satoshis,
1208+
holder_selected_channel_reserve_satoshis,
11561209
inbound_capacity_msat,
11571210
outbound_capacity_msat,
11581211
user_id: channel.get_user_id(),
1212+
confirmations_required: channel.minimum_depth(),
1213+
to_self_delay: channel.get_counterparty_selected_contest_delay(),
11591214
is_outbound: channel.is_outbound(),
11601215
is_funding_locked: channel.is_usable(),
11611216
is_usable: channel.is_live(),

lightning/src/ln/functional_tests.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1878,11 +1878,12 @@ fn test_inbound_outbound_capacity_is_not_zero() {
18781878
assert_eq!(channels0.len(), 1);
18791879
assert_eq!(channels1.len(), 1);
18801880

1881-
assert_eq!(channels0[0].inbound_capacity_msat, 95000000);
1882-
assert_eq!(channels1[0].outbound_capacity_msat, 95000000);
1881+
let reserve = Channel::<EnforcingSigner>::get_holder_selected_channel_reserve_satoshis(100000);
1882+
assert_eq!(channels0[0].inbound_capacity_msat, 95000000 - reserve*1000);
1883+
assert_eq!(channels1[0].outbound_capacity_msat, 95000000 - reserve*1000);
18831884

1884-
assert_eq!(channels0[0].outbound_capacity_msat, 100000 * 1000 - 95000000);
1885-
assert_eq!(channels1[0].inbound_capacity_msat, 100000 * 1000 - 95000000);
1885+
assert_eq!(channels0[0].outbound_capacity_msat, 100000 * 1000 - 95000000 - reserve*1000);
1886+
assert_eq!(channels1[0].inbound_capacity_msat, 100000 * 1000 - 95000000 - reserve*1000);
18861887
}
18871888

18881889
fn commit_tx_fee_msat(feerate: u32, num_htlcs: u64) -> u64 {

lightning/src/routing/router.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,9 @@ mod tests {
16421642
user_id: 0,
16431643
outbound_capacity_msat: 100000,
16441644
inbound_capacity_msat: 100000,
1645+
counterparty_selected_channel_reserve_satoshis: None,
1646+
holder_selected_channel_reserve_satoshis: 0,
1647+
confirmations_required: None, to_self_delay: None,
16451648
is_outbound: true, is_funding_locked: true,
16461649
is_usable: true, is_public: true,
16471650
counterparty_forwarding_info: None,
@@ -1962,6 +1965,9 @@ mod tests {
19621965
user_id: 0,
19631966
outbound_capacity_msat: 250_000_000,
19641967
inbound_capacity_msat: 0,
1968+
counterparty_selected_channel_reserve_satoshis: None,
1969+
holder_selected_channel_reserve_satoshis: 0,
1970+
confirmations_required: None, to_self_delay: None,
19651971
is_outbound: true, is_funding_locked: true,
19661972
is_usable: true, is_public: true,
19671973
counterparty_forwarding_info: None,
@@ -2012,6 +2018,9 @@ mod tests {
20122018
user_id: 0,
20132019
outbound_capacity_msat: 250_000_000,
20142020
inbound_capacity_msat: 0,
2021+
counterparty_selected_channel_reserve_satoshis: None,
2022+
holder_selected_channel_reserve_satoshis: 0,
2023+
confirmations_required: None, to_self_delay: None,
20152024
is_outbound: true, is_funding_locked: true,
20162025
is_usable: true, is_public: true,
20172026
counterparty_forwarding_info: None,
@@ -2079,6 +2088,9 @@ mod tests {
20792088
user_id: 0,
20802089
outbound_capacity_msat: 250_000_000,
20812090
inbound_capacity_msat: 0,
2091+
counterparty_selected_channel_reserve_satoshis: None,
2092+
holder_selected_channel_reserve_satoshis: 0,
2093+
confirmations_required: None, to_self_delay: None,
20822094
is_outbound: true, is_funding_locked: true,
20832095
is_usable: true, is_public: true,
20842096
counterparty_forwarding_info: None,
@@ -2218,6 +2230,9 @@ mod tests {
22182230
user_id: 0,
22192231
outbound_capacity_msat: 250_000_000,
22202232
inbound_capacity_msat: 0,
2233+
counterparty_selected_channel_reserve_satoshis: None,
2234+
holder_selected_channel_reserve_satoshis: 0,
2235+
confirmations_required: None, to_self_delay: None,
22212236
is_outbound: true, is_funding_locked: true,
22222237
is_usable: true, is_public: true,
22232238
counterparty_forwarding_info: None,
@@ -2349,6 +2364,9 @@ mod tests {
23492364
user_id: 0,
23502365
outbound_capacity_msat: 100000,
23512366
inbound_capacity_msat: 100000,
2367+
counterparty_selected_channel_reserve_satoshis: None,
2368+
holder_selected_channel_reserve_satoshis: 0,
2369+
confirmations_required: None, to_self_delay: None,
23522370
is_outbound: true, is_funding_locked: true,
23532371
is_usable: true, is_public: true,
23542372
counterparty_forwarding_info: None,
@@ -2483,6 +2501,9 @@ mod tests {
24832501
user_id: 0,
24842502
outbound_capacity_msat: 200_000_000,
24852503
inbound_capacity_msat: 0,
2504+
counterparty_selected_channel_reserve_satoshis: None,
2505+
holder_selected_channel_reserve_satoshis: 0,
2506+
confirmations_required: None, to_self_delay: None,
24862507
is_outbound: true, is_funding_locked: true,
24872508
is_usable: true, is_public: true,
24882509
counterparty_forwarding_info: None,

0 commit comments

Comments
 (0)