From 2d6f060c0602de257f762b87c4a00a5b916a2bbe Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 5 May 2021 02:33:29 +0000 Subject: [PATCH 1/3] Add flags for if a channel is pub and funding txo in ChannelDetails --- fuzz/src/router.rs | 4 ++++ lightning/src/ln/channelmanager.rs | 11 ++++++++++- lightning/src/routing/router.rs | 22 +++++++++++++++------- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index e80e080f3..42c97f4e4 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -12,6 +12,7 @@ use bitcoin::blockdata::transaction::TxOut; use bitcoin::hash_types::BlockHash; use lightning::chain; +use lightning::chain::transaction::OutPoint; use lightning::ln::channelmanager::ChannelDetails; use lightning::ln::features::InitFeatures; use lightning::ln::msgs; @@ -20,6 +21,7 @@ use lightning::util::logger::Logger; use lightning::util::ser::Readable; use lightning::routing::network_graph::{NetworkGraph, RoutingFees}; +use bitcoin::hashes::Hash; use bitcoin::secp256k1::key::PublicKey; use bitcoin::network::constants::Network; use bitcoin::blockdata::constants::genesis_block; @@ -204,6 +206,7 @@ pub fn do_test(data: &[u8], out: Out) { let rnid = node_pks.iter().skip(slice_to_be16(get_slice!(2))as usize % node_pks.len()).next().unwrap(); first_hops_vec.push(ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(scid), remote_network_id: *rnid, counterparty_features: InitFeatures::known(), @@ -211,6 +214,7 @@ pub fn do_test(data: &[u8], out: Out) { user_id: 0, inbound_capacity_msat: 0, is_live: true, + is_public: true, outbound_capacity_msat: 0, counterparty_forwarding_info: None, }); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a9f87fa14..8c9c702b7 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -604,6 +604,12 @@ pub struct ChannelDetails { /// Note that this means this value is *not* persistent - it can change once during the /// lifetime of the channel. pub channel_id: [u8; 32], + /// The Channel's funding transaction output, if we've negotiated the funding transaction with + /// our counterparty already. + /// + /// Note that, if this has been set, `channel_id` will be equivalent to + /// `funding_txo.unwrap().to_channel_id()`. + pub funding_txo: Option, /// The position of the funding transaction in the chain. None if the funding transaction has /// not yet been confirmed and the channel fully opened. pub short_channel_id: Option, @@ -631,7 +637,8 @@ pub struct ChannelDetails { /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) /// the peer is connected, and (c) no monitor update failure is pending resolution. pub is_live: bool, - + /// True if this channel is (or will be) publicly-announced. + pub is_public: bool, /// Information on the fees and requirements that the counterparty requires when forwarding /// payments to us through this channel. pub counterparty_forwarding_info: Option, @@ -954,6 +961,7 @@ impl ChannelMana let (inbound_capacity_msat, outbound_capacity_msat) = channel.get_inbound_outbound_available_balance_msat(); res.push(ChannelDetails { channel_id: (*channel_id).clone(), + funding_txo: channel.get_funding_txo(), short_channel_id: channel.get_short_channel_id(), remote_network_id: channel.get_counterparty_node_id(), counterparty_features: InitFeatures::empty(), @@ -962,6 +970,7 @@ impl ChannelMana outbound_capacity_msat, user_id: channel.get_user_id(), is_live: channel.is_live(), + is_public: channel.should_announce(), counterparty_forwarding_info: channel.counterparty_forwarding_info(), }); } diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 08fe95d23..795780f48 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1165,6 +1165,7 @@ pub fn get_route(our_node_id: &PublicKey, network: &NetworkGraph, paye mod tests { use routing::router::{get_route, RouteHintHop, RoutingFees}; use routing::network_graph::{NetworkGraph, NetGraphMsgHandler}; + use chain::transaction::OutPoint; use ln::features::{ChannelFeatures, InitFeatures, InvoiceFeatures, NodeFeatures}; use ln::msgs::{ErrorAction, LightningError, OptionalField, UnsignedChannelAnnouncement, ChannelAnnouncement, RoutingMessageHandler, NodeAnnouncement, UnsignedNodeAnnouncement, ChannelUpdate, UnsignedChannelUpdate}; @@ -1625,6 +1626,7 @@ mod tests { let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(2), remote_network_id: our_id, counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -1632,7 +1634,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -1943,6 +1945,7 @@ mod tests { // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: nodes[7].clone(), counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -1950,7 +1953,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -1991,6 +1994,7 @@ mod tests { // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: nodes[7].clone(), counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -1998,7 +2002,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -2056,6 +2060,7 @@ mod tests { // If we specify a channel to node7, that overrides our local channel view and that gets used let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: nodes[7].clone(), counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -2063,7 +2068,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -2193,6 +2198,7 @@ mod tests { // Simple test with outbound channel to 4 to test that last_hops and first_hops connect let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: nodes[3].clone(), counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -2200,7 +2206,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; let mut last_hops = last_hops(&nodes); @@ -2322,6 +2328,7 @@ mod tests { }]; let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: middle_node_id, counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -2329,7 +2336,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&source_node_id, &NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()), &target_node_id, None, Some(&our_chans.iter().collect::>()), &last_hops.iter().collect::>(), 100, 42, Arc::new(test_utils::TestLogger::new())).unwrap(); @@ -2454,6 +2461,7 @@ mod tests { // Now, limit the first_hop by the outbound_capacity_msat of 200_000 sats. let our_chans = vec![channelmanager::ChannelDetails { channel_id: [0; 32], + funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }), short_channel_id: Some(42), remote_network_id: nodes[0].clone(), counterparty_features: InitFeatures::from_le_bytes(vec![0b11]), @@ -2461,7 +2469,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 200_000_000, inbound_capacity_msat: 0, - is_live: true, + is_live: true, is_public: true, counterparty_forwarding_info: None, }]; From 6a79eece219858524b733953b96111b5061f8214 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 5 May 2021 16:15:11 +0000 Subject: [PATCH 2/3] Indiciate if a channel is outbound/confirmed in ChannelDetails --- fuzz/src/router.rs | 2 ++ lightning/src/ln/channelmanager.rs | 14 +++++++++++++- lightning/src/routing/router.rs | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 42c97f4e4..585ae9b35 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -213,6 +213,8 @@ pub fn do_test(data: &[u8], out: Out) { channel_value_satoshis: slice_to_be64(get_slice!(8)), user_id: 0, inbound_capacity_msat: 0, + is_outbound: true, + is_funding_locked: true, is_live: true, is_public: true, outbound_capacity_msat: 0, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 8c9c702b7..a970c52de 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -634,8 +634,18 @@ pub struct ChannelDetails { /// Note that there are some corner cases not fully handled here, so the actual available /// inbound capacity may be slightly higher than this. pub inbound_capacity_msat: u64, + /// True if the channel was initiated (and thus funded) by us. + pub is_outbound: bool, + /// True if the channel is confirmed, funding_locked messages have been exchanged, and the + /// channel is not currently being shut down. `funding_locked` message exchange implies the + /// required confirmation count has been reached (and we were connected to the peer at some + /// point after the funding transaction received enough confirmations). + pub is_funding_locked: bool, /// True if the channel is (a) confirmed and funding_locked messages have been exchanged, (b) - /// the peer is connected, and (c) no monitor update failure is pending resolution. + /// the peer is connected, (c) no monitor update failure is pending resolution, and (d) the + /// channel is not currently negotiating a shutdown. + /// + /// This is a strict superset of `is_funding_locked`. pub is_live: bool, /// True if this channel is (or will be) publicly-announced. pub is_public: bool, @@ -969,6 +979,8 @@ impl ChannelMana inbound_capacity_msat, outbound_capacity_msat, user_id: channel.get_user_id(), + is_outbound: channel.is_outbound(), + is_funding_locked: channel.is_usable(), is_live: channel.is_live(), is_public: channel.should_announce(), counterparty_forwarding_info: channel.counterparty_forwarding_info(), diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 795780f48..87214b8f5 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1634,6 +1634,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -1953,6 +1954,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -2002,6 +2004,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -2068,6 +2071,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -2206,6 +2210,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -2336,6 +2341,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -2469,6 +2475,7 @@ mod tests { user_id: 0, outbound_capacity_msat: 200_000_000, inbound_capacity_msat: 0, + is_outbound: true, is_funding_locked: true, is_live: true, is_public: true, counterparty_forwarding_info: None, }]; From 62f466a0a2370b9f9696e05d3ce651216d7410d9 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 6 May 2021 20:26:39 +0000 Subject: [PATCH 3/3] Rename ChannelDetails::is_live to is_usable This matches is_usable_channels and slightly better captures the meaning. --- fuzz/src/router.rs | 2 +- lightning/src/ln/channelmanager.rs | 9 +++++---- lightning/src/routing/router.rs | 14 +++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/fuzz/src/router.rs b/fuzz/src/router.rs index 585ae9b35..f9a263cc3 100644 --- a/fuzz/src/router.rs +++ b/fuzz/src/router.rs @@ -215,7 +215,7 @@ pub fn do_test(data: &[u8], out: Out) { inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, + is_usable: true, is_public: true, outbound_capacity_msat: 0, counterparty_forwarding_info: None, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a970c52de..5441ab4b5 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -646,7 +646,7 @@ pub struct ChannelDetails { /// channel is not currently negotiating a shutdown. /// /// This is a strict superset of `is_funding_locked`. - pub is_live: bool, + pub is_usable: bool, /// True if this channel is (or will be) publicly-announced. pub is_public: bool, /// Information on the fees and requirements that the counterparty requires when forwarding @@ -981,7 +981,7 @@ impl ChannelMana user_id: channel.get_user_id(), is_outbound: channel.is_outbound(), is_funding_locked: channel.is_usable(), - is_live: channel.is_live(), + is_usable: channel.is_live(), is_public: channel.should_announce(), counterparty_forwarding_info: channel.counterparty_forwarding_info(), }); @@ -1005,8 +1005,9 @@ impl ChannelMana /// Gets the list of usable channels, in random order. Useful as an argument to /// get_route to ensure non-announced channels are used. /// - /// These are guaranteed to have their is_live value set to true, see the documentation for - /// ChannelDetails::is_live for more info on exactly what the criteria are. + /// These are guaranteed to have their [`ChannelDetails::is_usable`] value set to true, see the + /// documentation for [`ChannelDetails::is_usable`] for more info on exactly what the criteria + /// are. pub fn list_usable_channels(&self) -> Vec { // Note we use is_live here instead of usable which leads to somewhat confused // internal/external nomenclature, but that's ok cause that's probably what the user diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 87214b8f5..ca7f30e30 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -1635,7 +1635,7 @@ mod tests { outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; @@ -1955,7 +1955,7 @@ mod tests { outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -2005,7 +2005,7 @@ mod tests { outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -2072,7 +2072,7 @@ mod tests { outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&our_id, &net_graph_msg_handler.network_graph.read().unwrap(), &nodes[2], None, Some(&our_chans.iter().collect::>()), &Vec::new(), 100, 42, Arc::clone(&logger)).unwrap(); @@ -2211,7 +2211,7 @@ mod tests { outbound_capacity_msat: 250_000_000, inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; let mut last_hops = last_hops(&nodes); @@ -2342,7 +2342,7 @@ mod tests { outbound_capacity_msat: 100000, inbound_capacity_msat: 100000, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }]; let route = get_route(&source_node_id, &NetworkGraph::new(genesis_block(Network::Testnet).header.block_hash()), &target_node_id, None, Some(&our_chans.iter().collect::>()), &last_hops.iter().collect::>(), 100, 42, Arc::new(test_utils::TestLogger::new())).unwrap(); @@ -2476,7 +2476,7 @@ mod tests { outbound_capacity_msat: 200_000_000, inbound_capacity_msat: 0, is_outbound: true, is_funding_locked: true, - is_live: true, is_public: true, + is_usable: true, is_public: true, counterparty_forwarding_info: None, }];