Files
plm-lottery/docs/adr/ADR-24-l-estrazione-commit-reveal-fra-server.md
T
davideandClaude Sonnet 5.5 b424f670c5 Restructure docs: docs-first, SSOT, one ADR per decision
- Add docs/README.md as the index of all documentation.
- Split the 52 DEC entries of decisioni-e-limiti.md into docs/adr/ADR-NN
  files (same numbers), add ADR-53 (audit log), TEMPLATE.md and an ADR index
  with a feature -> ADR table.
- Rename decisioni-e-limiti.md to limiti-noti.md (LIM only) and rewrite all
  DEC-nn references as links to the ADRs.
- Document the docs-first / SSOT / ADR rules in processo-di-modifica.md and
  map the docs in CLAUDE.md and README.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 12:05:57 +02:00

63 lines
3.9 KiB
Markdown

# ADR-24 — L'estrazione è un commit-reveal fra il server e un blocco futuro
- **Stato:** Accettata — implementazione da completare (B-73)
- **Area:** Round ed estrazione
- **Fonte di verità per:** la scelta di progetto descritta qui sotto; i requisiti (`PREFISSO-NN`) che la attuano stanno nei documenti di dominio, indicati nelle *Conseguenze*.
## Decisione
**L'estrazione è un commit-reveal fra il server e un blocco
futuro** (decisione del 2026-09-28). All'apertura del round il server genera
un segreto casuale di 32 byte (`server_seed`), lo salva e pubblica solo la
sua impronta `server_seed_hash = sha256(server_seed)`. All'ingresso in
`drawing` si fissano l'elenco dei partecipanti confermati, ordinato per txid
della scommessa crescente, la sua impronta `participants_hash` (sha256 delle
righe `txid:vout:indirizzo`) e l'altezza del blocco di estrazione
(`draw_height`, [ADR-25](ADR-25-blocco-estrazione-fissato-altezza-successivo-chiusura.md)). Il seme è
`sha256(server_seed || block_hash || participants_hash)` letto come intero,
l'indice del vincitore è seme modulo numero di partecipanti. Dopo il
salvataggio del vincitore il server rivela `server_seed` e pubblica la prova
completa (`GET /rounds/{id}/proof`), da cui chiunque ricalcola l'esito.
L'algoritmo resta un **componente sostituibile**: il resto del sistema non
va architettato attorno alla sua forma, ma ogni sostituto deve mantenere le
stesse quattro proprietà — impegno pubblicato prima delle scommesse, elenco
dei partecipanti fissato prima del blocco, esito ricalcolabile dai dati
pubblicati, esito non calcolabile da chi produce o trasmette i blocchi.
- *Motivazione:* il vincitore non deve essere calcolabile da chi controlla
la produzione dei blocchi: la potenza di calcolo di PLM (~22 TH/s) si può
affittare. Un minatore che non conosce `server_seed` non sa chi vincerebbe
con il suo blocco e quindi non ha motivo di scartarlo; l'operatore non
può cambiare `server_seed` dopo averne pubblicato l'impronta e non conosce
il blocco quando si impegna. L'ordine per txid e l'impronta dell'elenco
rendono l'esito riproducibile e impediscono di aggiungere o togliere
partecipanti dopo aver visto il blocco (B-73).
- *Alternative scartate:*
- *hash del solo blocco* (la forma precedente): un minatore con biglietti
in gioco trattiene i blocchi finché uno lo fa vincere, e il server
Electrum attivo sceglie quale blocco reale usare semplicemente non
annunciandone uno;
- *hash di più blocchi consecutivi*: chi produce l'ultimo blocco della
serie può ancora scartarlo e riprovare, quindi resta manipolabile;
- *segreti forniti dai giocatori* (commit-reveal fra partecipanti): chi non
rivela blocca o condiziona l'estrazione, e servirebbe un'azione in più a
ogni giocatore;
- *sorgente di casualità esterna* (beacon): una dipendenza di rete in più,
di cui fidarsi quanto del server.
- *Conseguenze:* l'operatore, che conosce `server_seed`, può calcolare
l'esito appena il blocco è noto: una collusione fra operatore e minatore
resta possibile ed è accettata ([LIM-25]), perché l'operatore è già
fidato come custode ([LIM-26]). `server_seed` non è esposto da nessun
endpoint prima della rivelazione, e nel database è cifrato con la chiave
della master xprv finché non viene rivelato
([sicurezza.md](../sicurezza.md#sec-56) SEC-56): una copia del database da
sola non basta a conoscerlo. Regole in
[ciclo-di-vita-del-round.md](../ciclo-di-vita-del-round.md#3--estrazione),
endpoint in [api.md](../api.md) (B-73).
*Codice:* `app/rounds/draw.py:draw_winner` · `app/rounds/scheduler.py:RoundScheduler._close_and_draw` · `app/rounds/service.py:open_new_round_if_needed` ·
*Test:* `tests/unit/test_draw.py`
*Stato:* da implementare (B-73) · *Oggi:* seme = hash del primo blocco
confermato dopo la chiusura, partecipanti ordinati per `broadcast_at` (dato
solo del server, senza criterio di pareggio), nessun impegno né prova
pubblica.