Skip to content

solarpunkgirl/vesta

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vesta

A thought experiment inspired and motivated by the concepts of permacomputing, community resilience, and library/gift economies.

Vesta is a federated compute daemon for small, trusted networks of personal machines. Run vestad on two or more machines and they form a shared resource pool. CPU-bound and memory-bound workloads route automatically to whichever node has the most spare capacity. When a node is saturated, work spills to peers. Large jobs split across multiple nodes and run in parallel.

No container runtime, no root, no cloud account. Three static binaries.

  desktop                           pi4
  vestad (8 cores)  <-- LAN -->  vestad (4 cores)
     |                               |
  vesta submit cpu 500       auto-splits across both

What it does and does not do

Does: route self-contained batch jobs (hashing, memory allocation, shell commands) to the node with the most spare capacity. When you submit a job, the daemon measures real /proc/stat CPU load and /proc/meminfo availability across all peers and places the work accordingly. If the best node is overwhelmed mid-job, a future submission goes elsewhere; no manual targeting.

Does not: transparently share CPU or RAM between running processes. A compile running in your shell stays on your machine. Only workloads explicitly submitted through vesta participate in the pool.

Binaries

Binary Purpose
vestad Daemon: one per machine. Discovers peers, runs jobs, serves the control socket.
vesta CLI: submit jobs, query status, stress-test routing.
vestatop Live monitor: htop-style view of all nodes, real CPU/RAM bars, active flows.
piwork Example workload: Monte Carlo Pi estimator, demonstrates real federated compute.

Quick start

1. Start the daemon on each machine with the same key

# desktop:
./vestad -name desk -key "your-shared-secret-here"

# Pi (over SSH):
./vestad -name pi4 -key "your-shared-secret-here"

Defaults: TCP 7777 (peer protocol), UDP 7778 (discovery). Nodes on the same subnet find each other automatically within about 5 seconds.

For cross-subnet or VPN peers, add -seed <other-ip>:7778 on each side.

2. Verify discovery

./vesta peers

Both nodes should appear within a few seconds. If not: same -key? Same subnet? Check that UDP 7778 is not blocked by a firewall.

3. Submit work to the pool

./vesta cpu 200        # 200M SHA-256 iterations, routed automatically
./vesta mem 512 5000   # hold 512 MiB for 5 seconds, routed automatically

The daemon checks live CPU load and picks the best node. If the local machine is loaded, the job goes to a peer. If two or more nodes are viable and the job is large enough, it splits across them in parallel.

4. Watch it happen

./vestatop

You can see the CPU bars on the receiving node jump when a job arrives, and active flows show which node is lending to which.

5. Run a real federated computation

# Submit 500M iterations to the whole federation
./vesta cpu 500

# Stress the local machine first so the job spills to a peer
./vesta stress 0 30        # pin all cores for 30 seconds
./vesta cpu 200            # will route to the idle peer
./vesta stop-stress        # cancel early if you want

The piwork binary is a self-contained Monte Carlo Pi estimator that makes federated routing visible:

./vesta exec -- ./piwork 100

The result includes the hostname of the machine that ran it. When the submitting node is saturated, piwork runs on the peer and the output -- with the peer's hostname; appears in your terminal.

Configuration

Flags on the command line cover the common case:

vestad -name NAME -key SECRET [-port 7777] [-dport 7778]
      [-allow-exec] [-power auto|grid|solar|battery]
      [-seed host:port,...] [-advertise-spare MS]
      [-config path/to/node.json]

For more control, use a JSON config file. See config.example.json for all fields with explanations.

Key configuration options

Field Default Notes
cpu_offer_pct 75 Percentage of cores offered for lending
mem_offer_mb 1024 Hard cap on RAM offered in MiB
reserve_pct 20 Kept for local use, never lended
spill_cpu_pct 80 CPU% at which jobs spill to peers
allow_exec false Permit peers to run shell commands
exec_allowlist [] If non-empty, only these commands are allowed
max_borrow_ratio 5 Leeching cap: max borrow without contributing
battery_min_pct 15 Stop lending below this battery charge

Fairness

