Skip to content

Commit 100197c

Browse files
authored
Merge pull request #340 from TheBlueMatt/2019-06-channeldetails-fields
Add balance and is_live fields to ChannelDetails
2 parents fbd58b4 + 3d55d71 commit 100197c

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
@@ -1581,6 +1581,16 @@ impl Channel {
15811581
(htlc_outbound_count as u32, htlc_outbound_value_msat)
15821582
}
15831583

1584+
/// Get the available (ie not including pending HTLCs) inbound and outbound balance in msat.
1585+
/// Doesn't bother handling the
1586+
/// if-we-removed-it-already-but-haven't-fully-resolved-they-can-still-send-an-inbound-HTLC
1587+
/// corner case properly.
1588+
pub fn get_inbound_outbound_available_balance_msat(&self) -> (u64, u64) {
1589+
// Note that we have to handle overflow due to the above case.
1590+
(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,
1591+
cmp::min(self.value_to_self_msat as i64 - self.get_outbound_pending_htlc_stats().1 as i64, 0) as u64)
1592+
}
1593+
15841594
pub fn update_add_htlc(&mut self, msg: &msgs::UpdateAddHTLC, pending_forward_state: PendingHTLCStatus) -> Result<(), ChannelError> {
15851595
if (self.channel_state & (ChannelState::ChannelFunded as u32 | ChannelState::RemoteShutdownSent as u32)) != (ChannelState::ChannelFunded as u32) {
15861596
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
@@ -388,6 +388,20 @@ pub struct ChannelDetails {
388388
pub channel_value_satoshis: u64,
389389
/// The user_id passed in to create_channel, or 0 if the channel was inbound.
390390
pub user_id: u64,
391+
/// The available outbound capacity for sending HTLCs to the remote peer. This does not include
392+
/// any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
393+
/// available for inclusion in new outbound HTLCs). This further does not include any pending
394+
/// outgoing HTLCs which are awaiting some other resolution to be sent.
395+
pub outbound_capacity_msat: u64,
396+
/// The available inbound capacity for the remote peer to send HTLCs to us. This does not
397+
/// include any pending HTLCs which are not yet fully resolved (and, thus, who's balance is not
398+
/// available for inclusion in new inbound HTLCs).
399+
/// Note that there are some corner cases not fully handled here, so the actual available
400+
/// inbound capacity may be slightly higher than this.
401+
pub inbound_capacity_msat: u64,
402+
/// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b)
403+
/// the peer is connected, and (c) no monitor update failure is pending resolution.
404+
pub is_live: bool,
391405
}
392406

393407
macro_rules! handle_error {
@@ -609,19 +623,26 @@ impl ChannelManager {
609623
let channel_state = self.channel_state.lock().unwrap();
610624
let mut res = Vec::with_capacity(channel_state.by_id.len());
611625
for (channel_id, channel) in channel_state.by_id.iter() {
626+
let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
612627
res.push(ChannelDetails {
613628
channel_id: (*channel_id).clone(),
614629
short_channel_id: channel.get_short_channel_id(),
615630
remote_network_id: channel.get_their_node_id(),
616631
channel_value_satoshis: channel.get_value_satoshis(),
632+
inbound_capacity_msat,
633+
outbound_capacity_msat,
617634
user_id: channel.get_user_id(),
635+
is_live: channel.is_live(),
618636
});
619637
}
620638
res
621639
}
622640

623641
/// Gets the list of usable channels, in random order. Useful as an argument to
624642
/// Router::get_route to ensure non-announced channels are used.
643+
///
644+
/// These are guaranteed to have their is_live value set to true, see the documentation for
645+
/// ChannelDetails::is_live for more info on exactly what the criteria are.
625646
pub fn list_usable_channels(&self) -> Vec<ChannelDetails> {
626647
let channel_state = self.channel_state.lock().unwrap();
627648
let mut res = Vec::with_capacity(channel_state.by_id.len());
@@ -630,12 +651,16 @@ impl ChannelManager {
630651
// internal/external nomenclature, but that's ok cause that's probably what the user
631652
// really wanted anyway.
632653
if channel.is_live() {
654+
let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat();
633655
res.push(ChannelDetails {
634656
channel_id: (*channel_id).clone(),
635657
short_channel_id: channel.get_short_channel_id(),
636658
remote_network_id: channel.get_their_node_id(),
637659
channel_value_satoshis: channel.get_value_satoshis(),
660+
inbound_capacity_msat,
661+
outbound_capacity_msat,
638662
user_id: channel.get_user_id(),
663+
is_live: true,
639664
});
640665
}
641666
}

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)