• v0.3.0 e0ab965755

    agorise released this 2026-09-11 19:46:39 +00:00 | 13 commits to main since this release

    hidden-rpc v0.3.0

    A node that went down and stayed down was the whole problem. This release is
    about making that impossible — and about a node that stops eating the machine it
    lives on.

    Nothing about your addresses, your chain data or your setup changes. Re-run the
    installer on each node and it picks all of this up.

    Why nodes were going dark and staying dark

    Four separate mechanisms, each found in the v0.2.1 code rather than guessed at:

    • DEGRADED was a dead end. Once a transport used up its restart budget, the
      supervisor kept probing it but never repaired it again. The only way back
      was a recovery that happened on its own. Any node that reached this state was
      off the network until a human walked over to it.
    • "The node is down" meant "do nothing", forever. When the chain daemon
      stopped answering, the supervisor correctly refused to restart Tor and I2P —
      and then stopped there. Nothing in the system ever restarted blurtd, its
      container, or Docker.
    • Repairs were never checked. On Linux Mint, tor.service is a wrapper whose
      start command is literally /bin/true, so restarting it can report success
      while the real daemon stays dead. And after five quick failures systemd latches
      a service into a permanent failed state that refuses every further restart until
      someone runs reset-failed — which nothing ever did, including for the
      supervisor itself. Self-healing could be switched off by a single bad minute.
    • The replay flag was pinned forever. A node set up from the block_log kept
      --replay-blockchain in its container command permanently, so every reboot
      re-ran a multi-hour replay. Which looks exactly like "it went down and never
      came back".

    What's new

    • The supervisor now owns the whole node, not just the two transports: the
      chain daemon, the container, the container runtime, the clock, the disk and the
      power settings. A stopped node is started; a missing container is rebuilt from a
      saved spec; a node whose head block has frozen is treated as wedged and
      repaired; a dead Docker is restarted.
    • DEGRADED is now a slow retry, never a grave. It deep-repairs and tries
      again on a doubling backoff (15m → 30m → 60m) for as long as the machine has
      power. Restart thrash is still capped.
    • Every repair is verified. After a restart the supervisor checks that the
      unit really is active with a live process, that the proxy port answers, and that
      the address still exists — and escalates if not. It resolves the real Tor unit
      at runtime instead of trusting a name guessed at install time, and runs
      reset-failed before every restart.
    • Deeper repairs for the failures restarting can never fix: a torrc that lost
      its hidden-service stanza (put back, verified with tor --verify-config, rolled
      back if it would break Tor), an i2pd tunnel file reverted by a package upgrade
      (now written to tunnels.conf.d, where upgrades cannot touch it), and missing
      hidden-service keys (restored from a local backup, so your .onion and
      .b32.i2p survive a purge or a bad restore).
    • Reboots are boring now. The replay flag is removed automatically as soon as
      a node proves it is serving; a new shutdown unit gives the blockchain the full
      time it needs to save itself before Docker goes away, so there are no more dirty
      shutdowns and no surprise replays; and everything is enabled to come back on its
      own. Move a node to another room whenever you like.
    • Laptops stay awake. Suspend, hibernate and the lid switch are disabled at
      the systemd level, where no desktop power setting can override them. If a
      machine does sleep anyway, waking up triggers an immediate full re-check.
    • A controlled reboot as the genuine last resort — only when every transport
      is down, only after two hours of failed repairs, never during a replay, never
      just after booting, at most once a day, and always after stopping the blockchain
      cleanly. Set ALLOW_REBOOT="0" in /etc/hidden-rpc/supervisor.conf to forbid it.

    A much lighter node

    Full detail, with measurements and the trade-offs, in docs/FOOTPRINT.md.

    • No more permanent replay. This was the single largest CPU cost in the fleet,
      and it is gone.
    • The supervisor went from ~104,000 processes a day to roughly 7,000. Its idle
      loop no longer spawns anything at all: it reads /proc with shell builtins
      instead of shelling out to ip, awk, cksum, date and sed several times
      every five seconds. Measured, 200 runs: 5.23 ms → 0.54 ms per network check.
    • Tor circuits cut by ~80%. Health self-dials relax from every 60s to every
      5 minutes once a transport has been steady for half an hour, and snap back
      instantly on any network change, wake-up or failure.
    • I2P stops relaying strangers' traffic. Stock i2pd accepts transit tunnels;
      on a ten-year-old laptop that is the biggest ongoing CPU and bandwidth cost the
      node carries, for no benefit to its own reachability. Now notransit = true,
      with the distro's always-on IRC tunnel switched off too. Your own .b32.i2p
      server tunnel is unaffected.
    • blurtd's web thread pool 256 → 16 (Blurt's own default is 32) and fewer p2p
      connections with a smaller sync prefetch. Neither needs a replay.
    • Optional --headless stops the desktop on a node nobody looks at, freeing
      RAM and the GPU. Reversible with --desktop.

    New commands

    hidden-rpc-status                  # everything: node, reachability, self-repairs, host
    hidden-rpc-status --watch          # live progress, one calm line
    sudo hidden-rpc-nodectl stop       # stop a node safely before unplugging or moving it
    sudo hidden-rpc-nodectl start      # and back on again
    ./installer/hidden-rpc-setup.sh --doctor    # check and repair everything, right now
    

    hidden-rpc-nodectl stop also turns maintenance mode on, so the supervisor leaves
    the node alone while you work; start turns it back off. A node can never be left
    quietly un-supervised. hidden-rpc-transport-status still works and shows the
    transports-only view.

    Upgrading

    Re-run the installer on each node (safe anytime, never harms a node):

    bash installer/hidden-rpc-setup.sh
    

    On a node that is currently pinned to the replay flag, this removes it with one
    short restart — after which reboots take minutes instead of hours. Your
    /etc/hidden-rpc/supervisor.conf is kept as you have it; only the new settings
    this version adds are appended.

    To fix a node without a full installer run: hidden-rpc-setup.sh --doctor.

    Minimum requirements

    • A standard 64-bit PC (amd64), Linux Mint or Ubuntu, Docker-capable.
    • About 90 GB free for a first-time trustless setup.
    • Wired Ethernet is strongly recommended. In this fleet, Wi-Fi connects
      successfully around 50% of the time versus 100% for Ethernet.

    Testing

    Both suites run anywhere, with no Tor, I2P or Docker needed:

    bash supervisor/tests/fsm-sim.sh    # state machine + policy  -> ALL FSM TESTS PASSED
    bash supervisor/tests/heal-sim.sh   # the repairs themselves  -> ALL HEAL TESTS PASSED
    

    heal-sim.sh drives the repair code against fake systemctl and docker
    commands that reproduce the real traps: the /bin/true Tor wrapper, systemd's
    start limiter, a pinned replay flag, and unless-stopped. The hardware scenarios
    are in docs/SELF-HEALING.md.

    Downloads