Fix too-long-mempool-chain error in anchor API
**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)
This commit is contained in:
parent
26a53327a4
commit
c31d3a4f0c
@ -248,7 +248,7 @@ class BitcoinRPC {
|
||||
jsonrpc: '1.0',
|
||||
id: 'listunspent',
|
||||
method: 'listunspent',
|
||||
params: [0],
|
||||
params: [1], // Minimum 1 confirmation to avoid too-long-mempool-chain errors
|
||||
}),
|
||||
});
|
||||
|
||||
@ -283,15 +283,18 @@ class BitcoinRPC {
|
||||
throw new Error('No unspent outputs available');
|
||||
}
|
||||
|
||||
// Filtrer les UTXOs verrouillés et trouver un gros UTXO
|
||||
// Filtrer les UTXOs verrouillés et non confirmés pour éviter les erreurs "too-long-mempool-chain"
|
||||
// Ne garder que les UTXOs avec au moins 1 confirmation
|
||||
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); // Trier par montant décroissant
|
||||
|
||||
logger.info('Available UTXOs (after filtering locked)', {
|
||||
logger.info('Available UTXOs (after filtering locked and unconfirmed)', {
|
||||
total: unspent.length,
|
||||
available: availableUtxos.length,
|
||||
locked: unspent.length - 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,
|
||||
});
|
||||
|
||||
|
||||
@ -85,14 +85,21 @@ anchorRouter.post('/document', async (req, res) => {
|
||||
|
||||
// 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';
|
||||
}
|
||||
|
||||
res.status(statusCode).json({
|
||||
error: error.message.includes('Insufficient balance') ? 'Insufficient Balance' : 'Internal Server Error',
|
||||
error: errorType,
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
|
||||
208
fixKnowledge/api-anchorage-too-long-mempool-chain.md
Normal file
208
fixKnowledge/api-anchorage-too-long-mempool-chain.md
Normal file
@ -0,0 +1,208 @@
|
||||
# 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)
|
||||
Loading…
x
Reference in New Issue
Block a user