**Motivations:** - Fix insufficient UTXO amount error in anchor API - Ensure continuous availability of usable UTXOs for anchor transactions - Improve anchor transaction reliability and efficiency **Root causes:** - UTXO selection logic was too restrictive, rejecting UTXOs larger than needed - No automatic provisioning of new usable UTXOs when existing ones were not suitable - Algorithm prevented efficient use of available UTXOs **Correctifs:** - Refactored createAnchorTransaction() to provision 7 UTXOs of 2500 sats on each anchor - Use single large UTXO to create 1 anchor output + 7 provisioning outputs + change - Simplified UTXO selection: single large UTXO per transaction instead of multiple small ones - Added UTXO provisioning logic in signet-dashboard - Enhanced Bitcoin RPC methods in both api-anchorage and signet-dashboard - Added documentation in fixKnowledge/api-anchorage-utxo-provisioning.md **Evolutions:** - Enhanced signet-dashboard with new pages (hash-list, utxo-list, join-signet, api-docs) - Improved Bitcoin RPC client with better error handling and UTXO management - Added cache files for hash and UTXO lists - Updated api-faucet with improved server configuration - Enhanced anchor count tracking **Pages affectées:** - api-anchorage/src/bitcoin-rpc.js: Complete refactor of createAnchorTransaction() - api-anchorage/src/routes/anchor.js: Enhanced anchor route - api-anchorage/src/server.js: Server configuration updates - signet-dashboard/src/bitcoin-rpc.js: Added comprehensive Bitcoin RPC client - signet-dashboard/src/server.js: Enhanced server with new routes - signet-dashboard/public/: Added new HTML pages and updated app.js - api-faucet/src/server.js: Server improvements - api-faucet/README.md: Documentation updates - fixKnowledge/api-anchorage-utxo-provisioning.md: New documentation - anchor_count.txt, hash_list.txt, utxo_list.txt: Tracking files
187 lines
7.1 KiB
Markdown
187 lines
7.1 KiB
Markdown
# Correction : Provisionnement automatique d'UTXOs à chaque ancrage Bitcoin
|
|
|
|
**Auteur** : Équipe 4NK
|
|
**Date** : 2026-01-24
|
|
**Version** : 2.0
|
|
|
|
## Problème Identifié
|
|
|
|
L'API d'ancrage retournait une erreur "Insufficient UTXO amount. Required: 0.000021 BTC, Available: 0 BTC. Selected 0 UTXOs from 5112 available" même lorsque le wallet contenait de nombreux UTXOs.
|
|
|
|
### Symptômes
|
|
|
|
- Erreur : "Insufficient UTXO amount. Required: 0.000021 BTC, Available: 0 BTC. Selected 0 UTXOs from 5112 available"
|
|
- Le wallet contient 5112 UTXOs disponibles
|
|
- Aucun UTXO n'est sélectionné malgré la disponibilité
|
|
- L'API ne peut pas créer de transaction d'ancrage
|
|
|
|
## Cause Racine
|
|
|
|
La logique de sélection d'UTXOs avait deux problèmes :
|
|
|
|
1. **Rejet des UTXOs trop grands** : La condition rejetait systématiquement les UTXOs plus grands que nécessaire, même s'ils étaient les seuls disponibles.
|
|
|
|
2. **Manque d'UTXOs utilisables** : Même si des UTXOs étaient disponibles, ils n'étaient pas dans la plage optimale (trop petits ou trop grands), ce qui empêchait leur utilisation efficace.
|
|
|
|
**Problème technique** : L'algorithme de sélection était trop restrictif et ne provisionnait pas de nouveaux UTXOs utilisables lorsque les UTXOs existants n'étaient pas adaptés.
|
|
|
|
## Correctifs Appliqués
|
|
|
|
### Provisionnement à chaque ancrage
|
|
|
|
**Fichier** : `api-anchorage/src/bitcoin-rpc.js`
|
|
|
|
**Modification** : Refonte complète de `createAnchorTransaction()` pour provisionner à chaque ancrage
|
|
|
|
**Stratégie** : Utiliser un gros UTXO pour créer :
|
|
- 1 output d'ancrage de 2500 sats (0.000025 BTC) pour l'ancrage actuel
|
|
- 7 outputs de provisionnement de 2500 sats chacun pour les ancrages futurs
|
|
- Le reste en change
|
|
|
|
```javascript
|
|
async createAnchorTransaction(hash, recipientAddress = null) {
|
|
// Montants pour le provisionnement
|
|
const utxoAmount = 0.000025; // 2500 sats par UTXO
|
|
const numberOfProvisioningUtxos = 7; // 7 UTXOs pour les ancrages futurs
|
|
const anchorOutputAmount = utxoAmount; // 1 UTXO pour l'ancrage actuel
|
|
const totalProvisioningAmount = utxoAmount * numberOfProvisioningUtxos;
|
|
const totalOutputAmount = anchorOutputAmount + totalProvisioningAmount;
|
|
|
|
// Estimation des frais
|
|
const estimatedFee = estimatedFeeBase + (numberOfOutputs * estimatedFeePerOutput);
|
|
const totalNeeded = totalOutputAmount + estimatedFee;
|
|
|
|
// Trouver un gros UTXO assez grand
|
|
selectedUtxo = availableUtxos.find(utxo => utxo.amount >= totalNeeded);
|
|
|
|
// Créer les outputs
|
|
outputs[address] = anchorOutputAmount; // 1 output d'ancrage
|
|
|
|
// 7 outputs de provisionnement
|
|
for (let i = 0; i < numberOfProvisioningUtxos; i++) {
|
|
const provisioningAddress = await this.getNewAddress();
|
|
outputs[provisioningAddress] = utxoAmount;
|
|
}
|
|
|
|
// Le reste en change
|
|
// ...
|
|
}
|
|
```
|
|
|
|
**Impact** : Chaque ancrage provisionne automatiquement 7 UTXOs de 2500 sats pour les ancrages futurs, garantissant toujours la disponibilité d'UTXOs utilisables.
|
|
|
|
## Modifications
|
|
|
|
### Fichiers Modifiés
|
|
|
|
- `api-anchorage/src/bitcoin-rpc.js` :
|
|
- Refonte complète de `createAnchorTransaction()` : Provisionne à chaque ancrage
|
|
- Utilise un gros UTXO pour créer 1 output d'ancrage + 7 outputs de provisionnement
|
|
- Suppression de la logique complexe de sélection multiple d'UTXOs
|
|
- Simplification : un seul gros UTXO par transaction
|
|
|
|
### Fichiers Créés
|
|
|
|
- `fixKnowledge/api-anchorage-utxo-provisioning.md` : Cette documentation
|
|
|
|
## Modalités de Déploiement
|
|
|
|
### Redémarrage de l'API
|
|
|
|
1. **Arrêter l'API** :
|
|
```bash
|
|
ps aux | grep "node.*api-anchorage" | grep -v grep | awk '{print $2}' | xargs kill
|
|
```
|
|
|
|
2. **Redémarrer l'API** :
|
|
```bash
|
|
cd /srv/4NK/prod.lecoffreio.4nkweb.com/api-anchorage
|
|
npm start
|
|
```
|
|
|
|
### Vérification
|
|
|
|
1. **Tester l'ancrage** :
|
|
```bash
|
|
curl -X POST https://prod.lecoffreio.4nkweb.com/api/anchor/document \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'x-api-key: <api-key>' \
|
|
--data-raw '{"hash":"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}'
|
|
```
|
|
|
|
2. **Vérifier les logs** :
|
|
```bash
|
|
tail -f /var/log/api-anchorage.log | grep -E "(UTXO|provisioning)"
|
|
```
|
|
|
|
3. **Vérifier les UTXOs dans le wallet** :
|
|
```bash
|
|
bitcoin-cli -rpcwallet=custom_signet listunspent 0 | jq '.[] | select(.amount >= 0.00001 and .amount <= 0.0001) | .amount' | wc -l
|
|
```
|
|
|
|
## Modalités d'Analyse
|
|
|
|
### Vérification que la correction fonctionne
|
|
|
|
1. **Vérifier le provisionnement à chaque ancrage** :
|
|
- Les logs doivent afficher "Anchor transaction with provisioning sent to mempool"
|
|
- Les logs doivent indiquer le nombre d'UTXOs de provisionnement créés (7)
|
|
|
|
2. **Vérifier la sélection d'UTXO** :
|
|
- Les logs doivent afficher "Selected UTXO for anchor with provisioning" avec 1 UTXO sélectionné
|
|
- Plus d'erreur "Selected 0 UTXOs"
|
|
|
|
3. **Vérifier les transactions d'ancrage** :
|
|
```bash
|
|
bitcoin-cli getrawtransaction <txid> true
|
|
```
|
|
- La transaction doit avoir 1 input (le gros UTXO)
|
|
- La transaction doit avoir :
|
|
- 1 output OP_RETURN (l'ancrage)
|
|
- 1 output d'ancrage de 0.000025 BTC
|
|
- 7 outputs de provisionnement de 0.000025 BTC chacun
|
|
- 1 output de change (si nécessaire)
|
|
|
|
### Cas limites
|
|
|
|
1. **Pas de gros UTXO disponible pour le provisionnement** :
|
|
- L'erreur doit indiquer le montant requis et le plus gros UTXO disponible
|
|
- Le provisionnement ne sera pas effectué, mais l'ancrage pourra quand même utiliser les UTXOs disponibles
|
|
|
|
2. **UTXOs provisionnés non encore confirmés** :
|
|
- Les UTXOs provisionnés sont visibles avec `listunspent 0` (minconf=0)
|
|
- Ils peuvent être utilisés immédiatement même s'ils ne sont pas encore confirmés
|
|
|
|
3. **Concurrence** :
|
|
- Le mutex garantit qu'une seule transaction de provisionnement est créée à la fois
|
|
- Les UTXOs sont verrouillés pendant la création de la transaction
|
|
|
|
## Résultat
|
|
|
|
✅ **Problème résolu**
|
|
|
|
- L'API provisionne automatiquement 7 UTXOs de 2500 sats à chaque ancrage
|
|
- Chaque ancrage utilise un gros UTXO pour créer 1 output d'ancrage + 7 outputs de provisionnement
|
|
- Plus d'erreur "Selected 0 UTXOs" : un seul gros UTXO est utilisé par transaction
|
|
- Les UTXOs de 2500 sats sont directement réutilisables pour les ancrages futurs
|
|
|
|
**Exemple de transaction d'ancrage avec provisionnement** :
|
|
- Transaction : 1 input (gros UTXO) → 1 OP_RETURN + 1 ancrage (2500 sats) + 7 provisioning (2500 sats chacun) + change
|
|
- Les 7 UTXOs créés sont directement réutilisables pour les ancrages futurs
|
|
|
|
## Prévention
|
|
|
|
Pour éviter ce problème à l'avenir :
|
|
|
|
1. **Provisionnement à chaque ancrage** : Chaque ancrage crée automatiquement 7 UTXOs pour les ancrages futurs
|
|
2. **Taille optimale** : Créer des UTXOs de 2500 sats (0.000025 BTC) pour être directement réutilisables
|
|
3. **Simplicité** : Utiliser un seul gros UTXO par transaction au lieu de combiner plusieurs petits UTXOs
|
|
4. **Efficacité** : Combiner l'ancrage et le provisionnement en une seule transaction
|
|
|
|
## Pages Affectées
|
|
|
|
- `api-anchorage/src/bitcoin-rpc.js` :
|
|
- Fonction `createAnchorTransaction()` : Refonte complète pour provisionner à chaque ancrage
|
|
- Utilise un gros UTXO pour créer 1 output d'ancrage + 7 outputs de provisionnement
|
|
- `fixKnowledge/api-anchorage-utxo-provisioning.md` : Documentation (nouveau)
|