Skip to content

Commit 3d55d71

Browse files
committed
Add balance and is_live fields to ChannelDetails
1 parent fb7fc69 commit 3d55d71

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

fuzz/fuzz_targets/router_target.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,9 @@ pub fn do_test(data: &[u8]) {
205205
remote_network_id: get_pubkey!(),
206206
channel_value_satoshis: slice_to_be64(get_slice!(8)),
207207
user_id: 0,
208+
inbound_capacity_msat: 0,
209+
is_live: true,
210+
outbound_capacity_msat: 0,
208211
});
209212
}
210213
Some(&first_hops_vec[..])

src/ln/channel.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,16 @@ impl Channel {
15831583
(htlc_outbound_count as u32, htlc_outbound_value_msat)
15841584
}
15851585

1586+
/// Get the available (ie not including pending HTLCs) inbound and outbound balance in msat.
1587+
/// Doesn't bother handling the
1588+
/// if-we-removed-it-already-but-haven't-fully-resolved-they-can-still-send-an-inbound-HTLC
1589+
/// corner case properly.
1590+
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
1591+
// Note that we have to handle overflow due to the above case.
1592+
(cmp::min(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,
1593+
cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64)
1594+
}
1595+
15861596
pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus) -> Result<(), ChannelError> {
15871597
if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32) {
15881598
return Err(ChannelError::Close("Got add HTLC message when channel was not in an operational state"));

src/ln/channelmanager.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,20 @@ pub struct ChannelDetails {
391391
pub channel_value_satoshis: u64,
392392
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
393393
pub user_id: u64,
394+
/// The available outbound capacity for sending HTLCs to the remote peer. This does not include
395+
/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
396+
/// available for inclusion in new outbound HTLCs). This further does not include any pending
397+
/// outgoing HTLCs which are awaiting some other resolution to be sent.
398+
pub outbound_capacity_msat: u64,
399+
/// The available inbound capacity for the remote peer to send HTLCs to us. This does not
400+
/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
401+
/// available for inclusion in new inbound HTLCs).
402+
/// Note that there are some corner cases not fully handled here, so the actual available
403+
/// inbound capacity may be slightly higher than this.
404+
pub inbound_capacity_msat: u64,
405+
/// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
406+
/// the peer is connected, and (c) no monitor update failure is pending resolution.
407+
pub is_live: bool,
394408
}
395409

396410
macro_rules! handle_error {
@@ -613,19 +627,26 @@ impl ChannelManager {
613627
let channel_state = self.channel_state.lock().unwrap();
614628
let mut res = Vec::with_capacity(channel_state.by_id.len());
615629
for (channel_id, channel) in channel_state.by_id.iter() {
630+
let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
616631
res.push(ChannelDetails {
617632
channel_id: (*channel_id).clone(),
618633
short_channel_id: channel.get_short_channel_id(),
619634
remote_network_id: channel.get_their_node_id(),
620635
channel_value_satoshis: channel.get_value_satoshis(),
636+
inbound_capacity_msat,
637+
outbound_capacity_msat,
621638
user_id: channel.get_user_id(),
639+
is_live: channel.is_live(),
622640
});
623641
}
624642
res
625643
}
626644

627645
/// Gets the list of usable channels, in random order. Useful as an argument to
628646
/// Router::get_route to ensure non-announced channels are used.
647+
///
648+
/// These are guaranteed to have their is_live value set to true, see the documentation for
649+
/// ChannelDetails::is_live for more info on exactly what the criteria are.
629650
pub fn list_usable_channels(&self) -> Vec<ChannelDetails> {
630651
let channel_state = self.channel_state.lock().unwrap();
631652
let mut res = Vec::with_capacity(channel_state.by_id.len());
@@ -634,12 +655,16 @@ impl ChannelManager {
634655
// internal/external nomenclature, but that's ok cause that's probably what the user
635656
// really wanted anyway.
636657
if channel.is_live() {
658+
let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
637659
res.push(ChannelDetails {
638660
channel_id: (*channel_id).clone(),
639661
short_channel_id: channel.get_short_channel_id(),
640662
remote_network_id: channel.get_their_node_id(),
641663
channel_value_satoshis: channel.get_value_satoshis(),
664+
inbound_capacity_msat,
665+
outbound_capacity_msat,
642666
user_id: channel.get_user_id(),
667+
is_live: true,
643668
});
644669
}
645670
}

src/ln/router.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,6 +1468,9 @@ mod tests {
14681468
remote_network_id: node8.clone(),
14691469
channel_value_satoshis: 0,
14701470
user_id: 0,
1471+
outbound_capacity_msat: 0,
1472+
inbound_capacity_msat: 0,
1473+
is_live: true,
14711474
}];
14721475
let route = router.get_route(&node3, Some(&our_chans), &Vec::new(), 100, 42).unwrap();
14731476
assert_eq!(route.hops.len(), 2);
@@ -1543,6 +1546,9 @@ mod tests {
15431546
remote_network_id: node4.clone(),
15441547
channel_value_satoshis: 0,
15451548
user_id: 0,
1549+
outbound_capacity_msat: 0,
1550+
inbound_capacity_msat: 0,
1551+
is_live: true,
15461552
}];
15471553
let route = router.get_route(&node7, Some(&our_chans), &last_hops, 100, 42).unwrap();
15481554
assert_eq!(route.hops.len(), 2);

0 commit comments

Comments
 (0)