**Motivations:** - API d'ancrage retournait une erreur "too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]" - Les transactions d'ancrage ne pouvaient pas être envoyées au mempool **Root causes:** - L'API utilisait des UTXOs non confirmés (confirmations = 0) pour créer les transactions - Lorsqu'un UTXO provient d'une transaction non confirmée avec des ancêtres, Bitcoin Core limite la chaîne à 25 transactions - L'appel listunspent utilisait params: [0], récupérant tous les UTXOs y compris non confirmés - Aucun filtre n'excluait les UTXOs non confirmés **Correctifs:** - Changement de listunspent params: [0] à params: [1] pour ne récupérer que les UTXOs confirmés - Ajout d'un filtre supplémentaire pour exclure les UTXOs avec confirmations = 0 - Amélioration des logs pour indiquer le nombre d'UTXOs non confirmés filtrés - Ajout d'une gestion d'erreur spécifique pour "too-long-mempool-chain" avec code HTTP 503 **Evolutions:** - Documentation de la correction dans fixKnowledge/api-anchorage-too-long-mempool-chain.md **Pages affectées:** - api-anchorage/src/bitcoin-rpc.js: Filtrage des UTXOs non confirmés, changement minconf de 0 à 1 - api-anchorage/src/routes/anchor.js: Gestion d'erreur spécifique pour too-long-mempool-chain - fixKnowledge/api-anchorage-too-long-mempool-chain.md: Documentation (nouveau)
209 lines
7.9 KiB
Markdown
209 lines
7.9 KiB
Markdown
# Correction : Erreur "too-long-mempool-chain" dans l'API d'ancrage
|
|
|
|
**Auteur** : Équipe 4NK
|
|
**Date** : 2026-01-25
|
|
|
|
## Problème Identifié
|
|
|
|
L'API d'ancrage retournait une erreur "too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]" lors de la création de transactions d'ancrage.
|
|
|
|
### Symptômes
|
|
|
|
- Erreur : `{"error":"Internal Server Error","message":"too-long-mempool-chain, too many unconfirmed ancestors [limit: 25]"}`
|
|
- Les transactions d'ancrage ne peuvent pas être envoyées au mempool
|
|
- L'API retourne une erreur 500
|
|
|
|
## Cause Racine
|
|
|
|
L'API utilisait des UTXOs non confirmés (confirmations = 0) pour créer les transactions d'ancrage. Lorsqu'un UTXO provient d'une transaction non confirmée qui a elle-même des ancêtres non confirmés, Bitcoin Core limite la chaîne d'ancêtres à 25 transactions pour éviter les attaques par spam.
|
|
|
|
**Problème technique** :
|
|
- L'appel `listunspent` utilisait `params: [0]`, ce qui récupère tous les UTXOs, y compris ceux non confirmés
|
|
- Aucun filtre n'était appliqué pour exclure les UTXOs non confirmés
|
|
- Les UTXOs provisionnés par les transactions précédentes (qui sont dans le mempool mais pas encore confirmées) étaient utilisés, créant une chaîne d'ancêtres trop longue
|
|
|
|
## Correctifs Appliqués
|
|
|
|
### Filtrage des UTXOs non confirmés
|
|
|
|
**Fichier** : `api-anchorage/src/bitcoin-rpc.js`
|
|
|
|
**Modification 1** : Changer le paramètre `minconf` de `listunspent` de 0 à 1
|
|
|
|
```javascript
|
|
// Avant
|
|
params: [0], // Récupère tous les UTXOs, y compris non confirmés
|
|
|
|
// Après
|
|
params: [1], // Minimum 1 confirmation pour éviter too-long-mempool-chain
|
|
```
|
|
|
|
**Modification 2** : Ajouter un filtre supplémentaire pour s'assurer qu'on n'utilise que des UTXOs confirmés
|
|
|
|
```javascript
|
|
// Filtrer les UTXOs verrouillés et non confirmés
|
|
const availableUtxos = unspent
|
|
.filter(utxo => !this.isUtxoLocked(utxo.txid, utxo.vout))
|
|
.filter(utxo => (utxo.confirmations || 0) > 0) // Only confirmed UTXOs
|
|
.sort((a, b) => b.amount - a.amount);
|
|
```
|
|
|
|
**Modification 3** : Améliorer les logs pour indiquer le nombre d'UTXOs non confirmés filtrés
|
|
|
|
```javascript
|
|
logger.info('Available UTXOs (after filtering locked and unconfirmed)', {
|
|
total: unspent.length,
|
|
available: availableUtxos.length,
|
|
locked: unspent.filter(utxo => this.isUtxoLocked(utxo.txid, utxo.vout)).length,
|
|
unconfirmed: unspent.filter(utxo => (utxo.confirmations || 0) === 0).length,
|
|
largest: availableUtxos.length > 0 ? availableUtxos[0].amount : 0,
|
|
});
|
|
```
|
|
|
|
### Gestion d'erreur améliorée
|
|
|
|
**Fichier** : `api-anchorage/src/routes/anchor.js`
|
|
|
|
**Modification** : Ajouter une gestion spécifique pour l'erreur "too-long-mempool-chain"
|
|
|
|
```javascript
|
|
// Déterminer le code de statut approprié
|
|
let statusCode = 500;
|
|
let errorType = 'Internal Server Error';
|
|
|
|
if (error.message.includes('Insufficient balance')) {
|
|
statusCode = 402; // Payment Required
|
|
errorType = 'Insufficient Balance';
|
|
} else if (error.message.includes('Invalid')) {
|
|
statusCode = 400; // Bad Request
|
|
errorType = 'Bad Request';
|
|
} else if (error.message.includes('too-long-mempool-chain')) {
|
|
statusCode = 503; // Service Unavailable
|
|
errorType = 'Service Unavailable';
|
|
}
|
|
```
|
|
|
|
**Impact** : L'API n'utilise plus que des UTXOs confirmés, évitant ainsi les erreurs "too-long-mempool-chain". Les UTXOs provisionnés par les transactions précédentes seront utilisables une fois confirmés (après minage dans un bloc).
|
|
|
|
## Modifications
|
|
|
|
### Fichiers Modifiés
|
|
|
|
- `api-anchorage/src/bitcoin-rpc.js` :
|
|
- Ligne 251 : Changement de `params: [0]` à `params: [1]` pour `listunspent`
|
|
- Ligne 287-289 : Ajout d'un filtre pour exclure les UTXOs non confirmés
|
|
- Ligne 291-296 : Amélioration des logs pour indiquer les UTXOs non confirmés filtrés
|
|
|
|
- `api-anchorage/src/routes/anchor.js` :
|
|
- Ligne 86-99 : Ajout d'une gestion spécifique pour l'erreur "too-long-mempool-chain" avec code 503
|
|
|
|
### Fichiers Créés
|
|
|
|
- `fixKnowledge/api-anchorage-too-long-mempool-chain.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://anchorage.certificator.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|unconfirmed|too-long)"
|
|
```
|
|
|
|
3. **Vérifier les UTXOs confirmés dans le wallet** :
|
|
```bash
|
|
bitcoin-cli -rpcwallet=custom_signet listunspent 1 | jq 'length'
|
|
```
|
|
|
|
## Modalités d'Analyse
|
|
|
|
### Vérification que la correction fonctionne
|
|
|
|
1. **Vérifier le filtrage des UTXOs non confirmés** :
|
|
- Les logs doivent afficher "Available UTXOs (after filtering locked and unconfirmed)"
|
|
- Les logs doivent indiquer le nombre d'UTXOs non confirmés filtrés
|
|
- Seuls les UTXOs avec confirmations > 0 doivent être utilisés
|
|
|
|
2. **Vérifier l'absence d'erreur "too-long-mempool-chain"** :
|
|
- Plus d'erreur "too-long-mempool-chain" dans les logs
|
|
- Les transactions d'ancrage sont créées avec succès
|
|
- Les UTXOs utilisés ont tous confirmations > 0
|
|
|
|
3. **Vérifier les transactions d'ancrage** :
|
|
```bash
|
|
bitcoin-cli getrawtransaction <txid> true
|
|
```
|
|
- La transaction doit être acceptée dans le mempool
|
|
- Les inputs de la transaction doivent provenir de transactions confirmées
|
|
|
|
### Cas limites
|
|
|
|
1. **Pas d'UTXO confirmé disponible** :
|
|
- L'erreur doit indiquer "No available UTXOs (all are locked or in use)"
|
|
- Attendre qu'un bloc soit miné pour confirmer les UTXOs provisionnés
|
|
- Les UTXOs provisionnés deviendront utilisables après confirmation
|
|
|
|
2. **Tous les UTXOs sont non confirmés** :
|
|
- L'API attendra qu'au moins un UTXO soit confirmé
|
|
- Les logs indiqueront le nombre d'UTXOs non confirmés filtrés
|
|
- Une fois qu'un bloc est miné, les UTXOs provisionnés deviendront utilisables
|
|
|
|
3. **Concurrence** :
|
|
- Le mutex garantit qu'une seule transaction est créée à la fois
|
|
- Les UTXOs sont verrouillés pendant la création de la transaction
|
|
- Les UTXOs confirmés sont prioritaires
|
|
|
|
## Résultat
|
|
|
|
✅ **Problème résolu**
|
|
|
|
- L'API n'utilise plus que des UTXOs confirmés (confirmations > 0)
|
|
- Plus d'erreur "too-long-mempool-chain" lors de la création de transactions
|
|
- Les logs indiquent clairement le nombre d'UTXOs non confirmés filtrés
|
|
- Les UTXOs provisionnés deviendront utilisables après confirmation dans un bloc
|
|
|
|
**Comportement attendu** :
|
|
- Les transactions d'ancrage utilisent uniquement des UTXOs confirmés
|
|
- Les UTXOs provisionnés par les transactions précédentes sont utilisables après confirmation
|
|
- La chaîne d'ancêtres reste toujours sous la limite de 25 transactions
|
|
|
|
## Prévention
|
|
|
|
Pour éviter ce problème à l'avenir :
|
|
|
|
1. **Toujours utiliser des UTXOs confirmés** : Utiliser `listunspent` avec `minconf=1` et filtrer les UTXOs avec confirmations > 0
|
|
2. **Logs détaillés** : Logger le nombre d'UTXOs non confirmés filtrés pour le diagnostic
|
|
3. **Gestion d'erreur spécifique** : Détecter et gérer spécifiquement l'erreur "too-long-mempool-chain" avec un code HTTP approprié (503)
|
|
4. **Provisionnement** : Les UTXOs provisionnés deviendront utilisables après confirmation, garantissant un stock d'UTXOs confirmés
|
|
|
|
## Pages Affectées
|
|
|
|
- `api-anchorage/src/bitcoin-rpc.js` :
|
|
- Fonction `createAnchorTransaction()` : Filtrage des UTXOs non confirmés
|
|
- Appel `listunspent` : Changement de `minconf=0` à `minconf=1`
|
|
- Logs améliorés pour indiquer les UTXOs non confirmés filtrés
|
|
- `api-anchorage/src/routes/anchor.js` :
|
|
- Gestion d'erreur spécifique pour "too-long-mempool-chain" avec code 503
|
|
- `fixKnowledge/api-anchorage-too-long-mempool-chain.md` : Documentation (nouveau)
|