68 lines
3.1 KiB
Python
68 lines
3.1 KiB
Python
"""commit-reveal draw: round secret, participant order and draw height (B-73)
|
|||
|
|
|
||
|
|
Revision ID: d3e8b15a7c42
|
||
|
|
Revises: b7d2e41c9a05
|
||
|
|
Create Date: 2026-10-14 16:40:00.000000
|
||
|
|
|
||
|
|
"""
|
||
|
|
from typing import Sequence, Union
|
||
|
|
|
||
|
|
from alembic import op
|
||
|
|
import sqlalchemy as sa
|
||
|
|
|
||
|
|
|
||
|
|
# revision identifiers, used by Alembic.
|
||
|
|
revision: str = 'd3e8b15a7c42'
|
||
|
|
down_revision: Union[str, Sequence[str], None] = 'b7d2e41c9a05'
|
||
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
||
|
|
depends_on: Union[str, Sequence[str], None] = None
|
||
|
|
|
||
|
|
_ACTIVE = "'open', 'closing', 'drawing', 'paying_out'"
|
||
|
|
|
||
|
|
|
||
|
|
def upgrade() -> None:
|
||
|
|
"""Upgrade schema.
|
||
|
|
|
||
|
|
B-73 (DAT-61 … DAT-66): the round's secret (`server_seed_enc`, `server_seed`,
|
||
|
|
`server_seed_hash`), the fixed participant list (`participants_hash`, `draw_height`,
|
||
|
|
`round_participants.draw_position`) and the number of confirmations the draw block
|
||
|
|
needs (`draw_confirmations` on the round, copied from `round_config` at open).
|
||
|
|
`bet_vout` records which output of a bet pays the pool; every existing bet pays it
|
||
|
|
with its first output.
|
||
|
|
|
||
|
|
Rounds that already exist keep NULL in the three secret columns (they were drawn,
|
||
|
|
or are drawn, on the block hash alone) and take the default of 3 confirmations.
|
||
|
|
|
||
|
|
Plain add_column / create_index calls — never batch_alter_table, which on SQLite
|
||
|
|
rebuilds the table and silently drops the expression indexes (B-97, DAT-56).
|
||
|
|
"""
|
||
|
|
op.add_column("rounds", sa.Column("draw_confirmations", sa.Integer(), server_default="3", nullable=False))
|
||
|
|
op.add_column("rounds", sa.Column("server_seed_enc", sa.Text(), nullable=True))
|
||
|
|
op.add_column("rounds", sa.Column("server_seed", sa.String(length=64), nullable=True))
|
||
|
|
op.add_column("rounds", sa.Column("server_seed_hash", sa.String(length=64), nullable=True))
|
||
|
|
op.add_column("rounds", sa.Column("participants_hash", sa.String(length=64), nullable=True))
|
||
|
|
op.add_column("rounds", sa.Column("draw_height", sa.Integer(), nullable=True))
|
||
|
|
|
||
|
|
op.add_column("round_participants", sa.Column("bet_vout", sa.Integer(), server_default="0", nullable=False))
|
||
|
|
op.add_column("round_participants", sa.Column("draw_position", sa.Integer(), nullable=True))
|
||
|
|
op.create_index(
|
||
|
|
"ux_round_participants_round_draw_position",
|
||
|
|
"round_participants",
|
||
|
|
["round_id", "draw_position"],
|
||
|
|
unique=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
op.add_column("round_config", sa.Column("draw_confirmations", sa.Integer(), server_default="3", nullable=False))
|
||
|
|
|
||
|
|
|
||
|
|
def downgrade() -> None:
|
||
|
|
"""Downgrade schema."""
|
||
|
|
op.drop_column("round_config", "draw_confirmations")
|
||
|
|
op.drop_index("ux_round_participants_round_draw_position", table_name="round_participants")
|
||
|
|
op.drop_column("round_participants", "draw_position")
|
||
|
|
op.drop_column("round_participants", "bet_vout")
|
||
|
|
for column in ("draw_height", "participants_hash", "server_seed_hash", "server_seed", "server_seed_enc", "draw_confirmations"):
|
||
|
|
op.drop_column("rounds", column)
|
||
|
|
# drop_column on SQLite is a table rebuild: recreate the expression index (B-97).
|
||
|
|
op.execute("DROP INDEX IF EXISTS ix_rounds_single_active")
|
||
|
|
op.execute(f"CREATE UNIQUE INDEX ix_rounds_single_active ON rounds ((1)) WHERE status IN ({_ACTIVE})")
|