geth/docs/user-workflows.md

7.7 KiB

User Workflows

This document describes geth from the operator's point of view. Each workflow states the intended outcome, the shortest supported command path, the success signal, and important trust or durability boundaries.

Choose A Startup Mode

Try geth without keeping state

User story: as a curious user or test author, I want an isolated daemon without choosing a directory or cleaning it up afterward.

geth daemon run --ephemeral

The command initializes a temporary home, prints its path and a ready-to-copy control command, and runs in the foreground. In another terminal:

geth --home <printed-path> status
geth --home <printed-path> node id

Success means geth status reports geth daemon: running. Ctrl-C performs a graceful shutdown and removes the temporary home. An abrupt process kill may leave temporary files for the operating system's normal temp cleanup.

Keep a persistent background node

User story: as a workstation user, I want geth to start now and at future logins without learning my platform's service-manager syntax.

geth daemon install
geth wait daemon
geth status

daemon install initializes the selected home if needed, installs and enables a service for the current user, and starts it. It never installs a system service. Common lifecycle operations are direct:

geth daemon status
geth daemon stop
geth daemon start
geth daemon uninstall

The older geth daemon service ... family remains supported for scripts and advanced options. In particular, geth daemon service install installs without starting unless --start is supplied.

Keep state but run in the foreground

User story: as a developer, I want persistent state and logs attached to my terminal.

geth init
geth daemon run

Set RUST_LOG=geth_node=debug when more daemon diagnostics are useful. Use geth --home <dir> ... to operate an isolated home without exporting an environment variable.

Inspect And Change Configuration

User story: as an operator, I want to find and validate the exact configuration used by one geth home without guessing an OS-specific path or hand-editing common boolean and interval settings.

geth config path
geth config show
geth config set sync.live_sync_interval_ms 10000
geth config validate
geth daemon stop
geth daemon start

config show reports built-in defaults when the file has not been created yet. config set preserves unrelated TOML and comments and refuses to replace the file if the complete prospective configuration is invalid. Success means config validate identifies the selected path as valid. Configuration is loaded at daemon startup, so restart the user service after changes.

Establish An Owner Trust Root

User story: as the mesh owner, I want my first node rooted in an existing SSH or hardware-backed OpenSSH admin key without copying that private key into geth.

geth init \
  --admin-key ~/.ssh/id_ed25519_sk.pub \
  --signing-key ~/.ssh/id_ed25519_sk \
  --owner eric \
  --node-name owner-laptop
geth daemon install
geth keychain status
geth node list

The public key becomes an admin trust anchor. The private key or FIDO/YubiKey stub is passed to ssh-keygen -Y sign; geth does not copy it into local state. Success means keychain status reports accepted signed operations and node list includes the named owner node.

Enroll A Second Node

User story: as the owner, I want to approve a new device without treating discovery or a peer card as proof of trust.

  1. Export and transfer the owner's signed peer card:

    geth peer export --out owner.peer.json
    
  2. On the new node, initialize, import the card, and submit a request:

    geth init
    geth daemon install
    geth peer import owner.peer.json
    geth node enroll request --node-name workstation --out workstation.enroll.json
    geth node enroll submit owner-laptop --path workstation.enroll.json
    
  3. On the owner node, review and approve with the admin key:

    geth node enroll list --status pending
    geth node enroll approve <request-id> --signing-key ~/.ssh/id_ed25519_sk
    
  4. On the new node, pull and inspect the approved state:

    geth sync now owner-laptop
    geth wait sync owner-laptop
    geth node list
    

Peer-card import only supplies signed endpoint metadata. The owner-signed keychain and authorization operations are what create trust and capabilities.

Move A Blob Between Nodes

User story: as a mesh user, I want to address content by hash and let an authorized node fetch it over Iroh.

On the provider:

geth cas add ./archive.tar
geth node grant workstation resource:cas:local cas.fetch \
  --signing-key ~/.ssh/id_ed25519_sk

On the consumer, after peer cards and grants have synchronized:

geth cas fetch owner-laptop <blob-hash>
geth cas providers <blob-hash>
geth cas get <blob-hash> --out ./archive.tar

Success means the fetch reports the provider, cas providers records it, and the output hashes to the requested CAS hash. Remote fetch is Iroh-only and is checked against cas.fetch on resource:cas:local.

Synchronize Application State

User story: as a script author, I want small durable state primitives without building transport, peer authentication, and retry handling myself.

Start locally with one of:

geth kv create preferences
geth kv set preferences theme dark

geth document create settings
geth document set settings '{"theme":"dark"}'

geth db add inventory ./inventory.sqlite

geth cas root add notes ./notes
geth cas root scan notes

Grant the matching resource capability to a node, then use the module's sync command or geth sync now <node>. Check geth sync status --json for per-peer/per-stream cursors and retry state. File-root application is conservative: it does not overwrite local edits, and ambiguous changes become durable conflicts for geth cas conflict list.

Automate Reliably

User story: as an automation author, I want explicit homes, readiness checks, machine-readable output, and stable errors.

geth --home "$job_home" init
geth --home "$job_home" daemon run >"$job_home/daemon.log" 2>&1 &
daemon_pid=$!
geth --home "$job_home" wait daemon --timeout-ms 30000 --json
geth --home "$job_home" status --json

Use --json for single responses and --jsonl for streaming responses. A missing daemon returns the stable error code daemon_unavailable plus a startup hint. See automation-examples.md and command-stability.md before depending on experimental command families.

Diagnose, Back Up, And Recover

User story: as an operator, I want actionable local diagnostics and a backup that does not accidentally collect private trust anchors.

geth doctor
geth status
geth sync status
geth backup create --out ./geth-backup

doctor works even when the daemon is unavailable. Backups exclude daemon runtime files, private geth identity keys, and external private SSH admin keys. Restore always targets a separate empty home:

geth backup restore ./geth-backup --target-home ./restored-geth
geth --home ./restored-geth daemon run

Workflow Verification Coverage

  • CLI tests cover help discoverability, --home selection, initialization, daemon control, stable JSON errors, wait behavior, service-definition generation, and the owner/enrollment/sync path.
  • Two-daemon integration tests cover peer-card exchange, authorization denials, signed log import, CAS/KV/document/DB/file-root sync, pipe/pubsub, and restart behavior where practical.
  • Real user-service managers, hardware keys, real relays, TUN/Wintun privileges, and the full two-machine experience remain dogfood checks because automated tests must not mutate host services or require privileged hardware.

The real-machine acceptance checklist is in dogfood-checklist.md.