# 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):** ```nginx 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` ```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:** ```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:** ```bash # 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:** ```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:** ```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 4. **Optimiser la configuration bitcoind RPC** - Amélioration générale des performances 5. **Rate limiting général pour `/api/anchor`** - Protection contre les pics de trafic ### Priorité basse 6. **Monitoring des appels RPC** - Visibilité et optimisation future 7. **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:** ```env BITCOIN_RPC_TIMEOUT=60000 ``` **Redémarrage:** ```bash 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:** ```bash # 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** ```bash # 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** ```bash # 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.