Files
casino/migrations/0002_rounds.sql
drjones 2a2a1db8de feat: playable arcade — rooms, identity, client, deployment
Round length is now bounded: the multiplier follows a hyperbolic curve
diverging at 60s, replacing an exponential one where a 275x crash point
produced a two-and-a-half minute round.

Fixes seed reveal, which silently failed every round because pgx cannot
encode a fixed-size byte array as bytea.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 15:34:52 +00:00

59 lines
2.4 KiB
SQL

-- Rounds, bets, and the verification record for every settled outcome.
--
-- Seeds are stored so that any round can be re-verified indefinitely. The
-- server seed column is NULL until the round settles: revealing it early would
-- let a player compute the outcome before betting closes.
CREATE TABLE rounds (
id BIGSERIAL PRIMARY KEY,
game TEXT NOT NULL, -- 'rocket', 'orbital', 'tower'
nonce BIGINT NOT NULL,
commitment BYTEA NOT NULL, -- SHA-256 of the server seed
server_seed BYTEA, -- revealed only after settlement
client_seed BYTEA, -- derived from participants
crash_point BIGINT, -- Q32.32 fixed-point
opened_at TIMESTAMPTZ NOT NULL DEFAULT now(),
locked_at TIMESTAMPTZ,
settled_at TIMESTAMPTZ,
CONSTRAINT reveal_is_complete CHECK (
settled_at IS NULL OR (server_seed IS NOT NULL AND crash_point IS NOT NULL)
)
);
CREATE TABLE bets (
id BIGSERIAL PRIMARY KEY,
round_id BIGINT NOT NULL REFERENCES rounds(id),
account_id BIGINT NOT NULL REFERENCES accounts(id),
stake_msat BIGINT NOT NULL CHECK (stake_msat > 0),
-- Set when the player cashes out; NULL means they rode it to the crash.
cashout_at BIGINT, -- Q32.32 multiplier
payout_msat BIGINT,
placed_at TIMESTAMPTZ NOT NULL DEFAULT now(),
settled_at TIMESTAMPTZ,
UNIQUE (round_id, account_id)
);
CREATE INDEX bets_round_idx ON bets (round_id);
CREATE INDEX bets_account_idx ON bets (account_id, id DESC);
CREATE TABLE scratch_plays (
id BIGSERIAL PRIMARY KEY,
account_id BIGINT NOT NULL REFERENCES accounts(id),
ticket_id TEXT NOT NULL,
nonce BIGINT NOT NULL,
commitment BYTEA NOT NULL,
server_seed BYTEA NOT NULL,
stake_msat BIGINT NOT NULL CHECK (stake_msat > 0),
tier_name TEXT NOT NULL,
payout_msat BIGINT NOT NULL CHECK (payout_msat >= 0),
cells INTEGER[] NOT NULL,
played_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX scratch_account_idx ON scratch_plays (account_id, id DESC);
-- Rounds and plays are historical records; they are never rewritten.
CREATE TRIGGER scratch_plays_append_only
BEFORE UPDATE OR DELETE ON scratch_plays
FOR EACH ROW EXECUTE FUNCTION reject_mutation();