Each node tracks what it has lended and borrowed per peer (see vestad-ledger-*.json). New peers start with a goodwill floor and can borrow freely up to max_borrow_ratio * goodwill without contributing anything. Once they have contributed even a little, they're treated as full participants. Nodes that never lend are eventually capped.

vesta status and vestatop show each node's ledger balance so you can see whether the exchange is roughly equal over time.

Energy-aware lending

On battery-powered nodes (laptops, Pi with UPS), vestad reads /sys/class/power_supply and scales back how much it offers:

  • Grid/charging: lends at 100% willingness
  • Discharging, charge >= 50%: "solar" mode, lends proportionally to charge
  • Discharging, charge < 50%: 35% willingness
  • Charge < battery_min_pct (default 15%): stops lending entirely

Override with -power grid|solar|battery to force a specific mode.

Shell command execution

Off by default. To allow peers to run arbitrary commands on your node:

vestad -name mynode -key SECRET -allow-exec

With an allowlist (recommended if you enable exec):

{
  "allow_exec": true,
  "exec_allowlist": ["make", "ffmpeg", "python3"]
}

The allowlist matches against both the basename and full path of argv[0], so listing "make" will permit /usr/bin/make as well as ./make.

Warning: nodes that can reach your vestad with the correct key can run any permitted command. Only enable exec in a federation of machines you fully control and trust.

Security

All inter-node traffic is AES-256-GCM encrypted. The federation key is the membership credential. Anyone with the key can submit jobs to any node, so treat it like a password: long, random, and not reused elsewhere.

What the encryption covers:

  • All peer-to-peer job traffic (TCP, AES-256-GCM)
  • All discovery beacons (UDP, AES-256-GCM)

What it does not cover:

  • The lender can see the contents of any job it runs. For a network of your own machines this is expected. For untrusted federations, hardware TEE support (AMD SEV-SNP, Intel TDX) would be required; this is on the roadmap.
  • The control socket (/tmp/vestad-NAME.sock) is restricted to the owner (mode 0600) but trusts any local process running as the same user.

Node identity files (vestad-identity-*.json) are written with mode 0600.

Building from source

cargo build --release -p vestad -p vesta -p vestatop -p piwork

Cross-compiling for Raspberry Pi (aarch64)

rustup target add aarch64-unknown-linux-gnu
cargo install cargo-zigbuild
sudo dnf install zig    # Fedora/RHEL
# or: sudo apt install zig

cargo zigbuild --release --target aarch64-unknown-linux-gnu \
    -p vestad -p vesta -p vestatop -p piwork

Binaries land in target/aarch64-unknown-linux-gnu/release/. Run ./build.sh to build all targets (amd64, arm64, armv7) at once.

Codebase layout

src/
  lib.rs        crate root and re-exports
  proto.rs      wire protocol types (Budget, NodeStatus, Job, JobResult, Msg)
  crypto.rs     AES-256-GCM cipher derived from the federation key
  wire.rs       length-prefixed sealed TCP framing
  identity.rs   Ed25519 keypair and node fingerprint
  config.rs     Config struct, JSON loading, name sanitization
  sysstat.rs    Linux /proc and /sys readers (CPU, memory, power, GPU, thermals)
  ledger.rs     per-peer reciprocity accounting, persistence
  peertable.rs  in-memory peer discovery table
  discovery.rs  UDP beacon broadcast and listener
  executor.rs   job runner (cpu, mem, gpu, exec)
  autopilot.rs  routing logic and distributed job splitting
  daemon.rs     daemon core, TCP/Unix accept loops, job dispatch
  control.rs    CLI-side Unix socket client

vestad/          daemon binary entry point
vesta/           control CLI
vestatop/        live terminal monitor
piwork/         example federated workload (Monte Carlo Pi)

Project status

This project is released as-is. I will look at pull requests occasionally and may merge ones that are clearly correct and self-contained, but I have little interest in maintaining this long term.

If you want to take it further, please fork it. The codebase is small and self-contained by design, so a fork is easy to own. It also makes a reasonable exercise if you want to learn Rust systems programming, distributed protocols, or federated network design.

License

GNU Affero General Public License v3.0 or later. See LICENSE.

The AGPL requires that if you run a modified version of this software on a server and allow others to interact with it over a network, you must make the corresponding source code available to those users.

About

federated compute daemon

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors