Files
plm-lottery/docs/adr
davideandClaude Sonnet 5.5 a3c51719bd Confirm transactions by merkle proof and reinstate coins only on a quorum (B-83, TX-06, TX-22, TX-23, ELC-25, ELC-26, DEP-02, DEP-08, AUD-18, ADR-07)
poll_once marked a transaction confirmed on one server's `height > 0`, and
reinstate_reappeared_utxos restored a coin written off as spent outside the platform on
the active server's word alone, so a hostile active server could report a
never-relayed payout as confirmed (winner unpaid, round closed) or put a spent coin
back into a balance.

- electrum/merkle.py: pure merkle-branch verification against a block header.
- ElectrumListener.confirmation_proven(txid, height): the *other* servers are asked for
  blockchain.transaction.get_merkle; a strict majority of at least the quorum minimum
  must return a proof that recomputes to the merkle root of that block's header (block
  height and position checked too). The header is the tip the listener holds, or for an
  older block the one a majority of the quorum agrees on and that meets its own target;
  a height above our tip cannot be proven. Quorum rules are _corroborate_majority's.
- poll_once takes the listener as `network`: the active server's history only nominates
  a candidate (txid, height); the row confirms only when the proof holds, and stays
  pending otherwise. With no network nothing confirms. ConfirmationPoller wires it.
- The reconciler's late-confirmation check of failed rows (B-78) now puts each claimed
  (txid, height) to the same proof instead of counting histories.
- refresh_user splits reinstatement like a credit: find_reinstate_candidates (read-only;
  same outpoint, recorded amount, confirmed) -> corroborate_utxo_reinstatement (same
  quorum as a credit) -> reinstate_reappeared_utxos writes only what was corroborated,
  rechecking the mark under the lock. Nothing is committed in the read phase any more.
- Broadcast fan-out, the third part of the finding, shipped with B-76.

Tests changed because the spec changed: every poll_once call now passes a network that
proves (FakeNetwork) — the confirmation tests are otherwise unchanged; the failed-row
"quorum does not confirm" test now asserts the claim goes to the proof.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:29:30 +02:00
..

Architecture Decision Records (ADR)

Una decisione di progetto = un file. Ogni ADR spiega perché una scelta è stata fatta (contesto, alternative scartate, conseguenze); le regole verificabili che la attuano restano nei documenti di dominio con il loro PREFISSO-NN. Così ogni informazione ha un solo proprietario: l'ADR possiede il perché, il requisito possiede il cosa, il codice il come. Regole: processo-di-modifica.md. Modello per i nuovi: TEMPLATE.md.

Gli identificativi ADR-NN sono stabili e non si riusano (i primi 52 coincidono con i vecchi DEC-NN). Un ADR superato non si cancella: passa a Sostituita da ADR-MM.

Indice per area

Custodia, chiavi e indirizzi

ADR Decisione
ADR-01 La piattaforma è custodiale: tutte le chiavi sono generate e tenute dal server
ADR-02 Un indirizzo per utente, permanente, per tutti gli usi
ADR-03 Ogni round ha il proprio indirizzo del montepremi
ADR-04 Accesso alla rete solo via protocollo Electrum
ADR-05 Solo indirizzi bech32 PLM (plm1…) come destinazione

Conferme e fiducia nella rete

ADR Decisione
ADR-06 I depositi richiedono deposit_confirmations conferme (6 per default, configurabile in round_config), le uscite coinbase 120; ogni altra transazione ne richiede 1
ADR-07 Ogni decisione che sposta denaro in base a una risposta di rete è corroborata da un quorum degli altri server configurati
ADR-52 Le riorganizzazioni della catena si contengono invece di ignorarle

Configurazione e ambiente

ADR Decisione
ADR-08 I parametri operativi stanno nel database, i segreti nell'ambiente
ADR-09 Le modifiche di configurazione sono validate, non fidate
ADR-10 I parametri del round sono fotografati all'apertura
ADR-11 Il server rifiuta di partire con segreti inadeguati
ADR-12 Il server gira solo in Docker, in sviluppo come in produzione
ADR-13 Un solo processo, un solo file SQLite

Economia del gioco

ADR Decisione
ADR-14 Ripartizione fissa 70% al vincitore / 30% alla piattaforma
ADR-15 Biglietto a prezzo fisso, una scommessa per utente per round, probabilità uguale per tutti
ADR-16 La commissione di rete si toglie dall'importo che si muove
ADR-17 La commissione del pagamento esce dalla quota del vincitore; la riserva per l'RBF esce dalla quota della piattaforma
ADR-18 L'accelerazione RBF la paga chi riceve il resto
ADR-19 Ogni transazione utente conserva un'uscita di resto verso l'utente, e un'accelerazione che porterebbe quel resto sotto DUST_LIMIT_SATS (294 sat) lo elimina
ADR-20 Il prelievo minimo è il costo corrente della scommessa
ADR-21 Tre limiti distinti sul numero di monete e di giocatori:

