anchorage_layer_simple/userwallet/features/userwallet-dh-systematique-scan-fetch.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

5.2 KiB
Raw Blame History

UserWallet DH systématique et flux scan → fetch par hash → déchiffrer

Author: Équipe 4NK
Date: 2026-01-26

Question

Le DH est-il systématiquement mis en place pour les types de messages envoyés (sauf DH) afin que lutilisateur scanneaille chercher le hash avec le message → quil sache alors déchiffrer ?

Réponse courte (avant implémentation)

Non. Aujourdhui le DH nest pas systématique pour tous les types de messages. Seul le pairing utilise ECDH + MsgCle lorsque la clé publique du pair distant est connue ; le login et le sync générique ne suivent pas ce schéma.

État après implémentation (DH systématique + flux scan → fetch → déchiffrer)

1. Pairing (membre finaliser)

  • Envoi : DH obligatoire. recipientPublicKey (clé du pair distant) et senderIdentity requis. Chiffrement ECDH, POST MsgChiffre + POST MsgCle (df_ecdh_scannable = clé publique de lémetteur). Plus de base64.
  • Réception : fetchPairingMessage → fetch messages → fetch keys par hash → déchiffrement ECDH uniquement (plus de base64). Si pas de senderPublicKey / identité → message ignoré.
  • UX : formulaire pairing avec saisie « Clé publique (hex, 66 car.) » du pair distant ; affichage de la clé publique locale pour copie sur lautre appareil.

2. Login (challenge)

  • Envoi : ECDH vers lidentité (destinataire = nous). POST MsgChiffre + POST MsgCle (df_ecdh_scannable = clé publique émetteur) + POST signatures. Plus de encryptForAll ni clé symétrique.
  • Réception : preuve envoyée au parent (iframe). Message login sur le relais déchiffrable via sync (scan keys → fetch par hash → ECDH).

3. Sync générique

  • Flux : scan des MsgCle (GET /keys?start=&end=) → regroupement par hash_messagefetch message par hash (GET /messages/:hash) → déchiffrement ECDH (tryDecryptWithKeys avec df_ecdh_scannable + identité). Plus de base64.
  • Identité : SyncService reçoit LocalIdentity | null ; sans identité, messages traités comme indéchiffrables.

Ce que prévoient les specs

  • Message individuel de déchiffrement : hash + clé de chiffrement + df = « diffie-hellman à scanner » pour obtenir la clé de déchiffrement (secret partagé).
  • Flux : « Récupérer et scanner tous les messages de clés » (depuis date anniversaire / checkpoint) ; les messages déchiffrables sont identifiés via les DH ; puis on va chercher le message par hash et on déchiffre.
  • Publish to all : tout est chiffré ; seuls les pairs qui peuvent dériver la clé (via ECDH) peuvent lire. Le « matériel DH » est publiable car inexploitable par les tiers.

Donc, pour les types de messages hors DH : chiffrement + MsgCle avec df_ecdh_scannable systématique, et flux scan des clés → fetch message par hash → déchiffrer.


Écarts principaux (avant implémentation)

Aspect Specs Actuel (avant)
DH pour tous les messages (hors DH) Oui, via MsgCle + df Non : login sans MsgCle ; pairing optionnel ; sync en base64
Flux Scan MsgCle → hashes déchiffrables → fetch message par hash Fetch messages → fetch keys par hash ; pas de scan MsgCle centré ECDH
Utilisation des clés en sync Déchiffrement ECDH avec df Base64 si keys.length > 0 ; clés non utilisées
Login Sous-entendu publish to all + MsgCle/DH encryptForAll seul, pas de MsgCle

Implémentation réalisée

  1. api-relay : GET /keys?start=&end= (fenêtre received_at), StorageService.getKeysInWindow.
  2. userwallet relay : getKeysInWindow, getMessageByHash.
  3. Login : LoginBuilder utilise encryptWithECDH (identité comme destinataire), challengeToMsgCle, loginPublish POST MsgCle en plus de MsgChiffre et signatures.
  4. Pairing : DH obligatoire ; publishPairingMessage exige recipientPublicKey et senderIdentity ; plus de base64. fetchPairingMessage ECDH uniquement. UX : saisie clé publique (hex 66 car.) + affichage clé locale.
  5. Sync : flux scan-first. SyncService(relays, graphResolver, identity). Pour chaque relais : getKeysInWindow → regroupement par hash → getMessageByHashtryDecryptWithKeys (ECDH) → validation → mise à jour graphe. syncDecrypt.tryDecryptWithKeys utilise decryptWithECDH avec df_ecdh_scannable.

Références

  • userwallet/docs/specs.md : Message individuel de déchiffrement, df DH à scanner, « récupérer et scanner tous les messages de clés », fenêtre de scan, fetch par hash.
  • userwallet/features/userwallet-pairing-connecte.md : chiffrement pairing ECDH vs base64, MsgCle.
  • userwallet/src/utils/encryption.ts : encryptWithECDH / decryptWithECDH.
  • userwallet/src/services/pairingConfirm.ts : publication pairing + MsgCle (DH obligatoire), fetchPairingMessage (ECDH seul).
  • userwallet/src/services/syncService.ts : flux scan-first, getKeysInWindowgetMessageByHashtryDecryptWithKeys.
  • userwallet/src/services/syncDecrypt.ts : tryDecryptWithKeys (ECDH).
  • userwallet/src/services/loginBuilder.ts : ECDH + challengeToMsgCle.