REST interface

After 0.0.8. The gridnode endpoints, file storage through /storage with its 64 GiB limit, the storage settings spork, the communication spork and the /ledger endpoints are on the master branch and not part of a release yet. Release 0.0.9 answers them with 503 unless the node runs with the hidden --preview switch, which turns on the parts the release leaves off.

A running Hedgehog node can be controlled and queried over HTTPS, on a port separate from the one it uses to talk to other nodes. Operators use it to read the network settings the board maintains, to inspect and edit the node’s list of peers, to start or stop a gridnode, and to store and retrieve files on the network. The hedgehog cli command is simply a client of this interface, so everything it can do, any other program can do as well.

The endpoints

The endpoints are grouped by purpose, and each group has a page where every endpoint has a heading of its own with its parameters, answers and fields.

Page Endpoints For
Grid sporks /gridspork Read the network-wide settings described in Grid sporks, see who signed each change, list proposals, and hand a signed spork in and out in wire form
Peers /node List the nodes this node knows about, and add or remove one
Gridnode /gridnode Start or stop announcing this node as a gridnode, list the known gridnodes and read the collateral
File storage /storage Store a file and get back a fingerprint, then read or delete it with that fingerprint
Legacy chain /bootstrap The balance and the dated history of a legacy address, from the legacy chain snapshot
Ledger /ledger Read the state of the node’s ledger, an account or a legacy address and any block, and send in a signed transaction
Node control /height, /status, /version, /stop The height, the download status of the snapshot, the version and protocols, and shutting the node down

How it works

The node runs an HTTPS server next to its peer-to-peer listener. Each request passes a token check first and is then handed to the matching resource, which reads or changes the same state the rest of the daemon uses. For how this listener fits with the other parts of the daemon, see Architecture overview.

flowchart LR
    A[HTTPS request] --> B[Bearer token check]
    B --> C[Resource class]
    C --> D[Daemon state<br/>sporks, peers, storage]
    D --> E[JSON response]

Authentication. Every request must carry the header Authorization: Bearer <token>, including requests for paths that do not exist. The token is taken from --resttoken or the environment variable HEDGEHOG_REST_TOKEN. When neither is set, the node generates a random token at each start and writes it to a file named rest.token in its data directory, readable only by its owner, so a hedgehog cli on the same machine works without configuration. A client on another machine passes the token explicitly. The token is checked as soon as the head of a request arrives: a request without it is answered with 401 before any of its body is read, and its connection is closed.

Parts the release leaves off. The /gridnode, /storage and /ledger endpoints stay registered, but a node run without --preview answers each of them with 503 and a plain-text reason, such as This release does not include the ledger part, once the token is checked and before the resource does anything. A path that does not exist still gets 404, and a method a path does not take 405. The sporks of those parts answer 503 the same way, see REST: grid sporks.

OPTIONS. The server answers an OPTIONS request by itself, without the resource, once the token is checked, on the paths of the parts left off as well. It answers 200 with the methods of the path in an Allow header and as a plain-text list in the body: OPTIONS on every path, and HEAD where the path takes GET. The server describes no resource: /application.wadl answers 404, and an OPTIONS request that asks for application/vnd.sun.wadl+xml gets the Allow header and an empty body.

Encryption. The server uses a self-signed certificate created at each start. The bundled client accepts any certificate, so the connection is encrypted but the server is not authenticated. For this reason the interface listens on localhost by default and should be exposed beyond it only with that in mind.

Spork changes are signed by the board, not the node. The wire endpoints hand out a stored spork or a proposal in the form peers exchange, and take a signed spork back. A board member’s command fetches the wire form, checks it, shows what the change sets, signs on its own machine with a key from -k, --key-file or $HEDGEHOG_BOARD_KEY, and posts the signed spork. The node checks the signatures and the signature history as it checks a spork from a peer. The board key never reaches the node. A change over a stored spork is held as a proposal until a second board key has co-signed it, and only then is it stored and published to the network.

Uploads. File storage through /storage accepts files up to the limit in the table below and streams them, so a large file does not need to fit in memory. The fingerprint returned on upload is the only key to the file and is sent in a header rather than in the URL.

Body limits. The server bounds every request body before a resource reads it: 1 MiB on every path but a signed spork and the storage uploads. A signed spork posted to /gridspork/wire may be up to the 16 MiB a peer may send. The storage uploads take up to 64 GiB. A body above its limit is answered with 413. A body of any other path that is not complete within 30 seconds is answered with 408. A refused request, whether 401, 413 or 408, is answered with Connection: close. Its connection is closed two seconds later, so that the sender can still read the answer, and whatever the sender sends in the meantime is dropped. POST /ledger/transaction sets a lower limit of its own, see REST: ledger.

Idle connections. A connection has 30 seconds for the head of its next request to arrive. The time counts from when the connection opens, and again from when the last request has ended and its answer is written out. A sender that sends nothing on a new connection, or does not finish the head of a request in time, is answered 408 with {"error":"A request has to arrive within 30 seconds"} and its connection is closed. A kept-alive connection that has sent nothing since its last request is closed after 30 seconds without an answer. The time a resource takes to answer a request that has arrived whole is not counted.

Key facts

Item Value
Protocol HTTPS with a self-signed certificate
Default address localhost, port 52884 (options --resthost, --restport)
Authentication Bearer token on every request (--resttoken, HEDGEHOG_REST_TOKEN or rest.token)
Largest request body 1 MiB, 16 MiB (16,777,216 bytes) on POST /gridspork/wire, 64 GiB on /storage; 413 above it
Spork signing On the machine of a board member; the node checks both signatures and the key never reaches it
Time to send a body other than an upload 30 seconds, then 408
Time for the head of a request 30 seconds from the connection opening or from the last answer; then 408, or a close without an answer on a kept-alive connection that has sent nothing
Data format JSON; the wire form of a spork and the files of /storage in application/octet-stream
Protocol names reported by /version hedgehog/0.0.9, hedgehog/0.0.4, gridspork/0.0.4; with --preview hedgehog-proxy/0.0.2 ahead of them, and hedgehog-ledger/0.0.2 first with --preview --ledger
Parts left off /gridnode, /storage and /ledger answer 503 without --preview, except to OPTIONS

In the source

  • application/src/main/java/org/unigrid/hedgehog/server/rest/RestServer.java: starts the HTTPS listener and lists every resource class.
  • application/src/main/java/org/unigrid/hedgehog/server/rest/BearerTokenFilter.java: the token check.
  • application/src/main/java/org/unigrid/hedgehog/server/rest/RequestBodyLimit.java: the body limits, the time a request has to arrive, and the 401, 413 and 408 answers.
  • application/src/main/java/org/unigrid/hedgehog/server/rest/PreviewPartFilter.java and PreviewPart.java: the 503 answer of the endpoints of the parts left off.
  • application/src/main/java/org/unigrid/hedgehog/model/option/BoardKeyOptions.java: the three sources of the board key and their messages.
  • application/src/main/java/org/unigrid/hedgehog/model/option/RestOptions.java: the command-line options.
  • application/src/main/java/org/unigrid/hedgehog/client/rest/RestClient.java: the client the CLI uses.
  • application/src/main/java/org/unigrid/hedgehog/command/CLI.java: the hedgehog cli subcommands.

The resources of each group are listed on its page.


Table of contents