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

114 lines
7.5 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.

# Synthèse structurée UserWallet & API Relay
**Author:** Équipe 4NK
**Date:** 2026-01-26
## 1. userwallet/docs
### ports.md
- **UserWallet (Vite)** : port **3018** (`vite.config.ts`).
- **api-relay (Express)** : port **3019** (ou `PORT`), défaut 3019 dans `index.ts`. Le README api-relay indique 3019.
- **Ports à éviter** : 3007, 8080, 30153017.
### specs.md
Spécification du login décentralisé (secp256k1, contrats, pairing mFA, relais) :
**Complément** : `specs-champs-obligatoires-cnil.md` — champs obligatoires (partage, RSSI, CNIL, cybersécurité, support N1/N2/N3, etc.) et attributs CNIL dans `datajson` (`raisons_usage_tiers`, `raisons_partage_tiers`, `conditions_conservation`, `membre_miner_uuid` pour les champs infogérant). Voir `features/userwallet-membre-miner-infogerant.md`.
- **Modèle** : messages publiés sans signatures ni clés ; signatures et clés publiées séparément ; tout adressé par hash canonique ; récupération par **GET uniquement** (pull).
- **Objets** : Service, Contrat, Champ, Action, ActionLogin, Membre, Pair, MessageBase, Hash, Signature, Validateurs, MsgChiffre, MsgSignature, MsgCle.
- **Graphe** : Service → Contrat → Champ → Action(login) → Membre → Pair ; contraintes « au moins 1 parent ».
- **Pairing** : UUID pair ↔ mots BIP32 ; pairing **obligatoire** pour login.
- **Écrans** : accueil, création/import identité, relais, pairing, sync, services, chemin login, challenge, signatures mFA, publication, résultat.
- **Machine à états** : S_INIT → S_HOME, S_SYNC_GLOBAL, S_PAIR_*, S_LOGIN_*, etc., avec erreurs récupérables / fatales.
### storage.md
- **Relais** : stockage hybride (mémoire + `./data/messages.json`). Messages, `seenHashes`, **signatures et clés** persistés. Sauvegarde à larrêt et périodique (`SAVE_INTERVAL_SECONDS`).
- **Front** : LocalStorage (`userwallet_identity`, `userwallet_relays`, `userwallet_pairs` ; legacy `userwallet_keypair`, `userwallet_services`). **IndexedDB** : `hash_cache`, `userwallet_pairing_confirm`. Protection par mot de passe (identité chiffrée). Graphe en mémoire uniquement (`GraphResolver`).
---
## 2. userwallet/ (frontend)
### Stack
- React 18, React Router, Vite, TypeScript.
- Crypto : `@noble/secp256k1`, `@noble/hashes`.
- Pas de state global (hooks + services).
### Structure
- **/components** : Home, CreateIdentity, ImportIdentity, Login, PairManagement, RelaySettings, Sync, ServiceList, ErrorDisplay, etc.
- **/hooks** : useIdentity, useChannel, useErrorHandler, useServices, etc.
- **/services** : GraphResolver, LoginBuilder, SyncService.
- **/utils** : relay, storage, identity, crypto, canonical, encryption, verification, cache, bip32, pairing, iframeChannel, etc.
- **/types** : identity, message, contract, auth, etc.
### Points notables
- **Identité** : création (secp256k1), import (clé hex 64 car. ou phrase BIP39, dérivation m/44'/0'/0'/0/0 ; passphrase BIP39 non supportée). Protection par mot de passe (PBKDF2 + AES-GCM), déverrouillage (UnlockScreen), verrouillage manuel.
- **Relais** : config dans LocalStorage, test `/health`, GET/POST messages/signatures/keys via `utils/relay`.
- **Pairing** : BIP32 UUID ↔ 8 mots (BIP32-style), `PairConfig` avec `membres_parents_uuid`, `is_local`, `can_sign`, `publicKey?` (optionnel, ECDH). WordInputGrid pour saisie. Confirmation croisée « membre finaliser » (IndexedDB), statut « Connecté ».
- **Graphe** : GraphResolver avec caches (services, contrats, champs, actions, membres, pairs), `resolveLoginPath`, validation des parents.
- **Login** : LoginBuilder (challenge, nonce, chiffrement « for all », preuve avec signatures), publication message → signatures → clés.
- **Sync** : SyncService, HashCache (IndexedDB), `markSeenBatch`, déduplication, fetch clés/signatures, vérification hash/signatures/timestamp, mise à jour du graphe. Détection des confirmations de pairing au sync. **Acceptation** : une version d'objet (MessageAValider) n'est acceptée que si elle est signée par les validateurs conformément aux conditions de l'action de validation ; voir `features/userwallet-acceptation-version-validateurs.md`. **DH** : DH systématique et flux scan → fetch par hash → déchiffrer (login + MsgCle, pairing obligatoire, sync scan-first ECDH) ; voir `features/userwallet-dh-systematique-scan-fetch.md`.
- **Iframe** : iframeChannel + useChannel ; messages `auth-request`, `auth-response`, `login-proof`, `service-status`, `error` ; postMessage vers parent avec `'*'`.
- **Export/import** : identité, relais, pairs, hash_cache, pairing_confirm (IndexedDB). « Supprimer » global avec option export avant suppression.
- **ESLint** : config flat, `typescript-eslint`, type-aware ; voir `features/userwallet-eslint-fix.md`.
---
## 3. api-relay (backend relais)
Voir **api-relay/docs/synthese.md** et **api-relay/README.md**.
### Stack
- Express, CORS, JSON. TypeScript, build ESM (`node dist/index.js`). Pino, compression, rate limiting, validation POST.
### Structure
- **/routes** : messages, signatures, keys, health, **metrics**, **bloom**.
- **/services** : StorageService (index `byService`), RelayService.
- **/lib** : logger, validate. **/middleware** : CORS, logging HTTP, compression, rate limit.
### Endpoints
- **GET /health** : `{ status: 'ok', timestamp }`.
- **GET /messages?start=&end=&service=** : messages dans la fenêtre, indexés par `service_uuid`.
- **POST /messages**, **GET /messages/:hash** : idem.
- **GET/POST /signatures**, **GET /signatures/:hash** : idem.
- **GET/POST /keys**, **GET /keys/:hash** : idem.
- **GET /metrics** : Prometheus (`relay_storage_entries` par kind).
- **GET /bloom** : Bloom filter (JSON) des hash vus.
### Comportement
- **Storage** : messages, signatures, keys, `seenHashes` en mémoire ; **tout persisté** dans `messages.json`. Sauvegarde à larrêt et périodique (`SAVE_INTERVAL_SECONDS`). Déduplication par hash ; relais uniquement si `!alreadySeen` avant `storeMessage`.
- **Config** : PORT, HOST, STORAGE_PATH, PEER_RELAYS, BODY_LIMIT, REQUEST_TIMEOUT_MS, RATE_LIMIT_*, CORS_ORIGINS, LOG_LEVEL. **Déploiement** : `start.sh`, `api-relay.service` (systemd).
---
## 4. Liens entre UserWallet et api-relay
- UserWallet appelle les endpoints du relais (messages, signatures, keys, health) via `utils/relay`.
- Types alignés : MsgChiffre, MsgSignature, MsgCle (structure équivalente, noms français).
- UserWallet utilise `datajson_public` (services_uuid, types_uuid, timestamp, etc.) comme le relais.
- Ports : front 3018, relais 3019 (voir `ports.md`).
---
## 5. Synthèse
| Élément | userwallet | api-relay |
|-----------|--------------------------------------------------------------------|----------------------------------------------------------|
| **Rôle** | Front login décentralisé (secp256k1, contrats, pairing mFA) | Relais stockage + diffusion messages/signatures/clés |
| **Port** | 3018 | 3019 |
| **Stockage** | LocalStorage (identité, relais, pairs) ; IndexedDB (hash_cache, pairing_confirm) ; protection optionnelle | Mémoire + JSON (messages, seenHashes, signatures, keys) |
| **Specs** | Aligné avec specs.md (graphe, ordre message→sig→clés, pull-only) | Séparation messages / signatures / clés, dédup par hash |
**Reste à faire (contrat & login)** : voir `features/userwallet-contrat-login-reste-a-faire.md` (machine à états, écrans, anti-rejeu, validation, etc.).