anchorage_layer_simple/features/userwallet-collecte-distante-2-devices.md
ncantu 0960e43a45 Optimisation mémoire api-anchorage avec base de données SQLite
**Motivations:**
- Réduction drastique de la consommation mémoire lors des ancrages
- Élimination du chargement de 173k+ UTXOs à chaque requête
- Stabilisation de la mémoire système sous charge élevée (50+ ancrages/minute)

**Root causes:**
- api-anchorage chargeait tous les UTXOs (173k+) via listunspent RPC à chaque ancrage
- Filtrage et tri de 173k+ objets en mémoire pour sélectionner un seul UTXO
- Croissance mémoire de ~16 MB toutes les 12 secondes avec 50 ancrages/minute
- Saturation mémoire système en quelques minutes

**Correctifs:**
- Création du module database.js pour gérer la base de données SQLite partagée
- Remplacement de listunspent RPC par requête SQL directe avec LIMIT 1
- Sélection directe d'un UTXO depuis la DB au lieu de charger/filtrer 173k+ objets
- Marquage des UTXOs comme dépensés dans la DB après utilisation
- Fermeture propre de la base de données lors de l'arrêt

**Evolutions:**
- Utilisation de la base de données SQLite partagée avec signet-dashboard
- Réduction mémoire de 99.999% (173k+ objets → 1 objet par requête)
- Amélioration des performances (requête SQL indexée vs filtrage en mémoire)
- Optimisation mémoire de signet-dashboard (chargement UTXOs seulement si nécessaire)
- Monitoring de lockedUtxos dans api-anchorage pour détecter les fuites
- Nettoyage des intervalles frontend pour éviter les fuites mémoire

**Pages affectées:**
- api-anchorage/src/database.js (nouveau)
- api-anchorage/src/bitcoin-rpc.js
- api-anchorage/src/server.js
- api-anchorage/package.json
- signet-dashboard/src/bitcoin-rpc.js
- signet-dashboard/public/app.js
- features/optimisation-memoire-applications.md (nouveau)
- features/api-anchorage-optimisation-base-donnees.md (nouveau)
2026-01-27 21:12:22 +01:00

48 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UserWallet Collecte distante (2 devices)
**Author:** Équipe 4NK
**Date:** 2026-01-26
## Objectif
Supporter `cardinalite_minimale > 1` avec deux appareils : signature locale sur le 1ᵉʳ, signature sur le 2ᵉ, récupération des sigs via les relais, puis publication de la preuve lorsque toutes les sigs requises sont réunies.
## Flux
1. **Device 1** : construire le challenge, signer localement (pairs locaux du membre), publier message + sigs locales sur les relais.
2. **Device 1** : boucle de collecte — fetch des sigs par hash sur les relais, merge avec les sigs locales, dédup par pair. Dès que `hasEnoughSignatures` (assez de pairs distincts par membre par rapport à `cardinalite_minimale`), on arrête.
3. **Device 2** : obtenir hash et nonce (lien ou QR émis par Device 1 pendant la collecte). Ouvrir `/login-sign?hash=...&nonce=...`, signer `hash-nonce` avec la clé du pair local, poster la signature sur les relais.
4. **Device 1** : une fois assez de sigs (dont celle du 2ᵉ), **si au moins une signature provient du 2ᵉ appareil** (pair non local) → **confirmation manuelle** : « Les mots ont pu être visibles à lécran et interceptés. Confirmer que cest bien vous qui avez validé sur lautre appareil ? » [Accepter] / [Refuser]. **Accepter** → vérification (dépendances, clés autorisées, strict), marquage du nonce, envoi de la preuve au parent. **Refuser** → pas denvoi, transition vers `S_LOGIN_FAILURE`.
5. **Device 1** : si aucune sig distante (cardinalité 1, sig locale seule), pas de confirmation ; vérification et envoi directement.
## Modifications
- **`loginBuilder.signChallenge`** : signature de `hash-nonce` uniquement (plus `pairUuid`), pour alignement vérif + relais.
- **`loginValidation`** : `requiredSigsPerMember`, `hasEnoughSignatures`, **`hasRemoteSignatures`** (au moins une sig dun pair non local). Suppression du refus systématique `cardinalite > 1`.
- **`collectSignatures`** : `fetchSignaturesForHash`, `buildPairToMembers`, `buildPubkeyToPair`, `mapMsgSignaturesToProofFormat`, `runCollectLoop` (poll + timeout).
- **`loginPublish`** : `publishMessageAndSigs` (message + sigs locales vers relais).
- **`LoginScreen`** : signature pour les **pairs locaux** du membre uniquement ; après publication, boucle de collecte si `loginPath` ; **si `hasRemoteSignatures`** → écran de confirmation [Accepter] / [Refuser], puis vérification et envoi uniquement sur Accepter ; sinon vérification et envoi directs. Affichage « En attente des signatures des autres appareils… » + `LoginCollectShare` (lien + QR vers `/login-sign`). **Retour** désactivé pendant la confirmation.
- **Machine à états** : `E_LOCAL_VERDICT_REJECT` depuis `S_LOGIN_PUBLISH_PROOF``S_LOGIN_FAILURE` (refus des sigs distantes sans envoi).
- **`LoginSignScreen`** : route `/login-sign?hash=...&nonce=...` ; signature et publication de la sig sur les relais.
- **`LoginCollectShare`** : lien et QR vers `/login-sign?hash=...&nonce=...` pendant la collecte.
## Modalités de déploiement
Déploiement classique du front userwallet. Aucune évolution côte relais.
## Confirmation manuelle (signatures 2ᵉ appareil)
Les mots (lien/QR) sont affichés à lécran et peuvent être interceptés (épaule, tiers). Quand au moins une signature reçue provient dun **pair non local** (2ᵉ device), Device 1 **nenvoie pas** la preuve tant que lutilisateur na pas **manuellement accepté** (« cest bien moi qui ai validé sur lautre appareil »). [Refuser] → pas denvoi, `S_LOGIN_FAILURE`.
## Modalités danalyse
- **Device 1** : construction du chemin, challenge, publication → collecte → affichage du lien/QR. Ouvrir le lien sur le 2ᵉ appareil, signer → retour sur le 1ᵉʳ, la collecte doit finir. **Si sigs distantes** : affichage de la confirmation Accepter/Refuser ; Accepter → envoi preuve, Refuser → échec.
- **Device 2** : aller sur `/login-sign?hash=...&nonce=...` (ou scanner le QR), vérifier « Signature publiée ».
- Vérifier timeout de collecte (5 min) si le 2ᵉ ne signe pas.
- Vérifier que [Refuser] nenvoie pas la preuve et mène à létat déchec.
## Références
- `features/userwallet-validation-conformite.md` (§ Cardinalite_minimale)
- `userwallet/docs/specs.md` (collecte signatures mFA, S_LOGIN_COLLECT_SIGNATURES)