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

3.9 KiB

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). 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 SEC-56): una copia del database da sola non basta a conoscerlo. Regole in ciclo-di-vita-del-round.md, endpoint in 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.