Fail RGS data processing early if there is a chain hash mismatch
authorDuncan Dean <git@dunxen.dev>
Mon, 29 May 2023 12:43:05 +0000 (14:43 +0200)
committerDuncan Dean <git@dunxen.dev>
Mon, 29 May 2023 14:15:42 +0000 (16:15 +0200)
No point in doing any extra processing if we don't even have a match
for the chain hash.

lightning-background-processor/src/lib.rs
lightning-rapid-gossip-sync/src/processing.rs
lightning/src/routing/gossip.rs

index 4d270286d5027c780d36a16a58711d11e72dcf47..297a980239756b7d36ef7844ad3dc0711fc2410c 100644 (file)
@@ -1124,7 +1124,7 @@ mod tests {
        fn create_nodes(num_nodes: usize, persist_dir: &str) -> (String, Vec<Node>) {
                let persist_temp_path = env::temp_dir().join(persist_dir);
                let persist_dir = persist_temp_path.to_string_lossy().to_string();
-               let network = Network::Testnet;
+               let network = Network::Bitcoin;
                let mut nodes = Vec::new();
                for i in 0..num_nodes {
                        let tx_broadcaster = Arc::new(test_utils::TestBroadcaster::new(network));
@@ -1135,7 +1135,7 @@ mod tests {
                        let scorer = Arc::new(Mutex::new(TestScorer::new()));
                        let seed = [i as u8; 32];
                        let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), seed, scorer.clone(), ()));
-                       let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
+                       let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
                        let persister = Arc::new(FilesystemPersister::new(format!("{}_persister_{}", &persist_dir, i)));
                        let now = Duration::from_secs(genesis_block.header.time as u64);
                        let keys_manager = Arc::new(KeysManager::new(&seed, now.as_secs(), now.subsec_nanos()));
index b387d49998e9a38d6f1693e1a18d05c4da57e675..fca318a5fa5f8cfac735ff8d3880819e8b6d93a0 100644 (file)
@@ -68,6 +68,16 @@ impl<NG: Deref<Target=NetworkGraph<L>>, L: Deref> RapidGossipSync<NG, L> where L
                }
 
                let chain_hash: BlockHash = Readable::read(read_cursor)?;
+               let ng_genesis_hash = self.network_graph.get_genesis_hash();
+               if chain_hash != ng_genesis_hash {
+                       return Err(
+                               LightningError {
+                                       err: "Rapid Gossip Sync data's chain hash does not match the network graph's".to_owned(),
+                                       action: ErrorAction::IgnoreError,
+                               }.into()
+                       );
+               }
+
                let latest_seen_timestamp: u32 = Readable::read(read_cursor)?;
 
                if let Some(time) = current_time_unix {
@@ -667,4 +677,22 @@ mod tests {
                        panic!("Unexpected update result: {:?}", update_result)
                }
        }
+
+       #[test]
+       fn fails_early_on_chain_hash_mismatch() {
+               let logger = TestLogger::new();
+               // Set to testnet so that the VALID_RGS_BINARY chain hash of mainnet does not match.
+               let network_graph = NetworkGraph::new(Network::Testnet, &logger);
+
+               assert_eq!(network_graph.read_only().channels().len(), 0);
+
+               let rapid_sync = RapidGossipSync::new(&network_graph, &logger);
+               let update_result = rapid_sync.update_network_graph_no_std(&VALID_RGS_BINARY, Some(0));
+               assert!(update_result.is_err());
+               if let Err(GraphSyncError::LightningError(err)) = update_result {
+                       assert_eq!(err.err, "Rapid Gossip Sync data's chain hash does not match the network graph's");
+               } else {
+                       panic!("Unexpected update result: {:?}", update_result)
+               }
+       }
 }
index f134bd0569e9905cf7a54b5359215c6b434ae4d0..5ac2f9ed6979c6509ca9b070d2f5a8f658a0081f 100644 (file)
@@ -366,6 +366,11 @@ impl<L: Deref> NetworkGraph<L> where L::Target: Logger {
                        },
                }
        }
+
+       /// Gets the genesis hash for this network graph.
+       pub fn get_genesis_hash(&self) -> BlockHash {
+               self.genesis_hash
+       }
 }
 
 macro_rules! secp_verify_sig {