From: Matt Corallo Date: Wed, 5 May 2021 00:19:11 +0000 (+0000) Subject: By default sort network addrs before inclusion in node_announcements X-Git-Tag: v0.0.98~33^2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=37fe22fece33156d9a969aef8337d9c5913a857d;p=rust-lightning By default sort network addrs before inclusion in node_announcements In #797, we stopped enforcing that read/sent node_announcements had their addresses sorted. While this is fine in practice, we should still make a best-effort to sort them to comply with the spec's forward-compatibility requirements, which we do here in the ChannelManager. --- diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index a9f87fa14..7b8b2a258 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1743,13 +1743,17 @@ impl ChannelMana /// only Tor Onion addresses. /// /// Panics if addresses is absurdly large (more than 500). - pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], addresses: Vec) { + pub fn broadcast_node_announcement(&self, rgb: [u8; 3], alias: [u8; 32], mut addresses: Vec) { let _persistence_guard = PersistenceNotifierGuard::new(&self.total_consistency_lock, &self.persistence_notifier); if addresses.len() > 500 { panic!("More than half the message size was taken up by public addresses!"); } + // While all existing nodes handle unsorted addresses just fine, the spec requires that + // addresses be sorted for future compatibility. + addresses.sort_by_key(|addr| addr.get_id()); + let announcement = msgs::UnsignedNodeAnnouncement { features: NodeFeatures::known(), timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel) as u32, diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 974e30095..be99596be 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -390,6 +390,17 @@ pub enum NetAddress { }, } impl NetAddress { + /// Gets the ID of this address type. Addresses in node_announcement messages should be sorted + /// by this. + pub(crate) fn get_id(&self) -> u8 { + match self { + &NetAddress::IPv4 {..} => { 1 }, + &NetAddress::IPv6 {..} => { 2 }, + &NetAddress::OnionV2 {..} => { 3 }, + &NetAddress::OnionV3 {..} => { 4 }, + } + } + /// Strict byte-length of address descriptor, 1-byte type not recorded fn len(&self) -> u16 { match self {