Running Hedgehog
This page takes you from a download to a running Hedgehog 0.0.8 node: where to get the program, how to
check it, how to start and stop it, and where it keeps its data. A 0.0.8 node joins the peer-to-peer
network, holds the signed network settings (Grid sporks) and serves the signed
legacy chain snapshot. Gridnodes, network storage, the ledger, the S3 endpoint, the
SOCKS proxy and the board keys spork are on the master branch and not part of a release yet; the tables
below mark what they add after 0.0.8. Of these, the next release, 0.0.9, turns on only the board keys
spork. A plain daemon runs none of the others and hides their options and commands from --help; the hidden
switch daemon --preview turns them on for development and testing, and the tables mark them with
--preview.
Download
Every file is on the 0.0.8 release page.
| Your computer | File | Needs |
|---|---|---|
| Linux, x86_64 | hedgehog-0.0.8-x86_64-linux-gnu.bin |
nothing else |
| macOS, Apple Silicon | hedgehog-0.0.8-osx-arm64.bin |
nothing else |
| Windows, x86_64 | hedgehog-0.0.8-win64.exe |
nothing else |
| Anything else, such as an Intel Mac | hedgehog-0.0.8-jar-with-dependencies.jar |
Java 25 or newer |
The executables carry their own Java runtime, see
Build, testing and native image. You do not download the legacy chain
snapshot yourself: a node fetches and checks it the first time it starts. On Linux and macOS, make the
executable runnable with chmod +x.
Check the download
Each release is signed by the Unigrid Foundation release key, whose public half is
release-key.asc in the
repository. Download SHA256SUMS and SHA256SUMS.asc from the release page next to your file, then run:
gpg --import release-key.asc
gpg --verify SHA256SUMS.asc SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
gpg reports a good signature, and warns that the key is not certified because you have not marked it as
trusted. That warning is expected. What matters is that the fingerprint it prints is
A1CB 0037 B3B9 2D59 5FA1 536C 95A9 8E88 8B0B A5D9
sha256sum then prints OK for your file. Every file also has its own .asc signature, so
gpg --verify <file>.asc <file> works as well. Where there is no sha256sum, compare the hash of your
file with its line in SHA256SUMS: shasum -a 256 <file> on macOS, and
certutil -hashfile <file> SHA256 on Windows.
Start a node
./hedgehog-0.0.8-x86_64-linux-gnu.bin daemon
With the jar, run java -jar hedgehog-0.0.8-jar-with-dependencies.jar daemon instead. The rest of this page
writes hedgehog for either form.
The first start of an executable unpacks its runtime into the data directory, which takes a moment. The node then:
- binds the peer-to-peer port and the REST port, see Open ports;
- dials the six seed nodes to find other peers, unless you pass
--no-seeds; - downloads and verifies the legacy chain snapshot in the background when it has none it can open, about
314 MB, and keeps serving everything else meanwhile. A download that fails, as when the network is not up
yet after a boot, is tried again for as long as the node runs without a snapshot: first after 10 seconds,
then after a pause twice as long as the one before, at most 10 minutes.
GET /statusreportsdownloadingwith a percentage,failedwith the reason between attempts, thenrunning, see REST interface.
A running node prints nothing by default. Add -v to see errors, and more of them for more detail:
| Flag | Shows |
|---|---|
| none | nothing |
-v |
errors |
-vv |
warnings as well |
-vvv |
progress messages as well, such as the snapshot download |
-vvvv |
debug output |
-vvvvv |
trace output |
Logging goes to the console only, there is no log file. Java may print a few WARNING lines about native
access when the node starts. They are harmless.
When a part of the node fails as the daemon starts, the daemon prints one line on standard error and exits
with code 1. When a server cannot listen on its address, as when the port is taken, the line names the
address, the server and the options that set the address, followed by what the system says, for example
Cannot listen on localhost:52884 for REST (--resthost, --restport): Address already in use, or
... for P2P (--nethost, --netport): ... for the peer-to-peer port. Any other failure prints its
innermost cause as <exception class>: <message>. The full trace is logged as an error,
The node failed to start, which -v shows.
Stop a node
Stop a node with hedgehog cli stop. It asks the running node to shut down over REST, and works from the
same computer without any setup.
Use it for the executables in particular. About a minute after the start, the launcher loses its hold on the program it started, which keeps running on its own, so interrupting the launcher afterwards does not stop the node.
Open ports
| Port | Used for | What to do |
|---|---|---|
| 52883, UDP | Other nodes, over QUIC | Allow inbound traffic if you want others to connect to you |
| 52884, TCP | The REST interface | Leave it on localhost, the default |
| 52885, TCP | The S3 endpoint, on by default with --preview |
Leave it on localhost, the default |
--socks-port, TCP, off by default |
The SOCKS proxy, with --preview; each UDP association gets a port of its own on the same address |
Leave it on 127.0.0.1, the default, as it checks no credentials |
The REST interface controls the node and its certificate is not verified by clients, so do not expose it
beyond the machine, see REST interface. Change the ports with --netport, --restport and
--s3port.
Options
These options go after the command, for example hedgehog daemon --no-seeds -vvv.
| Option | Default | Meaning |
|---|---|---|
-v, --verbose |
off | Raise the logging level, repeat for more |
-H, --nethost |
0.0.0.0 |
Address the peer-to-peer port binds to |
-p, --netport |
52883 |
Peer-to-peer port |
--no-seeds |
seeds on | Do not dial the seed nodes, --seeds turns them back on |
--netmaxinbound |
2000 |
Connections that all peers together may hold to this node at a time, 8 or more; only those that peers open count, not those the node dials and none from the loopback address. A seed, which every node dials, may need more; after 0.0.8 |
--network-keys |
the four foundation board keys | Replace the built-in board keys, comma-separated; they are the root of the chain of board keys, so every node and command on a network needs the same list |
--preview |
off | Turn on the parts of the node that the release leaves off, those marked with --preview; hidden from --help; after 0.0.8 |
--ledger, --ledger-genesis, --ledger-key, --ledger-trusted |
ledger off | Run the ledger, see Running a ledger node; with --preview |
-G, --gridnode |
not a gridnode | Run as a gridnode with the key pair in this file, as util key-generate prints it, see REST: gridnode; with --preview |
--announce-address |
the bind address | The host:port other nodes reach this gridnode on; with --preview |
--no-s3, --s3host, --s3port and more |
on, localhost, 52885 |
The S3 endpoint, see S3 endpoint; with --preview |
--socks-host, --socks-port, --socks-country, --socks-geoip |
127.0.0.1, 0 (off), any country, geoip/country.mmdb in the data directory |
The SOCKS proxy, see SOCKS proxy; with --preview |
-R, --resthost |
localhost |
Address the REST interface binds to |
-r, --restport |
52884 |
REST port |
--resttoken |
see below | Bearer token every REST request must carry |
-s, --snapshot |
bootstrap.dat in the data directory |
Snapshot file, for the bootstrap commands |
-h, --help |
Show the options of a command, without those marked with --preview |
|
-V, --version |
Print the version |
Without --preview, daemon refuses --ledger, -G and a --socks-port other than 0 before it starts,
with <option> is not part of this release, naming -G as --gridnode, and exit code 2. The other options
marked with --preview are taken and have no effect, so a node started with the S3 options still starts.
A --netmaxinbound below 8, or one that is not a whole number of at most 2147483647, is refused before the
node starts with a message that names the option and says Not 8 or more or '<value>' is not an int, and
exit code 2. While the node refuses new peers because the ceiling is reached, it logs a warning at most once
a minute, which -vv shows:
The ceiling of <n> inbound connections is reached, new peers are refused; a seed may need more: option --netmaxinbound.
An address other than the loopback address may hold at most 8 of these connections, and the node logs no
warning for a peer refused only for that.
The REST token is taken from --resttoken, then from the environment variable HEDGEHOG_REST_TOKEN, and
otherwise generated at each start into rest.token in the data directory. No configuration file is read.
The command line is the whole configuration.
Where the data lives
| System | Data directory |
|---|---|
| Linux | $XDG_DATA_HOME/hedgehog, by default ~/.local/share/hedgehog |
| macOS | ~/Library/Application Support/Hedgehog |
| Windows | %APPDATA%\Unigrid\Hedgehog |
| File or folder | Holds |
|---|---|
bootstrap.dat |
The legacy chain snapshot, about 556 MB |
snapshot-pid<process id>-<number>.part |
A snapshot that is being downloaded, moved into place as bootstrap.dat once verified; one whose process no longer runs is removed by the next download |
bootstrap-build-pid<process id>-<number>.tmp |
A snapshot that bootstrap import is building beside its target; one whose process no longer runs is removed by the next build |
spork.db |
The signed network settings the node has accepted |
spork.db.lock |
Held by a running node; a second node and util spork-db import refuse while it is held |
spork.db.unsigned-<epoch seconds> |
A copy of spork.db made before the node leaves out sporks it does not accept, such as one that no key that was ever a board key signed or one stamped ahead of its clock |
spork.db.unreadable-<epoch seconds> |
A spork.db that could not be read, moved aside before the node starts without it |
spork.db.<epoch seconds> |
A copy of spork.db made by util spork-db import before it installs another |
board-keys-<16 hex of the root>.seen |
The longest chain of board keys that a command on this machine verified, see Changing the board keys; after 0.0.8 |
board-keys-<16 hex of the root>.seen.lock |
Held while a command reads or writes the record beside it; after 0.0.8 |
rest.token |
The REST token, readable only by its owner |
gridnode-sealing.key |
The key a gridnode opens SOCKS proxy sessions with, made on its first start, readable only by its owner; with --preview |
geoip/country.mmdb |
A GeoIP country database you put there, which the SOCKS proxy finds the countries of gridnodes in; with --preview |
ledger/ |
The block log and sign state of the ledger, a folder for each chain, see Running a ledger node; with --preview |
s3data/ |
Buckets and objects of the local S3-compatible store of release 0.0.8 |
s3/ |
The index journal and root, the cache and the access keys of the S3 endpoint, see S3 endpoint; with --preview, in place of s3data/ |
| a folder named by a long hash | The unpacked runtime of an executable, safe to delete |
Deleting bootstrap.dat makes the next start download it again. A start also downloads it in place of a
bootstrap.dat that the node refuses to open: one that is cut off, of an older format, or signed by no key it
holds as a board key. The old file stays until the new one is verified. A bootstrap.dat that opens without
a signature, as one the operator built, is kept. On Linux, set XDG_DATA_HOME to keep the data somewhere
else.
Commands
A node is controlled with the same program. daemon runs it, and the commands below talk to a node that
is already running, or work on files.
| Command | What it does |
|---|---|
hedgehog cli stop |
Shut the node down |
hedgehog cli node-list, node-add <ip:port>, node-remove <ip:port> |
Show or change the peers the node knows, node-list prints JSON; a node added with node-add is configured and dialed again after a dial fails, see REST: peers |
hedgehog cli gridspork-list, gridspork-log, gridspork-pending |
Read the sporks, their signature history, and the changes awaiting a second signature |
hedgehog cli gridspork-get mint-supply\|mint-storage\|board-keys |
Read one spork; board-keys shows the epoch, the built-in keys, the chain and the keys active and inactive; with --preview also storage, ledger-blacklist, ledger-fee and communication |
hedgehog cli gridnode-start, gridnode-stop, gridnode-list |
Announce this node as a gridnode or stop, and list the gridnodes; with --preview |
hedgehog cli storage-put, storage-get, storage-delete |
Store a file on the network, read it back or delete it, see Network storage; with --preview |
hedgehog cli ledger |
Read the ledger, send coins, claim a legacy balance and vote, see Ledger command line; with --preview |
hedgehog s3 key create\|list\|delete |
Manage the access keys of the S3 endpoint, see S3 endpoint; with --preview |
hedgehog bootstrap info |
Show what the snapshot contains |
hedgehog bootstrap balance <address> |
Show the coins held by a legacy address |
hedgehog bootstrap history <address> |
List its transactions, with --limit (100 by default), --offset and --json |
hedgehog bootstrap fetch |
Download, verify and install the published snapshot, --force replaces an existing one |
hedgehog util key-generate |
Create a key pair |
hedgehog util board-keys propose, approve, apply |
Make a change of the board keys, approve it with a board key, or write it into a spork database file; after 0.0.8 |
hedgehog util spork-db validate\|sign\|import |
Check a spork database file, sign it again with board keys, or install it on this machine |
node-add prints the location of the node it added, followed for a node that a peer had told of by
The node was already known, as a peer told of it, and is configured from now on. For a node configured
before, it prints Conflict on standard error and exits with 1. For the node’s own address or one it cannot
use, it prints The node did not take <address>, which is its own address or one it cannot use and exits
with 1.
The commands marked with --preview are hidden from --help but still run. Those that talk to a node
started without the switch exit with 1, print one line on standard error and leave the node as it was:
storage-put,storage-get,storage-delete,gridnode-listand thecli ledgercommands print the node’s 503 with its reason, such as503 Service Unavailable: This release does not include the ledger part;gridnode-startandgridnode-stopprintGridnodes are not part of this release;gridspork-getandgridspork-setof thestorage,ledger-blacklist,ledger-feeandcommunicationsporks print503 Service Unavailable: This release does not take the <TYPE> spork, with the type in capitals such asLEDGER_FEE;gridspork-setwith--first-versionis refused withThis node takes no <TYPE> spork.
A change to a spork is signed on the machine of a board member: gridspork-set (the board keys among
them), gridspork-grow, gridspork-cosign and gridspork-renew take the board key from exactly one of
-k <hex>, --key-file <path> or $HEDGEHOG_BOARD_KEY, and never send it to a node. They are for the
board and are explained in Board instructions. A change of the board keys itself is
prepared with hedgehog util board-keys, see Changing the board keys. A spork
database is checked, signed again and installed with hedgehog util spork-db, see
Signing a spork database.
bootstrap import and bootstrap sign make a snapshot and are used when a release is prepared, see
Legacy chain snapshot; bootstrap sign judges its key by the longer of the chain
the release ships and this machine’s record of the board keys, and takes an optional --spork-db <file>.
Every cli command takes the --resthost, --restport and --resttoken options, so it can reach a node
on another machine given that node’s token.
A command exits with 0 when it is done, with 1 when the node or a check refused it, the node could not be
reached or there was nothing to act on, and with 2 when what it was given cannot be used, such as a malformed
option or a key file it cannot read. The executables exit with the same code. Among the lines a cli command
prints on standard error when it fails are:
- the status of the node’s answer, followed by the reason when the node gave one, such as
400 Bad Request: <reason>; Could not reach the node at <host>:<port>: <reason>when no answer came, also for an address that no request can be made to;The node answered something this command cannot read: <reason>when an answer came but could not be read;No REST token in <file>; is the daemon running? Otherwise pass --resttoken.when it was given no token and the daemon left none.
Running with Janus
Janus, the Unigrid desktop wallet, downloads and starts its own Hedgehog 0.0.8 and talks to it on port 52884 with a fresh token each time it runs, so it cannot use a node it did not start itself. Stop a node of your own before you open Janus, or Janus finds the port taken. The Janus troubleshooting page lists what it shows then.
Upgrading from 0.0.7
Nodes of 0.0.7 and earlier cannot talk to nodes of 0.0.8 or later, because the wire protocols went from
hedgehog/0.0.2 and gridspork/0.0.2 to hedgehog/0.0.4 and gridspork/0.0.4. The network keys were also
replaced, with one key per board member, so a spork a 0.0.7 build signed carries one signature of a key the
board no longer holds. A 0.0.9 node keeps from its spork.db only a spork that two different keys that were
ever board keys signed and co-signed, with a signature log that such keys signed: on its first start it
leaves out every spork of 0.0.7, after copying the file to spork.db.unsigned-<epoch seconds>, and logs one
warning for each type it drops.
The sporks come back through hedgehog util spork-db: one board member signs the copy with
spork-db sign --output <new file> and one current board key, a second member runs the same command on that
output with a different key, and spork-db import installs the result on one node. That node publishes the
sporks to its peers as first versions of the same data, and a first version takes the place of any other
first version by its time stamp. The mint storage entries at heights of the old chain stay as they are, as
history that chain paid. See Signing a spork database.
To upgrade, replace the program and start it again. The osx64.bin executable for Intel Macs of earlier
releases is gone: use the jar there.
Upgrading from 0.0.8
Nodes of 0.0.8 and 0.0.9 talk over hedgehog/0.0.4, but the board keys, vesting and storage sporks
travel only to a peer that agreed on hedgehog/0.0.9, hedgehog-proxy/0.0.2 or the ledger protocol, and
the communication and ledger sporks never reach a 0.0.8 node. A 0.0.8 node does not know the types of the
board keys and storage sporks, and reads the entries of the vesting spork without the three numbers they
have since gained. It refuses every spork signed by a key it does not know, so every node must be upgraded
before the board keys change. It also cannot read a spork.db that holds a board keys spork: it moves the
file aside as spork.db.unreadable-<epoch seconds> and starts without the sporks it held.
A 0.0.9 node has neither the local S3 store of 0.0.8 nor, without --preview, the S3 endpoint; it leaves
s3data/ as it is.
Key facts
| Version | 0.0.8, “Howling Husky” |
| Java | 25 or newer, only for the jar |
| Linux executable | about 94 MB |
| Peer-to-peer | UDP 52883 |
| REST | HTTPS 52884, localhost, bearer token |
| Release signing key | A1CB 0037 B3B9 2D59 5FA1 536C 95A9 8E88 8B0B A5D9 |
In the source
application/src/main/java/org/unigrid/hedgehog/Hedgehog.javais the root command and the-voption.application/src/main/java/org/unigrid/hedgehog/command/holdsdaemon,cli,util,bootstrapands3.application/src/main/java/org/unigrid/hedgehog/model/option/defines the options with their defaults.common/src/main/java/org/unigrid/hedgehog/common/model/ApplicationDirectory.javadecides the data directory.release.shandrelease-key.ascare how a release is signed.