diff --git a/lightning-net-tokio/src/lib.rs b/lightning-net-tokio/src/lib.rs index 6d001ca67fd..65393246a0c 100644 --- a/lightning-net-tokio/src/lib.rs +++ b/lightning-net-tokio/src/lib.rs @@ -590,9 +590,11 @@ mod tests { msg_events: Mutex>, } impl RoutingMessageHandler for MsgHandler { - fn handle_node_announcement(&self, _msg: &NodeAnnouncement) -> Result { Ok(false) } - fn handle_channel_announcement(&self, _msg: &ChannelAnnouncement) -> Result { Ok(false) } - fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result { Ok(false) } + fn handle_node_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &NodeAnnouncement) -> Result { Ok(false) } + fn handle_channel_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &ChannelAnnouncement) -> Result { Ok(false) } + fn handle_channel_update( + &self, _their_node_id: Option<&PublicKey>, _msg: &ChannelUpdate, + ) -> Result { Ok(false) } fn get_next_channel_announcement(&self, _starting_point: u64) -> Option<(ChannelAnnouncement, Option, Option)> { None } fn get_next_node_announcement(&self, _starting_point: Option<&NodeId>) -> Option { None } fn peer_connected(&self, _their_node_id: &PublicKey, _init_msg: &Init, _inbound: bool) -> Result<(), ()> { Ok(()) } diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 7d332f2ad78..cd21653274f 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -1941,10 +1941,11 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: let (channel_ready, channel_id) = create_chan_between_nodes_with_value_confirm_second(&nodes[0], &nodes[1]); (channel_id, create_chan_between_nodes_with_value_b(&nodes[1], &nodes[0], &channel_ready)) }; - for node in nodes.iter() { - assert!(node.gossip_sync.handle_channel_announcement(&announcement).unwrap()); - node.gossip_sync.handle_channel_update(&as_update).unwrap(); - node.gossip_sync.handle_channel_update(&bs_update).unwrap(); + for (i, node) in nodes.iter().enumerate() { + let counterparty_node_id = nodes[(i + 1) % 2].node.get_our_node_id(); + assert!(node.gossip_sync.handle_channel_announcement(Some(&counterparty_node_id), &announcement).unwrap()); + node.gossip_sync.handle_channel_update(Some(&counterparty_node_id), &as_update).unwrap(); + node.gossip_sync.handle_channel_update(Some(&counterparty_node_id), &bs_update).unwrap(); } if !restore_b_before_lock { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index c5361318fca..fdf5ecb60f2 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -1463,14 +1463,16 @@ pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: & pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(nodes: &'a Vec>, a: usize, b: usize, ann: &msgs::ChannelAnnouncement, upd_1: &msgs::ChannelUpdate, upd_2: &msgs::ChannelUpdate) { for node in nodes { - assert!(node.gossip_sync.handle_channel_announcement(ann).unwrap()); - node.gossip_sync.handle_channel_update(upd_1).unwrap(); - node.gossip_sync.handle_channel_update(upd_2).unwrap(); + let node_id_a = nodes[a].node.get_our_node_id(); + let node_id_b = nodes[b].node.get_our_node_id(); + assert!(node.gossip_sync.handle_channel_announcement(None, ann).unwrap()); + node.gossip_sync.handle_channel_update(Some(&node_id_a), upd_1).unwrap(); + node.gossip_sync.handle_channel_update(Some(&node_id_b), upd_2).unwrap(); // Note that channel_updates are also delivered to ChannelManagers to ensure we have // forwarding info for local channels even if its not accepted in the network graph. - node.node.handle_channel_update(&nodes[a].node.get_our_node_id(), &upd_1); - node.node.handle_channel_update(&nodes[b].node.get_our_node_id(), &upd_2); + node.node.handle_channel_update(&node_id_a, &upd_1); + node.node.handle_channel_update(&node_id_b, &upd_2); } } @@ -3463,9 +3465,10 @@ pub fn handle_announce_close_broadcast_events<'a, 'b, 'c>(nodes: &Vec Result; + /// + /// If `their_node_id` is `None`, the message was generated by our own local node. + fn handle_node_announcement(&self, their_node_id: Option<&PublicKey>, msg: &NodeAnnouncement) -> Result; /// Handle a `channel_announcement` message, returning `true` if it should be forwarded on, `false` /// or returning an `Err` otherwise. - fn handle_channel_announcement(&self, msg: &ChannelAnnouncement) -> Result; + /// + /// If `their_node_id` is `None`, the message was generated by our own local node. + fn handle_channel_announcement(&self, their_node_id: Option<&PublicKey>, msg: &ChannelAnnouncement) -> Result; /// Handle an incoming `channel_update` message, returning true if it should be forwarded on, /// `false` or returning an `Err` otherwise. - fn handle_channel_update(&self, msg: &ChannelUpdate) -> Result; + /// + /// If `their_node_id` is `None`, the message was generated by our own local node. + fn handle_channel_update(&self, their_node_id: Option<&PublicKey>, msg: &ChannelUpdate) -> Result; /// Gets channel announcements and updates required to dump our routing table to a remote node, /// starting at the `short_channel_id` indicated by `starting_point` and including announcements /// for a single channel. diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs index 6ae87e6001d..189d6e20e54 100644 --- a/lightning/src/ln/offers_tests.rs +++ b/lightning/src/ln/offers_tests.rs @@ -127,9 +127,10 @@ fn announce_node_address<'a, 'b, 'c>( contents: announcement }; - node.gossip_sync.handle_node_announcement(&msg).unwrap(); + let node_pubkey = node.node.get_our_node_id(); + node.gossip_sync.handle_node_announcement(None, &msg).unwrap(); for peer in peers { - peer.gossip_sync.handle_node_announcement(&msg).unwrap(); + peer.gossip_sync.handle_node_announcement(Some(&node_pubkey), &msg).unwrap(); } } diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 17e46a274b1..dc141348905 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -104,9 +104,9 @@ impl MessageSendEventsProvider for IgnoringMessageHandler { fn get_and_clear_pending_msg_events(&self) -> Vec { Vec::new() } } impl RoutingMessageHandler for IgnoringMessageHandler { - fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result { Ok(false) } - fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result { Ok(false) } - fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result { Ok(false) } + fn handle_node_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::NodeAnnouncement) -> Result { Ok(false) } + fn handle_channel_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::ChannelAnnouncement) -> Result { Ok(false) } + fn handle_channel_update(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::ChannelUpdate) -> Result { Ok(false) } fn get_next_channel_announcement(&self, _starting_point: u64) -> Option<(msgs::ChannelAnnouncement, Option, Option)> { None } fn get_next_node_announcement(&self, _starting_point: Option<&NodeId>) -> Option { None } @@ -1869,22 +1869,22 @@ impl { - if self.message_handler.route_handler.handle_channel_announcement(&msg) + if self.message_handler.route_handler.handle_channel_announcement(Some(their_node_id), &msg) .map_err(|e| -> MessageHandlingError { e.into() })? { should_forward = Some(wire::Message::ChannelAnnouncement(msg)); } self.update_gossip_backlogged(); }, wire::Message::NodeAnnouncement(msg) => { - if self.message_handler.route_handler.handle_node_announcement(&msg) + if self.message_handler.route_handler.handle_node_announcement(Some(their_node_id), &msg) .map_err(|e| -> MessageHandlingError { e.into() })? { should_forward = Some(wire::Message::NodeAnnouncement(msg)); } self.update_gossip_backlogged(); }, wire::Message::ChannelUpdate(msg) => { - self.message_handler.chan_handler.handle_channel_update(&their_node_id, &msg); - if self.message_handler.route_handler.handle_channel_update(&msg) + self.message_handler.chan_handler.handle_channel_update(their_node_id, &msg); + if self.message_handler.route_handler.handle_channel_update(Some(their_node_id), &msg) .map_err(|e| -> MessageHandlingError { e.into() })? { should_forward = Some(wire::Message::ChannelUpdate(msg)); } @@ -2267,13 +2267,13 @@ impl { log_debug!(self.logger, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id); - match self.message_handler.route_handler.handle_channel_announcement(&msg) { + match self.message_handler.route_handler.handle_channel_announcement(None, &msg) { Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) => self.forward_broadcast_msg(peers, &wire::Message::ChannelAnnouncement(msg), None), _ => {}, } if let Some(msg) = update_msg { - match self.message_handler.route_handler.handle_channel_update(&msg) { + match self.message_handler.route_handler.handle_channel_update(None, &msg) { Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) => self.forward_broadcast_msg(peers, &wire::Message::ChannelUpdate(msg), None), _ => {}, @@ -2282,7 +2282,7 @@ impl { log_debug!(self.logger, "Handling BroadcastChannelUpdate event in peer_handler for contents {:?}", msg.contents); - match self.message_handler.route_handler.handle_channel_update(&msg) { + match self.message_handler.route_handler.handle_channel_update(None, &msg) { Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) => self.forward_broadcast_msg(peers, &wire::Message::ChannelUpdate(msg), None), _ => {}, @@ -2290,7 +2290,7 @@ impl { log_debug!(self.logger, "Handling BroadcastNodeAnnouncement event in peer_handler for node {}", msg.contents.node_id); - match self.message_handler.route_handler.handle_node_announcement(&msg) { + match self.message_handler.route_handler.handle_node_announcement(None, &msg) { Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) => self.forward_broadcast_msg(peers, &wire::Message::NodeAnnouncement(msg), None), _ => {}, @@ -2653,7 +2653,7 @@ impl(msg: &ChannelAnnouncement, s impl>, U: Deref, L: Deref> RoutingMessageHandler for P2PGossipSync where U::Target: UtxoLookup, L::Target: Logger { - fn handle_node_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result { + fn handle_node_announcement(&self, _their_node_id: Option<&PublicKey>, msg: &msgs::NodeAnnouncement) -> Result { self.network_graph.update_node_from_announcement(msg)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY && msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY && msg.contents.excess_data.len() + msg.contents.excess_address_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } - fn handle_channel_announcement(&self, msg: &msgs::ChannelAnnouncement) -> Result { + fn handle_channel_announcement(&self, _their_node_id: Option<&PublicKey>, msg: &msgs::ChannelAnnouncement) -> Result { self.network_graph.update_channel_from_announcement(msg, &*self.utxo_lookup.read().unwrap())?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } - fn handle_channel_update(&self, msg: &msgs::ChannelUpdate) -> Result { + fn handle_channel_update(&self, _their_node_id: Option<&PublicKey>, msg: &msgs::ChannelUpdate) -> Result { self.network_graph.update_channel(msg)?; Ok(msg.contents.excess_data.len() <= MAX_EXCESS_BYTES_FOR_RELAY) } @@ -1463,6 +1463,15 @@ impl NetworkGraph where L::Target: Logger { /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept /// routing messages from a source using a protocol other than the lightning P2P protocol. pub fn update_node_from_announcement(&self, msg: &msgs::NodeAnnouncement) -> Result<(), LightningError> { + // First check if we have the announcement already to avoid the CPU cost of validating a + // redundant announcement. + if let Some(node) = self.nodes.read().unwrap().get(&msg.contents.node_id) { + if let Some(node_info) = node.announcement_info.as_ref() { + if node_info.last_update == msg.contents.timestamp { + return Err(LightningError{err: "Update had the same timestamp as last processed update".to_owned(), action: ErrorAction::IgnoreDuplicateGossip}); + } + } + } verify_node_announcement(msg, &self.secp_ctx)?; self.update_node_from_announcement_intern(&msg.contents, Some(&msg)) } @@ -1526,6 +1535,7 @@ impl NetworkGraph where L::Target: Logger { where U::Target: UtxoLookup, { + self.pre_channel_announcement_validation_check(&msg.contents, utxo_lookup)?; verify_channel_announcement(msg, &self.secp_ctx)?; self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), utxo_lookup) } @@ -1555,6 +1565,7 @@ impl NetworkGraph where L::Target: Logger { where U::Target: UtxoLookup, { + self.pre_channel_announcement_validation_check(&msg, utxo_lookup)?; self.update_channel_from_unsigned_announcement_intern(msg, None, utxo_lookup) } @@ -1636,6 +1647,52 @@ impl NetworkGraph where L::Target: Logger { Ok(()) } + /// If we already have all the information for a channel that we're gonna get, there's no + /// reason to redundantly process it. + /// + /// In those cases, this will return an `Err` that we can return immediately. Otherwise it will + /// return an `Ok(())`. + fn pre_channel_announcement_validation_check( + &self, msg: &msgs::UnsignedChannelAnnouncement, utxo_lookup: &Option, + ) -> Result<(), LightningError> where U::Target: UtxoLookup { + let channels = self.channels.read().unwrap(); + + if let Some(chan) = channels.get(&msg.short_channel_id) { + if chan.capacity_sats.is_some() { + // If we'd previously looked up the channel on-chain and checked the script + // against what appears on-chain, ignore the duplicate announcement. + // + // Because a reorg could replace one channel with another at the same SCID, if + // the channel appears to be different, we re-validate. This doesn't expose us + // to any more DoS risk than not, as a peer can always flood us with + // randomly-generated SCID values anyway. + // + // We use the Node IDs rather than the bitcoin_keys to check for "equivalence" + // as we didn't (necessarily) store the bitcoin keys, and we only really care + // if the peers on the channel changed anyway. + if msg.node_id_1 == chan.node_one && msg.node_id_2 == chan.node_two { + return Err(LightningError { + err: "Already have chain-validated channel".to_owned(), + action: ErrorAction::IgnoreDuplicateGossip + }); + } + } else if utxo_lookup.is_none() { + // Similarly, if we can't check the chain right now anyway, ignore the + // duplicate announcement without bothering to take the channels write lock. + return Err(LightningError { + err: "Already have non-chain-validated channel".to_owned(), + action: ErrorAction::IgnoreDuplicateGossip + }); + } + } + + Ok(()) + } + + /// Update channel information from a received announcement. + /// + /// Generally [`Self::pre_channel_announcement_validation_check`] should have been called + /// first. fn update_channel_from_unsigned_announcement_intern( &self, msg: &msgs::UnsignedChannelAnnouncement, full_msg: Option<&msgs::ChannelAnnouncement>, utxo_lookup: &Option ) -> Result<(), LightningError> @@ -1653,39 +1710,6 @@ impl NetworkGraph where L::Target: Logger { }); } - { - let channels = self.channels.read().unwrap(); - - if let Some(chan) = channels.get(&msg.short_channel_id) { - if chan.capacity_sats.is_some() { - // If we'd previously looked up the channel on-chain and checked the script - // against what appears on-chain, ignore the duplicate announcement. - // - // Because a reorg could replace one channel with another at the same SCID, if - // the channel appears to be different, we re-validate. This doesn't expose us - // to any more DoS risk than not, as a peer can always flood us with - // randomly-generated SCID values anyway. - // - // We use the Node IDs rather than the bitcoin_keys to check for "equivalence" - // as we didn't (necessarily) store the bitcoin keys, and we only really care - // if the peers on the channel changed anyway. - if msg.node_id_1 == chan.node_one && msg.node_id_2 == chan.node_two { - return Err(LightningError { - err: "Already have chain-validated channel".to_owned(), - action: ErrorAction::IgnoreDuplicateGossip - }); - } - } else if utxo_lookup.is_none() { - // Similarly, if we can't check the chain right now anyway, ignore the - // duplicate announcement without bothering to take the channels write lock. - return Err(LightningError { - err: "Already have non-chain-validated channel".to_owned(), - action: ErrorAction::IgnoreDuplicateGossip - }); - } - } - } - { let removed_channels = self.removed_channels.lock().unwrap(); let removed_nodes = self.removed_nodes.lock().unwrap(); @@ -2250,11 +2274,12 @@ pub(crate) mod tests { let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let zero_hash = Sha256dHash::hash(&[0; 32]); let valid_announcement = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!("No existing channels for node_announcement", e.err) }; @@ -2262,19 +2287,20 @@ pub(crate) mod tests { { // Announce a channel to add a corresponding node. let valid_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() }; } - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), Err(_) => panic!() }; let fake_msghash = hash_to_message!(zero_hash.as_byte_array()); match gossip_sync.handle_node_announcement( + Some(&node_1_pubkey), &NodeAnnouncement { signature: secp_ctx.sign_ecdsa(&fake_msghash, node_1_privkey), contents: valid_announcement.contents.clone() @@ -2283,12 +2309,17 @@ pub(crate) mod tests { Err(e) => assert_eq!(e.err, "Invalid signature on node_announcement message") }; + match gossip_sync.handle_node_announcement(&valid_announcement) { + Ok(res) => assert!(res), + Err(_) => panic!() + }; + let announcement_with_data = get_signed_node_announcement(|unsigned_announcement| { unsigned_announcement.timestamp += 1000; unsigned_announcement.excess_data.resize(MAX_EXCESS_BYTES_FOR_RELAY + 1, 0); }, node_1_privkey, &secp_ctx); // Return false because contains excess data. - match gossip_sync.handle_node_announcement(&announcement_with_data) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement_with_data) { Ok(res) => assert!(!res), Err(_) => panic!() }; @@ -2298,7 +2329,7 @@ pub(crate) mod tests { let outdated_announcement = get_signed_node_announcement(|unsigned_announcement| { unsigned_announcement.timestamp += 1000 - 10; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&outdated_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &outdated_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Update older than last processed update") }; @@ -2310,6 +2341,7 @@ pub(crate) mod tests { let logger = test_utils::TestLogger::new(); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let good_script = get_channel_script(&secp_ctx); @@ -2318,7 +2350,7 @@ pub(crate) mod tests { // Test if the UTXO lookups were not supported let network_graph = NetworkGraph::new(Network::Testnet, &logger); let mut gossip_sync = P2PGossipSync::new(&network_graph, None, &logger); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() }; @@ -2332,7 +2364,7 @@ pub(crate) mod tests { // If we receive announcement for the same channel (with UTXO lookups disabled), // drop new one on the floor, since we can't see any changes. - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Already have non-chain-validated channel") }; @@ -2346,7 +2378,7 @@ pub(crate) mod tests { let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.short_channel_id += 1; }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel announced without corresponding UTXO entry") }; @@ -2357,7 +2389,7 @@ pub(crate) mod tests { let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.short_channel_id += 2; }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() }; @@ -2373,7 +2405,7 @@ pub(crate) mod tests { // chain, we simply ignore all new (duplicate) announcements. *chain_source.utxo_ret.lock().unwrap() = UtxoResult::Sync(Ok(TxOut { value: 0, script_pubkey: good_script })); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Already have chain-validated channel") }; @@ -2390,7 +2422,7 @@ pub(crate) mod tests { let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.short_channel_id += 3; }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel with SCID 3 or one of its nodes was removed from our network graph recently") } @@ -2398,31 +2430,36 @@ pub(crate) mod tests { gossip_sync.network_graph().remove_stale_channels_and_tracking_with_time(tracking_time + REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS); // The above channel announcement should be handled as per normal now. - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() } } - // Don't relay valid channels with excess data - let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { + let valid_excess_data_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.short_channel_id += 4; unsigned_announcement.excess_data.resize(MAX_EXCESS_BYTES_FOR_RELAY + 1, 0); }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(!res), _ => panic!() }; - let mut invalid_sig_announcement = valid_announcement.clone(); + let mut invalid_sig_announcement = valid_excess_data_announcement.clone(); invalid_sig_announcement.contents.excess_data = Vec::new(); - match gossip_sync.handle_channel_announcement(&invalid_sig_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &invalid_sig_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Invalid signature on channel_announcement message") }; + // Don't relay valid channels with excess data + match gossip_sync.handle_channel_announcement(&valid_excess_data_announcement) { + Ok(res) => assert!(!res), + _ => panic!() + }; + let channel_to_itself_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&channel_to_itself_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &channel_to_itself_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel announcement node had a channel with itself") }; @@ -2432,7 +2469,7 @@ pub(crate) mod tests { let incorrect_chain_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.chain_hash = ChainHash::using_genesis_block(Network::Bitcoin); }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&incorrect_chain_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &incorrect_chain_announcement) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel announcement chain hash does not match genesis hash") }; @@ -2447,6 +2484,7 @@ pub(crate) mod tests { let gossip_sync = P2PGossipSync::new(&network_graph, Some(&chain_source), &logger); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let amount_sats = 1000_000; @@ -2460,7 +2498,7 @@ pub(crate) mod tests { let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); short_channel_id = valid_channel_announcement.contents.short_channel_id; - match gossip_sync.handle_channel_announcement(&valid_channel_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_channel_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -2469,7 +2507,7 @@ pub(crate) mod tests { let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx); network_graph.verify_channel_update(&valid_channel_update).unwrap(); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(res) => assert!(res), _ => panic!(), }; @@ -2489,7 +2527,7 @@ pub(crate) mod tests { unsigned_channel_update.excess_data.resize(MAX_EXCESS_BYTES_FOR_RELAY + 1, 0); }, node_1_privkey, &secp_ctx); // Return false because contains excess data - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(res) => assert!(!res), _ => panic!() }; @@ -2498,7 +2536,7 @@ pub(crate) mod tests { unsigned_channel_update.timestamp += 110; unsigned_channel_update.short_channel_id += 1; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Couldn't find channel for update") }; @@ -2507,7 +2545,7 @@ pub(crate) mod tests { unsigned_channel_update.htlc_maximum_msat = MAX_VALUE_MSAT + 1; unsigned_channel_update.timestamp += 110; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "htlc_maximum_msat is larger than maximum possible msats") }; @@ -2516,7 +2554,7 @@ pub(crate) mod tests { unsigned_channel_update.htlc_maximum_msat = amount_sats * 1000 + 1; unsigned_channel_update.timestamp += 110; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "htlc_maximum_msat is larger than channel capacity or capacity is bogus") }; @@ -2526,7 +2564,7 @@ pub(crate) mod tests { let valid_channel_update = get_signed_channel_update(|unsigned_channel_update| { unsigned_channel_update.timestamp += 100; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Update had same timestamp as last processed update") }; @@ -2537,7 +2575,7 @@ pub(crate) mod tests { let zero_hash = Sha256dHash::hash(&[0; 32]); let fake_msghash = hash_to_message!(zero_hash.as_byte_array()); invalid_sig_channel_update.signature = secp_ctx.sign_ecdsa(&fake_msghash, node_1_privkey); - match gossip_sync.handle_channel_update(&invalid_sig_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &invalid_sig_channel_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Invalid signature on channel_update message") }; @@ -2548,7 +2586,7 @@ pub(crate) mod tests { unsigned_channel_update.chain_hash = ChainHash::using_genesis_block(Network::Bitcoin); }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&incorrect_chain_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &incorrect_chain_update) { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel update chain hash does not match genesis hash") }; @@ -2664,6 +2702,7 @@ pub(crate) mod tests { let secp_ctx = Secp256k1::new(); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); @@ -2674,11 +2713,11 @@ pub(crate) mod tests { // Submit two channel updates for each channel direction (update.flags bit). let valid_channel_update = get_signed_channel_update(|_| {}, node_1_privkey, &secp_ctx); - assert!(gossip_sync.handle_channel_update(&valid_channel_update).is_ok()); + assert!(gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update).is_ok()); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); let valid_channel_update_2 = get_signed_channel_update(|update| {update.flags |=1;}, node_2_privkey, &secp_ctx); - gossip_sync.handle_channel_update(&valid_channel_update_2).unwrap(); + gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update_2).unwrap(); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().two_to_one.is_some()); network_graph.remove_stale_channels_and_tracking_with_time(100 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); @@ -2710,7 +2749,7 @@ pub(crate) mod tests { let valid_channel_update = get_signed_channel_update(|unsigned_channel_update| { unsigned_channel_update.timestamp = (announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS) as u32; }, node_1_privkey, &secp_ctx); - assert!(gossip_sync.handle_channel_update(&valid_channel_update).is_ok()); + assert!(gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update).is_ok()); assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some()); network_graph.remove_stale_channels_and_tracking_with_time(announcement_time + 1 + STALE_CHANNEL_UPDATE_AGE_LIMIT_SECS); // Make sure removed channels are tracked. @@ -2793,6 +2832,7 @@ pub(crate) mod tests { let network_graph = create_network_graph(); let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); // Channels were not announced yet. @@ -2804,7 +2844,7 @@ pub(crate) mod tests { // Announce a channel we will update let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); short_channel_id = valid_channel_announcement.contents.short_channel_id; - match gossip_sync.handle_channel_announcement(&valid_channel_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_channel_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -2825,7 +2865,7 @@ pub(crate) mod tests { let valid_channel_update = get_signed_channel_update(|unsigned_channel_update| { unsigned_channel_update.timestamp = 101; }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => (), Err(_) => panic!() }; @@ -2847,7 +2887,7 @@ pub(crate) mod tests { unsigned_channel_update.timestamp = 102; unsigned_channel_update.excess_data = [1; MAX_EXCESS_BYTES_FOR_RELAY + 1].to_vec(); }, node_1_privkey, &secp_ctx); - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_1_pubkey), &valid_channel_update) { Ok(_) => (), Err(_) => panic!() }; @@ -2873,6 +2913,7 @@ pub(crate) mod tests { let network_graph = create_network_graph(); let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let node_id_1 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey)); @@ -2883,7 +2924,7 @@ pub(crate) mod tests { { // Announce a channel to add 2 nodes let valid_channel_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_channel_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_channel_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -2895,13 +2936,13 @@ pub(crate) mod tests { { let valid_announcement = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => (), Err(_) => panic!() }; let valid_announcement = get_signed_node_announcement(|_| {}, node_2_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -2920,7 +2961,7 @@ pub(crate) mod tests { unsigned_announcement.timestamp += 10; unsigned_announcement.excess_data = [1; MAX_EXCESS_BYTES_FOR_RELAY + 1].to_vec(); }, node_2_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(!res), Err(_) => panic!() }; @@ -2936,17 +2977,18 @@ pub(crate) mod tests { let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); // Announce a channel to add a corresponding node. let valid_announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() }; let valid_announcement = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx); - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -3024,6 +3066,7 @@ pub(crate) mod tests { let chain_hash = ChainHash::using_genesis_block(Network::Testnet); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let node_id_2 = PublicKey::from_secret_key(&secp_ctx, node_2_privkey); @@ -3044,7 +3087,7 @@ pub(crate) mod tests { let valid_announcement = get_signed_channel_announcement(|unsigned_announcement| { unsigned_announcement.short_channel_id = scid; }, node_1_privkey, node_2_privkey, &secp_ctx); - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(_) => (), _ => panic!() }; @@ -3503,11 +3546,12 @@ pub(crate) mod tests { let (secp_ctx, gossip_sync) = create_gossip_sync(&network_graph); let node_1_privkey = &SecretKey::from_slice(&[42; 32]).unwrap(); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); let node_2_privkey = &SecretKey::from_slice(&[41; 32]).unwrap(); let node_1_id = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey)); let announcement = get_signed_channel_announcement(|_| {}, node_1_privkey, node_2_privkey, &secp_ctx); - gossip_sync.handle_channel_announcement(&announcement).unwrap(); + gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &announcement).unwrap(); let tcp_ip_v4 = SocketAddress::TcpIpV4 { addr: [255, 254, 253, 252], @@ -3532,7 +3576,7 @@ pub(crate) mod tests { assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement(|_| {}, node_1_privkey, &secp_ctx); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3545,7 +3589,7 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3557,7 +3601,8 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); + assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3569,7 +3614,7 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3579,7 +3624,7 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3589,7 +3634,7 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); let announcement = get_signed_node_announcement( @@ -3599,7 +3644,7 @@ pub(crate) mod tests { }, node_1_privkey, &secp_ctx ); - gossip_sync.handle_node_announcement(&announcement).unwrap(); + gossip_sync.handle_node_announcement(Some(&node_1_pubkey), &announcement).unwrap(); assert!(!network_graph.read_only().node(&node_1_id).unwrap().is_tor_only()); } } diff --git a/lightning/src/routing/test_utils.rs b/lightning/src/routing/test_utils.rs index 6aca76a2167..b27d18acd72 100644 --- a/lightning/src/routing/test_utils.rs +++ b/lightning/src/routing/test_utils.rs @@ -32,7 +32,8 @@ pub(crate) fn add_channel( gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_1_privkey: &SecretKey, node_2_privkey: &SecretKey, features: ChannelFeatures, short_channel_id: u64 ) { - let node_id_1 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_1_privkey)); + let node_1_pubkey = PublicKey::from_secret_key(&secp_ctx, node_1_privkey); + let node_id_1 = NodeId::from_pubkey(&node_1_pubkey); let node_id_2 = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_2_privkey)); let unsigned_announcement = UnsignedChannelAnnouncement { @@ -54,7 +55,7 @@ pub(crate) fn add_channel( bitcoin_signature_2: secp_ctx.sign_ecdsa(&msghash, node_2_privkey), contents: unsigned_announcement.clone(), }; - match gossip_sync.handle_channel_announcement(&valid_announcement) { + match gossip_sync.handle_channel_announcement(Some(&node_1_pubkey), &valid_announcement) { Ok(res) => assert!(res), _ => panic!() }; @@ -64,7 +65,8 @@ pub(crate) fn add_or_update_node( gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, features: NodeFeatures, timestamp: u32 ) { - let node_id = NodeId::from_pubkey(&PublicKey::from_secret_key(&secp_ctx, node_privkey)); + let node_pubkey = PublicKey::from_secret_key(&secp_ctx, node_privkey); + let node_id = NodeId::from_pubkey(&node_pubkey); let unsigned_announcement = UnsignedNodeAnnouncement { features, timestamp, @@ -81,7 +83,7 @@ pub(crate) fn add_or_update_node( contents: unsigned_announcement.clone() }; - match gossip_sync.handle_node_announcement(&valid_announcement) { + match gossip_sync.handle_node_announcement(Some(&node_pubkey), &valid_announcement) { Ok(_) => (), Err(_) => panic!() }; @@ -91,13 +93,14 @@ pub(crate) fn update_channel( gossip_sync: &P2PGossipSync>>, Arc, Arc>, secp_ctx: &Secp256k1, node_privkey: &SecretKey, update: UnsignedChannelUpdate ) { + let node_pubkey = PublicKey::from_secret_key(&secp_ctx, node_privkey); let msghash = hash_to_message!(&Sha256dHash::hash(&update.encode()[..])[..]); let valid_channel_update = ChannelUpdate { signature: secp_ctx.sign_ecdsa(&msghash, node_privkey), contents: update.clone() }; - match gossip_sync.handle_channel_update(&valid_channel_update) { + match gossip_sync.handle_channel_update(Some(&node_pubkey), &valid_channel_update) { Ok(res) => assert!(res), Err(_) => panic!() }; diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 6b4d2acd4d9..a0badb49d7a 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -972,14 +972,14 @@ impl TestRoutingMessageHandler { } } impl msgs::RoutingMessageHandler for TestRoutingMessageHandler { - fn handle_node_announcement(&self, _msg: &msgs::NodeAnnouncement) -> Result { + fn handle_node_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::NodeAnnouncement) -> Result { Err(msgs::LightningError { err: "".to_owned(), action: msgs::ErrorAction::IgnoreError }) } - fn handle_channel_announcement(&self, _msg: &msgs::ChannelAnnouncement) -> Result { + fn handle_channel_announcement(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::ChannelAnnouncement) -> Result { self.chan_anns_recvd.fetch_add(1, Ordering::AcqRel); Err(msgs::LightningError { err: "".to_owned(), action: msgs::ErrorAction::IgnoreError }) } - fn handle_channel_update(&self, _msg: &msgs::ChannelUpdate) -> Result { + fn handle_channel_update(&self, _their_node_id: Option<&PublicKey>, _msg: &msgs::ChannelUpdate) -> Result { self.chan_upds_recvd.fetch_add(1, Ordering::AcqRel); Err(msgs::LightningError { err: "".to_owned(), action: msgs::ErrorAction::IgnoreError }) }