Milestone 3: iroh endpoint, tickets, pin-triggered fetch
The daemon binds an iroh endpoint (ed25519 identity at secret.key, 0600), serves its store via Blobs/Router on the standard ALPN, and fetches with the iroh-blobs Downloader rather than the rpc client to keep quic-rpc out of the tree. Relay is disabled unless wan_upload is set: LAN-only, zero WAN upload by default. TicketImport pins first (the pin is the GC root protecting in-flight data), registers the ticket's NodeAddr with the endpoint (the downloader dials by NodeId alone), then fetches in the background; completion emits pin_complete. Tests: two-daemon localhost transfers (blob + directory collection, byte-identical), and kill -9 mid-transfer followed by restart on the same store resuming to completion. Dependencies: iroh 0.35 (endpoint/router, pairs with iroh-blobs 0.35), rand 0.8 (secret key generation, same version iroh uses). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# Milestone 3 — Transfer
|
||||
|
||||
The daemon now has an iroh endpoint: it serves its store over
|
||||
`iroh_blobs::ALPN` via the standard `Blobs`/`Router` stack, and fetches
|
||||
pinned content with the iroh-blobs `Downloader`. `TicketExport` /
|
||||
`TicketImport` complete the v1 out-of-band sharing loop; the pin created
|
||||
by an import triggers the fetch from the ticket-embedded provider.
|
||||
|
||||
## Decisions
|
||||
|
||||
- **Endpoint identity** is an ed25519 key at `<store_dir>/secret.key`
|
||||
(hex, mode `0600`, created on first start). Node ids surface in the
|
||||
API as opaque strings in iroh's canonical encoding.
|
||||
- **Relay disabled unless `wan_upload = true`.** The default posture is
|
||||
LAN-only with zero WAN upload; with the relay off the endpoint is only
|
||||
reachable over direct paths and never moves bytes through third-party
|
||||
infrastructure. Tickets between machines that can't reach each other
|
||||
directly need `wan_upload` on both ends — documented behavior, not a
|
||||
bug.
|
||||
- **Downloader, not the rpc client.** The `Blobs` rpc client
|
||||
(`add_from_path`/`download`) would pull in the whole quic-rpc feature
|
||||
surface; the underlying `Downloader` gives queueing, retries and
|
||||
resume with no extra dependencies. One found-the-hard-way detail: the
|
||||
downloader dials by NodeId only, so the ticket's `NodeAddr` must be
|
||||
registered with the endpoint (`add_node_addr`) before queueing, or
|
||||
every dial fails with "no addressing information".
|
||||
- **Pin-before-fetch.** `TicketImport` records the pin (and the format
|
||||
from the ticket) before the fetch starts: the pin is the GC root that
|
||||
protects in-flight data, and the standing intent survives an
|
||||
unreachable provider or a crash. Re-issuing the import after a crash
|
||||
resumes from iroh-blobs' on-disk partial state.
|
||||
- **Fetches are background tasks.** `TicketImport` replies immediately
|
||||
with the pinned hash; completion is observable via `Status {hash}`
|
||||
polling or the `pin_complete` event on a subscribed connection.
|
||||
- **A bare `Pin` still fetches nothing** — there are no known providers
|
||||
until LAN discovery lands in milestone 4. The pin is recorded and the
|
||||
spec's "fetch if absent" activates when provider sources exist.
|
||||
- **No serving gate yet**: this milestone serves any peer that presents
|
||||
the hash (tickets are unguessable capability tokens; BLAKE3 hashes of
|
||||
private content should be treated as secrets). The trust allowlist
|
||||
gate is milestone 4's first change.
|
||||
|
||||
## Tests
|
||||
|
||||
Two-daemon localhost integration: single blob and directory collection
|
||||
transfer, byte-identical after materialize on the fetcher. Crash test:
|
||||
SIGKILL the fetcher ~150 ms into a 64 MB transfer, restart on the same
|
||||
store, re-import the ticket, content completes and matches (proves
|
||||
clean restart with partial on-disk state; on a fast machine the kill
|
||||
may land after completion, which still exercises restart-with-state).
|
||||
Reference in New Issue
Block a user