7.1 KiB
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.
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 d’un
program_id; - historique d’un mint de token ;
- historique d’une 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 d’arrêt.
Après une signature
Le moteur transmet directement la signature d’ancrage 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 l’ancre. Le moteur ne conserve que les X candidates les plus proches de l’ancre, en plus de l’ensemble 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 d’augmenter 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 l’opérateur ;
requests_per_seconddu rôle sélectionné ;max_concurrent_requestsdu rôle sélectionné ;pause_after_rate_limit_msaprès une erreur 429 ;- un backoff borné pour les autres erreurs temporaires.
Le rôle HTTP doit supporter à la fois :
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 l’appel getTransaction.
Chaque tentative d’hydratation 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,missingoufailed; - erreur normalisée lorsque nécessaire.
Le payload source complet n’est jamais dupliqué dans la table d’observations.
Démo Tauri et arrêt coopératif
La fenêtre demo_backfill regroupe dans des accordéons Bootstrap 5 :
- paramètres communs ;
- signatures explicites ;
- programme ;
- token ;
- pool ;
- journal et résumé JSON.
Une seule campagne peut fonctionner à la fois. Le bouton Arrêter pose un drapeau d’annulation 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, l’annulation ne se limite plus aux frontières entre appels : les futures RPC getSignaturesForAddress et getTransaction sont mises en concurrence avec un observateur d’arrêt, l’attente du pacer est annulable et une pause de retry, y compris après un 429, est interrompue par sondage borné. L’abandon de la future HTTP empêche une campagne arrêtée d’attendre un timeout réseau complet.
Le moteur maintient une file bornée par la concurrence effective et cesse d’admettre de nouveaux candidats dès que l’arrê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 d’exé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 d’arrêt.
Les invariants attendus sont :
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 n’a terminé, le curseur reste la signature d’ancrage initiale. Cette règle interdit de sauter les candidats non traités lors d’une reprise.
Le calcul de cette frontière est couvert par les tests unitaires. Une campagne réelle de 500 candidats a déjà validé l’arrê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 :
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_afteravec 5 516 signatures indexées parcourues pour 5 transactions hydratées ; - arrêt d’une 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 d’arrê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 d’arrêt avant le premier candidat terminé, une campagne *_latest reprend depuis la page la plus récente et ne fabrique aucun curseur.