From 1971aeb3e3f4e1e8c877ddafbd5bf1c0143b58fb Mon Sep 17 00:00:00 2001 From: archipelago Date: Tue, 6 Oct 2026 06:40:59 -0400 Subject: [PATCH] Fail closed on corrupt peer records before content authentication --- core/archipelago/src/content_auth.rs | 3 ++- core/archipelago/src/federation/storage.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/archipelago/src/content_auth.rs b/core/archipelago/src/content_auth.rs index 15382034..f5f589ad 100644 --- a/core/archipelago/src/content_auth.rs +++ b/core/archipelago/src/content_auth.rs @@ -235,7 +235,8 @@ mod tests { .unwrap_err(); // The corrupt identity store fails before the separate missing-FIPS // route error. It reaches the payment caller's existing refund branch. - assert!(!error.to_string().contains("FIPS")); + assert!(error.to_string().contains("Invalid federation nodes")); + assert_eq!(tokio::fs::read(dir.path().join("federation/nodes.json")).await.unwrap(), b"invalid"); assert!(!dir.path().join("identity").exists()); } diff --git a/core/archipelago/src/federation/storage.rs b/core/archipelago/src/federation/storage.rs index d298a64e..2785e0af 100644 --- a/core/archipelago/src/federation/storage.rs +++ b/core/archipelago/src/federation/storage.rs @@ -84,7 +84,8 @@ async fn load_nodes_inner(data_dir: &Path) -> Result> { let content = fs::read_to_string(&path) .await .context("Failed to read federation nodes")?; - let file: NodesFile = serde_json::from_str(&content).unwrap_or_default(); + let file: NodesFile = serde_json::from_str(&content) + .context("Invalid federation nodes; existing peer records were preserved")?; Ok(dedup_nodes_by_onion(file.nodes)) }