Give every round its own pool address (B-80, RND-35, DAT-60, DAT-11, REG-14, SEC-08, BET-12, RND-22, WDR-14, SEC-43, API-23, API-36)
All bets of all rounds paid one address (m/84'/746'/0'/1/0), so its history grew forever, other rounds' money and stray coins mixed with a round's own, and the payout picked from everything it held. - hd.py: derive_pool_key/derive_pool_address(round_id) on branch 2 (m/84'/746'/0'/2/<round_id>); no argument is the reserve address 1/0. derive_round_pool_key checks the key against the address stored on the round, so a payout can never be signed for money its key does not control. - rounds.pool_address (migration 477bddae1a84, existing rounds backfilled with the reserve address since that is where their bets went; add_column, not a batch alter, so the expression indexes stay): written in the transaction that inserts the round, once its id exists. - place_bet pays round.pool_address; the payout reads, signs and takes change at the round's own address; own_address_for and bump_fee's _signing_context follow the round (confirmation poller and reconciler pass round_id). - Withdrawals to any round pool address, the reserve address or fee_address are refused (withdrawal_to_platform_address, 400, all seven languages). - GET /rounds/current and GET /admin/rounds expose pool_address. - RND-22/DAT-11 stay "da implementare" for B-82: the payout still spends every confirmed coin at the round's address, not only the participants' outpoints (participants carry no bet_vout yet). - tests/unit/conftest.py: every test now gets a throwaway master key. Opening a round derives an address, and tests that merely opened a round were silently reading the real key from the local .env. - Existing tests changed because the spec changed: payout fixtures give their round a pool_address; the reconciler's address-cache test uses two payouts of one round (rows of different rounds no longer share an address); own_address_for now takes the round id. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cc63753439
commit
fd6a91e93d
37 files changed
+673
-144
No files matched your search
+8
-9
@@ -504,7 +504,7 @@ esiste una API separata per l'amministrazione, solo un'autenticazione diversa.
|
||||
finché la rete non torna); poi `400`: `invalid_address`,
|
||||
`withdrawal_to_own_address`, `withdrawal_to_platform_address`
|
||||
(destinazione uguale a un indirizzo di montepremi, di riserva o delle
|
||||
commissioni, B-80), `amount_below_minimum` (`params.minimum_sats` = costo
|
||||
commissioni), `amount_below_minimum` (`params.minimum_sats` = costo
|
||||
attuale della scommessa; verificato anche sull'importo ridotto di un
|
||||
prelievo dell'intero saldo, B-96), `balance_pending_confirmation`
|
||||
(`params.pending_sats`), `insufficient_balance` (`params.required_sats`),
|
||||
@@ -521,10 +521,9 @@ esiste una API separata per l'amministrazione, solo un'autenticazione diversa.
|
||||
*Codice:* `app/api/routes/withdrawals.py:create_withdrawal`,
|
||||
`app/withdrawals/service.py:request_withdrawal` ·
|
||||
*Test:* `tests/unit/test_withdrawals.py`
|
||||
*Stato:* da implementare (B-76, B-80, B-96) · *Oggi:* ogni esito diverso
|
||||
*Stato:* da implementare (B-76, B-96) · *Oggi:* ogni esito diverso
|
||||
dal successo è `502 broadcast_failed` con il prelievo `failed`; la
|
||||
trasmissione va solo al server attivo; un prelievo verso l'indirizzo del
|
||||
pool o delle commissioni è accettato; l'importo ridotto di un prelievo
|
||||
trasmissione va solo al server attivo; l'importo ridotto di un prelievo
|
||||
dell'intero saldo non è riconfrontato con il minimo.
|
||||
|
||||
### Round
|
||||
@@ -560,7 +559,7 @@ esiste una API separata per l'amministrazione, solo un'autenticazione diversa.
|
||||
| `participants_hash` | stringa o `null` | impronta dell'elenco ordinato dei partecipanti, valorizzata dall'ingresso in `drawing` — *da implementare (B-73)* |
|
||||
| `draw_height` | intero o `null` | altezza del blocco di estrazione, fissata all'ingresso in `drawing` — *da implementare (B-73)* |
|
||||
| `draw_confirmations` | intero o `null` | conferme richieste sul blocco di estrazione, fissate all'apertura del round — *da implementare (B-73, B-95)* |
|
||||
| `pool_address` | stringa o `null` | indirizzo del montepremi del round, verificabile su un esploratore — *da implementare (B-80)* |
|
||||
| `pool_address` | stringa o `null` | indirizzo del montepremi del round, verificabile su un esploratore |
|
||||
| `chain_tip_height` | intero o `null` | ultima altezza nota della catena; `null` finché non è nota |
|
||||
| `lottery_paused` | booleano | lotteria in pausa, per qualunque motivo |
|
||||
| `paused_reason` | stringa o `null` | `operator`, `reorg`, `payout_blocked`, `resurrected_tx`, oppure `null` se non in pausa ([modello-dati.md](modello-dati.md), DAT-69) — *da implementare (B-78, B-82, B-85)* |
|
||||
@@ -585,7 +584,7 @@ esiste una API separata per l'amministrazione, solo un'autenticazione diversa.
|
||||
`app/rounds/service.py:round_deadline`, `app/rounds/service.py:winner_share`,
|
||||
`app/rounds/service.py:rounds_can_open` ·
|
||||
*Test:* `tests/unit/test_rounds_route.py`
|
||||
*Stato:* da implementare (B-73, B-78, B-80, B-82, B-85, B-95), per i campi
|
||||
*Stato:* da implementare (B-73, B-78, B-82, B-85, B-95), per i campi
|
||||
marcati · *Oggi:* quei campi non esistono, `bet_amount_sats` è sempre il
|
||||
costo configurato, e `draw_block_hash` è il seme dell'estrazione.
|
||||
|
||||
@@ -898,8 +897,8 @@ dei parametri operativi in
|
||||
completa di un round è in [API-45](#get-roundsround_idproof).
|
||||
*Codice:* `app/api/routes/admin.py:list_rounds` ·
|
||||
*Test:* `tests/unit/test_admin.py`
|
||||
*Stato:* da implementare (B-73, B-79, B-80, B-82), per gli ultimi cinque
|
||||
campi · *Oggi:* la lista si ferma a `payout_txid`.
|
||||
*Stato:* da implementare (B-73, B-79, B-82), per gli ultimi quattro
|
||||
campi · *Oggi:* la lista si ferma a `pool_address`.
|
||||
|
||||
#### GET /admin/audit-log
|
||||
|
||||
@@ -1065,7 +1064,7 @@ dei parametri operativi in
|
||||
| `withdrawal_to_own_address` | 400 | `app/withdrawals/service.py:request_withdrawal` | — | destinazione uguale all'indirizzo di deposito dell'utente | sì |
|
||||
| `amount_below_minimum` | 400 | `app/withdrawals/service.py:request_withdrawal` | `minimum_sats` | prelievo sotto il costo attuale della scommessa | sì |
|
||||
| `internal_error` | 500 | `app/main.py:log_unhandled_exception` | — | eccezione non gestita | sì |
|
||||
| `withdrawal_to_platform_address` | 400 | `app/withdrawals/service.py:request_withdrawal` | — | destinazione uguale a un indirizzo di montepremi, di riserva o delle commissioni — *da implementare (B-80)* | no — da aggiungere |
|
||||
| `withdrawal_to_platform_address` | 400 | `app/withdrawals/service.py:request_withdrawal` | — | destinazione uguale a un indirizzo di montepremi, di riserva o delle commissioni | sì |
|
||||
| `service_busy` | 503 | `app/bets/service.py:place_bet`, `app/withdrawals/service.py:request_withdrawal`, `app/auth/routes.py:register` | — | il database non ha concesso il lock di scrittura entro il timeout; nulla è stato trasmesso, si può riprovare | sì |
|
||||
| `registration_unavailable` | 503 | `app/auth/routes.py:register` | — | registrazione sospesa finché il controllo degli indici di derivazione dopo un ripristino non è concluso o risolto ([registrazione-e-depositi.md](registrazione-e-depositi.md), B-90) — *da implementare* | no — da aggiungere |
|
||||
| `not_authenticated` | 401 | dipendenza Bearer di FastAPI | — | header `Authorization` assente — oggi `detail` stringa — *da implementare (B-94)* | no — da aggiungere |
|
||||
|
||||
Reference in new issue
Block a user