Replace the per-attempt key-file side channel (DEMO_NODE_KEY_FILE,
read_key_report, JoinCheck) with a control-plane announce: node roles
send a tagged gossip frame {attempt, logical_node, key_hex,
endpoint_addr_json} after joining and every heartbeat thereafter.
- iroh-driver: IrohDriver::send_tagged_gossip — fire-and-forget
tag-routed gossip egress for bridge-less clients (reuses cached/join
connections, dials with backoff).
- provisioning: BootstrapMsg::Announce — first delivery while
bootstrapping completes the attempt (collector + exactly-once
Bootstrapped report); duplicates, misrouted attempts, and
terminal-phase announces drop. Unit-tested.
- xtask demo: AnnounceActor decodes the tag-routed frame and forwards
by attempt to the owning bootstrap actor; last_announce_ms is the
wire heartbeat. LocalProcessLogic keeps only process lifecycle.
- --docker: DockerProcessLogic (kind "docker") — attached
"docker run --rm" child on a per-run labeled bridge network
(foreign-node masking: per-container IPs, gateway-dialed
supervisor). Standalone scratch image from the static-musl xtask
binary (37MB), staged one-file build context. The container is
force-removed on every terminal path so a SIGKILLed docker CLI
cannot orphan a running container.
- Cleanup: no volumes/mounts; label-filtered exit sweep (SIGINT and
SIGTERM both drain first) + startup sweep of stale demo resources;
images persist per run token.
Verified live: process kind (kill -> replacement in 3.4s, provision/
remove/kill waves, zero orphans) and docker kind (8-node abuse waves
across docker kill, mid-provision control kills, CLI SIGKILL orphans
force-removed, SIGKILL-crash leftovers swept on restart, clean exits
leave zero containers/networks/CLIs). provisioning 22 + iroh-driver
13 tests pass.
|
||
|---|---|---|
| .. | ||
| src | ||
| tests | ||
| Cargo.toml | ||
| IROH_DRIVER_SPEC.md | ||
| README.md | ||
iroh-driver
iroh-driver is the iroh-backed transport bridge for the actorized distribution stack. It owns the concrete iroh endpoint, QUIC connections, relay configuration, peer authorization, and frame shuttling between iroh and swactor actor mailboxes.
Engine ownership
The driver runs on a caller-supplied swactor EngineHandle — the
single engine that owns the node's Tokio substrate. All accepts, reads, dials,
writes, retries, and teardown are scheduled through that handle; the driver
stores no raw Tokio handle and performs no ambient-runtime detection
(ENGINE_SPEC.md §7).
let driver = IrohDriver::with_engine(engine.handle(), config)?;
The driver validates that the engine provides the tasks, timers, and io
capabilities before binding the endpoint or starting any background work
(ENGINE_SPEC.md). Endpoint construction runs as an engine-hosted
task; with_engine blocks on a synchronous channel until the endpoint is bound
(or fails), so callers need not enter or possess the raw substrate runtime.
Engine-hosted progression
All adapter progression — actor-bridge ingress/egress, telemetry ingress, and
edge ingress — is driven by an engine-hosted interval pump installed via
install_actor_bridge_pump. Applications do not (and cannot) manually pump
these adapters; the single engine owns progression for the node's lifetime
(ENGINE_SPEC.md). snapshot is a pure-synchronous read of driver
state, callable from any thread. The shutdown method closes the endpoint via
an engine-hosted task, blocking on a synchronous channel until completion.