Compare commits
1 Commits
v1.7.24-al
...
v1.7.25-al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c634baa6d |
2
core/Cargo.lock
generated
2
core/Cargo.lock
generated
@@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "archipelago"
|
||||
version = "1.7.24-alpha"
|
||||
version = "1.7.25-alpha"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"archipelago-container",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "archipelago"
|
||||
version = "1.7.24-alpha"
|
||||
version = "1.7.25-alpha"
|
||||
edition = "2021"
|
||||
description = "Archipelago Bitcoin Node OS - Native backend"
|
||||
authors = ["Archipelago Team"]
|
||||
|
||||
@@ -13,22 +13,27 @@ use anyhow::{Context, Result};
|
||||
use std::path::Path;
|
||||
use tokio::process::Command;
|
||||
|
||||
use super::{DAEMON_CONFIG_PATH, DAEMON_KEY_PATH, DAEMON_PUB_PATH, DEFAULT_UDP_PORT};
|
||||
use super::{DAEMON_CONFIG_PATH, DAEMON_KEY_PATH, DAEMON_PUB_PATH, DEFAULT_TCP_PORT, DEFAULT_UDP_PORT};
|
||||
|
||||
/// Write the FIPS daemon config based on the local npub and default
|
||||
/// transports. Overwrites any existing file — callers are expected to
|
||||
/// re-run this whenever the key or daemon version changes.
|
||||
///
|
||||
/// Schema is intentionally minimal: node identity comes from the key
|
||||
/// file on disk (the daemon handles it), transports enable UDP + Tor,
|
||||
/// IPv6 TUN + DNS on defaults. Static peer list is empty — archipelago
|
||||
/// feeds peers dynamically via federation updates.
|
||||
/// file on disk (the daemon handles it), transports enable UDP + TCP
|
||||
/// (matching upstream factory default), IPv6 TUN + DNS on defaults.
|
||||
/// Static peer list is empty — archipelago feeds peers dynamically via
|
||||
/// the seed-anchors apply loop and federation-invite hooks.
|
||||
pub fn render_config_yaml() -> String {
|
||||
// Schema matches upstream jmcorgan/fips as of 2026-04. With
|
||||
// `node.identity.persistent: true` the daemon reuses the key file at
|
||||
// config-dir/fips.key (= DAEMON_KEY_PATH). Transports take `bind_addr`
|
||||
// rather than `enabled: true / port: N`, and the upstream no longer
|
||||
// has a `tor:` transport — archipelago's own Tor fallback handles that.
|
||||
// rather than `enabled: true / port: N`. Both UDP and TCP are
|
||||
// enabled by default because the public anchor (fips.v0l.io)
|
||||
// currently answers on TCP/8443 only, and networks that block UDP
|
||||
// outbound can still bootstrap via TCP. Upstream fips no longer
|
||||
// has a `tor:` transport variant — archipelago's own Tor fallback
|
||||
// handles that layer.
|
||||
format!(
|
||||
"# Generated by archipelago — do not edit by hand.\n\
|
||||
# Regenerated on every key change and daemon upgrade.\n\
|
||||
@@ -44,9 +49,12 @@ pub fn render_config_yaml() -> String {
|
||||
bind_addr: \"127.0.0.1\"\n\
|
||||
transports:\n \
|
||||
udp:\n \
|
||||
bind_addr: \"0.0.0.0:{port}\"\n\
|
||||
bind_addr: \"0.0.0.0:{udp}\"\n \
|
||||
tcp:\n \
|
||||
bind_addr: \"0.0.0.0:{tcp}\"\n\
|
||||
peers: []\n",
|
||||
port = DEFAULT_UDP_PORT,
|
||||
udp = DEFAULT_UDP_PORT,
|
||||
tcp = DEFAULT_TCP_PORT,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -185,7 +193,9 @@ mod tests {
|
||||
let yaml = render_config_yaml();
|
||||
assert!(yaml.contains("persistent: true"));
|
||||
assert!(yaml.contains(&format!("0.0.0.0:{}", DEFAULT_UDP_PORT)));
|
||||
assert!(yaml.contains(&format!("0.0.0.0:{}", DEFAULT_TCP_PORT)));
|
||||
assert!(yaml.contains("udp:"));
|
||||
assert!(yaml.contains("tcp:"));
|
||||
assert!(yaml.contains("tun:"));
|
||||
assert!(yaml.contains("name: fips0"));
|
||||
// Upstream fips dropped the `tor:` transport variant; archipelago
|
||||
|
||||
@@ -53,6 +53,14 @@ pub const UPSTREAM_REPO: &str = "jmcorgan/fips";
|
||||
/// Default UDP port the daemon listens on.
|
||||
pub const DEFAULT_UDP_PORT: u16 = 8668;
|
||||
|
||||
/// Default TCP port the daemon listens on. Used as a fallback when a
|
||||
/// peer can't be reached over UDP — common on networks that block UDP
|
||||
/// (corporate/guest wifi) and the path the public fips.v0l.io anchor
|
||||
/// currently accepts. Upstream factory default enables both transports
|
||||
/// and archipelago intentionally matches that baseline so fresh nodes
|
||||
/// can reach the broader FIPS mesh without operator config.
|
||||
pub const DEFAULT_TCP_PORT: u16 = 8443;
|
||||
|
||||
/// Upstream systemd unit shipped by the `fips` debian package. Archipelago
|
||||
/// prefers its own supervision (`archipelago-fips.service`) but respects an
|
||||
/// already-running upstream unit so legacy/dev nodes — where no seed-derived
|
||||
|
||||
@@ -510,10 +510,37 @@ impl Server {
|
||||
tracing::warn!("FIPS key load/migrate failed: {}", e);
|
||||
return;
|
||||
}
|
||||
// Check if the installed fips.yaml matches what we'd
|
||||
// render now. If not, we need to restart the daemon after
|
||||
// reinstalling so it picks up schema changes (e.g. the
|
||||
// v1.7.25 re-addition of the TCP transport). Without this,
|
||||
// OTA'd nodes would be stuck on the old UDP-only config
|
||||
// until someone manually clicked Reconnect.
|
||||
let expected = crate::fips::config::render_config_yaml();
|
||||
let installed = tokio::fs::read_to_string("/etc/fips/fips.yaml")
|
||||
.await
|
||||
.ok();
|
||||
let config_changed = installed.as_deref() != Some(expected.as_str());
|
||||
|
||||
if let Err(e) = crate::fips::config::install(&identity_dir).await {
|
||||
tracing::warn!("FIPS config install failed on startup: {}", e);
|
||||
return;
|
||||
}
|
||||
if config_changed {
|
||||
tracing::info!(
|
||||
"FIPS config schema changed on disk — restarting daemon to pick up new transports"
|
||||
);
|
||||
// Restart whichever unit is actually supervising
|
||||
// the daemon (archipelago-fips vs upstream fips).
|
||||
let unit = crate::fips::service::active_unit().await;
|
||||
if let Err(e) = crate::fips::service::restart(unit).await {
|
||||
tracing::warn!(
|
||||
"FIPS restart after config migration failed on {}: {} — user can retry via fips.reconnect",
|
||||
unit,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Err(e) = crate::fips::service::activate(crate::fips::SERVICE_UNIT).await {
|
||||
tracing::warn!(
|
||||
"archipelago-fips activate failed on startup: {} — user can retry via fips.install RPC",
|
||||
|
||||
@@ -34,27 +34,23 @@
|
||||
|
||||
<!-- Seed anchors modal — operator-editable list of peers this node
|
||||
dials to bootstrap the mesh. Tucked behind the gear so it
|
||||
doesn't crowd the card but is still one click away. -->
|
||||
doesn't crowd the card but is still one click away. Close
|
||||
button and layout mirror the What's New modal (and the rest
|
||||
of the app) so it feels like a first-class modal. -->
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
<div
|
||||
v-if="showAnchorsModal"
|
||||
class="fixed inset-0 z-[3000] flex items-center justify-center p-4"
|
||||
@click.self="showAnchorsModal = false"
|
||||
@click="showAnchorsModal = false"
|
||||
>
|
||||
<div class="absolute inset-0 bg-black/60 backdrop-blur-sm"></div>
|
||||
<div class="relative z-10 max-w-xl w-full" style="max-height: 90vh; overflow-y: auto">
|
||||
<div class="flex justify-end mb-2">
|
||||
<button
|
||||
type="button"
|
||||
class="p-2 rounded-md bg-white/10 hover:bg-white/20 text-white/70 hover:text-white transition-colors"
|
||||
aria-label="Close"
|
||||
@click="showAnchorsModal = false"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
<FipsSeedAnchorsCard />
|
||||
<div
|
||||
class="relative z-10 max-w-xl w-full"
|
||||
style="max-height: 90vh; overflow-y: auto"
|
||||
@click.stop
|
||||
>
|
||||
<FipsSeedAnchorsCard closable @close="showAnchorsModal = false" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
<template>
|
||||
<div data-controller-container tabindex="0" class="glass-card p-6 flex flex-col transition-all hover:-translate-y-1">
|
||||
<div class="flex items-start gap-4 mb-4 shrink-0">
|
||||
<div data-controller-container tabindex="0" class="glass-card p-6 flex flex-col transition-all hover:-translate-y-1 relative">
|
||||
<button
|
||||
v-if="closable"
|
||||
type="button"
|
||||
class="absolute top-4 right-4 p-2 rounded-lg hover:bg-white/10 text-white/70 hover:text-white transition-colors z-10"
|
||||
aria-label="Close"
|
||||
@click="$emit('close')"
|
||||
>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="flex items-start gap-4 mb-4 shrink-0" :class="{ 'pr-10': closable }">
|
||||
<div class="flex-shrink-0 w-12 h-12 rounded-lg bg-white/10 flex items-center justify-center">
|
||||
<!-- Radio/broadcast icon — three concentric arcs radiating from a
|
||||
dot. Reads as mesh, signal, anchor-reaching-peers. -->
|
||||
<svg class="w-6 h-6 text-white/80" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04.054-.09A13.916 13.916 0 0 0 8 11a4 4 0 1 1 8 0c0 1.017-.07 2.019-.203 3M9.497 10.997 14 18m-9.41-3.41L4 18.5" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.288 15.038a5.25 5.25 0 017.424 0M5.106 11.856c3.807-3.808 9.98-3.808 13.788 0M1.924 8.674c5.565-5.565 14.587-5.565 20.152 0" />
|
||||
<circle cx="12" cy="18" r="1.25" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
@@ -70,6 +84,9 @@
|
||||
import { onMounted, reactive, ref } from 'vue'
|
||||
import { rpcClient } from '@/api/rpc-client'
|
||||
|
||||
defineProps<{ closable?: boolean }>()
|
||||
defineEmits<{ (e: 'close'): void }>()
|
||||
|
||||
interface SeedAnchor {
|
||||
npub: string
|
||||
address: string
|
||||
|
||||
@@ -180,6 +180,18 @@ init()
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-y-auto flex-1 min-h-0 space-y-6 pr-1">
|
||||
<!-- v1.7.25-alpha -->
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.7.25-alpha</span>
|
||||
<span class="text-xs text-white/40">Apr 21, 2026</span>
|
||||
</div>
|
||||
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
|
||||
<p>Your node can now reach the broader FIPS public mesh, not just your own federated cluster. The FIPS daemon now binds both UDP (fast mesh forwarding) and TCP (NAT-friendly bootstrap) transports — matching the upstream factory default. The public anchor currently answers on TCP, so UDP-only nodes couldn't reach it; this fixes that without any action needed on your end.</p>
|
||||
<p>Upgrading the config happens automatically. On next startup, if the installed FIPS yaml doesn't match the new two-transport schema, the node reinstalls and restarts the daemon so the TCP transport comes online. No manual Reconnect required.</p>
|
||||
<p>Side benefit: TCP also helps on networks that block outbound UDP (corporate, some guest wifi) — your node falls back to TCP/8443 automatically and still joins the mesh.</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- v1.7.24-alpha -->
|
||||
<div>
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
{
|
||||
"version": "1.7.24-alpha",
|
||||
"version": "1.7.25-alpha",
|
||||
"release_date": "2026-04-21",
|
||||
"changelog": [
|
||||
"Frontend updates actually ship again. Since roughly v1.7.17 the release pipeline had been rebuilding the backend every version but silently skipping the frontend bundle — a permissions issue on the build server meant the TypeScript compile failed before vite ever ran, so every published tarball carried the same frozen v1.7.9-era UI. The backend moved forward; the UI didn't.",
|
||||
"Once this lands, your node gets the real current frontend: the FIPS Seed Anchors modal (gear icon on the FIPS Mesh card), the cancel-download button, the anchor-status fix, and every What's New entry for releases in between.",
|
||||
"The build pipeline now grep-verifies the packaged tarball actually contains the new version string before any commit or push, so a silently-stale bundle can't slip through again."
|
||||
"Your node can now reach the broader FIPS public mesh, not just your own federated cluster. The FIPS daemon now binds both UDP (fast mesh forwarding) and TCP (NAT-friendly bootstrap) transports — matching the upstream factory default. The public anchor currently answers on TCP, so UDP-only nodes couldn't reach it; this fixes that without any action needed on your end.",
|
||||
"Config upgrade is automatic. On next startup, if the installed FIPS yaml doesn't match the new two-transport schema, the node reinstalls and restarts the daemon so the TCP transport comes online. No manual Reconnect required.",
|
||||
"Side benefit: TCP also helps on networks that block outbound UDP (corporate, some guest wifi) — your node falls back to TCP/8443 automatically and still joins the mesh.",
|
||||
"The FIPS Seed Anchors modal got a design cleanup: new radio/mesh icon in the card header, and a matching close button styled like the rest of the app's modals instead of the earlier off-design placeholder."
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "archipelago",
|
||||
"current_version": "1.7.23-alpha",
|
||||
"new_version": "1.7.24-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.24-alpha/archipelago",
|
||||
"sha256": "a90428a6486d90c34e7e3dd9e1ac6d3dee171855f4cdae9680400e2b7dab200a",
|
||||
"size_bytes": 40817488
|
||||
"current_version": "1.7.24-alpha",
|
||||
"new_version": "1.7.25-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.25-alpha/archipelago",
|
||||
"sha256": "912e3baa0c97672e775e256adef97cf62be4873132bcd339738c6ee44cf940a0",
|
||||
"size_bytes": 40833768
|
||||
},
|
||||
{
|
||||
"name": "archipelago-frontend-1.7.24-alpha.tar.gz",
|
||||
"current_version": "1.7.23-alpha",
|
||||
"new_version": "1.7.24-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.24-alpha/archipelago-frontend-1.7.24-alpha.tar.gz",
|
||||
"sha256": "60cd9cc391faffe11b8b07982a416051977913831703474d2a433bd4fb81d5e9",
|
||||
"size_bytes": 162085926
|
||||
"name": "archipelago-frontend-1.7.25-alpha.tar.gz",
|
||||
"current_version": "1.7.24-alpha",
|
||||
"new_version": "1.7.25-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.25-alpha/archipelago-frontend-1.7.25-alpha.tar.gz",
|
||||
"sha256": "5d8aebfc72a3eacd76d74a3bd258cbadadaaf8079c590218186013de77139eb8",
|
||||
"size_bytes": 162089259
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
BIN
releases/v1.7.25-alpha/archipelago
Executable file
BIN
releases/v1.7.25-alpha/archipelago
Executable file
Binary file not shown.
BIN
releases/v1.7.25-alpha/archipelago-frontend-1.7.25-alpha.tar.gz
Normal file
BIN
releases/v1.7.25-alpha/archipelago-frontend-1.7.25-alpha.tar.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user