Skip to content

Commit ae53d1c

Browse files
committed
Better track lowest_inbound_channel_fees
Before this, we would not update per-node fees when deleting channels, resulting in worse routing decisions.
1 parent 093cf1d commit ae53d1c

File tree

1 file changed

+47
-40
lines changed

1 file changed

+47
-40
lines changed

lightning/src/routing/gossip.rs

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
14381438
// b) we don't track UTXOs of channels we know about and remove them if they
14391439
// get reorg'd out.
14401440
// c) it's unclear how to do so without exposing ourselves to massive DoS risk.
1441-
Self::remove_channel_in_nodes(&mut nodes, &entry.get(), short_channel_id);
1441+
self.remove_channel_in_nodes(&mut nodes, &entry.get(), short_channel_id);
14421442
*entry.get_mut() = channel_info;
14431443
} else {
14441444
return Err(LightningError{err: "Already have knowledge of channel".to_owned(), action: ErrorAction::IgnoreDuplicateGossip});
@@ -1570,7 +1570,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
15701570
if is_permanent {
15711571
if let Some(chan) = channels.remove(&short_channel_id) {
15721572
let mut nodes = self.nodes.write().unwrap();
1573-
Self::remove_channel_in_nodes(&mut nodes, &chan, short_channel_id);
1573+
self.remove_channel_in_nodes(&mut nodes, &chan, short_channel_id);
15741574
}
15751575
} else {
15761576
if let Some(chan) = channels.get_mut(&short_channel_id) {
@@ -1651,7 +1651,7 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
16511651
let mut nodes = self.nodes.write().unwrap();
16521652
for scid in scids_to_remove {
16531653
let info = channels.remove(&scid).expect("We just accessed this scid, it should be present");
1654-
Self::remove_channel_in_nodes(&mut nodes, &info, scid);
1654+
self.remove_channel_in_nodes(&mut nodes, &info, scid);
16551655
}
16561656
}
16571657
}
@@ -1785,56 +1785,24 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
17851785

17861786
let mut nodes = self.nodes.write().unwrap();
17871787
let node = nodes.get_mut(&dest_node_id).unwrap();
1788-
let mut updated_lowest_inbound_channel_fee = None;
17891788
if chan_enabled {
17901789
let mut base_msat = msg.fee_base_msat;
17911790
let mut proportional_millionths = msg.fee_proportional_millionths;
17921791
if let Some(fees) = node.lowest_inbound_channel_fees {
17931792
base_msat = cmp::min(base_msat, fees.base_msat);
17941793
proportional_millionths = cmp::min(proportional_millionths, fees.proportional_millionths);
17951794
}
1796-
updated_lowest_inbound_channel_fee = Some(RoutingFees {
1797-
base_msat,
1798-
proportional_millionths
1799-
});
1795+
self.update_lowest_inbound_channel_fees(dest_node_id, node, &mut channels, Some(RoutingFees {
1796+
base_msat, proportional_millionths
1797+
}));
18001798
} else if chan_was_enabled {
1801-
for chan_id in node.channels.iter() {
1802-
let chan = channels.get(chan_id).unwrap();
1803-
let chan_info_opt;
1804-
if chan.node_one == dest_node_id {
1805-
chan_info_opt = chan.two_to_one.as_ref();
1806-
} else {
1807-
chan_info_opt = chan.one_to_two.as_ref();
1808-
}
1809-
if let Some(chan_info) = chan_info_opt {
1810-
if chan_info.enabled {
1811-
let fees = updated_lowest_inbound_channel_fee.get_or_insert(RoutingFees {
1812-
base_msat: u32::max_value(), proportional_millionths: u32::max_value() });
1813-
fees.base_msat = cmp::min(fees.base_msat, chan_info.fees.base_msat);
1814-
fees.proportional_millionths = cmp::min(fees.proportional_millionths, chan_info.fees.proportional_millionths);
1815-
}
1816-
}
1817-
}
1818-
}
1819-
1820-
if updated_lowest_inbound_channel_fee.is_some() {
1821-
node.lowest_inbound_channel_fees = updated_lowest_inbound_channel_fee;
1822-
1823-
for (_, chan) in channels.iter_mut() {
1824-
if chan.node_one == dest_node_id {
1825-
chan.lowest_inbound_channel_fees_to_two = updated_lowest_inbound_channel_fee;
1826-
}
1827-
1828-
if chan.node_two == dest_node_id {
1829-
chan.lowest_inbound_channel_fees_to_one = updated_lowest_inbound_channel_fee;
1830-
}
1831-
}
1799+
self.recompute_and_update_lowest_inbound_channel_fees(dest_node_id, node, &mut channels);
18321800
}
18331801

18341802
Ok(())
18351803
}
18361804

