Files
plm-lottery/docs/come-funziona.md
T

151 lines
7.6 KiB
Markdown
Raw Normal View History

# Come funziona PLM Lottery
Panoramica del funzionamento della piattaforma. È il punto di partenza: ogni
sezione rimanda al documento che la approfondisce.
| Documento | Cosa spiega |
|---|---|
| [registrazione-e-depositi.md](registrazione-e-depositi.md) | Come nasce un account, come arrivano i fondi, come si calcola il saldo mostrato |
| [scommesse-e-prelievi.md](scommesse-e-prelievi.md) | Come si piazza una scommessa e come si ritirano i fondi |
| [ciclo-di-vita-del-round.md](ciclo-di-vita-del-round.md) | Apertura, chiusura, estrazione del vincitore, pagamento |
| [transazioni-e-riconciliazione.md](transazioni-e-riconciliazione.md) | Come ogni movimento di denaro viene registrato, inviato, accelerato (RBF) e riconciliato con la catena |
| [connessione-electrum.md](connessione-electrum.md) | Come il server parla con la rete PLM e perché non si fida di un solo server |
| [architettura.md](architettura.md) | Struttura del codice, processi in background, configurazione, frontend, traduzioni, test |
| [modello-dati.md](modello-dati.md) | Tabelle del database, campi, stati, vincoli, migrazioni |
| [api.md](api.md) | Tutti gli endpoint HTTP, formato delle risposte, catalogo dei codici di errore |
| [sicurezza.md](sicurezza.md) | Modello di fiducia, chiavi e segreti, autenticazione, limiti sui tentativi, header HTTP |
| [audit-log.md](audit-log.md) | Catalogo degli eventi del registro di audit |
| [operativita.md](operativita.md) | Backup, riavvii, procedure per gli incidenti |
| [decisioni-e-limiti.md](decisioni-e-limiti.md) | Decisioni di progetto con le loro motivazioni, limiti noti accettati |
| [storico-bug.md](storico-bug.md) | Tutti i bug B-nn trovati e corretti, con commit e test |
Questi documenti sono la **specifica** del software: ogni regola ha un
identificativo stabile (ad esempio `RND-11`) con il riferimento al codice che
la implementa. Come si usano per modificare il software è spiegato in
[processo-di-modifica.md](processo-di-modifica.md).
Per installazione e avvio vedi [setup.md](setup.md) e
[running-the-server.md](running-the-server.md); per l'uso delle interfacce
[guida-utente.md](guida-utente.md) e [guida-admin.md](guida-admin.md).
## In una frase
Gli utenti depositano PLM su un indirizzo personale custodito dal server,
comprano un biglietto a costo fisso per il round in corso, e allo scadere del
round l'hash del primo blocco successivo sceglie un vincitore, che riceve il
70% del montepremi; il 30% va alla piattaforma.
## Scelte di fondo
- **Custodiale.** Le chiavi sono generate e tenute dal server (una master xprv
cifrata a riposo). L'utente non controlla nulla finché non preleva.
- **Un indirizzo per utente, per sempre.** Lo stesso indirizzo serve per i
depositi, riceve le vincite e riceve il resto di ogni scommessa e prelievo.
- **Nessun nodo completo.** Tutto l'accesso alla rete passa dal protocollo
Electrum (vedi [connessione-electrum.md](connessione-electrum.md)).
- **1 conferma** per ogni tipo di transazione: depositi, scommesse, pagamenti,
prelievi.
- **Parametri operativi nel database**, modificabili a caldo da `/admin`
(costo della scommessa, durata del round, commissioni…). Nel file `.env`
restano solo segreti e collegamenti infrastrutturali.
## Le cinque fasi
```mermaid
flowchart LR
subgraph REG["1 · Registrazione"]
direction TB
A1["Username + password"] --> A2["Il server deriva un indirizzo<br/>dedicato e permanente"]
end
subgraph DEP["2 · Deposito"]
direction TB
B1["L'utente invia PLM<br/>al proprio indirizzo"] --> B2{"1 conferma e<br/>corroborato dagli<br/>altri server?"}
B2 -- "No" --> B1b["Si riprova al prossimo<br/>aggiornamento"] --> B2
B2 -- "Sì" --> B3["Saldo accreditato"]
end
subgraph PLAY["3 · Scommessa"]
direction TB
C1{"Saldo sufficiente,<br/>nessuna scommessa attiva,<br/>round aperto e non pieno?"}
C1 -- "Sì" --> C2["Transazione: indirizzo utente →<br/>montepremi, resto all'utente"]
C2 --> C3{"Confermata?"}
C3 -- "No, troppo tempo" --> C4["Commissione aumentata<br/>(RBF) e reinvio"] --> C3
C3 -- "Sì" --> C5["Partecipante del round"]
end
subgraph DRAW["4 · Round ed estrazione"]
direction TB
D1["Scadenza del round"] --> D2["Si attendono le scommesse<br/>già in volo"]
D2 --> D3["Il primo blocco successivo<br/>sceglie il vincitore"]
D3 --> D4["70% al vincitore,<br/>30% alla piattaforma"]
end
subgraph WITHDRAW["5 · Prelievo"]
direction TB
E1["Indirizzo esterno + importo"] --> E2["Transazione: indirizzo utente →<br/>esterno, resto all'utente"]
E2 --> E3{"Confermata?"}
E3 -- "No, troppo tempo" --> E4["RBF e reinvio"] --> E3
E3 -- "Sì" --> E5["Saldo aggiornato"]
end
A2 --> B1
B3 --> C1
B3 --> E1
C5 --> D1
D4 -.->|"round successivo"| C1
```
1. **Registrazione** — [registrazione-e-depositi.md](registrazione-e-depositi.md#registrazione)
2. **Deposito** — [registrazione-e-depositi.md](registrazione-e-depositi.md#deposito)
3. **Scommessa** — [scommesse-e-prelievi.md](scommesse-e-prelievi.md#scommessa)
4. **Round ed estrazione** — [ciclo-di-vita-del-round.md](ciclo-di-vita-del-round.md)
5. **Prelievo** — [scommesse-e-prelievi.md](scommesse-e-prelievi.md#prelievo)
## Componenti
Un solo processo Python (FastAPI) dietro Caddy, con un database SQLite. Dentro
il processo girano, oltre all'API HTTP, sei attività in background avviate
all'avvio del server:
| Attività | Ogni | Cosa fa |
|---|---|---|
| `ElectrumListener` | connessione continua, ping ogni 60s | L'unica connessione alla rete: riceve i nuovi blocchi, osserva gli indirizzi di tutti gli utenti, accredita i depositi |
| `RoundScheduler` | 5s | Apre e chiude i round, esegue l'estrazione, avvia e riprova i pagamenti |
| `ConfirmationPoller` | 10s | Porta le transazioni da "in attesa" a "confermate" |
| `RbfBumper` | 30s | Aumenta la commissione di ciò che non conferma entro il tempo limite |
| `PendingTransactionReconciler` | all'avvio, poi 120s | Confronta con la catena ogni transazione rimasta a metà |
| `DepositReconciler` | 300s | Ricontrolla tutti gli indirizzi, nel caso una notifica sia andata persa |
La cadenza di queste attività è ciò che determina quanto in fretta il sistema
si ripara da solo dopo un problema.
Le due interfacce web sono pagine statiche servite dallo stesso server, senza
build né framework:
- **`/`** — l'interfaccia per i giocatori (registrazione, deposito, scommessa,
prelievo, profilo, stato del round), tradotta in 7 lingue.
- **`/admin`** — il pannello operatore, protetto da un token condiviso,
in italiano.
Entrambe interrogano periodicamente l'API e in più ascoltano un canale
**SSE** (`GET /rounds/stream`): un semplice segnale "è cambiato qualcosa,
ricarica" inviato a ogni evento rilevante (round aperto o cambiato di stato,
scommessa o prelievo inviato, transazione confermata, deposito accreditato,
nuovo blocco). Se il canale cade, le pagine continuano a funzionare con il
solo polling.
## Parametri principali
| Parametro | Valore predefinito | Modificabile |
|---|---|---|
| Costo della scommessa | 10 PLM | da `/admin` |
| Ripartizione del montepremi | 70% vincitore / 30% piattaforma | no, è nel codice |
| Durata del round | 600s | da `/admin`, vale dal round successivo |
| Pausa tra un round e l'altro | 30s | da `/admin`, vale dal round successivo |
| Commissione di rete | 1 sat/vB | da `/admin` |
| Tempo prima di un RBF | 900s | da `/admin` |
| Prelievo minimo | pari al costo della scommessa | segue il costo |
| Deposito minimo | nessuno | — |
| Partecipanti massimi per round | 400 | no, è nel codice |
| Conferme richieste | 1 | no, è nel codice |