derive_beacon's own security note says it, and it is worth tracking rather than living only in a doc comment:
the anchor used here is the block hash at the epoch-start height. A miner who finds that block can choose among the candidate hashes it could publish, so this interim anchor's grinding-resistance is BOUNDED — adequate for a read-only, role-inactive view, but NOT the endgame.
Since then the beacon has stopped being read-only: it decides which node coordinates which tier (coordinator_for_tier), and wallets now verify against it (#697). So the bound matters more than it did when the note was written.
The exposure
A miner who finds the anchor block can grind candidate hashes to bias the epoch's draw toward a coordinator of their choosing. The cost is one block's worth of grinding per epoch, and the benefit is deciding who coordinates a denomination for ~a day. That is a poor trade at today's scale and a much better one once rounds carry real volume.
Note the anchor moved in 982b50deb from the first block of epoch E to the last block of E-1, so the epoch's inputs are frozen before it begins. That is a better property for other reasons but does not change the grinding exposure: it is still one block, still chosen by whoever mines it.
The fix, and why it is gated
The unbiasable construction is the threshold-VRF / DKG beacon from increment 5 of tasks/plan_decentralised_coordinators.md, which is gated on an external crypto audit.
Everything downstream takes the beacon as a 32-byte value — epoch.rs, service.rs and the wallet's verification all treat it opaquely — so swapping the construction changes nothing else in the wiring. That was deliberate and it holds.
derive_beacon's own security note says it, and it is worth tracking rather than living only in a doc comment:Since then the beacon has stopped being read-only: it decides which node coordinates which tier (
coordinator_for_tier), and wallets now verify against it (#697). So the bound matters more than it did when the note was written.The exposure
A miner who finds the anchor block can grind candidate hashes to bias the epoch's draw toward a coordinator of their choosing. The cost is one block's worth of grinding per epoch, and the benefit is deciding who coordinates a denomination for ~a day. That is a poor trade at today's scale and a much better one once rounds carry real volume.
Note the anchor moved in
982b50debfrom the first block of epochEto the last block ofE-1, so the epoch's inputs are frozen before it begins. That is a better property for other reasons but does not change the grinding exposure: it is still one block, still chosen by whoever mines it.The fix, and why it is gated
The unbiasable construction is the threshold-VRF / DKG beacon from increment 5 of
tasks/plan_decentralised_coordinators.md, which is gated on an external crypto audit.Everything downstream takes the beacon as a 32-byte value —
epoch.rs,service.rsand the wallet's verification all treat it opaquely — so swapping the construction changes nothing else in the wiring. That was deliberate and it holds.