1837-
fn remove_channel_in_nodes(nodes: &mut BTreeMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
1805+
fn remove_channel_in_nodes(&self, nodes: &mut BTreeMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
18381806
macro_rules! remove_from_node {
18391807
($node_id: expr) => {
18401808
if let BtreeEntry::Occupied(mut entry) = nodes.entry($node_id) {
@@ -1847,12 +1815,51 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
18471815
} else {
18481816
panic!("Had channel that pointed to unknown node (ie inconsistent network map)!");
18491817
}
1818+
if let Some(node) = nodes.get_mut(&$node_id) {
1819+
self.recompute_and_update_lowest_inbound_channel_fees($node_id, node, &mut self.channels.write().unwrap());
1820+
}
18501821
}
18511822
}
18521823

18531824
remove_from_node!(chan.node_one);
18541825
remove_from_node!(chan.node_two);
18551826
}
1827+
1828+
fn recompute_and_update_lowest_inbound_channel_fees(&self, node_id: NodeId, node: &mut NodeInfo, channels: &mut BTreeMap<u64, ChannelInfo>) {
1829+
let mut updated_lowest_inbound_channel_fee = None;
1830+
for chan_id in node.channels.iter() {
1831+
let chan = channels.get(chan_id).unwrap();
1832+
let chan_info_opt;
1833+
if chan.node_one == node_id {
1834+
chan_info_opt = chan.two_to_one.as_ref();
1835+
} else {
1836+
chan_info_opt = chan.one_to_two.as_ref();
1837+
}
1838+
if let Some(chan_info) = chan_info_opt {
1839+
if chan_info.enabled {
1840+
let fees = updated_lowest_inbound_channel_fee.get_or_insert(RoutingFees {
1841+
base_msat: u32::max_value(), proportional_millionths: u32::max_value() });
1842+
fees.base_msat = cmp::min(fees.base_msat, chan_info.fees.base_msat);
1843+
fees.proportional_millionths = cmp::min(fees.proportional_millionths, chan_info.fees.proportional_millionths);
1844+
}
1845+
}
1846+
}
1847+
self.update_lowest_inbound_channel_fees(node_id, node, channels, updated_lowest_inbound_channel_fee);
1848+
}
1849+
1850+
fn update_lowest_inbound_channel_fees(&self, node_id: NodeId, node: &mut NodeInfo, channels: &mut BTreeMap<u64, ChannelInfo>, updated_fees: Option<RoutingFees>) {
1851+
node.lowest_inbound_channel_fees = updated_fees;
1852+
for (_, chan) in channels.iter_mut() {
1853+
if chan.node_one == node_id {
1854+
chan.lowest_inbound_channel_fees_to_two = updated_fees;
1855+
}
1856+
1857+
if chan.node_two == node_id {
1858+
chan.lowest_inbound_channel_fees_to_one = updated_fees;
1859+
}
1860+
}
1861+
}
1862+
18561863
}
18571864

18581865
impl ReadOnlyNetworkGraph<'_> {

0 commit comments

Comments
 (0)