Round ed estrazione

ADR Decisione
ADR-22 Al più un round attivo, come invariante del database
ADR-23 Il limite per scommettere è la scadenza del round stesso, non il suo stato nel database
ADR-24 L'estrazione è un commit-reveal fra il server e un blocco futuro
ADR-25 Il blocco di estrazione è fissato per altezza, è successivo alla chiusura, e si usa solo quando è confermato e corroborato
ADR-26 Validazione degli header concatenata, senza ricalcolo della difficoltà
ADR-27 Pausa di cortesia fra un round e l'altro
ADR-28 La pausa per manutenzione ferma solo il round successivo
ADR-29 Senza fee_address non si apre nessun round
ADR-30 Il montepremi annunciato è quello che sarà pagato

Denaro in movimento

ADR Decisione
ADR-31 Tutto ciò che spende denaro si scrive prima di inviarlo
ADR-32 Il pagamento si ritenta da solo, mai due volte
ADR-33 Scommessa e prelievo si escludono solo tramite il blocco per-utente
ADR-34 Saldo spendibile e saldo mostrato sono due numeri distinti
ADR-35 Aritmetica solo in satoshi interi
ADR-51 Nel dubbio non si liberano mai i fondi

Account, amministrazione e sicurezza

ADR Decisione
ADR-36 Password con Argon2, sessioni con JWT HS256 da 24 ore, revocabili
ADR-37 Nessun recupero password, solo reset
ADR-38 Gli username sono un unico spazio di nomi senza distinzione fra maiuscole e minuscole
ADR-39 L'esportazione della chiave privata WIF di un utente è voluta, non una vulnerabilità
ADR-40 L'amministrazione usa un unico token condiviso
ADR-41 Limitazione dei tentativi solo su login e registrazione
ADR-42 L'IP del client è l'ultimo elemento di X-Forwarded-For
ADR-43 Header di sicurezza nel proxy, con 'unsafe-inline' accettato
ADR-44 /qr/{address} è pubblico ma limitato
ADR-45 Segnalazioni di bug aperte a tutti, triage in admin
ADR-53 Il registro di audit è in sola aggiunta e si scrive nella transazione che descrive

Interfacce, API e lingue

ADR Decisione
ADR-46 Il canale SSE è un'aggiunta al polling, non un sostituto
ADR-47 L'API parla una sola lingua e risponde con codici
ADR-48 Le pagine per l'utente (/ e /report-bug) sono in 7 lingue
ADR-49 Il pannello /admin e la pagina /guida non sono tradotti
ADR-50 Frontend statici, senza framework né build

Funzionalità → ADR

Per ogni funzionalità, gli ADR da leggere prima di toccarla.

Funzionalità Prefisso Documento di dominio ADR
Registrazione e account REG registrazione-e-depositi.md 01, 02, 36, 37, 38
Depositi e saldo DEP registrazione-e-depositi.md 06, 07, 34, 35, 52
Scommesse BET scommesse-e-prelievi.md 15, 16, 19, 21, 23, 33
Prelievi WDR scommesse-e-prelievi.md 05, 18, 19, 20, 33
Round, estrazione, pagamento RND ciclo-di-vita-del-round.md 03, 10, 14, 17, 21–30, 32
Transazioni, RBF, riconciliazione TX transazioni-e-riconciliazione.md 17, 18, 31, 32, 51
Connessione Electrum ELC connessione-electrum.md 04, 07, 26, 52
Registro di audit AUD audit-log.md 40, 53
Amministrazione SEC, API sicurezza.md, api.md 09, 28, 29, 39, 40
Sicurezza (limiti, header, QR) SEC sicurezza.md 41, 42, 43, 44
Segnalazioni di bug API api.md 45
Tempo reale (SSE) ARC architettura.md 46
Interfacce e lingue ARC, API architettura.md 47, 48, 49, 50
Configurazione e ambiente ARC, OPS architettura.md, operativita.md 08, 09, 10, 11, 12, 13

Le decisioni del 2026-09-28

Decisione ADR B-nn
Estrazione con commit-reveal ADR-24, ADR-25 B-73, B-81
Nel dubbio non si liberano mai i fondi ADR-51 B-76, B-77, B-78
Un indirizzo del montepremi per ogni round ADR-03 B-80
6 conferme per i depositi, 1 per il resto ADR-06 B-82
Le riorganizzazioni della catena si contengono ADR-52 B-82, B-85