v0.3.12-pre.012
This commit is contained in:
@@ -1,65 +1,147 @@
|
||||
<!-- file: crates/ksp-worker-raw-transaction-ingest-lib/README.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# ksp-worker-raw-transaction-ingest-lib
|
||||
|
||||
`ksp-worker-raw-transaction-ingest-lib` est le premier Worker concret de KSP pour l'alimentation continue de la couche RAW Transaction.
|
||||
`ksp-worker-raw-transaction-ingest-lib` est le Worker concret KSP chargé de l'alimentation continue de la couche RAW Transaction.
|
||||
|
||||
La crate fournit la fondation runtime **source-neutral** du Worker : identité et settings bornés, lifecycle Start/Stop, admission privée bornée, canonicalisation via `ksp-raw-transaction-lib`, persistance backend-neutral via `ksp-store-lib`, supervision des tâches, shutdown borné et snapshots latest-value projetables sur `ksp-worker-api`.
|
||||
|
||||
La fondation ne contient volontairement encore **aucune source réseau productive**. Elle ne dépend pas de `ksp-onchain-transport-lib` et n'expose pas d'API publique permettant au caller d'injecter directement des transactions dans la queue interne. Les adapters live/catch-up sont des responsabilités ultérieures du même Worker, pas de son API de fondation.
|
||||
|
||||
## Identité et réseau
|
||||
|
||||
Une exécution est liée à :
|
||||
La crate possède deux niveaux publics complémentaires :
|
||||
|
||||
```text
|
||||
RawNetworkId
|
||||
WorkerId
|
||||
Worker kind = raw_transaction_ingest
|
||||
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 réseau logique doit être identique à celui du `Store` remis au démarrage. La transaction canonique conserve l'identité durable définie par la couche RAW commune ; le Worker n'ajoute ni provider, ni endpoint, ni protocole à cette identité.
|
||||
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.
|
||||
|
||||
## Runtime
|
||||
## Pipeline productif actuel
|
||||
|
||||
Le point d'entrée public est :
|
||||
La première verticale live est :
|
||||
|
||||
```text
|
||||
RawTransactionIngestWorker::start(settings, Arc<Store>)
|
||||
-> RawTransactionIngestHandle
|
||||
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
|
||||
```
|
||||
|
||||
Le démarrage est synchrone mais nécessite qu'un runtime Tokio courant appartienne déjà au caller. Le Worker ne crée pas de runtime global et n'expose aucun `JoinHandle` public.
|
||||
`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 ;
|
||||
- obtenir une source de snapshots concrets latest-value ;
|
||||
- utiliser cette même source via `WorkerSnapshotSource` ;
|
||||
- attendre le terminal après drain/abort+join des tâches possédées.
|
||||
- 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.
|
||||
|
||||
La destruction du dernier handle de contrôle ferme aussi la voie de contrôle privée ; le runtime termine alors selon les mêmes règles de shutdown.
|
||||
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 et Common RAW
|
||||
## Admission, coalescence et backpressure
|
||||
|
||||
La queue centrale est un `tokio::sync::mpsc` privé borné par `admission_queue_capacity`. Les sources internes doivent subir la backpressure du channel ; aucune queue non bornée ni silent drop n'est autorisé.
|
||||
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é.
|
||||
|
||||
Chaque ingress admis est :
|
||||
La source Yellowstone possède également un coordinateur d'hydration borné :
|
||||
|
||||
1. vérifié contre le réseau attendu ;
|
||||
2. canonicalisé exclusivement par `ksp-raw-transaction-lib` ;
|
||||
3. associé à une observation key déterministe sous le domaine `ksp.raw_transaction_ingest.observation.v1` ;
|
||||
4. assemblé en acquisition RAW commune ;
|
||||
5. remis à la persistence Store.
|
||||
```text
|
||||
in-flight hydration <= persistence_concurrency
|
||||
pending source signals <= 65_536
|
||||
```
|
||||
|
||||
La crate ne possède pas un second format RAW et ne duplique pas le canonicaliseur commun.
|
||||
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 uniquement par `ksp-store-lib` avec `default-features = false` dans la crate Worker. Aucun backend physique n'est imposé ou importé directement.
|
||||
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 d'acquisition atomique `RawTransaction + RawTransactionObservation`. Les outcomes distingués sont notamment :
|
||||
L'écriture utilise le mode normal atomique `RawTransaction + RawTransactionObservation`. Les outcomes distingués incluent :
|
||||
|
||||
```text
|
||||
entity inserted
|
||||
@@ -72,21 +154,13 @@ content conflict
|
||||
store failure
|
||||
```
|
||||
|
||||
`persistence_concurrency` borne le nombre d'écritures Store simultanées. Un conflit de contenu est terminal et n'est jamais converti en succès idempotent.
|
||||
Un content conflict est terminal et n'est jamais converti en succès idempotent.
|
||||
|
||||
## Shutdown et faults
|
||||
## Snapshots et erreurs
|
||||
|
||||
Le shutdown possède une deadline bornée par `shutdown_drain_timeout`.
|
||||
`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.
|
||||
|
||||
Avant publication terminale, le supervisor :
|
||||
|
||||
- arrête les nouvelles admissions ;
|
||||
- signale le stop aux sources privées ;
|
||||
- draine le travail déjà admis tant que la deadline le permet ;
|
||||
- récolte les persistences et sources possédées ;
|
||||
- en cas de timeout, abort les tâches restantes puis les rejoint avant le terminal.
|
||||
|
||||
Les codes d'erreur publics du Worker sont :
|
||||
Les codes Worker publics sont :
|
||||
|
||||
```text
|
||||
worker_raw_transaction_ingest.settings_invalid
|
||||
@@ -98,26 +172,7 @@ worker_raw_transaction_ingest.source_failed
|
||||
worker_raw_transaction_ingest.drain_timeout
|
||||
```
|
||||
|
||||
Les diagnostics ne recopient pas de payload RAW, URL, credential, signature hostile ou texte backend/provider arbitraire.
|
||||
|
||||
## Snapshots
|
||||
|
||||
`RawTransactionIngestSnapshotSource` est latest-value. Les listeners peuvent rater des états intermédiaires mais obtiennent toujours une valeur complète et monotone par `WorkerSnapshotSequence`.
|
||||
|
||||
Le snapshot concret expose notamment :
|
||||
|
||||
```text
|
||||
lifecycle / health / activity
|
||||
admission_queue_capacity / admission_queue_depth
|
||||
persistence_concurrency / in_flight_persistence
|
||||
admitted_total / canonicalized_total / persisted_total
|
||||
entity_inserted_total / entity_already_present_total / entity_skipped_purged_total
|
||||
observation_inserted_total / observation_already_present_total
|
||||
content_conflict_total / store_failure_total / source_failure_total
|
||||
backpressure_wait_total
|
||||
```
|
||||
|
||||
Les compteurs ne wrapent jamais silencieusement.
|
||||
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
|
||||
|
||||
@@ -126,6 +181,7 @@ 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
|
||||
@@ -133,25 +189,25 @@ sha2
|
||||
tokio (macros, rt, sync, time)
|
||||
```
|
||||
|
||||
La crate ne dépend pas de Config, Job, `ksp-store-api` directement, backend Store concret, Transport, Tauri ou SDK provider.
|
||||
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 de la fondation source-neutral
|
||||
## Hors périmètre
|
||||
|
||||
Cette surface ne possède pas encore :
|
||||
La verticale actuelle ne possède pas :
|
||||
|
||||
- adapter HTTP/WS/Yellowstone productif ;
|
||||
- sélection Config de sources/endpoints/credentials ;
|
||||
- discovery/hydration/replay de continuité live ;
|
||||
- hot reconfiguration de listeners/sources ;
|
||||
- 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 ;
|
||||
- campagne historique/backfill ;
|
||||
- décodage STRUCTURAL/DECODED/DOMAIN.
|
||||
|
||||
Ces extensions doivent conserver la séparation avec `ksp-job-backfill-lib` et réutiliser les mêmes contrats RAW/Store.
|
||||
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 actuelle ;
|
||||
- [`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 ;
|
||||
|
||||
Reference in New Issue
Block a user