anchorage_layer_simple/features/api-anchorage-optimisation-bitcoind-rpc.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

9.3 KiB
Raw Blame History

Optimisation api-anchorage pour réduire la charge sur bitcoind

Date: 2026-01-27 Auteur: Équipe 4NK

Objectif

Réduire la charge RPC de api-anchorage sur bitcoind sans modifier le code de l'application, uniquement via des optimisations de configuration et d'infrastructure.

Analyse de la consommation RPC

Appels RPC identifiés

1. Health Check (/health)

  • Fréquence: À chaque requête GET /health
  • Appels RPC:
    • getNetworkInfo()
    • getBlockchainInfo()
  • Impact: 2 appels RPC par health check

2. Création de transaction d'ancrage (POST /api/anchor/document)

  • Appels RPC par transaction:
    • getNewAddress() - 9 fois (1 anchor + 7 provisioning + 1 change)
    • getBalance() - 1 fois
    • listunspent - 1 fois (via fetch direct)
    • createrawtransaction - 1 fois
    • signrawtransactionwithwallet - 1 fois
    • sendrawtransaction - 1 fois
    • getTransaction() - 1 fois
    • getBlockchainInfo() - 1 fois
    • getRawTransaction() - plusieurs fois (pour calculer les frais, 1 par input)
  • Total: ~15-20 appels RPC par transaction d'ancrage

3. Vérification d'ancrage (POST /api/anchor/verify)

  • Appels RPC:
    • getBlockchainInfo() - 1 fois
    • getBlockHash() - 100 fois (recherche dans les 100 derniers blocs)
    • getBlock() - 100 fois (un par bloc)
    • getRawTransaction() - plusieurs centaines (une par transaction dans chaque bloc)
  • Impact: Très élevé si beaucoup de transactions par bloc

Optimisations possibles (sans modifier le code)

1. Cache HTTP pour le health check

Problème: Le health check fait 2 appels RPC à chaque requête.

Solution: Mettre en cache la réponse du health check côté nginx.

Configuration nginx (sur le proxy):

location /health {
    proxy_pass http://192.168.1.103:3010/health;
    proxy_cache_valid 200 30s;  # Cache 30 secondes
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    add_header X-Cache-Status $upstream_cache_status;
}

Impact: Réduction de 95%+ des appels RPC pour le health check si appelé fréquemment.

2. Augmenter le timeout RPC

Configuration actuelle: BITCOIN_RPC_TIMEOUT=30000 (30 secondes)

Recommandation: Augmenter à 60000ms (60 secondes) pour éviter les timeouts lors de pics de charge.

Fichier: .env

BITCOIN_RPC_TIMEOUT=60000

Impact: Réduction des erreurs et reconnexions lors de pics de charge.

3. Optimiser la configuration bitcoind RPC

Configuration bitcoin.conf:

# Augmenter le nombre de threads RPC
rpcthreads=16

# Augmenter la taille du cache RPC
rpcmaxconnections=128

# Timeout RPC plus long
rpcservertimeout=60

# Désactiver les fonctionnalités non utilisées
disablewallet=0  # Nécessaire pour api-anchorage
txindex=1  # Nécessaire pour les vérifications

Impact: Meilleure gestion des requêtes concurrentes, réduction de la latence.

4. Limiter la fréquence des health checks externes

Problème: Si un monitoring externe appelle /health très fréquemment (toutes les 5-10 secondes), cela génère beaucoup d'appels RPC.

Solution:

  • Configurer le monitoring pour appeler /health toutes les 30-60 secondes au lieu de 5-10 secondes
  • Utiliser le cache nginx (voir point 1) pour les appels plus fréquents

Impact: Réduction proportionnelle des appels RPC.

5. Pool de connexions HTTP keep-alive

Problème: La bibliothèque bitcoin-core peut créer de nouvelles connexions pour chaque requête.

Solution: Vérifier que bitcoind accepte les connexions keep-alive (par défaut activé).

Vérification:

# Vérifier que bitcoind accepte keep-alive
docker exec bitcoin-signet-instance bitcoin-cli -signet getnetworkinfo | grep -i keep

Impact: Réduction de la surcharge de connexions TCP.

6. Limiter les requêtes concurrentes

Problème: Si plusieurs requêtes d'ancrage arrivent simultanément, elles font toutes des appels RPC en parallèle.

Solution: Mettre en place un rate limiting côté nginx pour limiter le nombre de requêtes simultanées.

Configuration nginx:

limit_req_zone $binary_remote_addr zone=anchor_api:10m rate=10r/s;

location /api/anchor {
    limit_req zone=anchor_api burst=5 nodelay;
    proxy_pass http://192.168.1.103:3010;
}

Impact: Réduction de la charge lors de pics de trafic, meilleure stabilité.

7. Optimiser la recherche dans verifyAnchor

Problème: verifyAnchor recherche dans les 100 derniers blocs, ce qui génère des centaines d'appels RPC.

Note: Cette optimisation nécessiterait une modification du code pour réduire le nombre de blocs recherchés ou utiliser un index. Non applicable sans modification du code.

