v0.3.12-pre.006
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/029-V0_3_12_YELLOWSTONE_HYDRATION_CONTINUITY.md -->
|
||||
<!-- version: 10 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Validation v0.3.12 — Yellowstone + hydration HTTP + continuité de run du Worker RawTransaction
|
||||
|
||||
@@ -1128,3 +1128,181 @@ cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib
|
||||
```
|
||||
|
||||
## 47. Gate opérateur `pre.005-fix.001`
|
||||
|
||||
Le gate opérateur communiqué pour `0.3.12-pre.5.fix.1` est entièrement vert :
|
||||
|
||||
```text
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
KSP workspace Rust rule audit: clean
|
||||
Markdown table audit: clean (340 tables, 809 fichiers)
|
||||
cargo check --workspace: PASS
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings: PASS
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib: PASS
|
||||
56 unit tests Worker: PASS
|
||||
6 dependency-boundary tests: PASS
|
||||
12 hardening tests: PASS
|
||||
8 public-api tests: PASS
|
||||
3 release-completeness tests: PASS
|
||||
Doc-tests: PASS
|
||||
```
|
||||
|
||||
Cette base ferme donc `pre.005` et son fix de conversion `YellowstoneTransactionSignature::as_bytes()` avant ouverture de la source productive.
|
||||
|
||||
## 48. `pre.006` — source Yellowstone productive
|
||||
|
||||
`start_with_runtime_resources` ne délègue plus au foundation sans source. Après les validations synchrones Store/settings/runtime-resources déjà qualifiées, il :
|
||||
|
||||
```text
|
||||
consomme RawTransactionIngestRuntimeResources
|
||||
extrait exactement une RawTransactionIngestYellowstoneSource
|
||||
clone les settings nécessaires au child privé
|
||||
spawn exactement un child dans le SourceTasks JoinSet existant
|
||||
laisse le supervisor 0.3.11 posséder stop/drain/fault
|
||||
```
|
||||
|
||||
Le child ouvre la session uniquement via :
|
||||
|
||||
```text
|
||||
YellowstoneGrpcChannel::open_standard_subscribe
|
||||
SolanaYellowstoneGrpcSubscribeSession::next_update
|
||||
SolanaYellowstoneGrpcSubscribeSession::close
|
||||
```
|
||||
|
||||
Le Worker ne crée aucun `tonic::Channel`, client Geyser, client Reqwest ou actor gRPC parallèle. Transport reste propriétaire des metadata, credentials, ping/pong, message-size bounds et reconnect interne.
|
||||
|
||||
Le stop privé est prioritaire pendant l'ouverture, pendant la lecture de stream et pendant l'envoi vers l'admission. Un stop avant ouverture abandonne le futur d'ouverture sans session orpheline. À la sortie, les hydrations privées sont abort/join puis la session Transport est fermée via son close borné.
|
||||
|
||||
## 49. Routage productif des updates
|
||||
|
||||
Le dispatch productif est désormais :
|
||||
|
||||
```text
|
||||
Transaction -> 1 RawTransactionIngestSourceSignal -> hydration
|
||||
TransactionStatus -> 1 RawTransactionIngestSourceSignal -> hydration
|
||||
Block -> N RawTransactionIngestSourceSignal dans l'ordre source -> hydration
|
||||
BlockMeta -> RawTransactionIngestContinuitySignal continuity-only
|
||||
Slot -> RawTransactionIngestContinuitySignal continuity-only
|
||||
Account/Entry/Ping/Pong -> aucun RAW Worker
|
||||
```
|
||||
|
||||
`BlockMeta` et `Slot` restent délibérément sans admission RAW. `dead_error` et `TransactionStatus.error` ne sont pas lus. Aucun `getBlock`/`get_block_observed` n'est ajouté.
|
||||
|
||||
Les adapters `pre.003-pre.005`, précédemment gardés sous `#[cfg(test)]` faute de consumer productif, sont maintenant compilés dans le build normal. Le wrapper fixture `hydrate_yellowstone_signal` reste test-only ; la production utilise les deux étapes séparées `fetch_yellowstone_hydration` puis `finalize_yellowstone_hydration`.
|
||||
|
||||
## 50. Coalescence bornée d'hydration
|
||||
|
||||
La clé privée est exactement :
|
||||
|
||||
```text
|
||||
network
|
||||
signature
|
||||
commitment
|
||||
```
|
||||
|
||||
Elle ne contient ni family ni filter. Ainsi `Transaction`, `TransactionStatus` et `Block` portant la même signature/network/commitment partagent au plus un `getTransaction` in-flight.
|
||||
|
||||
Le coordinator privé conserve :
|
||||
|
||||
```text
|
||||
BTreeMap<HydrationKey, PendingHydration>
|
||||
JoinSet<HydrationFetch>
|
||||
max_in_flight = persistence_concurrency validée
|
||||
max_pending_signals = MAX_RAW_TRANSACTION_INGEST_ADMISSION_QUEUE_CAPACITY
|
||||
```
|
||||
|
||||
Le nombre de tâches HTTP simultanées est donc borné par le réglage existant de concurrence, sans nouveau knob public. Le nombre de signaux coalescés/pending reste borné par la borne maximale déjà publiée du Worker. Quand cette borne est atteinte, la lecture Yellowstone est backpressurée ; un dépassement à l'intérieur d'une update composite produit un fault source sûr au lieu d'un drop silencieux.
|
||||
|
||||
À la complétion d'un unique fetch HTTP, chaque signal coalescé est finalisé séparément. Le fan-out reconstruit donc sa propre provenance :
|
||||
|
||||
```text
|
||||
transaction_get_transaction
|
||||
status_get_transaction
|
||||
block_get_transaction
|
||||
filter_id direct ou fingerprint propre au signal
|
||||
observed_at propre au signal quand représentable
|
||||
```
|
||||
|
||||
Store idempotence reste ensuite la seconde barrière. Aucun cache de déduplication terminé/non borné n'est conservé.
|
||||
|
||||
## 51. Hydration productive et admission
|
||||
|
||||
Le fetch utilise toujours le contrat `pre.004` :
|
||||
|
||||
```text
|
||||
get_transaction_observed
|
||||
encoding = base64
|
||||
commitment = confirmed | finalized de la source
|
||||
maxSupportedTransactionVersion = 0
|
||||
```
|
||||
|
||||
Le résultat observé est partagé uniquement entre les signaux ayant la même clé. Chaque finalisation réapplique avant admission :
|
||||
|
||||
```text
|
||||
network cohérent
|
||||
route Yellowstone cohérente
|
||||
slot HTTP == slot signal
|
||||
transaction_index cohérent lorsqu'il est présent des deux côtés
|
||||
signature embarquée == signature signal
|
||||
provenance composite sûre depuis le winner HTTP réel
|
||||
```
|
||||
|
||||
`null` reste `Missing` : aucun ingress n'est créé. Une erreur Transport est réduite à son `ErrorCode` KSP sûr. Aucun texte distant n'entre dans l'erreur Worker.
|
||||
|
||||
Les ingresses disponibles sont envoyés uniquement via le `tokio::sync::mpsc::Sender<RawTransactionIngress>` déjà créé par `RawTransactionAdmission::new`. Aucun second canal d'admission ou chemin Store n'est introduit.
|
||||
|
||||
## 52. Canaris `pre.006`
|
||||
|
||||
Les nouveaux canaris vérifient au minimum :
|
||||
|
||||
```text
|
||||
start_with_runtime_resources -> source.run -> children.spawn
|
||||
open_standard_subscribe/next_update/close présents uniquement via la façade Transport
|
||||
get_transaction_observed reste l'unique hydration HTTP
|
||||
aucun get_block_observed
|
||||
aucun Config/Backfill/backend/reqwest/tonic/proto direct
|
||||
coalescence key = network/signature/commitment
|
||||
Transaction + Status de même signature -> une seule entrée pending et une seule tâche HTTP in-flight
|
||||
signature différente -> clé différente
|
||||
pending et in-flight bornés
|
||||
stop preemptible pendant admission
|
||||
abort_all + join des hydrations privées
|
||||
aucun remote error/dead_error/secret dans la source productive
|
||||
public root inchangé
|
||||
module inventory inchangé
|
||||
```
|
||||
|
||||
## 53. Non-claims `pre.006`
|
||||
|
||||
`pre.006` ne prétend pas encore :
|
||||
|
||||
```text
|
||||
maintenir une processing frontier
|
||||
interpréter le snapshot reconnect Transport
|
||||
modifier from_slot au niveau Worker
|
||||
interpréter SubscribeReplayInfo
|
||||
prouver une continuité blockchain
|
||||
fault sur gap de rétention prouvé
|
||||
faire un repair/backfill implicite
|
||||
qualifier les races duplicate storm/Store lent finales de pre.009
|
||||
réussir un smoke provider live sans credentials opérateur
|
||||
```
|
||||
|
||||
Ces responsabilités restent respectivement `pre.007`, `pre.008`, `pre.009` et `pre.011` conformément au plan.
|
||||
|
||||
## 54. Gate opérateur requis pour `pre.006`
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
|
||||
cargo tree --duplicates
|
||||
```
|
||||
|
||||
Dans l'environnement d'assemblage, `cargo`, `rustc` et `rustfmt` ne sont pas installés ; aucun gate Cargo local n'est donc revendiqué.
|
||||
|
||||
Reference in New Issue
Block a user