The two Mermaid diagrams under flowchart/ described the intended flow but had drifted from the code and carried no link back to it. docs/ now holds the specification instead: 15 Italian documents (flows, architecture, data model, API, security, audit log, operations, decisions and limits, bug history) with 472 numbered requirements, each pointing at the function that implements it and the test that covers it. docs/processo-di-modifica.md defines the ID convention and the spec -> code -> test change workflow, and CLAUDE.md now names docs/ as authoritative. Writing the spec from the code also corrected stale claims in CLAUDE.md (B-41's get_history check, BUGS.md still tracking B-71/B-72, Cache-Control scope, the error contract's bare-string exceptions) and in the operator guides (payouts do retry, only `drawing` fails to resume, rounds do not open without fee_address). The B-70 doc test now pins the prose in docs/scommesse-e-prelievi.md instead of the deleted diagram. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
152 lines
7.6 KiB
Markdown
152 lines
7.6 KiB
Markdown
# 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 |
|