# Amélioration : Robustesse de la gestion des UTXOs pour les ancrages **Auteur** : Équipe 4NK **Date** : 2026-01-28 ## Problème Identifié L'API d'ancrage retournait des erreurs "No UTXO large enough for anchor with provisioning" même lorsque le wallet contenait suffisamment de fonds totaux, mais répartis sur plusieurs petits UTXOs. ### Symptômes - Erreur : "No UTXO large enough for anchor with provisioning. Required: 0.00023055 BTC, Largest available: 0.000025 BTC. Total from 9 UTXOs: 0.00021000 BTC" - Le wallet contient plusieurs petits UTXOs dont la somme totale est proche du montant requis - Le code essayait de combiner les UTXOs mais échouait à cause d'un bug de calcul des frais - Les UTXOs disponibles n'étaient pas tous utilisés même si nécessaire ## Cause Racine **Bug de calcul des frais** : La condition de vérification utilisait `totalNeeded + estimatedFeeForMultipleInputs`, mais `totalNeeded` inclut déjà `estimatedFee`. Cela créait un double comptage des frais, empêchant l'utilisation de tous les UTXOs disponibles. **Limitation** : Le code limitait la combinaison à 20 UTXOs maximum, et n'utilisait pas tous les UTXOs disponibles même si nécessaire. ## Correctifs Appliqués ### 1. Correction du bug de calcul des frais **Fichier** : `api-anchorage/src/bitcoin-rpc.js` **Avant** : ```javascript if (totalSelectedAmount >= totalNeeded + estimatedFeeForMultipleInputs) { break; } ``` **Problème** : `totalNeeded` inclut déjà `estimatedFee`, donc on ajoutait les frais deux fois. **Après** : ```javascript // Recalculer les frais avec le nombre actuel d'inputs const currentEstimatedFee = estimatedFee + (selectedUtxos.length * estimatedFeePerInput); const currentTotalNeeded = totalOutputAmount + currentEstimatedFee; if (totalSelectedAmount >= currentTotalNeeded) { estimatedFeeForMultipleInputs = currentEstimatedFee; break; } ``` **Impact** : Les frais sont maintenant calculés correctement, permettant d'utiliser tous les UTXOs disponibles si nécessaire. ### 2. Utilisation de tous les UTXOs disponibles si nécessaire **Modification** : Si la combinaison initiale n'est pas suffisante, le code essaie maintenant d'utiliser TOUS les UTXOs disponibles. ```javascript // Si on n'a pas assez avec les UTXOs sélectionnés, essayer d'utiliser TOUS les UTXOs disponibles if (totalSelectedAmount < finalTotalNeeded && selectedUtxos.length < availableUtxos.length) { // Essayer d'utiliser TOUS les UTXOs disponibles selectedUtxos = []; totalSelectedAmount = 0; for (let i = 0; i < availableUtxos.length; i++) { // Ajouter tous les UTXOs } // Recalculer les frais avec tous les UTXOs estimatedFeeForMultipleInputs = estimatedFee + (selectedUtxos.length * estimatedFeePerInput); finalTotalNeeded = totalOutputAmount + estimatedFeeForMultipleInputs; } ``` **Impact** : Le système utilise maintenant tous les UTXOs disponibles si nécessaire, maximisant les chances de réussite. ### 3. Augmentation de la limite de combinaison **Modification** : La limite de combinaison est passée de 20 à 100 UTXOs pour permettre d'utiliser tous les UTXOs disponibles. ```javascript const maxUtxosToCombine = 100; // Limite élevée pour permettre d'utiliser tous les UTXOs si nécessaire ``` **Impact** : Plus de flexibilité pour gérer les wallets avec de nombreux petits UTXOs. ### 4. Amélioration des messages d'erreur **Modification** : Les messages d'erreur incluent maintenant des suggestions de solutions. ```javascript let suggestion = ''; const shortfall = finalTotalNeeded - totalAvailable; if (shortfall > 0) { suggestion = ` Total available from all ${availableUtxos.length} UTXOs: ${totalAvailable.toFixed(8)} BTC. ` + `Shortfall: ${shortfall.toFixed(8)} BTC. ` + `Solutions: 1) Use faucet to get more funds, 2) Mine more blocks, 3) Consolidate UTXOs via dashboard, 4) Reduce provisioning count.`; } else { suggestion = ` All ${availableUtxos.length} available UTXOs total ${totalAvailable.toFixed(8)} BTC, which should be sufficient. ` + `This may be a fee estimation issue. Consider consolidating UTXOs via dashboard to create larger UTXOs.`; } ``` **Impact** : Les utilisateurs reçoivent des suggestions claires pour résoudre les problèmes de fonds insuffisants. ## Modifications ### Fichiers Modifiés - `api-anchorage/src/bitcoin-rpc.js` : - Correction du bug de calcul des frais dans la combinaison d'UTXOs - Utilisation de tous les UTXOs disponibles si nécessaire - Augmentation de la limite de combinaison (20 → 100) - Amélioration des messages d'erreur avec suggestions ### Fichiers Créés - `fixKnowledge/api-anchorage-utxo-robustness-improvements.md` : Cette documentation ## Modalités de Déploiement ### Redémarrage de l'API 1. **Redémarrer l'API** : ```bash sudo systemctl restart anchorage-api ``` 2. **Vérifier les logs** : ```bash sudo journalctl -u anchorage-api -f ``` ### Vérification 1. **Tester avec plusieurs petits UTXOs** : - Vérifier que l'API peut créer un ancrage même si tous les UTXOs sont petits - Vérifier que les logs indiquent "Combining multiple UTXOs for anchor transaction" - Vérifier que tous les UTXOs disponibles sont utilisés si nécessaire 2. **Vérifier les transactions** : - Les transactions doivent avoir plusieurs inputs si plusieurs UTXOs sont combinés - Le change doit être calculé correctement avec le montant total des inputs - Les frais doivent être correctement estimés ## Modalités d'Analyse ### Vérification que les corrections fonctionnent 1. **Vérifier que la transaction est créée** : - La réponse doit contenir un `txid` valide - Pas d'erreur "No UTXO large enough" si le solde total est suffisant 2. **Vérifier les logs** : - Les logs doivent afficher "Combining multiple UTXOs for anchor transaction" avec le nombre d'UTXOs sélectionnés - Les logs doivent afficher le montant total sélectionné et les frais estimés 3. **Vérifier la transaction sur la blockchain** : ```bash bitcoin-cli getrawtransaction true ``` - La transaction doit avoir plusieurs inputs (un par UTXO sélectionné) - La transaction doit avoir un output de change si le change est significatif ### Cas limites 1. **Pas assez de fonds totaux** : - L'erreur doit indiquer le montant total disponible - L'erreur doit indiquer le déficit (shortfall) - L'erreur doit suggérer des solutions (faucet, mining, consolidation, réduction du provisioning) 2. **Beaucoup de petits UTXOs** : - L'API doit combiner tous les UTXOs disponibles si nécessaire - Les frais doivent être correctement estimés en fonction du nombre d'inputs - La transaction doit être créée avec succès si le solde total est suffisant 3. **Fonds suffisants mais répartis** : - L'API doit utiliser tous les UTXOs disponibles - Les frais doivent être correctement calculés sans double comptage - La transaction doit être créée avec succès ## Résultat ✅ **Problème résolu** - Le bug de calcul des frais est corrigé - Le système utilise maintenant tous les UTXOs disponibles si nécessaire - Les messages d'erreur sont plus informatifs et suggèrent des solutions - La robustesse de la gestion des UTXOs est améliorée **Exemple de transaction réussie avec UTXOs combinés** : - Transaction : N inputs (tous les UTXOs disponibles) → 1 OP_RETURN + 1 ancrage (2500 sats) + 7 provisioning (2500 sats chacun) + change - Les frais sont correctement calculés sans double comptage - Tous les UTXOs disponibles sont utilisés si nécessaire ## Solutions Automatiques Le système réduit maintenant automatiquement le provisioning si les fonds sont insuffisants : 1. **Réduction automatique du provisioning** : Si les fonds sont insuffisants pour le provisioning complet (7 UTXOs), le système essaie automatiquement avec un provisioning réduit (6, 5, 4, 3, 2, 1, 0) 2. **Ancrage minimal** : En dernier recours, le système permet un ancrage sans provisioning (juste l'ancrage du hash) **Comportement** : - Essai initial avec provisioning complet (7 UTXOs par défaut) - Si échec, réduction progressive jusqu'à 0 UTXO de provisioning - L'ancrage est toujours créé si les fonds sont suffisants pour au moins l'ancrage minimal ## Prévention Pour éviter ce problème à l'avenir : 1. **Calcul correct des frais** : Toujours utiliser `totalOutputAmount + estimatedFee` au lieu de `totalNeeded + estimatedFee` 2. **Utilisation de tous les UTXOs** : Essayer d'utiliser tous les UTXOs disponibles si nécessaire 3. **Messages d'erreur informatifs** : Inclure des suggestions de solutions dans les messages d'erreur 4. **Réduction automatique du provisioning** : Le système réduit automatiquement le provisioning si les fonds sont insuffisants 5. **Consolidation automatique** : Considérer l'ajout d'une consolidation automatique des UTXOs quand ils deviennent trop nombreux ## Solutions Automatiques Le système réduit maintenant automatiquement le provisioning si les fonds sont insuffisants : 1. **Réduction automatique du provisioning** : Si les fonds sont insuffisants pour le provisioning complet (7 UTXOs), le système essaie automatiquement avec un provisioning réduit (6, 5, 4, 3, 2, 1, 0) 2. **Ancrage minimal** : En dernier recours, le système permet un ancrage sans provisioning (juste l'ancrage du hash) **Comportement** : - Essai initial avec provisioning complet (7 UTXOs par défaut) - Si échec, réduction progressive jusqu'à 0 UTXO de provisioning - L'ancrage est toujours créé si les fonds sont suffisants pour au moins l'ancrage minimal ## Solutions Recommandées Si le problème persiste malgré ces améliorations : 1. **Consolider les UTXOs** : Utiliser le dashboard pour consolider les petits UTXOs en un gros UTXO - Accéder au dashboard : `https://signet.4nkweb.com` - Utiliser la fonction "Consolidate Small UTXOs" 2. **Utiliser le faucet** : Obtenir plus de fonds via le faucet - Accéder au faucet : `https://faucet.4nkweb.com` - Demander des fonds pour le wallet d'ancrage 3. **Miner plus de blocs** : Générer plus de récompenses de bloc - Activer le mining si désactivé - Attendre que les blocs soient minés et confirmés ## Pages Affectées - `api-anchorage/src/bitcoin-rpc.js` : - Fonction `createAnchorTransaction()` : Correction du bug de calcul des frais - Logique de combinaison d'UTXOs : Utilisation de tous les UTXOs disponibles - Messages d'erreur : Amélioration avec suggestions - `fixKnowledge/api-anchorage-utxo-robustness-improvements.md` : Documentation (nouveau)