ZooBC wiki
Proof of Participation

Double-signing (equivocation)

Equivocation, or double-signing, means that one producer signs two different blocks on the same parent block. Different nodes could then see different blocks first, and the network could split for a while. ZooBC handles it in three ways: an honest node never does it, even after a crash; any registered node that sees two such blocks can prove it on the chain with an EquivocationReport; and the producer is charged a missed turn, with the loss of income and score that follows.

What counts as equivocation

When a node is drawn to produce, it builds one block on top of the current tip, its parent. Equivocation is signing two blocks with different headers over that same parent. A late block is not equivocation: it only adds less weight to its branch (see fork choice and cumulative difficulty). Making blocks at different heights is not equivocation either; each height has its own parent.

An honest producer never double-signs

A producer remembers, for each parent, the block it signed, and keeps that record on disk as well, so a restart does not make it forget. If it is drawn again for the same parent, it re-sends the block it already signed instead of making a new one.

There is one deliberate exception. Past the recovery limit, 3,600 seconds after the parent, a chain that has stalled must be able to start again. A producer may then sign one fresh block for that parent, which is not charged, and it re-sends that block afterwards. In the same way, a pair of blocks whose timestamps straddle the recovery limit (exactly one of them more than 3,600 seconds after the parent) is a resume of a stalled chain, not equivocation.

Detection

A node that receives two validly signed headers from one registered producer over one parent treats them as proof:

  • it records the producer as a proven liar, which blacklists it as a peer and disconnects it, unless that would cut the node off from the network;
  • it submits one EquivocationReport per parent and producer;
  • it still passes both blocks to validation as usual; fork choice picks the survivor, and on an exact tie the branch with the lower tip hash wins on every node.

The EquivocationReport

The report (transaction type 60) carries the proof itself: the two signed headers, each followed by the producer's 64-byte signature. With 284-byte headers the body is 704 bytes: a 4-byte length, header 1, signature 1, a 4-byte length, header 2, signature 2.

The 704-byte report body as six boxes; below, the two headers side by side with the same producer key at offset 76 and the same parent hash at offset 172.
The 704-byte report body as six boxes; below, the two headers side by side with the same producer key at offset 76 and the same parent hash at offset 172.

The chain makes thirteen checks, in this order:

  1. the report type is active;
  2. the fee is exactly 0, because reporting is a duty of the registered nodes;
  3. the body parses, and each header has the size of a signed header: 204 bytes, or 284 with the seed proof;
  4. the two headers are different;
  5. the producer key, at byte offset 76, is the same in both;
  6. the parent hash, at offset 172, is the same in both;
  7. both signatures verify under that producer key;
  8. the parent is a block of this chain;
  9. the pair does not straddle the one-hour recovery limit;
  10. the report arrives no later than 720 blocks after the equivocated height;
  11. the producer is a registered node;
  12. the reporter is a registered node;
  13. this producer has not already been charged for that height.

A statement that one saw a second block proves nothing; the two signatures do. No vote of the seats is needed, because anyone can check signatures.

The cost

A valid report charges the producer one missed turn, once per producer per height. Under the rules decided for version 0.5.8, a proven double-sign also makes the node missing until its next own block: no coinbase, fee or longevity share, and a falling participation score. Four missed turns in a row suspend a node. See missed turns, suspension and expulsion.

No balance moves. The reporter is not paid, and nothing is taken from the producer's stake: ZBC is never burned (see ZBC is never burned).

Headers A and B go into an EquivocationReport (type 60), which goes into a block: one missed turn, missing until the next own block, no income, score falls. Beside it, the link to the producer is cut, and no ZBC is burned.
Headers A and B go into an EquivocationReport (type 60), which goes into a block: one missed turn, missing until the next own block, no income, score falls. Beside it, the link to the producer is cut, and no ZBC is burned.

See also