Grid sporks

After 0.0.8. The storage spork, type 1030, is on the master branch and not in release 0.0.8, which has the mint storage, mint supply, vesting storage and statistics key sporks.

A grid spork is a small, signed settings record that every node on the Unigrid network holds and passes on to its peers. Sporks let the network’s key holders change shared parameters, such as the maximum coin supply or the rules for network storage, on every node at once, without a software release and without a consensus round. A node accepts a change only if two different trusted keys signed it, so no single key can alter the network on its own.

What a spork holds

Each spork has a type, a current value, the previous value, a timestamp and the signatures that authorise it. A node keeps at most one spork of each type.

Type Id What it carries
Mint storage 1000 Amounts credited to an address at a chain height, see Legacy chain snapshot
Mint supply 1010 The network’s maximum supply
Vesting storage 1020 Vesting schedules per address: amount, start, duration and number of parts
Storage 1030 The parameters of Network storage, such as chunk size and repair interval
Statistics public key 2001 The public key of the statistics service the network trusts

Hedgehog stores and distributes the vesting schedules but does not calculate any releases from them.

Who may change a spork

Trust comes from a short list of public keys, the network keys. The default of the --network-keys option is the four board-member keys, and an operator can override it on the command line. Three older foundation keys are kept as retired keys: they can no longer approve anything, but they let a spork’s history name who signed earlier versions.

Signatures use ECDSA with SHA-512 on the P-521 curve. A change needs two of them, from different network keys, and both cover exactly the same bytes: the type, flags, both timestamps, the current and previous values and the signature history described below. Those bytes are the spork’s own wire encoding, so a node that receives a spork from a peer checks exactly what the signer signed.

How a change travels

A change starts as a proposal signed by one key. A second key co-signs it, which turns it into an accepted spork. Both steps use the node’s REST interface or the hedgehog cli commands (gridspork-set, gridspork-pending and gridspork-cosign among them), and each request proves ownership of the signing key. See REST interface for the endpoints.

sequenceDiagram
    participant A as Board member A
    participant B as Board member B
    participant N as Node
    participant P as Peers
    A->>N: propose a new value, signed with key A
    N->>P: publish the proposal
    Note over N,P: every node holds it for up to 60 minutes
    B->>N: co-sign with key B
    N->>N: check both signatures and the history, store
    N->>P: publish the accepted spork
    P->>P: check, store and pass on

Peers pass on only what they have not seen before, so a spork spreads through the network and then stops. Nodes also publish their stored sporks to each peer every three minutes and whenever a connection comes up, which is how a node that was offline, or is new, catches up. The transport is described in Peer-to-peer network protocol.

When a replacement is accepted

A node replaces the spork it holds only when the incoming one meets all of these conditions:

  • it is newer than the stored spork;
  • it is signed by two different current network keys;
  • it carries the stored spork’s signature history unchanged, with new entries added at the end;
  • every new history entry is validly signed by a known key.

Each new version records a signed fingerprint of the version it replaced and the keys that signed it. The fingerprints are chained, so removing or rewriting an earlier entry breaks the current signatures. The history can be read with gridspork-log.

When the network keys change, sporks signed with the old keys stop verifying on upgraded nodes. A one-off renewal, gridspork-renew followed by gridspork-cosign, re-signs everything a node holds with the new keys and keeps the history.

Key facts

Item Value
Signatures needed Two, from different network keys
Default network keys Four board-member keys, plus three retired keys used for history only
Algorithm ECDSA, SHA-512, P-521 (secp521r1)
Proposal lifetime 60 minutes from its timestamp, held in memory only
Publish and save interval Every 3 minutes
Stored in spork.db in the user data directory
Default network port 52883 (--netport)

In the source

  • application/src/main/java/org/unigrid/hedgehog/model/spork/GridSpork.java: the base type and the acceptance rules
  • application/src/main/java/org/unigrid/hedgehog/model/spork/PendingSporks.java: proposals waiting for a second key
  • application/src/main/java/org/unigrid/hedgehog/model/spork/SignatureLog.java: the signature history
  • application/src/main/java/org/unigrid/hedgehog/model/crypto/NetworkKey.java: which keys are trusted
  • application/src/main/java/org/unigrid/hedgehog/model/network/handler/PublishSporkChannelHandler.java: receiving sporks
  • application/src/main/java/org/unigrid/hedgehog/model/network/schedule/PublishAndSaveSporkSchedule.java: the periodic publish
  • application/src/main/java/org/unigrid/hedgehog/server/rest/GridSporkResource.java: co-signing and renewing over REST