From f2e3710c28bc27cddbe9e6c76a67b6ec9d58a303 Mon Sep 17 00:00:00 2001 From: archipelago Date: Mon, 15 Jun 2026 13:02:13 -0400 Subject: [PATCH] fix(content): record peer transport on cloud browse/download/preview (B14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 4 content peer handlers (browse, download, download_paid, preview) captured the transport returned by PeerRequest::send_get() but discarded it, so the federation node's last_transport was never updated for cloud activity — the UI showed Tor/none even when FIPS was used. Call record_peer_transport() after each successful fetch (same as sync does). Note: live data shows FIPS still reaches only some peers (many genuinely fall back to Tor) — tracked separately as B14b (FIPS reachability). Co-Authored-By: Claude Opus 4.8 (1M context) --- core/archipelago/src/api/rpc/content.rs | 41 ++++++++++++++++++++++--- tests/production-quality/TRACKER.md | 5 ++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/core/archipelago/src/api/rpc/content.rs b/core/archipelago/src/api/rpc/content.rs index 2d9bea1b..3932712d 100644 --- a/core/archipelago/src/api/rpc/content.rs +++ b/core/archipelago/src/api/rpc/content.rs @@ -234,7 +234,7 @@ impl RpcHandler { let fips_npub = crate::federation::fips_npub_for_onion(&self.config.data_dir, onion).await; let path = format!("/content/{}", content_id); - let (response, _transport) = + let (response, transport) = crate::fips::dial::PeerRequest::new(fips_npub.as_deref(), onion, &path) .service(crate::settings::transport::PeerService::PeerFiles) .header("X-Federation-DID", local_did) @@ -242,6 +242,15 @@ impl RpcHandler { .send_get() .await .context("Failed to connect to peer")?; + // Record which transport actually reached the peer (B14) so the UI + // reflects FIPS vs Tor truthfully instead of always showing Tor/none. + let _ = crate::federation::storage::record_peer_transport( + &self.config.data_dir, + None, + Some(onion), + &transport.to_string(), + ) + .await; if response.status() == reqwest::StatusCode::PAYMENT_REQUIRED { let body: serde_json::Value = response.json().await.unwrap_or_default(); @@ -294,13 +303,21 @@ impl RpcHandler { fips_npub.is_some() ); - let (response, _transport) = + let (response, transport) = crate::fips::dial::PeerRequest::new(fips_npub.as_deref(), onion, "/content") .service(crate::settings::transport::PeerService::PeerFiles) .timeout(std::time::Duration::from_secs(30)) .send_get() .await .context("Failed to connect to peer")?; + // Record which transport actually reached the peer (B14). + let _ = crate::federation::storage::record_peer_transport( + &self.config.data_dir, + None, + Some(onion), + &transport.to_string(), + ) + .await; if !response.status().is_success() { return Err(anyhow::anyhow!( @@ -353,7 +370,7 @@ impl RpcHandler { let fips_npub = crate::federation::fips_npub_for_onion(&self.config.data_dir, onion).await; let path = format!("/content/{}", content_id); - let (response, _transport) = + let (response, transport) = crate::fips::dial::PeerRequest::new(fips_npub.as_deref(), onion, &path) .service(crate::settings::transport::PeerService::PeerFiles) .header("X-Federation-DID", local_did) @@ -362,6 +379,14 @@ impl RpcHandler { .send_get() .await .context("Failed to connect to peer")?; + // Record which transport actually reached the peer (B14). + let _ = crate::federation::storage::record_peer_transport( + &self.config.data_dir, + None, + Some(onion), + &transport.to_string(), + ) + .await; if response.status() == reqwest::StatusCode::PAYMENT_REQUIRED { // Payment was rejected — token is spent but content not received @@ -418,13 +443,21 @@ impl RpcHandler { fips_npub.is_some() ); - let (response, _transport) = + let (response, transport) = crate::fips::dial::PeerRequest::new(fips_npub.as_deref(), onion, &path) .service(crate::settings::transport::PeerService::PeerFiles) .timeout(std::time::Duration::from_secs(30)) .send_get() .await .context("Failed to connect to peer for preview")?; + // Record which transport actually reached the peer (B14). + let _ = crate::federation::storage::record_peer_transport( + &self.config.data_dir, + None, + Some(onion), + &transport.to_string(), + ) + .await; if !response.status().is_success() { return Err(anyhow::anyhow!( diff --git a/tests/production-quality/TRACKER.md b/tests/production-quality/TRACKER.md index 84bf86ad..174c93c5 100644 --- a/tests/production-quality/TRACKER.md +++ b/tests/production-quality/TRACKER.md @@ -59,7 +59,7 @@ Music/video preview files on peer nodes' cloud don't play (streaming/range/conte ### B4 — Cloud "my folders" fails (JSON parse / 502) — PASSED (content-type guard; built, guard in bundle, deployed .198). UI visual-confirm recommended. `Unexpected token '<', "/` instead of SPA shell. Handle BOTH absent + down. -### B14 — Trusted/peer cloud browse uses Tor not FIPS — ROOT-CAUSED (plan ready: record_peer_transport in 4 handlers; VERIFY actual transport) +### B14 — cloud browse transport not recorded — FIXED (record_peer_transport in 4 content handlers; build OK). NOTE: live data shows FIPS reaches only ~4/15 peers, 6 fall back to Tor genuinely → see B14b. Browsing trusted/peer nodes in the Cloud tab connects over Tor instead of FIPS (should prefer FIPS like the rest of mesh; same for peer browsing). cf project_fips_integration, project_tor_node_to_node_works (last_transport should be fips/mesh). --- @@ -105,6 +105,9 @@ When an update download fails, the UI sometimes shows the Install button instead ### B20 — Surface bitcoin-headers-over-mesh broadcast (send/receive toggles) — TODO (feature-adjacent, surfacing existing work) We previously broadcast bitcoin block headers over mesh to archipelago nodes but never fully surfaced it. Want two switches: "send headers" (you broadcast) and "receive headers" (you accept). NOTE: this is feature-adjacent — surfacing existing functionality; the user added it during the no-new-features push, so treat as low-priority polish until the bug list is clear. Code: mesh block-headers (mesh.block-headers RPC seen in logs; core/archipelago/src/mesh). +### B14b — FIPS reachability: many peers fall back to Tor — TODO (priority, deeper) +Live (2026-06-15) federation sync last_transport on .116/.198: ~4 peers fips, ~6 tor, ~5 none. So beyond the recording fix (B14), FIPS genuinely doesn't reach many federated peers (they use Tor). Investigate WHY: is fips_npub known for those peers? are they FIPS-online? is the shared anchor connecting them? (cf project_fips_integration, project_tor_node_to_node_works). This is the real "Tor not FIPS" depth. + ### B8 — netbird app doesn't work — TODO (LOW / much later) (RETRACTED: CryptPad placeholder-icon — user says cryptpad is fine.)