The pool normally holds exactly the round's bet outputs and the payout spent them all for exactly the pool amount, so it had no change output: bump_fee could never accelerate it, and a payout stuck in a mempool (never abandoned while a server knows it) kept the round in `paying_out` and the whole lottery stopped. - build_payout_transaction always has three outputs: winner, fee address, and a bump reserve of max(DUST_LIMIT_SATS, estimate_vsize(inputs, 3) * 10 sat/vB) paid to the reserve address m/84'/746'/0'/1/0. The reserve comes out of the platform's 30%, the network fee still out of the winner's 70%. Input value beyond winner share + commission (only rounds opened before the per-round pool address) is folded into the reserve output if >= dust, left to the network fee otherwise. `change_address` is replaced by `reserve_address`. - `rounds.bump_reserve_sats` (Alembic e5a91c3d7b26, plain add_column) is written with the payout intent before the broadcast; /admin/rounds returns it. - bump_fee takes the increase from the reserve output for a payout (_find_reducible_output; a payout already in flight with a change to the pool still falls back to that), never from the winner or fee-address outputs. - payout_config_problem / rounds_can_open (RND-40): a bet amount and fee rate under which a round of 1 or of MAX_PARTICIPANTS_PER_ROUND participants could not cover the network fee, the reserve and dust outputs opens no round (lottery_configured=false); PUT /admin/config refuses such a bet amount or fee rate with 422 config_not_payable, judged on the resulting values, since the payout reads the fee rate live. Ambiguity resolved: the reserve output and any excess input are one output (RND-23 says one output to the reserve address), and bump_reserve_sats records that output's initial value. DAT-22's "abandon clears all amounts" stays with B-96. Tests changed because the spec changed: the four test_payout_builder tests asserted the old two/three-output shape with change to the pool and the fee address receiving the whole 30%; the whitespace fee_address test now spells out the amounts rounds_can_open reads. New: reserve sizing, payout with 1 and with 400 participants (inputs = outputs + fee to the satoshi), exact commission/reserve/dust boundary, excess folded or left to the fee, a real payout bumped out of its reserve with the other outputs byte-identical and bumped five times, the old reserve-less shape still raising RbfError, the scheduler output addresses and recorded amounts, payability boundaries found independently by bisection, no round / unconfigured flag for an unpayable config, a round in progress surviving it, PUT /admin/config refusals and the migration column. Mutation-checked: dropping the reserve lookup in bump_fee and the payability check in rounds_can_open each fail tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Documentazione di PLM Lottery
Questa cartella è la fonte di verità del progetto: si lavora docs-first (prima si scrive o si modifica la documentazione, poi il codice) e ogni informazione ha un solo proprietario (SSOT). Questo file è l'indice: da qui si raggiunge tutto il resto.
I tre principi
- Docs-first. Nessuna modifica di comportamento parte dal codice. Si modifica il requisito (o si scrive l'ADR, se è una scelta nuova), poi si implementa, poi si testa. Spec, codice e test entrano nello stesso commit.
- SSOT — un solo proprietario per ogni informazione. Il perché di una
scelta sta in un ADR; il cosa verificabile in un requisito
(
PREFISSO-NN) del documento di dominio; il come nel codice; la cronologia dei difetti instorico-bug.md. Gli altri documenti rimandano all'ID, non ripetono il testo. Se due documenti dicono cose diverse, vince la specifica e si corregge l'altro. - Un ADR per ogni funzionalità. Ogni funzionalità nuova inizia con un ADR in adr/ (modello: adr/TEMPLATE.md) che registra contesto, decisione, alternative scartate e conseguenze, e ne elenca i requisiti.
Dove si trova cosa
| Domanda | Dove |
|---|---|
| Perché è fatto così? Quali alternative sono state scartate? | adr/ — indice per area e tabella funzionalità → ADR |
| Cosa deve fare esattamente il software? | I documenti di dominio qui sotto (requisiti con ID stabile) |
| Quali limiti abbiamo accettato? | limiti-noti.md (LIM-nn) |
| Che bug sono stati trovati/corretti? Quali restano aperti? | storico-bug.md; i soli aperti in ../BUGS.md |
| In che ordine si implementano le correzioni aperte? | piano-correzioni.md |
| Come si modifica la documentazione/il codice? | processo-di-modifica.md |
| Come si installa, si avvia, si usa? | Guide operative qui sotto |
Specifica (documenti di dominio)
Punto d'ingresso narrativo: come-funziona.md.
| Documento | Prefisso | Contenuto |
|---|---|---|
| registrazione-e-depositi.md | REG, DEP |
Account, indirizzi, depositi, saldo |
| scommesse-e-prelievi.md | BET, WDR |
Scommesse e prelievi |
| ciclo-di-vita-del-round.md | RND |
Apertura, chiusura, estrazione, pagamento |
| transazioni-e-riconciliazione.md | TX |
Ciclo di vita delle transazioni, RBF, riconciliazione |
| connessione-electrum.md | ELC |
Accesso alla rete PLM e difese |
| architettura.md | ARC |
Struttura del codice, processi, frontend, test |
| modello-dati.md | DAT |
Tabelle, campi, stati, vincoli |
| api.md | API |
Endpoint, risposte, codici di errore |
| sicurezza.md | SEC |
Fiducia, chiavi, autenticazione, limiti sui tentativi |
| audit-log.md | AUD |
Catalogo degli eventi di audit |
| operativita.md | OPS |
Backup, riavvii, incidenti |
Decisioni, limiti, storia
| Documento | Prefisso | Contenuto |
|---|---|---|
| adr/ | ADR |
Una decisione di progetto per file (53 al momento) |
| limiti-noti.md | LIM |
Limiti accettati consapevolmente |
| storico-bug.md | B-nn |
Tutti i bug trovati e corretti |
| piano-correzioni.md | — | Ordine di implementazione delle correzioni aperte |
Guide operative (senza requisiti)
setup.md · running-the-server.md · guida-utente.md · guida-admin.md. Si aggiornano quando la specifica cambia qualcosa di visibile.
Lingua
La documentazione di docs/ è in italiano, per scelta esplicita; tutto il
resto del repository (codice, commenti, commit, CLAUDE.md, BUGS.md) è in
inglese.