This commit is contained in:
2026-07-23 16:37:12 +02:00
parent 99c345f2f2
commit 0da75c1311
2159 changed files with 230833 additions and 0 deletions

145
docs/BACKFILL_HTTP.md Normal file
View File

@@ -0,0 +1,145 @@
<!-- file: docs/BACKFILL_HTTP.md -->
<!-- version: 6 -->
# Backfill HTTP transactionnel
## Objectif
Le jalon `0.3.3` fournit un moteur de backfill réutilisable qui transforme les réponses HTTP Solana standard en transactions canoniques indépendantes du fournisseur.
```text
signatures explicites
ou getSignaturesForAddress
-> getTransaction
-> kb_model::CanonicalTransaction
-> kb_sol_raw_transactions
-> kb_sol_obs_transaction_observations
```
Aucun décodeur DEX, aucune extraction core et aucune source temps réel payante ne sont exécutés dans ce jalon.
## Sources de signatures
Le moteur accepte quatre catégories :
- liste explicite de signatures, une signature par ligne ;
- historique dun `program_id` ;
- historique dun mint de token ;
- historique dune adresse de pool.
Les trois modes par adresse utilisent la même méthode standard `getSignaturesForAddress`. La catégorie est conservée dans le `filter_code` des observations afin de distinguer `program_before`, `program_after`, `program_latest`, et les équivalents token/pool.
## Sens de pagination
### Avant une signature
Avec une ancre, le paramètre RPC `before` sélectionne les transactions plus anciennes que cette signature. Sans ancre, le mode `Before` omet `before` et commence sur la page la plus récente retournée par le RPC. Le moteur poursuit la pagination jusquà atteindre la limite demandée, une page incomplète, la limite de pages ou une demande darrêt.
### Après une signature
Le moteur transmet directement la signature dancrage dans le paramètre RPC `until`. Les pages suivantes combinent le même `until` avec un curseur `before` correspondant à la dernière signature de la page précédente.
Le mode `after` utilise des pages RPC de 1 000 signatures afin que la limite par défaut de 20 pages puisse couvrir jusquà 20 000 signatures plus récentes que lancre. Le moteur ne conserve que les `X` candidates les plus proches de lancre, en plus de lensemble de déduplication borné par `max_pages × 1 000`.
Une page incomplète signifie que la borne `until` a été atteinte. Si toutes les pages autorisées sont pleines, la campagne échoue avec le nombre de signatures inspectées et demande daugmenter `max_pages`. Une erreur RPC de borne inconnue est propagée sans être transformée en résultat vide.
## Limites et retries
Le moteur combine :
- les limites saisies par lopérateur ;
- `requests_per_second` du rôle sélectionné ;
- `max_concurrent_requests` du rôle sélectionné ;
- `pause_after_rate_limit_ms` après une erreur 429 ;
- un backoff borné pour les autres erreurs temporaires.
Le rôle HTTP doit supporter à la fois :
```text
get_signatures_for_address
get_transaction
```
Le rôle recommandé reste `history_backfill`.
## Persistance
Une signature déjà présente dans `kb_sol_raw_transactions` est ignorée avant lappel `getTransaction`.
Chaque tentative dhydratation produit une observation légère :
- provider et endpoint ;
- protocole `solana_http_json_rpc` ;
- méthode `getTransaction` ;
- origine `backfill` ;
- commitment, session et filtre ;
- timestamps ;
- taille et hash du payload source lorsque disponibles ;
- statut `persisted`, `missing` ou `failed` ;
- erreur normalisée lorsque nécessaire.
Le payload source complet nest jamais dupliqué dans la table dobservations.
## Démo Tauri et arrêt coopératif
La fenêtre `demo_backfill` regroupe dans des accordéons Bootstrap 5 :
1. paramètres communs ;
2. signatures explicites ;
3. programme ;
4. token ;
5. pool ;
6. journal et résumé JSON.
Une seule campagne peut fonctionner à la fois. Le bouton `Arrêter` pose un drapeau dannulation coopérative lu entre les pages, les candidats, le pacer et les retries.
Depuis la préversion de clôture `0.3.4-pre.011`, lannulation ne se limite plus aux frontières entre appels : les futures RPC `getSignaturesForAddress` et `getTransaction` sont mises en concurrence avec un observateur darrêt, lattente du pacer est annulable et une pause de retry, y compris après un 429, est interrompue par sondage borné. Labandon de la future HTTP empêche une campagne arrêtée dattendre un timeout réseau complet.
Le moteur maintient une file bornée par la concurrence effective et cesse dadmettre de nouveaux candidats dès que larrêt est demandé. Les candidats non démarrés ne sont ni journalisés comme traités, ni inclus dans `candidates_completed`.
Le résumé distingue :
- `candidates_selected` : candidats découverts ;
- `candidates_started` : candidats admis dans la file dexécution ;
- `candidates_completed` : candidats arrivés à un résultat terminal ;
- `candidates_cancelled` : candidats démarrés puis interrompus avant un résultat terminal ;
- `candidates_not_started` : candidats jamais admis après la demande darrêt.
Les invariants attendus sont :
```text
candidates_selected = candidates_started + candidates_not_started
candidates_started = candidates_completed + candidates_cancelled
```
Pour une campagne `before`, `resume_before_signature` correspond à la dernière signature terminée dans un préfixe contigu de la liste ordonnée. Une transaction terminée hors ordre ne fait pas avancer seule ce curseur. Si aucun candidat na terminé, le curseur reste la signature dancrage initiale. Cette règle interdit de sauter les candidats non traités lors dune reprise.
Le calcul de cette frontière est couvert par les tests unitaires. Une campagne réelle de 500 candidats a déjà validé larrêt et la séparation entre terminés, annulés et non démarrés. Le rejeu manuel depuis `resume_before_signature` reste un contrôle opératoire recommandé, mais il ne constitue plus un jalon séparé ni un blocage pour `0.4.0`.
## Validation finale `0.3.3`
Validations locales :
```text
cargo test -p kb_rpc : 54 tests passés
cargo test -p kb_pipeline : 10 tests passés
cargo test -p kb_store_core: 31 tests passés
cargo test -p kb_store_pg : 32 tests passés
cargo test -p kb_app_demo : 38 tests passés
cargo clippy --all-targets : validé
```
Les campagnes Tauri ont validé :
- signatures explicites ;
- programme avant/après ;
- token avant/après ;
- pool avant/après ;
- parcours profond `program_after` avec 5 516 signatures indexées parcourues pour 5 transactions hydratées ;
- arrêt dune campagne de 500 candidats avec 7 démarrés, 3 terminés, 4 annulés et 493 non démarrés.
Les diagnostics PostgreSQL ont confirmé 62 transactions canoniques et 62 observations avant les derniers tests darrêt. Les tables core restent volontairement vides jusquà `0.3.4`.
## Recherche latest sans ancre
Pour programme, token et pool, une direction `before` avec ancre absente produit un filtre `*_latest`. La première page est demandée sans `before`, puis les pages suivantes utilisent normalement la dernière signature reçue comme curseur. Une direction `after` sans ancre est refusée, car la borne `until` ne peut pas être déterminée. En cas darrêt avant le premier candidat terminé, une campagne `*_latest` reprend depuis la page la plus récente et ne fabrique aucun curseur.