Files
khadhroony-solana-project/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md

22 KiB

Validation 0.2.9 — Yellowstone gRPC standard + PublicNode

Statut courant : le gate déterministe de pre.012 est vert sans warning ; le smoke PublicNode live et les graphes Cargo finaux ne figurent pas comme exécutés dans le log opérateur fourni. pre.012-fix.001 ajoute la règle durable de séparation de fermeture et déplace les gates restants vers pre.013 technique/live, pre.014 réconciliation documentaire et pre.015 publication minimale.

1. Autorités et baseline courante

Autorités :

RULES.md + docs/rules/*
plan 016 courant
code réel Transport/Config
prompts/014-V0_2_9_START_PROMPT.md pour les contraintes non supersédées
deltas/0.2.9/* pour l'historique immuable et les décisions postérieures au prompt
upstream Yellowstone primaire

Baseline opérateur immédiatement avant pre.012 (0.2.9-pre.011) :

Gate Résultat
cargo fmt --all PASS
audit Rust workspace PASS, 0 candidate export
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS sans warning
Config unit 113/113 PASS
Config public API 15/15 PASS
Config ownership 5/5 PASS
Transport unit 383/383 PASS
Transport public API 49/49 PASS
Transport release completeness 43/43 PASS
Transport doctests 4/4 PASS
workspace dependency canary 3/3 PASS
cargo test --workspace PASS

Cette baseline est le seuil de non-régression de pre.012.

2. Gate dépendances et licence

Exigence Décision / preuve État
proto officiel sans vendoring yellowstone-grpc-proto ^12.6 PASS
pas de client upstream runtime yellowstone-grpc-client absent PASS
runtime Tonic KSP-owned tonic ^0.14 + tonic-prost ^0.14 PASS
proto subtree compatible Apache-2.0 selon LICENSING.md upstream PASS
source AGPL copiée aucune PASS
raw client Tonic public aucun PASS
graph final réinspection pre.012 PENDING FINAL

Le graphe de dépendances n'est pas modifié par pre.012; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.

3. Matrice service Geyser

RPC Classification Cible Preuve Verdict
Subscribe standard oui stream bidi local + lifecycle PASS
SubscribeDeshred extension/pré-exécution Triton non exclusion documentée OUT
SubscribeReplayInfo standard unary oui fixture unary + reconnect tests PASS
Ping standard unary oui fixture exact echo PASS
GetLatestBlockhash standard unary oui fixture typed PASS
GetBlockHeight standard unary oui fixture typed PASS
GetSlot standard unary oui fixture typed PASS
IsBlockhashValid standard unary oui fixture typed + invalid input PASS
GetVersion standard unary oui fixture typed PASS

4. SubscribeRequest — coverage normative

4.1 Top-level

Champ Verdict Preuve minimale
accounts PASS maps typed + wire exact
slots PASS maps typed + wire exact
transactions PASS maps typed + wire exact
transactions_status PASS same filter family, separate map
blocks PASS maps typed + wire exact
blocks_meta PASS named empty marker preserved
entry PASS named empty marker preserved
commitment PASS optional wire semantics
accounts_data_slice PASS order + bounds
ping PASS optional id
from_slot PASS optional + replay mutation

4.2 Accounts

account[]
owner[]
filters[]
nonempty_txn_signature?
cuckoo_accounts_filter?
memcmp bytes/base58/base64
datasize
token_account_state
lamports eq/ne/lt/gt

Verdict : PASS — wire complet retenu, bounds déterministes, payload Debug redacted, malformed fixed-width rejeté.

4.3 Slots

filter_by_commitment?
interslot_updates?
processed
confirmed
finalized
first_shred_received
completed
created_bank
dead + dead_error?

Verdict : PASS.

4.4 Transactions et transaction_status

vote?
failed?
signature?
account_include[]
account_exclude[]
account_required[]
cuckoo_account_include?
token_accounts? = ALL | BALANCE_CHANGED

Verdict : PASS — request wire, transaction storage/meta, status error et malformed signature couverts.

4.5 Blocks, block_meta, entry

account_include[]
include_transactions?
include_accounts?
include_entries?
cuckoo_account_include?
blocks_meta marker
entry marker

Verdict : PASS — block complet, metadata, entries et champs optional/legacy couverts.

5. SubscribeUpdate — coverage normative

Variante Verdict
account PASS
slot PASS
transaction PASS
transaction_status PASS
block PASS
ping PASS
pong PASS
block_meta PASS
entry PASS
top-level filters[] / created_at PASS

Les raw protobufs ne sortent pas de la façade publique. Les décodeurs rejettent les formes structurellement invalides sans copier des payloads arbitraires dans les erreurs.

6. Settings, bounds et redaction

Contrôle État
URL http/https seulement et longueur bornée PASS
URL Debug redacted PASS
metadata key/value/count bornés PASS
metadata secret/public distincte PASS Transport
timeouts non nuls et bornés PASS
reconnect bounds cohérents PASS
inbound/outbound message sizes PASS
request/update queue capacities PASS
filter group/name bounds PASS
account/owner/memcmp/data slice bounds PASS
transaction/block selectors bounds PASS
remote Status message/details non recopiés PASS
Transport -> env/config absent ou PASS

7. Lifecycle, backpressure et replay

Exigence Verdict Preuve
stream bidi unique PASS round-trip fixture
mutation request PASS same request channel
server Ping / client reply PASS actor test
Pong decode PASS update decode
server half-close PASS state terminal observable
explicit client close PASS half-close avant deadline
hostile server shutdown PASS close timeout borné
slow receiver PASS overflow terminal observable
oversized inbound PASS Tonic decoder bound
oversized outbound PASS reject avant queue dispatch
reconnect backoff PASS budget borné
shutdown pendant backoff PASS interruption sans nouvelle connexion
resubscribe déterministe PASS last accepted full request
reprise from_slot PASS dernier slot observé + demande explicite
ReplayInfo first_available PASS clamp/gap seulement si prouvé
duplicate observability PASS compteur borné, pas de suppression silencieuse
exactly-once/lossless NON GARANTI contrat explicite

Snapshot public requis et présent :

reconnect_count
replay_attempt_count
continuity_gap_count
duplicate_update_count
last_requested_from_slot
last_observed_slot
state/error code safe

8. Gate Config V3 — pre.011

8.1 Schema et backward compatibility

Le gate opérateur pre.011 ferme les exigences suivantes :

Exigence Preuve Verdict
schema $id V3 urn:ksp:schema:std.transport:v3 PASS
branches V1/V2 conservées fixtures V1, V2 et document committé PASS
V1 HTTP-only v1_transport_fixture... PASS
V2 HTTP+WS fixture V2 + compatibilité constructeur PASS
V3 HTTP+WS+gRPC 113 tests Config PASS
grpc_endpoints optionnel par profil V3 profil devnet_public sans gRPC PASS
propriétés inconnues refusées branches schema strictes PASS

8.2 Mapping runtime

V3 doit mapper :

grpc_defaults -> YellowstoneGrpcSessionSettings
grpc_endpoints[].url -> YellowstoneGrpcEndpointUrl
provider -> YellowstoneGrpcProviderName
cluster -> YellowstoneGrpcClusterName
protocol = solana_yellowstone -> gate Config explicite
metadata -> YellowstoneGrpcMetadataEntry::public
secret_metadata -> YellowstoneGrpcMetadataEntry::secret
session overrides -> merge avec grpc_defaults

API :

Surface Exigence Statut source
http_settings() inchangée OK
ws_settings() V1 None, V2/V3 selon profil OK
grpc_settings() V1/V2 None, V3 optionnel PASS
into_transport_settings() tuple historique HTTP + WS inchangé PASS
into_all_transport_settings() nouveau tuple HTTP + WS + gRPC PASS

8.3 Provenance et secrets

Règles validées :

metadata publique + provenance KSP_SECRET_*       -> reject
secret_metadata sans provenance secret            -> reject
secret_metadata + variable KSP_PUBLIC_/KSP_*      -> reject
secret_metadata + KSP_SECRET_/KSPB_SECRET_        -> accept
segments littéraux autour du secret               -> accept
safe_value                                         -> secret segment ********
Transport Debug                                    -> URL/metadata secret absents

Les tests V3 démontrent le cas valide et les deux croisements invalides sans exposer les canaris.

8.4 PublicNode Mainnet

Profil committé et validé :

profile_id = publicnode_mainnet
provider   = publicnode
cluster    = mainnet-beta
protocol   = solana_yellowstone
url        = https://solana-yellowstone-grpc.publicnode.com:443  # provider affiche host:port ; KSP ajoute le scheme TLS requis
metadata   = aucune

Le mapping produit un endpoint TLS Yellowstone standard ; le test committed_v3_publicnode_mainnet_maps_provider_neutral_yellowstone_grpc passe et Debug ne doit pas exposer l'URL.

8.5 PublicNode Testnet

Verdict final documentaire : EXTERNAL BLOCK, NOT GUESSED.

Le réaudit officiel du 2026-08-24 confirme une capacité Solana Testnet gRPC chez PublicNode, mais l'hostname exact n'a pas été obtenu depuis une source PublicNode suffisamment autoritative. Aucun profil, aucun hostname déduit et aucun smoke Testnet ne sont versionnés.

capacité Testnet gRPC       confirmée
hostname exact              non confirmé
profil KSP                  absent
smoke KSP                   absent
raison                       interdiction d'inventer un endpoint provider

9. Provider-neutrality

Point Verdict
type public PublicNodeGrpc* sans divergence absent, PASS
protocol standard encodé comme provider non, PASS
provider descriptif séparé oui, PASS
auth PublicNode hardcodée dans Transport non, PASS
Helius/OrbitFlare runtime gRPC dans 0.2.9 non, PASS
provider extensions dans N2 aucune, PASS

10. Non-régressions obligatoires

Le gate final doit préserver :

HTTP current typed            52/52
HTTP historical               14/14 Deprecated/Removed
KSP-TRANSPORT-007             vert
Standard WebSocket            9 familles / 18 opérations
Helius LaserStream WebSocket  7 familles standard + transaction + slotsUpdates, heartbeat provider-owned
Transport -> Config           interdit
Transport -> std::env KSP_*   interdit
tracing direct Transport      interdit

pre.012 ne modifie pas le runtime Transport ; elle ajoute uniquement un smoke live ignoré par défaut et de la documentation/audit. Son seuil de non-régression est la baseline pre.011.

11. Historique des gates fermé

Les détails de commandes, warnings corrigés et fichiers exacts restent dans leurs deltas immuables.

Tranche Gate consolidé
pre.001 + fix.001 + fix.002 audit/sizing/providers/licence fermé
pre.002 + fix.001 + fix.002 moteur/settings/channel fermé
pre.003 + fix.001 TLS/metadata/unary fermé
pre.004 + fix.001 Subscribe common fermé
pre.005 + fix.001 Accounts/Slots fermé
pre.006 namespace HTTP fermé
pre.007 Transactions fermé
pre.008 + fix.001 Blocks fermé
pre.009 + fix.001 bidi/backpressure fermé
pre.010 + fix.001 reconnect/replay fermé sans warning
pre.011 Config V3/PublicNode mapping fermé

Cette table remplace les anciens appendices numérotés successivement 19.x, 20, 21, etc. qui rendaient le document ambigu.

12. Verdict opérateur pre.012

12.1 Gate déterministe reçu

Exigence Résultat opérateur
cargo fmt --all PASS
audit Rust workspace PASS, 0 candidate export
audit Markdown PASS, 87 tableaux / 252 fichiers
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS sans warning
Config unit 113/113 PASS
Config public API 15/15 PASS
Config ownership 5/5 PASS
Transport unit 383/383 PASS
Transport public API 49/49 PASS
Transport release completeness 43/43 PASS
Transport doctests 4/4 PASS
workspace dependencies 3/3 PASS
cargo test --workspace PASS
smoke Mainnet programmatique sans credential NOT RUN, ignored
graphes Cargo finaux NOT PROVIDED / NOT RUN

Le test yellowstone_publicnode_smoke compile et apparaît correctement comme ignored dans les tests Transport et workspace, mais cela ne constitue pas une exécution live. Aucune preuve de cargo tree final n'est présente dans le log fourni.

12.2 Effet de pre.012-fix.001

Le fix ne change ni runtime, ni schema, ni Config, ni smoke. Il corrige le workflow de fermeture afin que les responsabilités restantes ne soient plus mélangées :

pre.013  technique/live : smoke PublicNode + graphes Cargo finaux
pre.014  réconciliation documentaire : plan/validation/README/USAGE/références
pre.015  publication minimale : prompt suivant + CHANGELOG + ROADMAP
rel.001  mécanique stable uniquement

Le contenu prompt/README/USAGE déjà préparé en pre.012 n'est pas supprimé rétroactivement. Le prompt reste un brouillon jusqu'à pre.015 ; README/USAGE seront réconciliés définitivement en pre.014.

13. Gate pre.013 — technique/live

Commandes minimales :

cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture

Verdicts attendus :

smoke Mainnet réellement exécuté
GetVersion + GetSlot via TLS sans credential ou incident externe précisément classifié
graphes Cargo inspectés
aucun changement README/USAGE/prompt/CHANGELOG/ROADMAP

Un défaut local découvert dans ce gate reste dans pre.013-fix.NNN. Un incident externe n'est jamais maquillé en PASS local.

14. Gate pre.014 — réconciliation documentaire

Cette tranche ferme les documents durables après le gate technique réel :

plan 016
validation 012
README/USAGE Transport
documents de référence 0.2.9 réellement concernés
audit Markdown des documents touchés

Elle n'introduit aucun nouveau runtime/smoke et ne finalise pas CHANGELOG.md, ROADMAP.md ni le prompt suivant.

Le verdict de la validation 012 devient définitif dans cette tranche, sur la base exclusive des preuves réellement exécutées en pre.013 et des gates antérieurs.

15. Gate pre.015 — préparation de publication

Payload fonctionnel autorisé :

prompts/015-V0_2_10_START_PROMPT.md
CHANGELOG.md
ROADMAP.md

Seuls les fichiers mécaniques de version et de traçabilité (Cargo.toml, delta pre.015) peuvent s'ajouter à ce payload. Aucun README, USAGE, plan, validation, règle, code, test, schema ou config ne doit être corrigé dans pre.015.

Si un tel défaut est découvert, une nouvelle prerelease dédiée est ouverte puis la préparation de publication est rejouée sous un nouveau numéro.

16. Verdict stable attendu avant rel.001

0.2.9 peut passer à rel.001 seulement après la séquence suivante :

pre.013 technique/live fermé
pre.014 réconciliation documentaire fermée
pre.015 prompt/CHANGELOG/ROADMAP fermé

Et si tous les invariants suivants sont vrais :

standard vs extension explicitement classifié
SubscribeDeshred OUT documenté
7 unary verts
Subscribe + 9 updates verts
resource/backpressure/lifecycle verts
reconnect/replay sans promesse lossless
Config V3 backward V1/V2
provider/protocol distincts
PublicNode Mainnet live exécuté avec résultat consigné
Testnet jamais inventé
HTTP/WS/Helius non régressés
dependency firewall vert
cargo graphs inspectés
README/USAGE réconciliés avant la dernière pre
validation 012 fermée avant la dernière pre
prompt/CHANGELOG/ROADMAP seuls dans la dernière pre
workspace final vert