anchorage_layer_simple/features/synchronisation-automatique-utxos-depenses.md
ncantu 1d4b0d8f33 Pagination serveur, correction UTXO déjà dépensé et synchronisation automatique
**Motivations:**
- Réduire la consommation mémoire en paginant côté serveur au lieu de charger toutes les données
- Corriger les erreurs "Input not found or already spent" dans l'API d'ancrage
- Maintenir la synchronisation entre la base de données et l'état réel de Bitcoin
- Améliorer l'expérience utilisateur avec un suivi de progression pour la collecte de signatures

**Root causes:**
- Pagination effectuée côté client : le serveur retournait tous les UTXOs/hashes (68k+ UTXOs, 32k+ hashes) puis le frontend paginait en JavaScript
- Désynchronisation entre la DB et Bitcoin : UTXOs dépensés non mis à jour dans la base de données
- Détection d'erreur incomplète : ne couvrait pas tous les cas ("already spent", "input not found")
- Pas de vérification de disponibilité de l'UTXO juste avant utilisation dans une transaction

**Correctifs:**
- Implémentation de la pagination côté serveur pour `/api/utxo/list` et `/api/hash/list` avec paramètres `page` et `limit`
- Amélioration de la détection d'erreur pour inclure "already spent" et "input not found"
- Ajout d'une vérification de disponibilité de l'UTXO avant utilisation avec mécanisme de retry (max 3 tentatives)
- Mise à jour automatique de tous les UTXOs dépensés dans la base de données lors de chaque synchronisation
- Script de synchronisation périodique avec cron job toutes les heures
- Optimisation mémoire : utilisation de tables temporaires SQL au lieu de charger tous les UTXOs en mémoire

