X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Fgossip.rs;h=065472aa3c14158b1e24470490d70d7a917de84a;hb=efdd2217b78b1b5b3cbbcb8f4bce26f1c6a0cf87;hp=d0682d47d7ed15d475791956ac55022825595813;hpb=3a33693b1e279221f517b33af6bbdf38cc1330a9;p=rust-lightning diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index d0682d47..065472aa 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -1156,14 +1156,14 @@ impl ReadableArgs for NetworkGraph where L::Target: Logger { let genesis_hash: BlockHash = Readable::read(reader)?; let channels_count: u64 = Readable::read(reader)?; - let mut channels = BTreeMap::new(); + let mut channels: BTreeMap = BTreeMap::new(); for _ in 0..channels_count { let chan_id: u64 = Readable::read(reader)?; let chan_info = Readable::read(reader)?; channels.insert(chan_id, chan_info); } let nodes_count: u64 = Readable::read(reader)?; - let mut nodes = BTreeMap::new(); + let mut nodes: BTreeMap = BTreeMap::new(); for _ in 0..nodes_count { let node_id = Readable::read(reader)?; let node_info = Readable::read(reader)?; @@ -1175,6 +1175,22 @@ impl ReadableArgs for NetworkGraph where L::Target: Logger { (1, last_rapid_gossip_sync_timestamp, option), }); + // Regenerate inbound fees for all channels. The live-updating of these has been broken in + // various ways historically, so this ensures that we have up-to-date limits. + for (node_id, node) in nodes.iter_mut() { + let mut best_fees = RoutingFees { base_msat: u32::MAX, proportional_millionths: u32::MAX }; + for channel in node.channels.iter() { + if let Some(chan) = channels.get(channel) { + let dir_opt = if *node_id == chan.node_one { &chan.two_to_one } else { &chan.one_to_two }; + if let Some(dir) = dir_opt { + best_fees.base_msat = cmp::min(best_fees.base_msat, dir.fees.base_msat); + best_fees.proportional_millionths = cmp::min(best_fees.proportional_millionths, dir.fees.proportional_millionths); + } + } else { return Err(DecodeError::InvalidValue); } + } + node.lowest_inbound_channel_fees = Some(best_fees); + } + Ok(NetworkGraph { secp_ctx: Secp256k1::verification_only(), genesis_hash, @@ -1541,6 +1557,14 @@ impl NetworkGraph where L::Target: Logger { #[cfg(not(feature = "std"))] let current_time_unix = None; + self.channel_failed_with_time(short_channel_id, is_permanent, current_time_unix) + } + + /// Marks a channel in the graph as failed if a corresponding HTLC fail was sent. + /// If permanent, removes a channel from the local storage. + /// May cause the removal of nodes too, if this was their last channel. + /// If not permanent, makes channels unavailable for routing. + fn channel_failed_with_time(&self, short_channel_id: u64, is_permanent: bool, current_time_unix: Option) { let mut channels = self.channels.write().unwrap(); if is_permanent { if let Some(chan) = channels.remove(&short_channel_id) { @@ -1932,6 +1956,7 @@ mod tests { use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement, UnsignedChannelAnnouncement, ChannelAnnouncement, UnsignedChannelUpdate, ChannelUpdate, ReplyChannelRange, QueryChannelRange, QueryShortChannelIds, MAX_VALUE_MSAT}; + use crate::util::config::UserConfig; use crate::util::test_utils; use crate::util::ser::{ReadableArgs, Writeable}; use crate::util::events::{MessageSendEvent, MessageSendEventsProvider}; @@ -1991,7 +2016,7 @@ mod tests { fn get_signed_node_announcement(f: F, node_key: &SecretKey, secp_ctx: &Secp256k1) -> NodeAnnouncement { let node_id = PublicKey::from_secret_key(&secp_ctx, node_key); let mut unsigned_announcement = UnsignedNodeAnnouncement { - features: channelmanager::provided_node_features(), + features: channelmanager::provided_node_features(&UserConfig::default()), timestamp: 100, node_id: node_id, rgb: [0; 3], @@ -2015,7 +2040,7 @@ mod tests { let node_2_btckey = &SecretKey::from_slice(&[39; 32]).unwrap(); let mut unsigned_announcement = UnsignedChannelAnnouncement { - features: channelmanager::provided_channel_features(), + features: channelmanager::provided_channel_features(&UserConfig::default()), chain_hash: genesis_block(Network::Testnet).header.block_hash(), short_channel_id: 0, node_id_1, @@ -2537,18 +2562,18 @@ mod tests { // Mark the channel as permanently failed. This will also remove the two nodes // and all of the entries will be tracked as removed. - network_graph.channel_failed(short_channel_id, true); + network_graph.channel_failed_with_time(short_channel_id, true, Some(tracking_time)); // Should not remove from tracking if insufficient time has passed network_graph.remove_stale_channels_and_tracking_with_time( tracking_time + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS - 1); - assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1); + assert_eq!(network_graph.removed_channels.lock().unwrap().len(), 1, "Removed channel count ≠ 1 with tracking_time {}", tracking_time); // Provide a later time so that sufficient time has passed network_graph.remove_stale_channels_and_tracking_with_time( tracking_time + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS); - assert!(network_graph.removed_channels.lock().unwrap().is_empty()); - assert!(network_graph.removed_nodes.lock().unwrap().is_empty()); + assert!(network_graph.removed_channels.lock().unwrap().is_empty(), "Unexpectedly removed channels with tracking_time {}", tracking_time); + assert!(network_graph.removed_nodes.lock().unwrap().is_empty(), "Unexpectedly removed nodes with tracking_time {}", tracking_time); } #[cfg(not(feature = "std"))] @@ -3149,6 +3174,7 @@ mod tests { let node_cfgs = crate::ln::functional_test_utils::create_node_cfgs(2, &chanmon_cfgs); let node_chanmgrs = crate::ln::functional_test_utils::create_node_chanmgrs(2, &node_cfgs, &[None, None, None, None]); let nodes = crate::ln::functional_test_utils::create_network(2, &node_cfgs, &node_chanmgrs); + let config = crate::ln::functional_test_utils::test_default_channel_config(); // 1. Test encoding/decoding of ChannelUpdateInfo let chan_update_info = ChannelUpdateInfo { @@ -3185,7 +3211,7 @@ mod tests { // 2. Test encoding/decoding of ChannelInfo // Check we can encode/decode ChannelInfo without ChannelUpdateInfo fields present. let chan_info_none_updates = ChannelInfo { - features: channelmanager::provided_channel_features(), + features: channelmanager::provided_channel_features(&config), node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()), one_to_two: None, node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), @@ -3203,7 +3229,7 @@ mod tests { // Check we can encode/decode ChannelInfo with ChannelUpdateInfo fields present. let chan_info_some_updates = ChannelInfo { - features: channelmanager::provided_channel_features(), + features: channelmanager::provided_channel_features(&config), node_one: NodeId::from_pubkey(&nodes[0].node.get_our_node_id()), one_to_two: Some(chan_update_info.clone()), node_two: NodeId::from_pubkey(&nodes[1].node.get_our_node_id()), @@ -3245,7 +3271,7 @@ mod tests { // 1. Check we can read a valid NodeAnnouncementInfo and fail on an invalid one let valid_netaddr = crate::ln::msgs::NetAddress::Hostname { hostname: crate::util::ser::Hostname::try_from("A".to_string()).unwrap(), port: 1234 }; let valid_node_ann_info = NodeAnnouncementInfo { - features: channelmanager::provided_node_features(), + features: channelmanager::provided_node_features(&UserConfig::default()), last_update: 0, rgb: [0u8; 3], alias: NodeAlias([0u8; 32]),