# ksp-worker-raw-transaction-ingest-lib `ksp-worker-raw-transaction-ingest-lib` est le Worker concret KSP chargé de l'alimentation continue de la couche RAW Transaction. La crate possède deux niveaux publics complémentaires : ```text RawTransactionIngestWorker::start -> fondation source-neutral, sans source productive RawTransactionIngestWorker::start_with_runtime_resources -> même runtime + une source Yellowstone productive supervisée + hydration HTTP getTransaction ``` Le Worker reste indépendant de Config et de tout backend Store physique. Le caller compose les ressources Transport et Store, puis les remet à la crate par ses façades publiques. ## Pipeline productif actuel La première verticale live est : ```text Yellowstone standard subscribe -> Transaction / TransactionStatus / Block -> signal source-neutral (network, signature, slot, commitment, provenance sûre) -> coalescence bornée par (network, signature, commitment) -> HTTP getTransaction observed -> ksp-raw-transaction-lib -> admission centrale bornée -> ksp-store-lib -> RawTransaction + RawTransactionObservation ``` `BlockMeta` et `Slot` ne produisent pas de RAW directement. Ils servent uniquement à la projection de continuité du run. La qualification reste conservative : même lorsqu'une update Yellowstone contient une transaction complète côté protobuf, le Worker hydrate actuellement les signaux transactionnels par HTTP `getTransaction` avant de construire le RAW canonique. Il n'existe donc pas de second canonicaliseur Yellowstone. ## Contrat de source Yellowstone + HTTP `RawTransactionIngestYellowstoneSource::new` reçoit : ```text YellowstoneGrpcChannel YellowstoneSubscribeRequest HttpTransportPool HttpRoleName d'hydration ``` La construction est sans I/O et refuse notamment : - une requête Yellowstone invalide ; - l'absence de famille porteuse d'ingestion ; - un commitment `Processed` ou implicite ; - un réseau Yellowstone non représentable ; - une provenance provider/endpoint non représentable ; - l'absence d'une route HTTP compatible pour `getTransaction` sur le même réseau. Le runtime-resource aggregate public contient exactement une source Yellowstone validée. Il n'expose ni enum provider, ni collection de sources, ni callback, ni queue d'enqueue, ni client inférieur. ## Runtime et lifecycle Le Worker s'exécute sur le runtime Tokio courant du caller. Il ne crée pas de runtime global et n'expose aucun `JoinHandle` public. `RawTransactionIngestHandle` permet de : - demander un stop coopératif et idempotent ; - lire une source de snapshots concrets latest-value ; - utiliser la même source via `WorkerSnapshotSource` ; - attendre le terminal après drain et join des tâches possédées. Le shutdown est borné par `shutdown_drain_timeout`. Les tâches source, hydration et persistence possédées sont drainées ou abort+join avant publication terminale. L'abandon terminal d'une hydration retire son pending run-local sans le convertir artificiellement en travail `settled`. ## Admission, coalescence et backpressure La queue centrale est un `tokio::sync::mpsc` privé borné par `admission_queue_capacity`. Les sources internes subissent la backpressure ; aucune queue non bornée ni silent drop n'est autorisé. La source Yellowstone possède également un coordinateur d'hydration borné : ```text in-flight hydration <= persistence_concurrency pending source signals <= 65_536 ``` Les signaux partageant le même `(network, signature, commitment)` sont coalescés avant le fan-out HTTP. Les provenances utiles restent néanmoins conservées pour les ingress produits après hydration. Les retries/reroutages HTTP appartiennent à `ksp-onchain-transport-lib`. Le Worker ne possède pas une seconde boucle de retry autour de `getTransaction`. ## Processing frontier run-local Le snapshot expose : ```text hydration_pending processing_frontier_slot oldest_pending_slot ``` Cette frontier mesure uniquement le traitement des signaux réellement observés pendant le run courant. Elle n'est ni un checkpoint durable, ni une preuve de complétude blockchain, ni un curseur de Backfill. Un signal transactionnel devient pending après validation de sa clé d'hydration et insertion dans le coordinateur. Il devient settled pour la source lorsque : ```text getTransaction -> Missing ou getTransaction -> Available puis ingress envoyé avec succès vers l'admission centrale ``` Un `BlockMeta` ou `Slot` continuity-only est settled localement sans produire de RAW. La frontier n'avance jamais à travers le plus ancien pending connu. ## Reconnect, replay et continuité Le reconnect/replay Yellowstone appartient à Transport. Le Worker n'écrit pas `from_slot` et n'interprète pas directement `SubscribeReplayInfo`. Le snapshot Worker projette uniquement des informations sûres : ```text source_state source_reconnect_total source_replay_attempt_total source_continuity_gap_total ``` `RawTransactionIngestSourceState` distingue : ```text Active Reconnecting Closing Closed Failed ``` Un replay attempt n'est pas une preuve de replay réussi ni de continuité parfaite. Si Transport augmente son compteur de continuity gap parce que la borne de rétention prouve que le slot demandé n'est plus rejouable, le Worker classe la source en failure et termine avec `worker_raw_transaction_ingest.source_failed`. Le Worker ne lance alors ni Job Backfill ni campagne historique automatique. ## Persistence Store La persistance passe exclusivement par `ksp-store-lib` avec `default-features = false`. Aucun backend physique n'est importé directement. L'écriture utilise le mode normal atomique `RawTransaction + RawTransactionObservation`. Les outcomes distingués incluent : ```text entity inserted entity already present entity skipped purged observation inserted observation already present observation not recorded for purged entity content conflict store failure ``` Un content conflict est terminal et n'est jamais converti en succès idempotent. ## Snapshots et erreurs `RawTransactionIngestSnapshotSource` est latest-value : les lecteurs peuvent rater des transitions intermédiaires mais récupèrent toujours la dernière projection complète et monotone. Les codes Worker publics sont : ```text worker_raw_transaction_ingest.settings_invalid worker_raw_transaction_ingest.runtime_invalid worker_raw_transaction_ingest.store_failed worker_raw_transaction_ingest.content_conflict worker_raw_transaction_ingest.counter_exhausted worker_raw_transaction_ingest.source_failed worker_raw_transaction_ingest.drain_timeout ``` Les diagnostics et `Debug` ne recopient pas de payload RAW, signature, URL, credential, filtre provider, texte backend/provider arbitraire ou client inférieur. ## Dépendances Les dépendances normales sont exactement : ```text ksp-core-lib ksp-logging-lib ksp-onchain-transport-lib ksp-raw-transaction-lib ksp-store-lib (default-features = false) ksp-worker-api sha2 tokio (macros, rt, sync, time) ``` La crate ne dépend pas de Config, Job, `ksp-store-api` directement, backend Store concret, `reqwest`, `tonic`, `yellowstone-grpc-proto` ou Tauri. ## Hors périmètre La verticale actuelle ne possède pas : - plusieurs sources productives simultanées dans `RawTransactionIngestRuntimeResources` ; - source WS/Helius-specific ou HTTP polling Worker ; - sélection Config interne au Worker ; - checkpoint persistent de processing frontier ; - campagne de réparation historique automatique ; - application Desk ou process autonome ; - décodage STRUCTURAL/DECODED/DOMAIN. Les futures extensions doivent conserver la séparation avec `ksp-job-backfill-lib` et réutiliser les mêmes contrats Common RAW/Store. ## Documentation - [`USAGE.md`](USAGE.md) — utilisation de la façade publique ; - [`../ksp-worker-api/README.md`](../ksp-worker-api/README.md) — contrats Worker génériques ; - [`../ksp-raw-transaction-lib/README.md`](../ksp-raw-transaction-lib/README.md) — canonicalisation RAW commune ; - [`../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) — séparation Worker/Job ; - [`../../docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md`](../../docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md) — architecture d'acquisition RawTransaction.