From 772727b0ef7d63144bf629d774f8b6c1c996bf78 Mon Sep 17 00:00:00 2001 From: salmonik Date: Thu, 29 Oct 2026 21:36:26 +0100 Subject: v2.3.1: settle orphaned reservations on server restart --- docs/GAMES.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'docs/GAMES.md') diff --git a/docs/GAMES.md b/docs/GAMES.md index 844d1b0..2b8adf5 100644 --- a/docs/GAMES.md +++ b/docs/GAMES.md @@ -137,6 +137,34 @@ plays ( The balance update and the `plays` insert happen in one transaction (`database::apply_play`). +### Reserved bets and restarts + +Blackjack and crash reserve the bet before the round can settle. The debit and +a `pending_plays` row are written in one transaction +(`database::reserve_play`); settling deletes that row and writes the `plays` +audit row in the same transaction. + +``` +pending_plays ( + session_id TEXT PRIMARY KEY, + username TEXT NOT NULL, + game_type TEXT NOT NULL, + bet_amount INTEGER NOT NULL, + details TEXT NOT NULL DEFAULT '{}', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +) +``` + +If the server dies with a round in flight, the reservation survives the process. +The next startup calls `recover_orphaned_reservations` before the listener +accepts connections, and each leftover is settled as a **forfeit**: the bet is +not refunded, and the audit row gets `winnings = 0`, +`details.result = "abandoned"`, `details.reason = "server_restart"`. + +The sweep runs once per process, never per connection. A per-connection sweep +would settle another player's live hand, and only one server process may own a +database. + ## Wire protocol Slots keeps its original exchange: -- cgit v1.2.3