ncantu cad73cb265 UTXO-list: dates/blockTime historiques, récupération frais depuis ancrages, diagnostic Bloc Rewards
**Motivations:**
- Ajouter dates manquantes dans hash_list.txt et compléter historique
- Compléter blockTime manquants dans utxo_list.txt et compléter historique
- Récupérer frais depuis transactions d'ancrage (OP_RETURN) et les stocker
- Bouton UI pour déclencher récupération frais
- Diagnostic Bloc Rewards (pourquoi ~4700 BTC au lieu de 50 BTC)

**Root causes:**
- hash_list.txt sans date (format ancien)
- utxo_list.txt blockTime souvent vide
- Frais absents du fichier (métadonnées OP_RETURN non stockées)
- Pas de moyen de récupérer/compléter frais depuis UI

**Correctifs:**
- hash_list.txt : format étendu avec date (rétrocompatible)
- utxo_list.txt : blockTime complété automatiquement lors écritures
- fees_list.txt : nouveau fichier pour stocker frais
- updateFeesFromAnchors() : récupère frais depuis OP_RETURN ancrages
- Endpoint /api/utxo/fees/update pour déclencher récupération
- Bouton "Récupérer les frais depuis les ancrages" dans section Frais (spinner)
- Scripts batch : complete-hash-list-dates.js, complete-utxo-list-blocktime.js
- Script diagnostic : diagnose-bloc-rewards.js (subsidy, coinbase, listunspent)

**Evolutions:**
- Frais chargés depuis fees_list.txt dans getUtxoList
- Complétion automatique dates/blockTime lors écritures futures

**Pages affectées:**
- signet-dashboard/src/bitcoin-rpc.js
- signet-dashboard/src/server.js
- signet-dashboard/public/utxo-list.html
- scripts/complete-hash-list-dates.js
- scripts/complete-utxo-list-blocktime.js
- scripts/diagnose-bloc-rewards.js
- features/utxo-list-fees-update-and-historical-completion.md
2026-01-26 01:59:46 +01:00

172 lines
4.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.

# Stockage des données - UserWallet
**Author:** Équipe 4NK
**Date:** 2026-01-26
## Synthèse
- **Relais (api-relay)** : Stockage hybride (mémoire + `./data/messages.json`). Messages, `seenHashes`, signatures et clés persistés. Sauvegarde à larrêt (SIGINT/SIGTERM) et périodique (configurable via `SAVE_INTERVAL_SECONDS`).
- **Front (userwallet)** : LocalStorage (`userwallet_identity`, `userwallet_relays`, `userwallet_pairs`, `userwallet_hash_cache` ; legacy : `userwallet_keypair`, `userwallet_services`). Graphe contractuel en mémoire uniquement (`GraphResolver`).
## Stockage sur le relais (api-relay)
### Architecture
Le relais utilise un stockage **hybride** : mémoire + persistance sur disque.
### Structure de stockage
**En mémoire :**
- `messages: Map<string, StoredMessage>` - Messages chiffrés indexés par hash
- `signatures: Map<string, StoredSignature[]>` - Signatures indexées par hash de message
- `keys: Map<string, StoredKey[]>` - Clés de déchiffrement indexées par hash de message
- `seenHashes: Set<string>` - Hash vus pour déduplication
**Sur disque :**
- Fichier `{STORAGE_PATH}/messages.json` contenant :
- `messages`: Array de `[hash, StoredMessage]`
- `seenHashes`: Array de hash (string[])
- `signatures`: Array de `[hash, StoredSignature[]]`
- `keys`: Array de `[hash, StoredKey[]]`
### Persistance
- **Chargement** : Au démarrage, charge `messages.json` si présent (ENOENT = premier run, démarrage à vide).
- **Sauvegarde** : À larrêt (SIGINT/SIGTERM) et périodiquement si `SAVE_INTERVAL_SECONDS` > 0 (défaut 300 s).
### Format de données
**StoredMessage :**
```typescript
{
msg: {
hash: string,
message_chiffre: string,
datajson_public: {
services_uuid: string[],
types_uuid: string[],
timestamp?: number,
...
}
},
received_at: number,
relayed: boolean
}
```
**StoredSignature :**
```typescript
{
msg: {
signature: {
hash: string,
cle_publique: string,
signature: string,
nonce: string,
materiel?: object
},
hash_cible?: string
},
received_at: number,
relayed: boolean
}
```
**StoredKey :**
```typescript
{
msg: {
hash_message: string,
cle_de_chiffrement_message: {
algo: string,
params: object,
cle_chiffree?: string
},
df_ecdh_scannable: string
},
received_at: number,
relayed: boolean
}
```
### Configuration
- `STORAGE_PATH` : Chemin du répertoire de stockage (défaut: `./data`)
- `SAVE_INTERVAL_SECONDS` : Intervalle de sauvegarde périodique en secondes (défaut: 300). Mettre à 0 pour désactiver.
### Limitations actuelles
- Pas de base de données (SQLite/PostgreSQL recommandé en production)
- Pas de compression des données
## Stockage sur le front (userwallet)
### Architecture
Le front utilise **LocalStorage** du navigateur pour toutes les données locales.
### Structure de stockage
**Clés utilisées :**
1. **`userwallet_identity`** : Identité locale
```typescript
{
uuid: string,
privateKey: string,
publicKey: string,
name?: string,
t0_anniversaire: number,
version: string
}
```
2. **`userwallet_relays`** : Configuration des relais
```typescript
Array<{
endpoint: string,
priority: number,
enabled: boolean,
last_sync?: number
}>
```
3. **`userwallet_pairs`** : Configuration des pairs
```typescript
Array<{
uuid: string,
membres_parents_uuid: string[],
is_local: boolean,
can_sign: boolean
}>
```
4. **`userwallet_hash_cache`** : Cache des hash vus
```typescript
string[] // Array de hash
```
5. **`userwallet_keypair`** : (Legacy) Paire de clés
6. **`userwallet_services`** : (Legacy) Services configurés
### Données en mémoire (non persistées)
- **Graphe contractuel** : Résolu dynamiquement depuis les messages synchronisés
- Services, Contrats, Champs, Actions, Membres, Pairs
- Stocké dans `GraphResolver.cache` (Map)
- Perdu au rechargement de page
### Limitations
- **Taille limitée** : LocalStorage a une limite (~5-10MB selon navigateur)
- **Pas de synchronisation** : Données locales uniquement
- **Sécurité** : Clés privées stockées en clair (à chiffrer avec mot de passe)
- **Pas de backup** : Pas de mécanisme d'export/import automatique
### Recommandations
- Chiffrer les clés privées avec un mot de passe utilisateur
- Implémenter un mécanisme d'export/import
- Utiliser IndexedDB pour des données plus volumineuses
- Implémenter une synchronisation cloud optionnelle (chiffrée)