Closes the "tickets work for pull but not sync" asymmetry
from 0.41.1. Adds a StaticAddressLookup provider seeded
from PeerConfig.peers (now Vec<EndpointAddr> instead of
Vec<EndpointId>), plugged into iroh's endpoint via
Builder::address_lookup. The N0 preset's pkarr+DNS lookups
stay layered alongside for unknown peers; for known
ticket peers, the static provider answers immediately with
no network roundtrip.
End-user effect: `pile net sync --peers <EndpointTicket>`
now successfully bootstraps the gossip mesh against the
ticketed peers even when iroh's pkarr publish or DNS
resolution is blocked (Anthropic web sandbox, corporate
proxies, etc.). The bootstrap connect goes through the
local AddressLookupServices chain; our static provider
matches first and yields the embedded relay URL + direct
sockets directly.
Public API change: PeerConfig.peers is now
Vec<EndpointAddr>. Source-compatible for existing callers
passing EndpointId via the standard Into impl
(`peers: vec![my_id.into()]`).
Wire-up:
- New module triblespace-net/src/address_lookup.rs (~80
lines): StaticAddressLookup struct + AddressLookup impl.
- host_loop builds the lookup from config.peers and
plumbs it via Endpoint::builder().address_lookup(...).
- host_loop extracts Vec<EndpointId> from config.peers
for the gossip/DHT bootstrap surfaces (they take ids).
- trible run_sync passes the parsed Vec<EndpointAddr>
directly into PeerConfig.peers — no EndpointId
extraction in the CLI.
Tests: 17 lib + 2 + 3 + 1 doctest in triblespace-net pass.
Full workspace test suite green (260+ tests across all
crates). The new module compiles cleanly against
iroh-base 0.98 + iroh 0.98 + n0-future 0.3.
All 8 workspace crates bumped 0.41.1 → 0.41.2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>