X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Frouting%2Fgossip.rs;h=90ead987e7c99c4c8079f57a4c9f91ea4485fb64;hb=refs%2Fheads%2F2023-05-no-background-event-dup-persist;hp=e5f5e63c93893b114137c888b941519e28e5488f;hpb=c89fd38f2a6681b28f853d0f7d80795ca38d9ffd;p=rust-lightning diff --git a/lightning/src/routing/gossip.rs b/lightning/src/routing/gossip.rs index e5f5e63c..90ead987 100644 --- a/lightning/src/routing/gossip.rs +++ b/lightning/src/routing/gossip.rs @@ -28,7 +28,7 @@ use crate::ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMes use crate::ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, GossipTimestampFilter}; use crate::ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd}; use crate::ln::msgs; -use crate::routing::utxo::{self, UtxoLookup}; +use crate::routing::utxo::{self, UtxoLookup, UtxoResolver}; use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, MaybeReadable}; use crate::util::logger::{Logger, Level}; use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK}; @@ -1439,8 +1439,8 @@ impl NetworkGraph where L::Target: Logger { /// Store or update channel info from a channel announcement. /// - /// You probably don't want to call this directly, instead relying on a P2PGossipSync's - /// RoutingMessageHandler implementation to call it indirectly. This may be useful to accept + /// You probably don't want to call this directly, instead relying on a [`P2PGossipSync`]'s + /// [`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. /// /// If a [`UtxoLookup`] object is provided via `utxo_lookup`, it will be called to verify @@ -1459,6 +1459,19 @@ impl NetworkGraph where L::Target: Logger { self.update_channel_from_unsigned_announcement_intern(&msg.contents, Some(msg), utxo_lookup) } + /// Store or update channel info from a channel announcement. + /// + /// You probably don't want to call this directly, instead relying on a [`P2PGossipSync`]'s + /// [`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. + /// + /// This will skip verification of if the channel is actually on-chain. + pub fn update_channel_from_announcement_no_lookup( + &self, msg: &ChannelAnnouncement + ) -> Result<(), LightningError> { + self.update_channel_from_announcement::<&UtxoResolver>(msg, &None) + } + /// Store or update channel info from a channel announcement without verifying the associated /// signatures. Because we aren't given the associated signatures here we cannot relay the /// channel announcement to any of our peers. @@ -1560,6 +1573,13 @@ impl NetworkGraph where L::Target: Logger { return Err(LightningError{err: "Channel announcement node had a channel with itself".to_owned(), action: ErrorAction::IgnoreError}); } + if msg.chain_hash != self.genesis_hash { + return Err(LightningError { + err: "Channel announcement chain hash does not match genesis hash".to_owned(), + action: ErrorAction::IgnoreAndLog(Level::Debug), + }); + } + { let channels = self.channels.read().unwrap(); @@ -1806,6 +1826,13 @@ impl NetworkGraph where L::Target: Logger { fn update_channel_intern(&self, msg: &msgs::UnsignedChannelUpdate, full_msg: Option<&msgs::ChannelUpdate>, sig: Option<&secp256k1::ecdsa::Signature>) -> Result<(), LightningError> { let chan_enabled = msg.flags & (1 << 1) != (1 << 1); + if msg.chain_hash != self.genesis_hash { + return Err(LightningError { + err: "Channel update chain hash does not match genesis hash".to_owned(), + action: ErrorAction::IgnoreAndLog(Level::Debug), + }); + } + #[cfg(all(feature = "std", not(test), not(feature = "_test_utils")))] { // Note that many tests rely on being able to set arbitrarily old timestamps, thus we @@ -2298,6 +2325,16 @@ pub(crate) mod tests { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Channel announcement node had a channel with itself") }; + + // Test that channel announcements with the wrong chain hash are ignored (network graph is testnet, + // announcement is mainnet). + let incorrect_chain_announcement = get_signed_channel_announcement(|unsigned_announcement| { + unsigned_announcement.chain_hash = genesis_block(Network::Bitcoin).header.block_hash(); + }, node_1_privkey, node_2_privkey, &secp_ctx); + match gossip_sync.handle_channel_announcement(&incorrect_chain_announcement) { + Ok(_) => panic!(), + Err(e) => assert_eq!(e.err, "Channel announcement chain hash does not match genesis hash") + }; } #[test] @@ -2402,6 +2439,17 @@ pub(crate) mod tests { Ok(_) => panic!(), Err(e) => assert_eq!(e.err, "Invalid signature on channel_update message") }; + + // Test that channel updates with the wrong chain hash are ignored (network graph is testnet, channel + // update is mainet). + let incorrect_chain_update = get_signed_channel_update(|unsigned_channel_update| { + unsigned_channel_update.chain_hash = genesis_block(Network::Bitcoin).header.block_hash(); + }, node_1_privkey, &secp_ctx); + + match gossip_sync.handle_channel_update(&incorrect_chain_update) { + Ok(_) => panic!(), + Err(e) => assert_eq!(e.err, "Channel update chain hash does not match genesis hash") + }; } #[test]