ZooBC wiki
Proof of Participation

The draw: who makes the next block

In Proof of Participation nobody races to make a block. For every new height, a random draw over the node registry names the producers in order: the first draw names the producer of round 1, the second the producer of round 2, and so on. Every node runs the same draw on the same data and gets the same list, so every node knows who may make the next block and refuses a block from anyone else.

A lottery that everyone can repeat

A fair draw needs randomness that nobody controls and that everybody can reproduce. ZooBC takes it from the previous block. Every block carries a 64-byte seed, a value its producer cannot choose (see block seed (VRF)). The seed starts a pseudo-random number generator, and each number the generator yields picks one entry from the list of nodes that may be drawn.

Because the seed of a block exists only once that block exists, nobody knows the order for the following block in advance: the order is normally known only one block ahead. (An attacker holding many seats can occasionally see further; see block seed (VRF).) And because every node holds the same previous block and the same registry, every node computes the same list. There is no puzzle to solve, no published rota and no coordinator.

The previous block's seed is hashed with the tag zbc-blocksmith and drives a generator that names the producer of each round; every node computes the same list.
The previous block's seed is hashed with the tag zbc-blocksmith and drives a generator that names the producer of each round; every node computes the same list.

The list that is drawn from

The draw picks from the selectable set:

  • the active registry as of the previous block, that is, the admitted (registered) nodes; queued nodes are not in it;
  • ordered by node id, from lowest to highest (a node's id is taken from the first 8 bytes of its node key);
  • minus every node with a suspension in force (see missed turns, suspension and expulsion). If removing them would leave nobody, the whole active set is used instead.

If every active node is suspended, the best queued node that has kept up its attendance is added as a resume candidate (see queue), so that the chain can always restart; a block from it admits it at once.

Blocks are judged strictly against the registry as of the previous block, with no fallback to any other height. A block from a node that was not drawn for its round is refused by every node.

The generator

The exact recipe, which every implementation must follow bit for bit:

h = SHA3-256("zbc-blocksmith" ‖ seed of the previous block)
v = bytes 24 to 31 of h, read as a big-endian 64-bit number
Splitmix64(v) seeds a xoroshiro128+ generator
each draw: r = the next non-negative 63-bit number
the draw names entry (r mod n) of the selectable set, n = its size

Draw 1 names the round-1 producer, draw 2 the round-2 producer, and so on (see rounds, timing and windows). The draws are independent, so the same node can be named more than once in one list.

The tag zbc-blocksmith keeps this draw apart from the other random choices taken from block seeds, each of which uses its own tag: zbc-coinbase for the coinbase lottery, zbc-receipt and zbc-receipt-datum for receipts and the network topology, zbc-topology-v2 for the peer topology and zbc-apps for apps on ZooBC.

Every seat has the same chance

Each draw picks every entry of the selectable set with the same probability. Nothing else enters: not the node's hardware, not its owner's balance, not its stake, and not its participation score. An operator who holds 3 of 30 active seats makes about one block in ten.

This is the first design goal of Proof of Participation: uniform block-producing power. The only way to more power is more seats, and seats come only through the queue, one admission at a time, at a pace the protocol sets (see admission pace). Keeping the score out of the draw is deliberate: a high-scoring node earns more, but it makes no more blocks, chooses no more seeds and has no more chances to leave transactions out.

Two refinements

See also