Architecture overview

After 0.0.8. Gridnodes, their announcements, the storage service and the repair job are on the master branch and not in release 0.0.8. A 0.0.8 node finds peers, shares sporks and serves the legacy chain snapshot.

Hedgehog is the software that runs the Unigrid peer-to-peer network. Each computer that runs it becomes a node that finds other nodes, agrees with them on signed network settings and, on gridnodes, helps store files that its users can retrieve later. One program does all of this, so anyone can run a node, operate it from the command line, or build on top of it.

What a node does

  • Joins the network. A node connects to other nodes over QUIC, an encrypted transport built on UDP. It starts from six seed hosts and learns more peers from the ones it meets. See Peer-to-peer network protocol.
  • Shares network settings. Parameters such as the maximum supply and the storage layout travel as sporks, small records signed by the Unigrid Foundation’s keys. A change takes effect only when two different foundation keys have signed it, and nodes pass accepted changes on to their peers without a voting round. See Grid sporks.
  • Stores files. A file is encrypted, split into small erasure-coded fragments and spread over the gridnodes, which repair lost fragments among themselves while the owner is offline. The network keeps no index of files, and only the holder of a file’s fingerprint can read or delete it. See Network storage and Erasure coding.
  • Takes commands. A local REST interface lets an operator inspect and steer the node, and the hedgehog cli command is a thin client of that interface. See REST interface.
  • Reads the legacy chain. The hedgehog bootstrap commands turn the foundation’s older chain data into a signed snapshot that anyone can verify. See Legacy chain snapshot.

How it fits together

The same program becomes a daemon, a client or a key utility depending on the command it is given.

flowchart LR
    OP["Operator<br/>hedgehog cli ..."] -->|"HTTPS + token"| REST
    subgraph NODE["hedgehog daemon: one process"]
        REST["REST server"]
        P2P["Peer-to-peer server"]
        TOP["Known peers"]
        SP["Sporks, saved to disk"]
        ST["Storage service"]
        REST --> TOP
        REST --> SP
        REST --> ST
        P2P --> TOP
        P2P --> SP
        P2P --> ST
    end
    P2P <-->|"QUIC"| PEERS["Other nodes and seeds"]
  • hedgehog daemon starts the node and keeps it running. On shutdown it saves the spork database to disk.
  • hedgehog cli talks to a running daemon through the REST interface and never joins the peer network itself.
  • hedgehog util generates, signs with and validates keys without needing a daemon.
  • hedgehog bootstrap builds and queries the legacy chain snapshot.

Three Maven modules make up the project: application holds nearly everything, common holds only the version and data-directory helpers, and native-image wraps the program and a Java runtime into one executable. The component wiring and startup order are described in CDI container and component lifecycle, and the build and test tooling in Build, testing and native image.

Trust

  • Network settings are authenticated. A node accepts a spork only with two different signatures from the network keys it trusts. The four built-in keys belong to the Unigrid Foundation board and can be replaced with --network-keys, which is how a private network is set up.
  • The control interface is local and needs a token. The REST server listens on localhost by default, and every request must carry a bearer token that the daemon writes to rest.token in its data directory.
  • Transport encryption does not identify the other side. Both the peer and the REST connections use self-signed certificates that the bundled clients accept without checking, so they protect against eavesdropping but not against an active attacker in the middle.

Key facts

Fact Value
Language and runtime Java 25
Peer-to-peer port 52883 over UDP, bound to all interfaces (-p, -H)
REST port 52884 over HTTPS, bound to localhost (-r, -R)
Seed hosts seed1 to seed6 at unigrid.org; --no-seeds turns them off
Wire protocols hedgehog/0.0.4 and gridspork/0.0.4
Change signed by one key Expires after 60 minutes unless a second key co-signs it
Gridnode announcement Renewed every 5 minutes
Storage sizes 1 MiB chunks cut into 64 KiB fragments, the storage spork defaults
Largest REST upload 1 GiB, set with --restmaxupload
Data directory on Linux ~/.local/share/hedgehog, holding spork.db, rest.token and s3data/

In the source

All paths are relative to the repository root.

  • application/src/main/java/org/unigrid/hedgehog/Hedgehog.java, the entry point and root command
  • application/src/main/java/org/unigrid/hedgehog/command/, the daemon, client, key and bootstrap commands
  • application/src/main/java/org/unigrid/hedgehog/server/p2p/P2PServer.java, the QUIC server
  • application/src/main/java/org/unigrid/hedgehog/server/rest/RestServer.java, the REST server
  • application/src/main/java/org/unigrid/hedgehog/model/network/Topology.java, the known peers
  • application/src/main/java/org/unigrid/hedgehog/model/spork/, the signed network settings
  • application/src/main/java/org/unigrid/hedgehog/service/storage/StorageService.java, the storage entry point