# Correction : Erreur "Input not found or already spent" dans l'API d'ancrage **Auteur** : Équipe 4NK **Date** : 2026-01-27 **Version** : 1.0 ## Problème Identifié L'API d'ancrage retournait une erreur HTTP 500 avec le message "Input not found or already spent" lors de la création de transactions d'ancrage. ### Symptômes - Erreur HTTP 500 lors des tests d'ancrage - Message d'erreur : "Transaction signing failed: Input not found or already spent" - L'UTXO sélectionné depuis la base de données n'est plus disponible dans Bitcoin - La base de données n'est pas synchronisée avec l'état réel de Bitcoin ### Impact - Les ancrages échouent avec une erreur 500 - Les UTXOs sélectionnés peuvent être déjà dépensés mais toujours marqués comme disponibles dans la DB - Dégradation de la fiabilité de l'API d'ancrage ## Cause Racine 1. **Désynchronisation entre la DB et Bitcoin** : Un UTXO peut être dépensé entre le moment où il est sélectionné depuis la DB et le moment où il est utilisé dans une transaction. 2. **Détection d'erreur incomplète** : La détection d'erreur ne couvrait pas tous les cas ("already spent", "input not found"). 3. **Pas de vérification de disponibilité** : Aucune vérification de disponibilité de l'UTXO juste avant de l'utiliser. ## Correctifs Appliqués ### 1. Amélioration de la détection d'erreur **Fichier** : `api-anchorage/src/bitcoin-rpc.js` **Modification** : Extension de la détection d'erreur pour inclure "already spent" et "input not found" : ```javascript // Si l'erreur indique que l'UTXO n'existe plus ou est déjà dépensé, le marquer comme dépensé const hasUtxoNotFoundError = errorDetails.some(e => { const errorMsg = (e.error || '').toLowerCase(); return errorMsg.includes('not found') || errorMsg.includes('does not exist') || errorMsg.includes('missing') || errorMsg.includes('already spent') || errorMsg.includes('input not found'); }); ``` ### 2. Vérification de disponibilité avant utilisation **Fichier** : `api-anchorage/src/bitcoin-rpc.js` **Modification** : Ajout d'une vérification de disponibilité de l'UTXO juste avant de l'utiliser, avec mécanisme de retry : ```javascript // Vérifier que l'UTXO est toujours disponible avant de l'utiliser // (peut avoir été dépensé entre la sélection et l'utilisation) // Limiter les tentatives pour éviter les boucles infinies if (retryCount < 3) { try { const utxoCheck = await this.client.listunspent(0, 9999999, [selectedUtxo.address]); const utxoStillAvailable = utxoCheck.some(u => u.txid === selectedUtxo.txid && u.vout === selectedUtxo.vout ); if (!utxoStillAvailable) { // L'UTXO n'est plus disponible, le marquer comme dépensé et réessayer this.unlockUtxo(selectedUtxo.txid, selectedUtxo.vout); // Marquer comme dépensé dans la DB // Réessayer avec un autre UTXO return this.createAnchorTransaction(hash, recipientAddress, provisioningAddresses, numberOfProvisioningUtxos, retryCount + 1); } } catch (checkError) { // Continuer même si la vérification échoue } } ``` ### 3. Ajout du paramètre retryCount **Fichier** : `api-anchorage/src/bitcoin-rpc.js` **Modification** : Ajout du paramètre `retryCount` à la fonction `createAnchorTransaction` pour limiter les tentatives : ```javascript async createAnchorTransaction(hash, recipientAddress = null, provisioningAddresses = null, numberOfProvisioningUtxos = null, retryCount = 0) { // ... } ``` ## Modifications - `api-anchorage/src/bitcoin-rpc.js` : - Ligne 207 : Ajout des paramètres `provisioningAddresses`, `numberOfProvisioningUtxos`, `retryCount` à `createAnchorTransaction` - Ligne 404-431 : Ajout de la vérification de disponibilité de l'UTXO avant utilisation - Ligne 455-477 : Amélioration de la détection d'erreur pour inclure "already spent" et "input not found" ## Modalités de Déploiement ### Redémarrage de l'API 1. **Redémarrer l'API** : ```bash sudo systemctl restart anchorage-api.service ``` 2. **Vérifier le statut** : ```bash systemctl is-active anchorage-api.service ``` ### Vérification 1. **Tester l'ancrage** : ```bash curl -X POST https://anchorage.certificator.4nkweb.com/api/anchor/document \ -H 'Content-Type: application/json' \ -H 'x-api-key: ' \ --data-raw '{"hash":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}' ``` 2. **Vérifier les logs** : ```bash journalctl -u anchorage-api.service --since "5 minutes ago" | grep -E "(UTXO|already spent|retrying)" ``` ## Modalités d'Analyse ### Vérification que la correction fonctionne 1. **Vérifier la détection d'erreur** : - Les logs doivent afficher "UTXO marked as spent due to signing error" si un UTXO est déjà dépensé - Les erreurs "already spent" et "input not found" doivent être détectées 2. **Vérifier la vérification de disponibilité** : - Les logs doivent afficher "Selected UTXO no longer available, marking as spent and retrying" si un UTXO n'est plus disponible - Le mécanisme de retry doit fonctionner (maximum 3 tentatives) 3. **Vérifier les transactions d'ancrage** : - Les ancrages doivent réussir même si le premier UTXO sélectionné est déjà dépensé - Les UTXOs dépensés doivent être correctement marqués dans la DB ### Cas limites 1. **Tous les UTXOs sont déjà dépensés** : - L'erreur doit indiquer "No available UTXOs in database (all are locked, spent, or unconfirmed)" - Pas de boucle infinie 2. **Problème réseau lors de la vérification** : - La vérification échoue silencieusement et l'opération continue - L'erreur sera détectée lors de la signature de la transaction 3. **Maximum de tentatives atteint** : - L'erreur doit indiquer "Failed to find available UTXO after multiple attempts" - Pas de boucle infinie