Make a stalled draw wait observable (B-36)
_wait_for_next_block had no timeout, no log, and no audit entry: a connection that stopped advancing the tip left a round silently frozen in "drawing" with nothing in /admin to explain why. Log progress periodically, write a draw_stalled audit entry past a threshold (a few block-time multiples), and surface the wait via a new Round.drawing_started_at column, exposed as draw_waiting_since in GET /rounds/current. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ from pydantic import BaseModel
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.timeutil import isoformat_utc
|
||||
from app.auth.dependencies import get_optional_user
|
||||
from app.db.models import RoundParticipant, User
|
||||
from app.db.session import get_session
|
||||
@@ -90,6 +91,10 @@ class CurrentRoundResponse(BaseModel):
|
||||
winner_amount_sats: int | None = None
|
||||
draw_block_height: int | None = None
|
||||
draw_block_hash: str | None = None
|
||||
# B-36: set only while status == "drawing", so the frontend can show "still
|
||||
# waiting for a block" rather than a countdown implying a bounded wait — this
|
||||
# phase has no timeout, only draw_animation_seconds' cosmetic minimum.
|
||||
draw_waiting_since: str | None = None
|
||||
chain_tip_height: int | None = None
|
||||
lottery_paused: bool = False
|
||||
user_played: bool = False
|
||||
@@ -168,6 +173,7 @@ async def current_round(
|
||||
winner_amount_sats=round_.winner_amount_sats,
|
||||
draw_block_height=round_.draw_block_height,
|
||||
draw_block_hash=round_.draw_block_hash,
|
||||
draw_waiting_since=isoformat_utc(round_.drawing_started_at) if round_.status == "drawing" else None,
|
||||
chain_tip_height=chain_tip_height,
|
||||
lottery_paused=config.paused,
|
||||
user_played=user_played,
|
||||
|
||||
Reference in New Issue
Block a user