Alternative: Limiter l'accès à l'endpoint /api/anchor/verify via rate limiting strict.

Configuration nginx:

limit_req_zone $binary_remote_addr zone=verify_api:10m rate=1r/s;

location /api/anchor/verify {
    limit_req zone=verify_api burst=2 nodelay;
    proxy_pass http://192.168.1.103:3010;
}

Impact: Réduction drastique des appels RPC pour la vérification.

8. Monitoring et alertes

Solution: Mettre en place un monitoring des appels RPC pour identifier les pics de charge.

Métriques à surveiller:

  • Nombre d'appels RPC par seconde
  • Latence des appels RPC
  • Taux d'erreur RPC
  • Utilisation CPU/mémoire de bitcoind

Impact: Identification proactive des problèmes de performance.

Recommandations prioritaires

Priorité haute (impact immédiat)

  1. Cache HTTP pour /health - Impact immédiat si le health check est appelé fréquemment
  2. Rate limiting pour /api/anchor/verify - Réduction drastique des appels RPC coûteux
  3. Augmenter BITCOIN_RPC_TIMEOUT - Réduction des erreurs et reconnexions

Priorité moyenne

  1. Optimiser la configuration bitcoind RPC - Amélioration générale des performances
  2. Rate limiting général pour /api/anchor - Protection contre les pics de trafic

Priorité basse

  1. Monitoring des appels RPC - Visibilité et optimisation future
  2. Limiter la fréquence des health checks externes - Si applicable

Modalités de déploiement

1. Cache HTTP pour health check

Fichier: Configuration nginx sur le proxy (192.168.1.100)

Étapes:

  1. Identifier le fichier de configuration nginx pour certificator.4nkweb.com
  2. Ajouter la configuration de cache pour /health
  3. Tester avec curl -I https://certificator.4nkweb.com/health
  4. Vérifier le header X-Cache-Status

2. Augmenter le timeout RPC

Fichier: /home/ncantu/Bureau/code/bitcoin/api-anchorage/.env

Modification:

BITCOIN_RPC_TIMEOUT=60000

Redémarrage:

systemctl restart anchorage-api.service

3. Rate limiting nginx

Fichier: Configuration nginx sur le proxy

Étapes:

  1. Ajouter les zones de rate limiting
  2. Appliquer aux endpoints appropriés
  3. Tester avec des requêtes multiples
  4. Ajuster les limites selon les besoins

4. Optimisation bitcoind

Fichier: Configuration bitcoin dans le conteneur Docker

Étapes:

  1. Identifier le fichier bitcoin.conf du conteneur
  2. Ajouter les paramètres d'optimisation
  3. Redémarrer le conteneur bitcoin-signet-instance
  4. Vérifier les performances

Modalités d'analyse

Métriques à surveiller

Avant optimisation:

# Compter les appels RPC par minute
docker exec bitcoin-signet-instance bitcoin-cli -signet getrpcinfo

# Surveiller la charge CPU de bitcoind
top -p $(pgrep -f bitcoind)

# Surveiller les logs d'api-anchorage
journalctl -u anchorage-api.service -f

Après optimisation:

  • Comparer le nombre d'appels RPC
  • Comparer la latence des requêtes
  • Comparer l'utilisation CPU/mémoire de bitcoind
  • Vérifier le taux de cache hit pour /health

Tests de charge

Test 1: Health check fréquent

# Avant cache
for i in {1..100}; do curl -s https://certificator.4nkweb.com/health > /dev/null; done

# Après cache (vérifier X-Cache-Status: HIT)
for i in {1..100}; do curl -sI https://certificator.4nkweb.com/health | grep X-Cache-Status; done

Test 2: Vérification d'ancrage

# Tester avec rate limiting
for i in {1..10}; do 
  curl -X POST https://certificator.4nkweb.com/api/anchor/verify \
    -H "Content-Type: application/json" \
    -d '{"hash":"0000000000000000000000000000000000000000000000000000000000000000"}' \
    -w "\nTime: %{time_total}s\n"
done

Impact attendu

Réduction des appels RPC

  • Health check: 95%+ de réduction si appelé fréquemment (avec cache)
  • Verify anchor: 90%+ de réduction (avec rate limiting à 1 req/s)
  • Create anchor: 10-20% de réduction (avec rate limiting et timeout optimisé)

Amélioration des performances

  • Latence RPC: Réduction de 20-30% avec configuration bitcoind optimisée
  • Stabilité: Réduction des erreurs de timeout et reconnexions
  • Charge CPU bitcoind: Réduction de 30-50% lors de pics de trafic

Limitations

Ces optimisations ne peuvent pas résoudre:

  • Le nombre élevé d'appels getNewAddress() dans createAnchorTransaction (9 appels par transaction)
  • La recherche exhaustive dans verifyAnchor (100 blocs × transactions par bloc)
  • Les appels getRawTransaction() multiples pour le calcul des frais

Pour ces optimisations, une modification du code serait nécessaire.