**Evolutions:**
- Pagination serveur avec métadonnées (total, totalPages, page, limit) pour les endpoints `/api/utxo/list` et `/api/hash/list`
- Adaptation du frontend pour utiliser la pagination serveur (compatibilité maintenue avec chargement jusqu'à 1000 éléments)
- Ajout de `onProgress` callback dans `runCollectLoop` pour notifier la progression de la collecte de signatures
- Nouvelle fonction `collectProgress` pour calculer la progression (satisfied vs required) pour les notifications/UI
- Refactoring de `hasEnoughSignatures` avec extraction de `pairsPerMemberFromSigs` pour réutilisabilité

**Pages affectées:**
- `api-anchorage/src/bitcoin-rpc.js` : Vérification disponibilité UTXO, amélioration détection erreur, paramètre retryCount
- `api-anchorage/src/routes/anchor.js` : Passage des nouveaux paramètres à createAnchorTransaction
- `signet-dashboard/src/server.js` : Pagination pour `/api/hash/list` et `/api/utxo/list`
- `signet-dashboard/src/bitcoin-rpc.js` : Mise à jour automatique de tous les UTXOs dépensés avec optimisation mémoire
- `signet-dashboard/public/hash-list.html` : Adaptation pour charger avec pagination serveur
- `signet-dashboard/public/utxo-list.html` : Adaptation pour utiliser la pagination serveur par catégorie
- `userwallet/src/utils/collectSignatures.ts` : Ajout interface CollectLoopOpts avec onProgress callback
- `userwallet/src/utils/loginValidation.ts` : Ajout fonction collectProgress, refactoring avec pairsPerMemberFromSigs
- `data/sync-utxos-spent-status.mjs` : Script de synchronisation périodique des UTXOs dépensés
- `data/sync-utxos-cron.sh` : Script wrapper pour cron job
- `features/pagination-serveur-base-donnees.md` : Documentation de la pagination serveur
- `features/synchronisation-automatique-utxos-depenses.md` : Documentation de la synchronisation automatique
- `fixKnowledge/api-anchorage-utxo-already-spent-error.md` : Documentation de la correction de l'erreur UTXO déjà dépensé
2026-01-27 22:21:38 +01:00

180 lines
6.1 KiB
Markdown

# Synchronisation automatique des UTXOs dépensés
**Auteur** : Équipe 4NK
**Date** : 2026-01-27
**Version** : 1.0
## Objectif
Mettre à jour automatiquement tous les UTXOs dépensés dans la base de données pour maintenir la synchronisation avec l'état réel de Bitcoin, tout en réduisant l'usage mémoire.
## Problème Identifié
### Avant
- `signet-dashboard` ne mettait à jour que les UTXOs chargés en mémoire lors d'une mise à jour
- Les UTXOs dépensés n'étaient pas mis à jour dans la base de données s'ils n'étaient pas en mémoire
- Désynchronisation entre la DB et l'état réel de Bitcoin
- 442 UTXOs dépensés détectés lors de la première synchronisation
### Impact
- L'API d'ancrage sélectionnait des UTXOs déjà dépensés
- Erreurs "Input not found or already spent" lors de la création de transactions
- Dégradation de la fiabilité de l'API d'ancrage
## Solutions Implémentées
### 1. Mise à jour automatique dans signet-dashboard
**Fichier** : `signet-dashboard/src/bitcoin-rpc.js`
**Modification** : Mise à jour de TOUS les UTXOs de la base de données lors de chaque synchronisation, pas seulement ceux en mémoire.
**Optimisations mémoire** :
- Utilisation d'une table temporaire SQL au lieu de charger tous les UTXOs en mémoire
- Traitement par batch de 1000 UTXOs pour réduire la consommation mémoire
- Une seule requête SQL pour mettre à jour tous les UTXOs dépensés
**Code** :
```javascript
// Créer une table temporaire pour stocker les UTXOs disponibles
db.exec(`
CREATE TEMP TABLE IF NOT EXISTS temp_available_utxos (
txid TEXT,
vout INTEGER,
PRIMARY KEY (txid, vout)
)
`);
// Insérer les UTXOs disponibles par batch
const SYNC_BATCH_SIZE = 1000;
for (let i = 0; i < unspent.length; i += SYNC_BATCH_SIZE) {
const batch = unspent.slice(i, i + SYNC_BATCH_SIZE);
insertBatch(batch);
}
// Mettre à jour les UTXOs dépensés en une seule requête SQL
const updateSpentStmt = db.prepare(`
UPDATE utxos
SET is_spent_onchain = 1, updated_at = CURRENT_TIMESTAMP
WHERE is_spent_onchain = 0
AND (txid || ':' || vout) NOT IN (
SELECT txid || ':' || vout FROM temp_available_utxos
)
`);
```
### 2. Script de synchronisation périodique
**Fichier** : `data/sync-utxos-spent-status.mjs`
**Fonctionnalités** :
- Vérifie tous les UTXOs marqués comme non dépensés dans la DB
- Compare avec `listunspent` depuis Bitcoin
- Met à jour `is_spent_onchain = 1` pour ceux qui ne sont plus disponibles
- Optimisé pour la mémoire : utilise une table temporaire SQL au lieu de charger tous les UTXOs en mémoire
**Optimisations mémoire** :
- Ne charge pas tous les UTXOs de la DB en mémoire (compte seulement)
- Utilise une table temporaire SQL pour les UTXOs disponibles
- Traitement par batch de 1000 UTXOs
### 3. Cron job pour synchronisation automatique
**Fichier** : `data/sync-utxos-cron.sh`
**Configuration** : Exécution toutes les heures via cron
```bash
0 * * * * /home/ncantu/Bureau/code/bitcoin/data/sync-utxos-cron.sh
```
**Fonctionnalités** :
- Exécute le script de synchronisation
- Log les résultats dans `data/sync-utxos.log`
- Garde seulement les 100 dernières lignes du log
## Modifications
### Fichiers Modifiés
- `signet-dashboard/src/bitcoin-rpc.js` :
- Ligne 1033-1101 : Mise à jour automatique de tous les UTXOs dépensés lors de chaque synchronisation
- Utilisation d'une table temporaire SQL pour réduire la mémoire
- Traitement par batch de 1000 UTXOs
### Fichiers Créés
- `data/sync-utxos-spent-status.mjs` : Script de synchronisation des UTXOs dépensés
- `data/sync-utxos-cron.sh` : Script wrapper pour cron
- `features/synchronisation-automatique-utxos-depenses.md` : Cette documentation
## Modalités de Déploiement
### Déploiement Automatique
1. **Redémarrer signet-dashboard** :
```bash
sudo systemctl restart signet-dashboard.service
```
2. **Vérifier le cron** :
```bash
crontab -l | grep sync-utxos
```
3. **Tester le script manuellement** :
```bash
cd /home/ncantu/Bureau/code/bitcoin
node data/sync-utxos-spent-status.mjs
```
### Vérification
1. **Vérifier les logs de synchronisation** :
```bash
tail -f /home/ncantu/Bureau/code/bitcoin/data/sync-utxos.log
```
2. **Vérifier les statistiques** :
```bash
cd /home/ncantu/Bureau/code/bitcoin/signet-dashboard
node -e "const Database = require('better-sqlite3'); const db = new Database('../data/signet.db'); const stats = { total: db.prepare('SELECT COUNT(*) as count FROM utxos').get().count, spent: db.prepare('SELECT COUNT(*) as count FROM utxos WHERE is_spent_onchain = 1').get().count, notSpent: db.prepare('SELECT COUNT(*) as count FROM utxos WHERE is_spent_onchain = 0').get().count }; console.log('Total:', stats.total, 'Dépensés:', stats.spent, 'Non dépensés:', stats.notSpent); db.close();"
```
## Modalités d'Analyse
### Vérification que la correction fonctionne
1. **Vérifier la synchronisation automatique** :
- Les logs de `signet-dashboard` doivent afficher "UTXOs dépensés mis à jour dans la base de données" lors de chaque synchronisation
- Le nombre d'UTXOs dépensés doit augmenter progressivement
2. **Vérifier le cron** :
- Le script doit s'exécuter toutes les heures
- Les logs doivent être écrits dans `data/sync-utxos.log`
3. **Vérifier l'API d'ancrage** :
- Plus d'erreurs "Input not found or already spent"
- Les UTXOs sélectionnés sont toujours disponibles
### Optimisations Mémoire
1. **Avant** :
- Chargement de tous les UTXOs en mémoire (68k+ UTXOs)
- Création d'un Set avec tous les UTXOs disponibles
- Consommation mémoire élevée
2. **Après** :
- Utilisation d'une table temporaire SQL
- Traitement par batch de 1000 UTXOs
- Réduction significative de la consommation mémoire
## Bénéfices
1. **Synchronisation complète** : Tous les UTXOs sont mis à jour, pas seulement ceux en mémoire
2. **Réduction mémoire** : Utilisation de tables temporaires SQL au lieu de structures en mémoire
3. **Fiabilité** : L'API d'ancrage ne sélectionne plus d'UTXOs déjà dépensés
4. **Automatisation** : Synchronisation automatique via cron toutes les heures