# Delta `0.2.9-pre.003` — TLS + metadata générique + fixture locale + 7 unary Yellowstone ## 1. Objet Cette tranche poursuit le moteur Yellowstone après la fermeture opérateur complète de `pre.002-fix.002`. Elle matérialise exactement le forecast prévu : ```text N1 : connexion HTTP/2 réelle + TLS WebPKI + metadata ASCII publique/secrète redacted N2 : sept unary RPCs Yellowstone standard typed derrière une façade KSP tests : fixture Geyser locale couvrant le wire réel, metadata, Status hostile et timeout ``` Restent hors tranche : ```text Subscribe / streaming bidi SubscribeDeshred PublicNode / N3 provider Config V3 reconnect/resubscribe/replay lifecycle complet ``` Version workspace : ```text 0.2.9-pre.3 ``` Commit attendu après validation opérateur : ```text v0.2.9-pre.003 ``` ## 2. Preuve héritée — fermeture de `pre.002` Le gate opérateur final fourni pour `0.2.9-pre.2.fix.2` est intégralement vert : ```text cargo fmt --all PASS python3 scripts/audit_rust_workspace_rules.py PASS / clean cargo check --workspace PASS cargo clippy --workspace --all-targets PASS cargo test -p ksp-onchain-transport-lib PASS unit 346/346 public_api 42/42 release_completeness 35/35 doctests 4/4 cargo test -p ksp-core-lib --test workspace_dependencies PASS 3/3 cargo test --workspace PASS ``` `pre.003` part donc d'une base technique fermée, sans dette reportée de `pre.002`. ## 3. Dépendances et features La stratégie B reste inchangée : le runtime KSP utilise les messages publiés `yellowstone-grpc-proto` et un client KSP autour de Tonic ; `yellowstone-grpc-client` reste absent. Ajouts workspace : ```text http = ^1.5, default-features = false tonic-prost = ^0.14, default-features = false ``` Features Transport runtime : ```text tonic = channel + tls-aws-lc + tls-webpki-roots tonic-prost = runtime ProstCodec yellowstone-grpc-proto = aucune feature locale ``` Features uniquement dev/test : ```text tonic = codegen + server yellowstone-grpc-proto = tonic ``` La feature `tonic` de la crate proto est donc utilisée uniquement pour générer `GeyserServer` dans la fixture locale. Le runtime ne consomme ni le client généré upstream ni sa sémantique de lifecycle. Toujours absents comme dépendances KSP directes : ```text yellowstone-grpc-client prost prost-types ``` Le choix `tls-aws-lc` reste aligné avec la stack Rustls déjà présente via Reqwest ; le gate Cargo opérateur doit confirmer l'absence de duplication injustifiée. ## 4. N1 — TLS, connexion réelle et metadata `YellowstoneGrpcChannel` possède maintenant deux chemins explicites : ```text prepare() -> connect_lazy(), aucun socket connect() -> établissement réel du channel HTTP/2 ``` Pour un endpoint `https://`, le builder applique : ```text ClientTlsConfig WebPKI roots TLS handshake timeout borné connect timeout borné request buffer borné ``` Les erreurs d'établissement restent projetées vers `onchain_transport/grpc_channel_failed` sans recopier URI ou message arbitraire Tonic. Ajout de `YellowstoneGrpcMetadataEntry` : ```text ASCII uniquement clé <= 128 bytes valeur <= 8 KiB <= 64 entrées par endpoint clés grpc-* refusées metadata binaire *-bin hors contrat pre.003 public et secret séparés explicitement valeurs toujours absentes de Debug secret -> MetadataValue::set_sensitive(true) ``` Transport ne connaît aucun nom `KSP_SECRET_*`, ne lit pas l'environnement et ne lie aucune clé provider particulière au standard N1/N2. ## 5. N2 — sept unary standard Ajout de `SolanaYellowstoneGrpcUnaryClient`, construit uniquement depuis `YellowstoneGrpcChannel`. Le Tonic `Channel`, `Grpc`, les Requests et les messages protobuf restent privés. Surface exacte : ```text SubscribeReplayInfo Ping GetLatestBlockhash GetBlockHeight GetSlot IsBlockhashValid GetVersion ``` Les chemins wire sont les chemins `geyser.Geyser` officiels. `SolanaCommitment` existant est réutilisé et mappé vers `Processed / Confirmed / Finalized`. DTOs publics KSP : ```text YellowstoneReplayInfo YellowstonePong YellowstoneLatestBlockhash YellowstoneBlockHeight YellowstoneSlot YellowstoneBlockhashValidity YellowstoneVersionInfo ``` Bornes/sécurité : ```text max inbound/outbound appliqués au dispatcher Tonic une seule deadline KSP couvre readiness + metadata + unary dispatch blockhash request localement borné/validé avant I/O blockhash/version response textuellement bornés Ping exige l'echo exact du count ``` Nouveau code d'erreur : ```text onchain_transport/grpc_status ``` Un `tonic::Status` distant n'est jamais copié dans `KspError` : seuls l'opération et le code gRPC sont conservés. Message/details/metadata provider restent hors diagnostic public. ## 6. Fixture Geyser locale Les tests dev activent le serveur généré officiel et démarrent un `GeyserServer` sur `127.0.0.1:0`. Les deux RPCs streaming obligatoires du trait retournent volontairement `Unimplemented`, car ils restent hors `pre.003`. La fixture vérifie réellement : ```text les 7 paths unary commitment wire metadata publique reçue metadata secrète reçue replay optional first_available Ping exact latest blockhash / height / slot / validity / version Status hostile contenant un canari secret non propagé timeout unary local déterministe blockhash invalide rejeté avant I/O Debug client/channel sans URL ni secret ``` La fixture est locale et déterministe ; aucun provider externe n'est requis pour fermer cette tranche. ## 7. Canaries structurels Les canaries vérifient en plus : ```text feature set runtime/dev exact yellowstone-grpc-client absent proto runtime sans feature tonic server/codegen uniquement dev/test aucun pub use tonic/yellowstone_grpc_proto sept chemins unary exacts aucun Subscribe standard ajouté aucun SubscribeDeshred ajouté aucun PublicNode ajouté Transport -X-> Config/env/WS pour la surface gRPC ``` ## 8. Documentation Mise à jour de : ```text docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md ``` La matrice enregistre la fermeture réelle de `pre.002` et place les sept unary/TLS/metadata/fixture en candidate `pre.003`. Le forecast reste inchangé : `pre.004` ouvre seulement la foundation `Subscribe`. ## 9. Validation exécutée dans l'environnement de préparation Exécuté réellement après les modifications source/documentaires : ```text python3 scripts/audit_rust_workspace_rules.py General Rust rule audit: clean Rust export completeness audit: 0 candidate(s) KSP workspace Rust rule audit: clean ``` L'environnement de préparation ne fournit pas Cargo/Rust ; aucune commande Cargo n'est déclarée réussie localement. ## 10. Gate opérateur requis ```bash cargo fmt --all python3 scripts/audit_rust_workspace_rules.py cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib cargo test -p ksp-core-lib --test workspace_dependencies cargo test --workspace cargo tree -p ksp-onchain-transport-lib cargo tree -p ksp-onchain-transport-lib -e features cargo tree -p ksp-onchain-transport-lib --duplicates cargo tree --duplicates ``` Les graphes doivent être réinspectés car `http`, `tonic-prost` et les features TLS/server/codegen changent le graphe de `pre.002`. Contrôler notamment : ```text tonic / tonic-prost prost / prost-types http / hyper / hyper-util / tower rustls / tokio-rustls / aws-lc yellowstone-grpc-proto runtime vs dev feature unification solana-pubkey yellowstone-grpc-client absent router/gzip/zstd non activés par la surface KSP ; server/codegen uniquement via dev/test ``` ## 11. Fichiers ajoutés/modifiés ```text Cargo.toml crates/ksp-core-lib/tests/workspace_dependencies.rs crates/ksp-onchain-transport-lib/Cargo.toml crates/ksp-onchain-transport-lib/src/error.rs crates/ksp-onchain-transport-lib/src/grpc_channel.rs crates/ksp-onchain-transport-lib/src/grpc_settings.rs crates/ksp-onchain-transport-lib/src/grpc_unary.rs crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/rpc_common.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs crates/ksp-onchain-transport-lib/unit_tests/grpc_channel.rs crates/ksp-onchain-transport-lib/unit_tests/grpc_settings.rs crates/ksp-onchain-transport-lib/unit_tests/grpc_unary.rs docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md deltas/0.2.9/pre.003.md ```