What an anchor is
At any moment, either player may send the server the head of its newest record (about 98 bytes: signer, seq, body hash, signature). The server checks the signature against the genesis and answers with a signed receipt carrying its own clock. Anchors never sit between the players: a move goes to the opponent first, and is anchored beside it. Where the server must read them (online and hybrid games), an anchor also carries the full records, and in games with peer clocks the opponent's latest heartbeat.
One head covers both chains
A head commits to its signer's whole chain through prev, and to the opponent's chain up to what it had seen through seen_hash. So a player that has just acknowledged the opponent's latest move anchors its own ACK, and that single head pins down every record of both players. The server learns sequence numbers and timing, never the moves.
Why a head must carry its signature
An early design anchored bare hashes. That opens a neat attack, and it is the reason heads are signed headers.
With signed heads this fails: each head names its seq, so anchoring two candidates for the same number is two signed headers for one seq. That is a fork, and the cheater loses the game.
What the server checks
- Genesis and certificates. Valid, not revoked.
- Every head. The header rebuilt from genesis, signer, seq and body hash verifies under the signer's key.
- No second head per number. Another body hash for a (signer, seq) it already holds is a fork: kept as evidence, the signer loses.
- Records, when sent. They hash to their heads and link through
prev. If the server has the whole chain it also checks the state hash the client sent.
Older heads are checked when the chain is revealed later (a report, or records in a later anchor): every anchored head must lie on the revealed chain. One that does not is a second signed header for its seq, a fork.
The receipt
- It covers the server's highest heads for both players, so it also tells the anchoring player what the opponent has anchored.
- Receipts form their own chain through
prev_receipt, so the server cannot drop or reorder one unnoticed. - Both players keep their receipts; the server keeps all of them.
Existence time
The existence time E(r) of a record is the server time of the first receipt whose head for that signer has seq ≥ r.seq. It is an upper bound: the record existed no later than that. Anchoring can make your own records look later (which only hurts you), never earlier than they really existed.
Delivery
When anchors carry full records (online and hybrid games) and a player has a live session, the server pushes every record it receives from the opponent, and its receipts, straight to that player, each push followed by a fresh nonce (the hybrid away rule uses it). So withholding a move from the opponent while anchoring it gains nothing: the server delivers it.
What anchors are for
| Game | Anchors give you |
|---|---|
offline (none) | a timestamped proof of the game and its state; a server-side backup if both phones are lost. Optional. |
hybrid (checkpoints) | evidence of who was there and did not answer; never a condition for play |
online (full) | the clock: moves are timed by existence times |
| any game, in a dispute | evidence: "X was to move at T and had nothing newer anchored by then" |