ncantu 3c212e56e9 api-anchorage: combine multiple UTXOs, api-relay: storage interface refactor
**Motivations:**
- Résoudre erreur "No UTXO large enough" en combinant plusieurs petits UTXOs
- Refactorer api-relay avec interface StorageServiceInterface pour meilleure abstraction
- Ajouter script restart-bitcoind.sh

**Root causes:**
- api-anchorage: logique cherchait uniquement un UTXO assez grand, ne combinait pas plusieurs petits UTXOs
- api-relay: code dupliqué entre StorageService et DatabaseStorageService

**Correctifs:**
- api-anchorage: combinaison automatique de plusieurs petits UTXOs si aucun assez grand, ajustement frais pour inputs multiples, limite 20 UTXOs, gestion cohérente verrouillage/déverrouillage

**Evolutions:**
- api-relay: StorageServiceInterface (abstraction commune), refactoring routes (keys, messages, signatures, metrics, bloom) pour utiliser interface, eslint config, package updates
- fixKnowledge: api-anchorage-combine-utxos.md (documentation correction)
- restart-bitcoind.sh: script redémarrage bitcoind

**Pages affectées:**
- api-anchorage: bitcoin-rpc.js
- api-relay: eslint.config.mjs, package.json, index.ts, middleware/auth.ts, routes (bloom, keys, messages, metrics, signatures), services (apiKeyService, database, relay, storageAdapter, storageInterface)
- fixKnowledge: api-anchorage-combine-utxos.md
- restart-bitcoind.sh
2026-01-28 07:50:56 +01:00

38 lines
1.2 KiB
TypeScript

import { Router, type Request, type Response } from 'express';
import { Gauge, register } from 'prom-client';
import type { StorageServiceInterface } from '../services/storageInterface.js';
import { logger } from '../lib/logger.js';
export function createMetricsRouter(storage: StorageServiceInterface): Router {
const router = Router();
const gauge = new Gauge({
name: 'relay_storage_entries',
help: 'Number of stored entries by kind',
labelNames: ['kind'],
});
/**
* GET /metrics - Prometheus metrics.
*/
router.get('/', (_req: Request, res: Response): void => {
void (async (): Promise<void> => {
try {
const msgCount = storage.getMessages(0, Number.MAX_SAFE_INTEGER).length;
gauge.set({ kind: 'messages' }, msgCount);
gauge.set({ kind: 'signatures' }, storage.getSignatureCount());
gauge.set({ kind: 'keys' }, storage.getKeyCount());
gauge.set({ kind: 'seen_hashes' }, storage.getSeenHashCount());
res.set('Content-Type', register.contentType);
res.send(await register.metrics());
} catch (err) {
logger.error({ err }, 'Error generating metrics');
res.status(500).json({ error: 'Internal server error' });
}
})();
});
return router;
}