**Motivations:** - Avoid unnecessary re-anchoring of already anchored hashes - Improve performance by using database as source of truth - Return consistent information without additional RPC calls **Evolutions:** - Added optional skipIfExists parameter to /api/anchor/document endpoint - Check database for existing anchors before creating new transaction - Automatically store anchors in database after transaction creation - Return old: true/false flag and ok: true in all responses - Enrich anchors table with all necessary information for retrieval without RPC calls **Pages affectées:** - api-anchorage/src/routes/anchor.js: Added skipIfExists parameter and database check - api-anchorage/src/bitcoin-rpc.js: Store anchor in database after transaction creation - api-anchorage/README.md: Updated documentation with new parameter and response format - features/api-anchorage-skip-if-exists.md: Evolution documentation
130 lines
4.8 KiB
Markdown
130 lines
4.8 KiB
Markdown
# API d'ancrage - Paramètre skipIfExists
|
|
|
|
**Date:** 2026-01-28
|
|
**Auteur:** Équipe 4NK
|
|
|
|
## Objectif
|
|
|
|
Ajouter un paramètre optionnel `skipIfExists` à l'endpoint `/api/anchor/document` pour éviter de réancrer des hash déjà ancrés. L'API doit renvoyer le résultat avec un tag `old: true/false` et les informations de la transaction depuis la base de données sans appel RPC supplémentaire.
|
|
|
|
## Motivations
|
|
|
|
- **Éviter les réancrages inutiles** : Si un hash est déjà ancré, ne pas créer une nouvelle transaction
|
|
- **Performance** : Utiliser la base de données comme source de vérité pour éviter les appels RPC coûteux
|
|
- **Cohérence** : Retourner toujours les mêmes informations (txid, confirmations, block_height) qu'un ancrage normal
|
|
|
|
## Impacts
|
|
|
|
### Fonctionnels
|
|
|
|
- L'endpoint `/api/anchor/document` accepte maintenant un paramètre optionnel `skipIfExists`
|
|
- Si `skipIfExists: true` et que le hash existe déjà en base, retourne immédiatement les informations sans créer de transaction
|
|
- Toutes les réponses incluent maintenant `ok: true` et `old: true/false`
|
|
- Les ancres sont automatiquement stockées dans la table `anchors` après création
|
|
|
|
### Techniques
|
|
|
|
- Enrichissement de la table `anchors` : Les ancres sont maintenant stockées automatiquement lors de la création
|
|
- Pas d'appel RPC supplémentaire : Les informations sont récupérées directement depuis la base de données
|
|
- Compatibilité : Le paramètre est optionnel, le comportement par défaut reste inchangé
|
|
|
|
## Modifications
|
|
|
|
### Fichiers modifiés
|
|
|
|
1. **`api-anchorage/src/routes/anchor.js`**
|
|
- Ajout du paramètre `skipIfExists` dans le body de la requête
|
|
- Vérification en base de données si le hash existe déjà
|
|
- Retour des informations existantes avec `old: true` si le hash est trouvé
|
|
- Ajout de `ok: true` et `old: false` dans la réponse pour les nouveaux ancrages
|
|
|
|
2. **`api-anchorage/src/bitcoin-rpc.js`**
|
|
- Stockage automatique de l'ancre dans la table `anchors` après création de la transaction
|
|
- Utilisation de `INSERT OR REPLACE` pour gérer les cas de mise à jour
|
|
|
|
3. **`api-anchorage/README.md`**
|
|
- Documentation du nouveau paramètre `skipIfExists`
|
|
- Documentation des nouveaux champs de réponse (`ok`, `old`)
|
|
- Exemples d'utilisation avec `skipIfExists: true`
|
|
|
|
### Structure de la réponse
|
|
|
|
**Nouvel ancrage** :
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"txid": "...",
|
|
"status": "confirmed",
|
|
"confirmations": 0,
|
|
"block_height": 152321,
|
|
"outputs": [...],
|
|
"fee": 0.00001,
|
|
"fee_sats": 1000,
|
|
"old": false
|
|
}
|
|
```
|
|
|
|
**Hash déjà ancré (avec skipIfExists: true)** :
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"txid": "...",
|
|
"status": "confirmed",
|
|
"confirmations": 5,
|
|
"block_height": 152316,
|
|
"old": true
|
|
}
|
|
```
|
|
|
|
## Modalités de déploiement
|
|
|
|
1. **Vérifier la base de données** : S'assurer que la table `anchors` existe (créée par `init-db.mjs`)
|
|
2. **Déployer le code** : Les modifications sont rétrocompatibles, aucun changement de schéma requis
|
|
3. **Tester** : Vérifier que les ancres existantes sont bien retournées avec `old: true`
|
|
4. **Monitoring** : Surveiller les logs pour vérifier que les ancres sont bien stockées en base
|
|
|
|
## Modalités d'analyse
|
|
|
|
### Vérification du fonctionnement
|
|
|
|
1. **Test avec hash nouveau** :
|
|
```bash
|
|
curl -X POST http://localhost:3010/api/anchor/document \
|
|
-H "Content-Type: application/json" \
|
|
-H "x-api-key: your-api-key" \
|
|
-d '{"hash": "nouveau_hash_64_caracteres_hex", "skipIfExists": true}'
|
|
```
|
|
- Doit créer une nouvelle transaction
|
|
- Doit retourner `old: false`
|
|
- Doit stocker l'ancre en base
|
|
|
|
2. **Test avec hash existant** :
|
|
```bash
|
|
curl -X POST http://localhost:3010/api/anchor/document \
|
|
-H "Content-Type: application/json" \
|
|
-H "x-api-key: your-api-key" \
|
|
-d '{"hash": "hash_deja_ancré_64_caracteres_hex", "skipIfExists": true}'
|
|
```
|
|
- Ne doit pas créer de nouvelle transaction
|
|
- Doit retourner `old: true`
|
|
- Doit retourner les informations depuis la base de données
|
|
|
|
3. **Vérification en base** :
|
|
```sql
|
|
SELECT * FROM anchors WHERE hash = 'hash_test';
|
|
```
|
|
- Doit contenir l'enregistrement avec txid, block_height, confirmations
|
|
|
|
### Logs à surveiller
|
|
|
|
- `Hash already anchored, returning existing anchor` : Hash trouvé en base avec skipIfExists
|
|
- `Anchor stored in database` : Ancre stockée après création
|
|
- `Error storing anchor in database` : Erreur lors du stockage (ne fait pas échouer la transaction)
|
|
|
|
## Notes
|
|
|
|
- Le paramètre `skipIfExists` est optionnel et par défaut à `false` pour maintenir la compatibilité
|
|
- Si `skipIfExists: false` ou non fourni, le comportement reste identique à avant (création systématique)
|
|
- Les ancres sont stockées avec `INSERT OR REPLACE` pour gérer les cas de mise à jour (confirmations, block_height)
|
|
- Le stockage en base ne fait pas échouer la transaction si une erreur survient (log warning uniquement)
|