Iroh.
- STATUS
- Phase A2 → D2 shipped
- CRATE
- tenzro-iroh
- TRANSPORT
- QUIC + iroh-blobs
- ADDRESSING
- tenzro://blob/<blake3>
Why a second transport
libp2p (gossipsub + Kademlia + AutoNAT v2 + DCUtR) handles every control-planemessage — blocks, votes, attestations, agent-to-agent control flow. It is excellent at small reliable broadcasts but it is not the right tool for shipping a 4 GB safetensors blob or a 256 MB outer gradient. Iroh fills that gap: every payload is content-addressed by BLAKE3, transferred over a single QUIC connection, and verified end-to-end on the receive side.
We never expose iroh:// in user-facing surfaces. The unified Tenzro URI scheme — tenzro://{blob,gradient,shard,manifest,memory}/... — hides the transport. A receiver does not need to know whether the bytes arrived over iroh-blobs or were inlined in a JSON-RPC response.
Resolver lifecycle
A node constructs one IrohBackedResolver at startup. The same endpoint services direct URI fetches, the DA backend, the gradient store, the sealed-shard store, the agent-memory archive, and the A2A trampoline — one ALPN, one hash space.
# config.toml
[iroh]
enable = true
pkarr_relay_url = "https://pkarr.tenzro.network/" # Tenzro-operated Pkarr relay (production default); local dev can omit
secret_key_seed = "<32-byte-hex>" # optional; defaults to TDIP key
# CLI shorthand
tenzro-node --role validator --iroh.enableDA backend
IrohBlobsDaBackend implements the tenzro_storage::da::DaBackend trait. The locator is the raw 32-byte BLAKE3 hash; commitment_kzg and attestation_root are None because iroh-blobs already verifies BLAKE3 end-to-end on transfer. Use it for receipt kinds whose default_mode() is OffloadedDA (SettlementChannel, Inference, AgentMessage).
Outer-gradient distribution
IrohGradientStore backs OuterGradient.safetensors_hash. Note the dual-hash design: the protocol field is SHA-256 (canonical Tenzro hash via compute_payload_hash) but iroh-blobs indexes by BLAKE3. The store keeps a DashMap<Hash, String> mapping so trainers can publish once and downstream syncers pull by SHA-256 over the tenzro/training topic.
Sealed dataset shards
IrohSealedShardStore distributes Confidential-tier SealedDatasetManifest envelopes. We deliberately do not use iroh-docs: the manifest is immutable once signed, and the sponsor DID is the auth model. Manifests are broadcast on tenzro/training; receivers fetch the envelopes by BLAKE3.
Peer-first model fetch
HfArtifactDownloader is peer-first via PeerHint: it asks any connected iroh peer for the BLAKE3 before falling back to HuggingFace Hub. On successful HF fetch it opportunistically publishes to the local blob store so subsequent fetchers (on this or any peer) skip the HF round trip.
Agent memory archive
When MemoryManager::archive() runs, the canonical MemoryRecord payload is submitted to the DA backend (iroh-blobs when the resolver is bound, InlineFallback otherwise) and the on-tier row is replaced by a kind=Archived stub holding the returned DaPointer. This lets large memories live durably off-tier without losing queryability.
A2A over iroh
Both tenzro/a2a and tenzro/mcp ALPNs run on the shared iroh router. A2A flows through a DeferredJsonRpcDispatcher trampoline so the same handler stack serves HTTP, iroh, and any future transport. MCP-over-iroh ships through a DeferredMcpHandler with rmcp 1.7's AsyncRwTransport — each inbound bi-stream becomes a full rmcp session.
Discovery (Pkarr)
Phase C2 anchors discovery to TDIP: TenzroIrohConfig.pkarr_relay_url + secret_key_seed let the endpoint publish a Pkarr record under the same Ed25519 key bytes as the agent's TDIP DID. The iroh EndpointId is byte-identical to the TDIP key, so DID resolution is bidirectional. Local development falls back to the n0 relay when no Pkarr relay is configured.