feat(dht): Phase 3 discovery glue + paid swarm serving
Phase 3 wiring (task #12): - NostrSeedDiscovery: async ProviderDiscovery that queries relays for signed seed adverts and parses endpoint ids (swarm/iroh_provider.rs, seed_advert.rs). - seed_and_advertise publish path; dep-free fetch/publish helpers reuse the node's Nostr identity (build_nostr_client/load_or_create_nostr_keys made pub(crate)). - swarm::init builds the IrohProvider once into a OnceLock runtime; providers() returns it; announce_held_blob() is called from update.rs after a release component passes both hash gates. - config swarm_enabled (ARCHIPELAGO_SWARM_ENABLED, default off); server.rs init. Paid swarm serving (Phase 4 step F): - swarm/paid.rs gates the iroh-blobs provider through streaming::gate, intercepting connect + GET (peer push hard-disabled). Free by default (content-download service disabled); denies unpaid peers when enabled; fails open on internal error so a payment fault never blocks distribution. Wired into IrohProvider::new. All iroh code behind the iroh-swarm feature; the default build is inert. Default build clean; --features iroh-swarm: 11/11 swarm tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
f14829542b
commit
be3ebd7fe0
@@ -27,7 +27,7 @@ const D_TAG: &str = "archipelago-node";
|
||||
const LEGACY_RELAYS: &[&str] = &["wss://relay.damus.io", "wss://relay.nostr.info"];
|
||||
|
||||
/// Load or create Nostr keys (secp256k1) for node discovery.
|
||||
async fn load_or_create_nostr_keys(identity_dir: &Path) -> Result<Keys> {
|
||||
pub(crate) async fn load_or_create_nostr_keys(identity_dir: &Path) -> Result<Keys> {
|
||||
let secret_path = identity_dir.join(NOSTR_SECRET_FILE);
|
||||
let pub_path = identity_dir.join(NOSTR_PUB_FILE);
|
||||
|
||||
@@ -78,7 +78,7 @@ async fn load_nostr_keys_if_exists(identity_dir: &Path) -> Result<Option<Keys>>
|
||||
/// Publish a replaceable event with empty content to overwrite/revoke previously published data.
|
||||
/// Uses NIP-33: same kind + d-tag + author = latest replaces. Sends to LEGACY_RELAYS only.
|
||||
/// Requires tor_proxy to avoid leaking IP to relay operators.
|
||||
fn build_nostr_client(keys: Keys, tor_proxy: Option<&str>) -> Result<Client> {
|
||||
pub(crate) fn build_nostr_client(keys: Keys, tor_proxy: Option<&str>) -> Result<Client> {
|
||||
let client = if let Some(proxy_str) = tor_proxy {
|
||||
let addr = parse_proxy_addr(proxy_str)
|
||||
.ok_or_else(|| anyhow::anyhow!("Invalid Nostr Tor proxy: {}", proxy_str))?;
|
||||
|
||||
Reference in New Issue
Block a user