EstimatedLatestRound is this realm's best estimate of the round drand is currently on. Panics if no round has ever been published.
A NEW CALLER SHOULD REACH FOR CurrentRound INSTEAD, AND THIS FUNCTION IS KEPT ONLY FOR WHAT ALREADY CONSUMES IT. This estimate extrapolates from the last RELAYED round, and this realm's own TestKnownWeaknessRelayingTheRoundJustAboveTheEstimateBuysTheWholeStalenessBudgetBack proves that extrapolation is poisonable for the cost of one Publish of a freely-fetched PAST round: relaying est+1 resets the staleness clock to zero while moving the estimate forward by exactly one round. CurrentRound instead reads the block's own clock and computes drand's round by arithmetic, so there is no relayed round to poison. See CurrentRound's comment for the full account, including what trusting the block's clock costs in its place. Nothing that calls EstimatedLatestRound today has been switched over -- that is a separate change -- so this function must keep working exactly as it does.
IT IS AN ESTIMATE AND THE NAME SAYS SO. There is no way to know the true current round on-chain: proving "round r is not signed yet" needs an UPPER bound on elapsed real time, published rounds give only a LOWER bound, and chain height gives none at all because a halted chain advances no height while drand advances 28800 rounds a day. Every round-number pin in this system is therefore an assumption about this chain keeping pace with drand, and this function is where that assumption lives instead of being spread across three realms.
THE CONSTRUCTION: take anchorScaled — the highest round-versus-height intercept any relay has ever evidenced — and read this height off that line. It is exactly latestRound at the moment latestRound is relayed. READ anchorScaled BEFORE CHANGING THIS: extrapolating from the highest round's own publication height instead is the obvious simplification, and it is exploitable.
WHY IT IS STRICTLY BETTER THAN Latest() FOR A PIN. A consumer pinning Latest() + offset measures its offset from whenever somebody last happened to relay something, so the pin drifts backwards in real time as the beacon goes quiet — and the raffle's offset is exactly one day larger than a week, so a single day of staleness puts the pinned round's randomness on the public API BEFORE the week's ticket sales close, which is finding 10's last-buyer attack verbatim. The correction removes that failure entirely in the honest case.
THE ERROR IS BOUNDED BY REFUSAL, AND THAT IS NEW AS OF THE STALENESS BOUND. The conversion assumes A = 86400/blocksPerDay = 3.29998 s blocks, so its error is S*(A - B) seconds of drand time for S blocks since the anchor was last raised and a real average block time B — 2.4 hours at one day of S and a 10% drift in B, NOT the ~14 minutes this comment claimed until the figure was re-derived (that number divided by the period twice; see maxEstimateStaleBlocks and AUDIT-2026-09-28.md finding 13). Unbounded S makes it unbounded in BOTH directions, so this function now REFUSES above maxEstimateStaleBlocks rather than returning a number nobody can put a bound on. What the refusal costs, and why it is nevertheless right, is at maxEstimateStaleBlocks and in AUDIT-2026-09-28.md finding 12.
MONOTONE IN HEIGHT AND NEVER BELOW latestRound: ChainHeight() only rises and anchorHeight/anchorScaled never move except upward, so the correction term is never negative.