A user could bet and then double-spend the 1-conference deposit that funded the bet with a private chain: the bet left the chain but its participant stayed `confirmed`, and the payout failed "insufficient pool UTXOs" for ever with everyone else's money stuck. Coinbase outputs were also credited at 1 confirmation (maturity is 120). Deposits - `round_config.deposit_confirmations` (default 6, 1-100, editable from /admin) is the threshold for a deposit; an output of a platform transaction (any txid of a pending_transactions row, RBF versions included) keeps 1; a coinbase output needs 120, recognised from the raw transaction, which must hash to the txid (`is_coinbase`, cached). `read_deposit_policy` / `classify_new_deposits` run between the read and the write, so no session is open across the lookup. - The quorum must also place the coin deep enough on our own tip (ELC-17). - Confirmed outputs short of their threshold are pending deposits (memory only, replaced at every refresh): shown in `pending_balance_sats` / `has_pending` (also for DEP-13's withdrawal message), never spendable. No scripthash notification announces a maturing deposit, so each new block refreshes only the users that have one, one task per user (DEP-09 now says so). Payout - `_trigger_payout` verifies the round's confirmed participants' bet outputs with the other servers (`verify_pool_outpoints`: strict majority of >= 2 answers per outpoint, a mempool-only coin or a tie gives no verdict) and builds from exactly those outpoints (RND-22), never from whatever else sits at the address. No quorum: `payout_failed`, `pool verification unavailable`, nothing changes. Bets that are gone become `reorged_out`, one `participant_reorged_out` row each, `pool_amount_sats` rewritten (only downward) in the same transaction, and the 70/30 split is computed on what is left. - Winner's own bet gone: nothing is built; `rounds.payout_blocked_at` (Alembic f2c64a8d1e93, with `deposit_confirmations`, plain add_column) is set, `payout_blocked` and the pause with `paused_reason = 'payout_blocked'` are written in one transaction; `POST /admin/resume` clears the mark and the next attempt verifies again. /admin/rounds returns it. - Rounds opened before B-80 (pool = the shared reserve address) keep the old active-server `listunspent` choice, since that address holds no single round's bets. Ambiguities resolved: the winner's row stays `confirmed` while held (AUD-45 says every participant whose bet is gone becomes `reorged_out`, but OPS-30/DAT-68 need the verification to repeat after the resume, which only a `confirmed` row allows); `/`'s deposit hint no longer says "1 confirmation" (7 languages, same keys); guides updated. Tests changed because the spec changed: listener tests that credited height-100 coins at tip 0 now set a tip past every threshold; the payout fixtures seed confirmed participants (the new source of the inputs) instead of an active-server `listunspent`, FakeNetwork answers the verification, and test_round_pool_address asserts the quorum is asked about the round's address. New: thresholds at exactly 6/5, configured value, coinbase at 119/120 and a mismatching or missing raw tx, platform outputs at 1, dust, quorum height, waiting-deposit display and disappearance, block-triggered refresh, resume, verification verdicts, gone bets excluded with the split recomputed, winner gone held and paused, held payouts untouched until the resume, re-verification after it, no quorum, a payout with 1 and with 400 participants against reserve+fee+dust, admin config bounds and migration. Mutation-checked: threshold 1, ignored coinbase, no height bound, no verification and no winner hold each fail tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
174 lines
8.5 KiB
Markdown
174 lines
8.5 KiB
Markdown
# Guida utente
|
|
|
|
Come usare PLM Lottery dall'interfaccia web (`https://<host>/` — vedi
|
|
[running-the-server.md](running-the-server.md) per come avviare il server).
|
|
Per cosa succede dietro le quinte (depositi, round, estrazione, pagamenti) vedi
|
|
[come-funziona.md](come-funziona.md).
|
|
|
|
## Registrazione e accesso
|
|
|
|
Nella schermata iniziale trovi due tab: **Registrati** e **Login**.
|
|
|
|
- **Registrati**: scegli username e password. Al termine ti viene assegnato
|
|
automaticamente un **indirizzo di deposito personale** (derivato
|
|
server-side) — è per sempre tuo, e riceverai anche eventuali vincite su
|
|
quello stesso indirizzo.
|
|
- **Login**: se hai già un account, accedi con username e password.
|
|
|
|
La sessione resta salvata nel browser (fino al logout): non serve rifare
|
|
login ogni volta che riapri la pagina.
|
|
|
|
## La dashboard
|
|
|
|
Dopo l'accesso vedi, in ordine:
|
|
|
|
1. **Barra di navigazione** (fissa in alto) — il tuo username e il bottone
|
|
"Esci" (logout) nella riga superiore, e i tab delle sezioni subito sotto
|
|
2. **Card del round corrente** — sempre visibile, indipendentemente dalla
|
|
sezione che stai guardando:
|
|
- numero del round e stato (*aperto*, *in chiusura*, *estrazione in
|
|
corso*, *pagamento in corso*)
|
|
- **timer** che conta alla rovescia il tempo rimanente prima della
|
|
chiusura del round
|
|
- **giocatori**: quanti hanno già piazzato una bet in questo round
|
|
- **jackpot**: quanto riceverà chi vince questo round
|
|
3. **Tab di navigazione** con quattro sezioni:
|
|
|
|
### Estrazione del vincitore
|
|
|
|
Appena il timer arriva a zero, **nessun nuovo giocatore può più entrare nel
|
|
round** — è un "semaforo giallo": il conteggio raggiunto lo zero blocca da
|
|
subito le nuove giocate, ma il round non chiude immediatamente. Se qualcuno
|
|
aveva già piazzato una bet negli ultimi istanti (transazione trasmessa ma
|
|
non ancora confermata), il round aspetta che anche quella si confermi prima
|
|
di procedere, così nessuna giocata già fatta viene persa al confine del
|
|
round. Solo a quel punto la card mostra un messaggio di stato ("Round
|
|
chiuso — attesa conferma puntate…", poi "Estrazione in corso…", poi
|
|
"Pagamento al vincitore in corso…") al posto del timer — la stessa cosa
|
|
compare nella dashboard di **ogni** utente, anche di chi non ha giocato in
|
|
questo round. Questo messaggio resta visibile per l'intera durata della fase
|
|
(chiusura → estrazione → pagamento), perché sotto la copertina servono
|
|
**diverse conferme sulla rete PLM in sequenza**, una diversa dall'altra:
|
|
|
|
1. conferma dell'ultima giocata rimasta in sospeso (se ce n'era una proprio
|
|
allo scadere del timer — altrimenti questo passo è già superato);
|
|
2. un blocco di estrazione, fissato alla chiusura (il primo dopo di essa), che
|
|
deve avere in tutto **3 conferme** (il valore è configurabile dall'operatore)
|
|
prima che il suo hash, insieme a un segreto del server impegnato
|
|
all'apertura del round, scelga il vincitore;
|
|
3. la conferma della transazione che paga effettivamente la vincita.
|
|
|
|
Con un blocco PLM ogni ~2 minuti, il tempo reale dall'azzeramento del
|
|
timer all'accredito della vincita è quindi in media **8-10 minuti** (se
|
|
c'era una giocata da confermare all'ultimo istante) o **6-8 minuti** (se
|
|
tutte le giocate erano già confermate prima dello zero) — non pochi
|
|
secondi, ed è normale.
|
|
|
|
Se **hai giocato in questo round**, appena il vincitore è determinato compare
|
|
**in aggiunta** (non al posto del messaggio di stato sopra, che resta
|
|
visibile finché il pagamento non è confermato) un secondo riquadro solo per
|
|
te:
|
|
- **"🎉 Hai vinto! +N PLM"** se sei tu il vincitore — l'importo ti verrà
|
|
accreditato non appena la transazione di payout viene confermata (il
|
|
round successivo non si apre finché questo non accade)
|
|
- **"Non hai vinto questa volta."** altrimenti
|
|
|
|
Chi non ha giocato in questo round non vede mai questo secondo riquadro,
|
|
solo il messaggio di stato generico. Il riquadro personale resta visibile
|
|
anche **dopo un refresh della pagina** (persiste nel browser), fino
|
|
all'apertura del round successivo — non serve restare sulla pagina per non
|
|
perderlo, e se hai perso completamente la finestra in tempo reale (es. tab in
|
|
background per diversi minuti), lo vedrai comunque comparire non appena
|
|
riapri la dashboard.
|
|
|
|
La dashboard si aggiorna anche **in tempo reale**, non solo a intervalli
|
|
fissi: appena qualcosa cambia sul server (una giocata, un cambio di fase del
|
|
round, un nuovo blocco confermato...) la pagina lo recepisce quasi subito,
|
|
senza bisogno di premere "Aggiorna" o ricaricare.
|
|
|
|
### Avviso di manutenzione
|
|
|
|
Se l'operatore ha messo in pausa la lotteria per manutenzione, in cima alla
|
|
pagina (visibile anche prima del login) compare un avviso: il round
|
|
eventualmente in corso viene comunque **completato normalmente**, vincitore
|
|
incluso, ma **non ne parte uno nuovo** finché la manutenzione non termina.
|
|
L'avviso sparisce da solo appena l'operatore riprende la lotteria.
|
|
|
|
### Deposito
|
|
|
|
- Il tuo **saldo interno**, con bottone "Aggiorna" per ricontrollarlo. Il
|
|
numero mostrato include anche il resto di una bet o un prelievo appena
|
|
inviati (non ancora confermato sulla rete) — non solo la parte già
|
|
confermata — così non sembra che il saldo sia crollato più del dovuto
|
|
subito dopo un'operazione. Il colore indica lo stato:
|
|
- **verde**: tutto confermato, il saldo mostrato è quello definitivo
|
|
- **arancione**: c'è una bet o un prelievo ancora in attesa di conferma,
|
|
oppure un deposito che ha qualche conferma ma non ancora quelle richieste —
|
|
il numero è corretto, ma non ancora "finale"; un deposito in attesa non è
|
|
spendibile finché non viene accreditato
|
|
- Il tuo **indirizzo di deposito**, con bottone per copiarlo negli appunti
|
|
- Il **QR code** dello stesso indirizzo, comodo per inviare PLM da un altro
|
|
wallet scansionandolo invece di copiare l'indirizzo a mano
|
|
|
|
Per depositare, invia PLM (mainnet reale) a quell'indirizzo da un wallet
|
|
esterno. Un deposito viene accreditato (e diventa spendibile) dopo
|
|
**6 conferme** sulla rete (il valore è configurabile dall'operatore; un'uscita
|
|
di mining ne richiede 120), cioè circa 12 minuti; nel frattempo compare in
|
|
arancione come in attesa. Il saldo si aggiorna da solo, con l'aggiornamento in
|
|
tempo reale; premi "Aggiorna" se vuoi comunque
|
|
ricontrollarlo a mano.
|
|
|
|
### Bet
|
|
|
|
Un bottone unico: piazza l'ingresso a costo fisso (mostrato in PLM) nel round
|
|
corrente. Puoi avere **al massimo una bet attiva alla volta**. Il costo viene
|
|
scalato dal tuo saldo interno.
|
|
|
|
### Prelievo
|
|
|
|
Form con due campi:
|
|
- **Indirizzo esterno**: dove vuoi ricevere i PLM
|
|
- **Importo (PLM)**: quanto prelevare, oppure spunta **"Preleva l'intero
|
|
importo"** per prelevare tutto il saldo confermato senza doverlo
|
|
ricopiare a mano (il campo importo si disabilita e si aggiorna da solo)
|
|
|
|
Il prelievo viene costruito e trasmesso sulla rete; la fee di rete viene
|
|
scalata dall'importo richiesto (non si aggiunge separatamente). L'importo
|
|
minimo prelevabile è pari alla quota fissa di ingresso al round (mostrata
|
|
nella sezione Bet).
|
|
|
|
Con "Preleva l'intero importo" restano sul tuo saldo pochi satoshi (294, cioè
|
|
0,00000294 PLM): senza quel resto la transazione non potrebbe essere
|
|
ritrasmessa con una fee più alta se la rete fosse lenta, e resterebbe bloccata
|
|
per ore. La cifra effettivamente inviata è quindi il saldo meno quei satoshi e
|
|
meno la fee di rete.
|
|
|
|
> **Nota**: attualmente è supportato solo l'indirizzo esterno in formato
|
|
> **P2WPKH bech32** (quelli che iniziano con `plm1q...`). Non inserire
|
|
> indirizzi legacy (quelli che iniziano con `P...`) o P2SH: al momento
|
|
> non sono gestiti correttamente dal server.
|
|
|
|
### Profilo
|
|
|
|
Due card:
|
|
|
|
- **Profilo**: le tue informazioni account — username, indirizzo di
|
|
deposito, saldo interno e data di iscrizione. Sola lettura, nessuna
|
|
modifica possibile qui.
|
|
- **Impostazioni**: form per **cambiare la password**. Serve la password
|
|
attuale (per conferma) più la nuova password (minimo 8 caratteri, digitata
|
|
due volte). Non richiede un nuovo login: la sessione attiva resta valida
|
|
anche dopo il cambio.
|
|
|
|
Se hai dimenticato la password e non riesci più ad accedere, questa sezione
|
|
non ti aiuta (serve la password attuale) — contatta l'operatore della
|
|
piattaforma, che può reimpostartene una nuova dal pannello admin.
|
|
|
|
## Notifiche
|
|
|
|
Ogni azione (registrazione, login, bet, prelievo, ecc.) mostra un breve
|
|
messaggio (toast) verde in caso di successo o rosso in caso di errore, in
|
|
basso nella pagina. Se qualcosa non va e il messaggio non basta a capire il
|
|
motivo, il dettaglio tecnico è nei log del server (`logs/app.log` o
|
|
`data/logs/app.log` con Docker) — non nell'interfaccia.
|