**Motivations:** - Resolve insufficient UTXO amount errors when wallet has many small UTXOs - Prevent race conditions when multiple anchor requests arrive simultaneously - Improve signet dashboard functionality and documentation **Root causes:** - API tried to find a single UTXO large enough instead of combining multiple UTXOs - No mutex mechanism to prevent concurrent transactions from using the same UTXOs - UTXOs in mempool still appear as available in listunspent before block confirmation **Correctifs:** - Implement coin selection algorithm to combine multiple UTXOs when needed - Add mutex-based locking mechanism to serialize UTXO access - Filter locked UTXOs during selection to prevent double spending - Properly handle change output when combining multiple UTXOs - Lock UTXOs during transaction creation and unlock after mempool broadcast **Evolutions:** - Enhance signet dashboard with improved Bitcoin RPC integration - Update mempool documentation - Add comprehensive fix documentation in fixKnowledge/ **Pages affectées:** - api-anchorage/src/bitcoin-rpc.js - signet-dashboard/src/bitcoin-rpc.js - signet-dashboard/src/server.js - signet-dashboard/public/app.js - signet-dashboard/public/index.html - signet-dashboard/public/styles.css - signet-dashboard/start.sh - docs/MEMPOOL.md - fixKnowledge/api-anchorage-insufficient-utxo.md (new) - fixKnowledge/api-anchorage-utxo-race-condition.md (new) - anchor_count.txt (new) - mempool (submodule update)
7.0 KiB
Correction : Erreur "Insufficient UTXO amount" sur l'API d'ancrage
Auteur : Équipe 4NK Date : 2026-01-24 Version : 1.0
Problème Identifié
L'API d'ancrage retournait une erreur "Insufficient UTXO amount. Required: 0.00006 BTC, Largest available: 0.00001 BTC" même lorsque le wallet avait suffisamment de fonds totaux.
Symptômes
- Erreur : "Insufficient UTXO amount. Required: 0.00006 BTC, Largest available: 0.00001 BTC"
- Le wallet contient de nombreux UTXOs de 0.00001 BTC chacun
- Le solde total du wallet est suffisant, mais aucun UTXO individuel n'est assez grand
- L'API ne peut pas créer de transaction d'ancrage
Cause Racine
L'API essayait de trouver un seul UTXO avec suffisamment de fonds pour couvrir le montant requis (0.00006 BTC = montant de sortie + frais estimés). Cependant, tous les UTXOs disponibles étaient de 0.00001 BTC chacun, ce qui est insuffisant individuellement.
Problème technique : L'algorithme de sélection d'UTXO ne combinait pas plusieurs UTXOs pour atteindre le montant requis. Il cherchait uniquement un UTXO unique assez grand.
Correctifs Appliqués
Modification de la sélection d'UTXOs dans bitcoin-rpc.js
Fichier : api-anchorage/src/bitcoin-rpc.js
Avant :
// Sélectionner un UTXO avec suffisamment de fonds
const sortedUnspent = [...unspent].sort((a, b) => b.amount - a.amount);
const amount = 0.00001;
const estimatedFee = 0.00005;
const totalNeeded = amount + estimatedFee;
// Trouver un UTXO avec suffisamment de fonds
let utxo = sortedUnspent.find(u => u.amount >= totalNeeded);
if (!utxo) {
utxo = sortedUnspent[0];
if (utxo.amount < totalNeeded) {
throw new Error(`Insufficient UTXO amount...`);
}
}
const inputs = [{
txid: utxo.txid,
vout: utxo.vout,
}];
Après :
// Sélectionner plusieurs UTXOs si nécessaire (coin selection)
const sortedUnspent = [...unspent].sort((a, b) => b.amount - a.amount);
const amount = 0.00001;
const estimatedFeePerInput = 0.000001;
const estimatedFeeBase = 0.00001;
// Sélectionner les UTXOs nécessaires pour couvrir le montant + frais
const selectedUtxos = [];
let totalSelected = 0;
let estimatedInputs = 1;
let totalNeeded = amount + estimatedFeeBase;
// Itérer jusqu'à trouver une combinaison qui fonctionne
for (let iteration = 0; iteration < 10; iteration++) {
totalNeeded = amount + estimatedFeeBase + (estimatedInputs * estimatedFeePerInput);
selectedUtxos.length = 0;
totalSelected = 0;
for (const utxo of sortedUnspent) {
if (totalSelected >= totalNeeded) break;
selectedUtxos.push(utxo);
totalSelected += utxo.amount;
}
if (totalSelected >= totalNeeded) break;
estimatedInputs = selectedUtxos.length + 1;
}
const inputs = selectedUtxos.map(utxo => ({
txid: utxo.txid,
vout: utxo.vout,
}));
Impact : L'API peut maintenant combiner plusieurs UTXOs pour créer une transaction, même si aucun UTXO individuel n'est assez grand.
Gestion du change (monnaie restante)
Ajout : Calcul et gestion du change lorsque plusieurs UTXOs sont utilisés :
// Calculer le change (monnaie restante après avoir payé le montant)
const estimatedFee = estimatedFeeBase + (selectedUtxos.length * estimatedFeePerInput);
const change = totalSelected - amount - estimatedFee;
const outputs = {
data: anchorData.toString('hex'), // OP_RETURN output
[address]: amount, // Montant minimal pour la transaction
};
// Si le change est significatif (> 0.000001 BTC), l'envoyer à une adresse de change
if (change > 0.000001) {
const changeAddress = await this.getNewAddress();
outputs[changeAddress] = change;
}
Impact : Le change est correctement géré et renvoyé au wallet au lieu d'être perdu.
Modifications
Fichiers Modifiés
api-anchorage/src/bitcoin-rpc.js: Implémentation de la sélection multiple d'UTXOs (coin selection) et gestion du change
Fichiers Créés
fixKnowledge/api-anchorage-insufficient-utxo.md: Cette documentation
Modalités de Déploiement
Redémarrage de l'API
-
Arrêter l'API :
ps aux | grep "node.*api-anchorage" | grep -v grep | awk '{print $2}' | xargs kill -
Redémarrer l'API :
cd /home/ncantu/Bureau/code/bitcoin/api-anchorage npm start
Vérification
-
Tester l'ancrage :
curl -X POST http://localhost:3010/api/anchor/document \ -H 'Content-Type: application/json' \ -H 'x-api-key: 770b9b33-8a15-4a6d-8f95-1cd2b36e7376' \ --data-raw '{"hash":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}' -
Vérifier les logs :
tail -f /tmp/anchorage-api.log | grep -E "(Selected UTXOs|change)"
Modalités d'Analyse
Vérification que la correction fonctionne
-
Vérifier que la transaction est créée :
- La réponse doit contenir un
txidvalide - Pas d'erreur "Insufficient UTXO amount"
- La réponse doit contenir un
-
Vérifier les logs :
- Les logs doivent afficher "Selected UTXOs for transaction" avec le nombre d'UTXOs sélectionnés
- Les logs doivent afficher le montant total sélectionné et le change calculé
-
Vérifier la transaction sur la blockchain :
bitcoin-cli getrawtransaction <txid> 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
-
Pas assez de fonds totaux :
- L'erreur doit indiquer le montant total disponible
- L'erreur doit indiquer le nombre d'UTXOs disponibles
-
Beaucoup de petits UTXOs :
- L'API doit combiner plusieurs UTXOs jusqu'à avoir suffisamment de fonds
- Les frais doivent être correctement estimés en fonction du nombre d'inputs
-
Change très petit :
- Si le change est < 0.000001 BTC, il sera inclus dans les frais (dust)
- Si le change est >= 0.000001 BTC, il sera renvoyé au wallet
Résultat
✅ Problème résolu
- L'API peut maintenant combiner plusieurs UTXOs pour créer une transaction
- Les transactions d'ancrage fonctionnent même avec de nombreux petits UTXOs
- Le change est correctement géré et renvoyé au wallet
- Les frais sont correctement estimés en fonction du nombre d'inputs
Exemple de transaction réussie :
- Transaction ID :
edacb5000f2f0520072f277e06406b1287f1d38531e7810d33939e5d9cbd598b - Plusieurs UTXOs de 0.00001 BTC combinés pour atteindre le montant requis
Prévention
Pour éviter ce problème à l'avenir :
- Utiliser un algorithme de coin selection : Toujours combiner plusieurs UTXOs si nécessaire
- Estimer correctement les frais : Prendre en compte le nombre d'inputs dans l'estimation des frais
- Gérer le change : Toujours renvoyer le change au wallet au lieu de le perdre
- Tester avec différents scénarios : Tester avec des wallets contenant de nombreux petits UTXOs
Pages Affectées
api-anchorage/src/bitcoin-rpc.js: Implémentation de la sélection multiple d'UTXOs et gestion du changefixKnowledge/api-anchorage-insufficient-utxo.md: Documentation (nouveau)