Files
plm-lottery/app/bets/confirmation.py
T

34 lines
1.5 KiB
Python
Raw Normal View History

2026-07-21 10:26:11 +02:00
from datetime import datetime, timezone
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.db.models import PendingTransaction, RoundParticipant
from app.tx.confirmation import register_handler
async def _on_bet_confirmed(session: AsyncSession, pending: PendingTransaction) -> None:
"""Resolved by (round_id, user_id) — the pair is unique per participant and,
unlike the txid, cannot change under us. Keying this on bet_txid meant an
RBF-bumped bet confirmed under a txid no participant carried, so the row stayed
"broadcast" forever and the round could never close (B-02). The txid is kept in
step by tx/broadcast.py too, but correctness here no longer depends on it."""
2026-07-21 10:26:11 +02:00
participant = await session.scalar(
select(RoundParticipant).where(
RoundParticipant.round_id == pending.round_id,
RoundParticipant.user_id == pending.user_id,
)
2026-07-21 10:26:11 +02:00
)
if participant is None:
# Fall back to the txid for rows written before this changed, and for any
# pending row missing its round/user link.
participant = await session.scalar(
select(RoundParticipant).where(RoundParticipant.bet_txid == pending.current_txid)
)
if participant is not None and participant.status in ("building", "broadcast"):
2026-07-21 10:26:11 +02:00
participant.status = "confirmed"
participant.confirmed_at = datetime.now(timezone.utc)
register_handler("bet", _on_bet_confirmed)