Files
khadhroony-solana-project/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md
2026-08-24 11:55:17 +02:00

43 KiB
Raw Blame History

Validation 0.2.9 — moteur Yellowstone + standard Solana + PublicNode

Statut : pre.003-fix.001 est fermé sur gate opérateur intégralement vert et graphes Cargo inspectés. 0.2.9-pre.004 est candidate et ajoute uniquement la fondation standard SubscribeRequest : sept maps, commitment, account-data slices, ping, from_slot, bornes communes et redaction Debug. Aucun stream bidi n'est encore ouvert ; les filtres détaillés Accounts/Slots/Transactions/Blocks restent réservés à pre.005007. PublicNode et Config V3 restent hors tranche. OrbitFlare et Helius sont les seules releases provider suivantes planifiées ; les autres providers restent en TODO/IDEAS sans numéro réservé.

1. Autorités du gate

Base interne :

v0.2.8 / archive Gitea stable fournie
workspace.package.version initial = 0.2.8
deltas/0.2.8/rel.001.md
prompts/014-V0_2_9_START_PROMPT.md

Sources upstream auditées le 2026-08-23 :

https://github.com/rpcpool/yellowstone-grpc/releases
https://github.com/rpcpool/yellowstone-grpc/blob/master/CHANGELOG.md
https://github.com/rpcpool/yellowstone-grpc/blob/master/LICENSING.md
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/geyser.proto
https://github.com/rpcpool/yellowstone-grpc/blob/master/yellowstone-grpc-proto/proto/solana-storage.proto
https://docs.rs/crate/yellowstone-grpc-client/latest
https://docs.rs/crate/yellowstone-grpc-proto/latest

Divergence enregistrée :

snapshot du prompt : GitHub release v14.2.2+solana.4.1.0
réaudit courant    : GitHub release v15.1.2+solana.4.2.0 (2026-08-18)
crate client       : 13.3.0
crate proto        : 12.6.0

2. Baseline stable

Gate Preuve État
cargo fmt --all log opérateur v0.2.8 DONE
audit Rust workspace clean DONE
cargo check --workspace log opérateur DONE
cargo clippy --workspace --all-targets log opérateur DONE
cargo test --workspace log opérateur DONE
Transport unit 335 passed DONE
Transport public API 41 passed DONE
Transport release completeness 34 passed DONE
Transport doctests 4 passed DONE
cargo tree -p ksp-onchain-transport-lib log opérateur DONE
cargo tree --duplicates log opérateur DONE

3. Matrice service Geyser

RPC Forme Classification Scope Preuve cible État
Subscribe bidi standard IN fixture locale + live PARTIAL pre.004 request / stream TODO pre.008
SubscribeDeshred bidi Triton extension/pré-exécution malgré présence proto OUT canari d'absence/API OUT
SubscribeReplayInfo unary standard IN fixture unary DONE pre.003
Ping unary standard IN fixture unary DONE pre.003
GetLatestBlockhash unary standard IN fixture unary DONE pre.003
GetBlockHeight unary standard IN fixture unary DONE pre.003
GetSlot unary standard IN fixture unary DONE pre.003
IsBlockhashValid unary standard IN fixture unary DONE pre.003
GetVersion unary standard IN fixture unary DONE pre.003

4. SubscribeRequest — coverage normative

4.1 Top-level

Champ Sémantique Scope Preuve
accounts map filter-name -> account filter IN exact wire + bounds
slots map -> slot filter IN exact wire
transactions map -> transaction filter IN exact wire + bounds
transactions_status map -> transaction filter IN exact wire + bounds
blocks map -> block filter IN exact wire + bounds
blocks_meta map -> empty filter IN presence/empty semantics
entry map -> empty filter IN presence/empty semantics
commitment optional Processed/Confirmed/Finalized IN omitted/value exact
accounts_data_slice repeated offset/length IN order + bounds
ping optional id IN Ping/Pong lifecycle
from_slot optional u64 IN reconnect/replay tests

4.2 Accounts

Capacité Scope Preuve
account[] IN order/cardinality/address validation
owner[] IN order/cardinality/address validation
filters[] IN AND semantics preserved structurally
nonempty_txn_signature? IN omitted/false/true
cuckoo_accounts_filter? IN exact wire + dimension/data bounds
memcmp bytes IN exact bytes + bounds
memcmp base58 IN exact string + validation
memcmp base64 IN exact string + validation
datasize IN exact u64
token_account_state IN bool
lamports eq/ne/lt/gt IN oneof exact

4.3 Slots

Capacité Scope Preuve
filter_by_commitment? IN optional semantics
interslot_updates? IN optional semantics
processed/confirmed/finalized IN enum decode
first_shred_received/completed/created_bank/dead IN enum decode + dead_error

4.4 Transactions / transaction_status

Capacité Scope Preuve
vote? IN optional semantics
failed? IN optional semantics
signature? IN exact/validated
account_include[] IN order/bounds
account_exclude[] IN order/bounds
account_required[] IN order/bounds
cuckoo_account_include? IN exact wire + bounds
token_accounts? = ALL IN optional enum
token_accounts? = BALANCE_CHANGED IN optional enum

4.5 Blocks

Capacité Scope Preuve
account_include[] IN order/bounds
include_transactions? IN optional semantics
include_accounts? IN optional semantics
include_entries? IN optional semantics
cuckoo_account_include? IN exact wire + bounds

5. SubscribeUpdate — coverage normative

Variante Champs structurants Scope Preuve
account account info, slot, is_startup IN exact decode
slot slot, parent?, status, dead_error? IN exact decode
transaction signature, vote, transaction, meta, index, slot IN exact decode
transaction_status slot, signature, vote, index, err IN exact decode
block hash/rewards/time/height/parents/counts + tx/accounts/entries IN exact decode + bounds
ping marker IN lifecycle
pong id IN lifecycle
block_meta metadata/counts IN exact decode
entry slot/index/hash/counts IN exact decode

Top-level à préserver :

filters[]
created_at
oneof absent/inconnu -> comportement explicitement testé

6. solana-storage.proto — nested wire utile

Le backend doit préserver les champs nécessaires des structures imbriquées actuelles, sans exposer les types upstream comme contrat public :

ConfirmedBlock
ConfirmedTransaction
Transaction
Message
MessageHeader
MessageAddressTableLookup
TransactionStatusMeta
TransactionError
InnerInstructions / InnerInstruction
CompiledInstruction
TokenBalance / UiTokenAmount
ReturnData
Reward / Rewards
UnixTimestamp
BlockHeight
NumPartitions

États optionnels/legacy particulièrement sensibles :

compute_units_consumed?
cost_units?
inner_instructions_none
log_messages_none
return_data_none
loaded writable/readonly addresses
commission / commission_bps

Preuve cible : fixtures issues du wire Protobuf + cas old/current + malformed/oversized, sans conversion JSON arbitraire.

7. Unary RPC matrix

RPC Request exact Response exact État
ReplayInfo empty first_available? CANDIDATE
Ping count count CANDIDATE
LatestBlockhash commitment? slot/hash/last_valid_height CANDIDATE
BlockHeight commitment? block_height CANDIDATE
Slot commitment? slot CANDIDATE
IsBlockhashValid blockhash + commitment? slot + bool CANDIDATE
Version empty version CANDIDATE

8. Dépendances / licence

Gate Décision / matérialisation pre.003 Preuve / état
repository default AGPL-3.0-only LICENSING.md
client subtree Apache-2.0 LICENSING.md
proto subtree Apache-2.0 LICENSING.md
strategy A client+proto rejetée comme default documenté
strategy B proto+Tonic KSP retenue ; TLS/unary matérialisés source PASS / Cargo pending
yellowstone-grpc-proto ^12.6, default-features = false, aucune feature KSP Cargo tree pending
tonic runtime channel+tls-aws-lc+tls-webpki-roots; dev codegen+server Cargo tree pending
yellowstone-grpc-client absent manifest canary ajouté
prost/prost-types direct KSP absent manifest / Cargo tree pending
http / tonic-prost direct ^1.5 / ^0.14, runtime minimal pour PathAndQuery/ProstCodec Cargo tree pending
strategy C vendored proto fallback seulement aucun vendoring
system protoc aucun outil système KSP ajouté proto publié/build vendored
raw upstream types public interdit ; aucun reexport Tonic/Yellowstone public API canary ajouté
executable Yellowstone deps interdit dependency firewall à revalider

Versions observées :

yellowstone-grpc-client 13.3.0
yellowstone-grpc-proto  12.6.0
tonic                   0.14.x (0.14.6 latest observé)
prost/prost-types       0.14.x (0.14.4 latest observé)

9. Architecture / ownership

Invariant Preuve cible État pre.003
backend gRPC distinct HTTP/WS source/API canary IMPLEMENTED / Cargo pending
aucun WsProtocolKind gRPC source scan SOURCE PASS
Transport owns gRPC dependency graph IMPLEMENTED / tree pending
Config -> Transport seulement ownership test hérité / final TODO
Transport -X-> Config ownership test SOURCE PASS / Cargo pending
Transport -X-> std::env KSP_* ownership test SOURCE PASS
Logging façade KSP only logging ownership SOURCE PASS
no raw Tonic client escape hatch public API canary IMPLEMENTED / Cargo pending
moteur Yellowstone partagé sans duplication provider source/API canary N1 FOUNDATION IMPLEMENTED
façade Solana Yellowstone standard distincte du moteur public API canary PARTIAL : 7 unary N2 / Subscribe TODO
PublicNode représenté comme provider/capabilities, pas comme nouveau protocole public API/config canary TODO pre.010/011
provider peut réutiliser, restreindre ou étendre N2 sans dupliquer N1 capability/completeness review architecture conservée
aucune équivalence provider/standard présumée sans preuve provider matrix/tests architecture conservée
façade provider spécialisée seulement si delta réel completeness review TODO provider integration

10. Settings, bounds et redaction

État après pre.003 :

DONE/source+tests ajoutés  endpoint schemes http/https validés ; TLS réel matérialisé en pre.003
DONE/source+tests ajoutés  endpoint URL, descripteurs et nombre dendpoints plafonnés
DONE/source+tests ajoutés  connect timeout > 0 et plafonné
DONE/source+tests ajoutés  unary timeout > 0 et plafonné
DONE/source+tests ajoutés  close timeout > 0 et plafonné
DONE/source+tests ajoutés  max inbound/outbound > 0 et plafonnés
DONE/source+tests ajoutés  request/update queue capacities > 0 et plafonnées
DONE/source+tests ajoutés  reconnect attempt/backoff bornés
CANDIDATE pre.004          filter-group count <= 1024 total sur les sept maps
CANDIDATE pre.004          filter-name non vide/trim/control-free <= 128 octets + unicité globale
DONE/source+tests ajoutés  metadata ASCII key/value count/size + reserved/bin bounds
TODO pre.005+              account/owner/include/exclude/required counts
CANDIDATE pre.004          data slice count <= 128, length <= 64 MiB, offset+length sans overflow ; memcmp TODO pre.005
TODO pre.005+              Cuckoo dimensions/data bounds

Security canaries :

DONE/source+tests ajoutés  endpoint URL Debug redacted
DONE/source+tests ajoutés  metadata publique/secrète redacted ; secret marqué sensitive
DONE/source+fixture       Status message/details/metadata distants exclus des KspError
DONE pre.003/fix.001        connect réel + TLS WebPKI configuré ; erreur connect/TLS safe, gate Cargo PASS
CANDIDATE pre.004          SubscribeRequest Debug sans filter names/payload arbitraire ; update Debug TODO pre.005+
DONE pre.003 source/tests   channel/client Debug sans URL, metadata value ni raw Tonic ; lifecycle stream ultérieur

11. Lifecycle / backpressure / replay

Cas Attendu État
stream open session bornée TODO
request mutation ordre déterministe TODO
server Ping -> client request ping -> Pong explicite TODO
server half-close terminal/reconnect selon policy TODO
client close cleanup borné TODO
receiver drop cleanup capacité TODO
slow subscription pas de queue infinie TODO
inbound oversized rejet avant allocation excessive TODO
outbound oversized rejet avant write TODO
reconnect budget borné TODO
resubscribe order déterministe TODO
from_slot utilisé sans promesse lossless TODO
ReplayInfo informatif DONE unary ; usage reconnect TODO
duplicates observables TODO
gaps observables TODO
divergent node history couverture documentée TODO
shutdown during reconnect aucune nouvelle connexion après shutdown TODO

Claims interdits sans nouvelle preuve :

exactly-once
lossless
historical replay complet
ordre global sans gap

12. Config V3

Décision de gate :

V1 HTTP reste lisible
V2 HTTP+WS reste lisible
V3 ajoute gRPC explicitement

Shape conceptuelle à matérialiser :

globals.grpc_defaults
profiles[].grpc_endpoints[]
endpoint.metadata[]         # public/non-secret
endpoint.secret_metadata[]  # Config-owned secret provenance

Canaries :

Gate État
V1 backward readable TODO
V2 backward readable TODO
V3 schema strict TODO
gRPC endpoint mapping TODO
secret provenance enforced TODO
safe projection redacted TODO
no Transport -> Config TODO
.env.example inventory if new env vars TODO

13. Providers — validation et séquence

Provider Accès gratuit/durable observé Rôle architectural Release cible Verdict
PublicNode / Allnodes-backed Mainnet + Testnet Yellowstone gRPC première intégration concrète 0.2.9 IN provider
OrbitFlare Devnet Free provider dédié ; compat/restrictions/extensions à auditer 0.2.10 PLANNED
Helius LaserStream gRPC accès dépendant du plan provider dédié ; compat/replay/auth/extensions à auditer 0.2.11 PLANNED
eRPC à réauditer waitlist provider non réservé TODO
Triton à réauditer upstream + extensions provider possibles non réservé TODO
Alchemy à réauditer waitlist provider non réservé TODO
QuickNode à réauditer waitlist provider non réservé TODO
Chainstack à réauditer waitlist provider non réservé TODO
Tatum / Shyft / Solinfra / NodeFlare / autres selon accès/capabilities attente exploratoire non réservé IDEAS

PublicNode 0.2.9

Cible principale officiellement affichée :

solana-yellowstone-grpc.publicnode.com:443

Gates :

utilise le moteur Yellowstone partagé
utilise la façade standard Solana
provider/capabilities/profile explicitement identifiables
aucune duplication actor/channel/stream
wire N2 réutilisé seulement pour les capacités réellement compatibles ; divergence N3 explicite
Mainnet smoke opt-in
Testnet smoke opt-in si endpoint exact confirmé

Providers suivants

OrbitFlare (0.2.10) et Helius LaserStream gRPC (0.2.11) sont les seules intégrations provider actuellement planifiées après PublicNode. Pour chacune, le gate doit comparer le provider au Yellowstone upstream courant : capacités supportées, restrictions, extensions wire, auth/metadata, compression, keepalive, replay/from_slot, limites et lifecycle.

Les autres providers restent en TODO/IDEAS sans release dédiée. Aucune façade, dépendance, Config profile ou smoke n'est préparé pour eux tant qu'une décision explicite ne les fait pas entrer dans la séquence active.

14. Non-régressions obligatoires

Surface héritée Attendu final État
HTTP current 52 typed TODO final
HTTP historical 14 Deprecated/Removed TODO final
Standard WS 18 opérations / 9 familles TODO final
Helius WS 7 standard + transaction TODO final
Helius heartbeat Ping 60 s TODO final
Config V1/V2 backward read TODO final
Wallet/Wallet Desk aucune dépendance protocolaire Yellowstone directe TODO final

15. Forecast / preuve par tranche — 1520 min max ; release <= une session

pre.001 DONE  audit/sizing/architecture                                      1520 min nominal
pre.002 DONE  moteur: deps/settings/errors/channel                            1520 min ; gate final fix.002 PASS
pre.003 DONE  TLS/metadata + fixture + 7 unary standard                      1520 min ; gate final fix.001 PASS
pre.004 CANDIDATE  standard: Subscribe common/from_slot/bounds                 1520 min
pre.005 TODO  standard: accounts + slots                                      1520 min
pre.006 TODO  standard: transactions + transaction_status                     1520 min
pre.007 TODO  standard: blocks + block_meta + entry                           1520 min
pre.008 TODO  moteur: bidi/backpressure/half-close/shutdown                   1520 min
pre.009 TODO  moteur: reconnect/replay/gap/duplicate                          1520 min
pre.010 TODO  Config V3 + protocol/provider + profils PublicNode              1520 min
pre.011 TODO  PublicNode live + compliance + docs/prompt 0.2.10               1520 min
rel.001 TODO stable

Gate de sizing : une prerelease estimée à plus de 20 minutes est scindée ; si 0.2.9 ne paraît plus clôturable dans la session courante, la release est scindée avant implémentation supplémentaire.

16. Gate pre.001

Critère du prompt Verdict
base stable v0.2.8 confirmée PASS
baseline opérateur enregistrée PASS
upstream courant relu PASS
divergence snapshot/latest enregistrée PASS
service/proto exhaustif inventorié PASS
standard vs provider extension classifié PASS
SubscribeDeshred classifié PASS / OUT
unary RPCs classifiés PASS / 7 IN
replay/from_slot audités PASS
strategy dependency choisie PASS / B
licence auditée avant ajout PASS
features/build/transitifs audit initial PASS / matérialisation pre.002
architecture distincte WS PASS
metadata/auth neutral PASS
Config shape décidée PASS / V3
resource/backpressure policy décidée PASS
smoke ownership décidé PASS
providers gratuits audités PASS
release dimensionnée PASS
forecast recalibré PASS
split criteria écrits PASS
aucune implémentation lourde prématurée PASS

Verdict pre.001 : gate positif ; pre.002 peut matérialiser la stratégie B sous validation Cargo.

17. Gate pre.002 / pre.002-fix.001

Premier passage opérateur sur pre.002 :

Gate / observation Résultat avant fix État après fix.001
workspace version 0.2.9-pre.2 0.2.9-pre.2.fix.1
cargo fmt --all PASS à réexécuter
audit Rust workspace PASS / clean PASS local / clean
cargo check --workspace PASS, avec warning channel jamais lu warning supprimé par état privé _channel
cargo clippy --workspace --all-targets FAIL : implicit_return dans unit_tests/grpc_settings.rs corrigé ; à réexécuter
cargo test -p ksp-onchain-transport-lib FAIL : connect_lazy() appelé hors reactor Tokio, 344/345 avant fix test/runtime corrigés ; à réexécuter
dependency canary Core PASS / 3 passed inchangé
cargo tree -p ksp-onchain-transport-lib obtenu et inspecté PASS graphe
cargo tree -p ... --duplicates / workspace duplicates obtenu et inspecté PASS avec doublons build/runtime documentés

Correction fix.001 :

le champ Tonic reste présent en production ; il n'est pas placé sous cfg(test)
le champ privé devient `_channel` tant qu'aucune opération pre.003 ne le consomme
prepare() vérifie tokio::runtime::Handle::try_current() avant connect_lazy()
absence de runtime -> KspError grpc_channel_failed sûr, jamais panic Tonic
le test positif s'exécute sous #[tokio::test]
un test sync couvre explicitement l'absence de runtime et la redaction
la closure de cardinalité settings utilise un return explicite conforme à Clippy

Le choix de ne pas mettre le channel sous #[cfg(test)] est intentionnel : pre.002 matérialise une ressource N1 réelle de production qui sera consommée par pre.003; une compilation normale sans ce champ rendrait le contrat de tranche artificiellement différent entre production et tests.

Inspection du graphe opérateur :

tonic                 0.14.6
yellowstone-grpc-proto 12.6.0
prost/prost-types      0.14.4
solana-pubkey          4.3.0 unifié
http/hyper/hyper-util  1.5.0 / 1.11.0 / 0.1.20
tower                  0.5.3
bytes                  1.12.1

Aucune version concurrente Tonic/Prost/Solana n'a été introduite dans le graphe Transport. Les répétitions Prost de même version proviennent des unités build/runtime de la crate proto publiée.

Verdict pre.002-fix.001 : correctif source prêt ; pre.002 reste ouverte jusqu'à réexécution verte de fmt/audit/check/clippy/tests/workspace et confirmation finale du graphe.

Second passage opérateur après fix.001

Gate / observation Résultat fix.001 État fix.002
workspace version 0.2.9-pre.2.fix.1 0.2.9-pre.2.fix.2
cargo fmt --all PASS à réexécuter
audit Rust workspace PASS / clean PASS local / clean
cargo check --workspace PASS inchangé
cargo clippy --workspace --all-targets PASS inchangé
Transport unit PASS / 346 passed inchangé
Transport public_api FAIL / 41 passed, 1 failed : prepare() appelé hors runtime Tokio canari placé sous #[tokio::test]
dependency canary Core PASS / 3 passed inchangé
graphes Cargo déjà fournis et inspectés inchangés

Le second échec ne révèle aucune nouvelle faiblesse du moteur N1 : il confirme au contraire le contrat introduit par fix.001. Le canari public API doit être exécuté dans le même contexte Tokio que le test unitaire positif ; aucune modification supplémentaire de YellowstoneGrpcChannel n'est nécessaire.

Verdict pre.002-fix.002 : correctif de test d'intégration prêt ; pre.002 reste ouverte jusqu'à réexécution verte de cargo test -p ksp-onchain-transport-lib, cargo test --workspace et des gates habituels.

Gate final opérateur pre.002-fix.002

Gate Résultat final
cargo fmt --all PASS
audit Rust workspace PASS / clean
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS
Transport unit 346/346 PASS
Transport public_api 42/42 PASS
Transport release_completeness 35/35 PASS
Transport doctests 4/4 PASS
Core dependency canary 3/3 PASS
cargo test --workspace PASS

Verdict : pre.002 fermée.

18. Gate pre.003 — candidate

Gate / surface État candidate
workspace version 0.2.9-pre.3
runtime proto sans feature tonic SOURCE PASS
Tonic runtime channel + AWS-LC + WebPKI TLS SOURCE PASS
Tonic server/codegen uniquement dev/test SOURCE PASS
metadata ASCII publique/secrète redacted SOURCE PASS
connexion réelle bornée SOURCE PASS
7 unary standard exacts SOURCE PASS
fixture Geyser locale SOURCE PASS
commitment mapping SOURCE PASS
Status hostile sans payload distant SOURCE PASS
timeout unary borné SOURCE PASS
Subscribe / SubscribeDeshred OUT pre.003
PublicNode / Config V3 OUT pre.003
audit Rust workspace local PASS / clean
fmt/check/Clippy/tests/Cargo trees opérateur TODO

La fixture active yellowstone-grpc-proto/tonic et Tonic codegen+server uniquement dans le graphe dev/test. Le runtime utilise les messages Protobuf publiés, tonic::client::Grpc et tonic-prost::ProstCodec derrière une façade KSP sans raw escape hatch.

Verdict pre.003 : candidate source prête ; fermeture seulement après gate Cargo opérateur complet et réinspection des graphes.

18.1 Premier gate opérateur pre.003 et pre.003-fix.001

Gate / observation Résultat pre.003 État fix.001
workspace version 0.2.9-pre.3 0.2.9-pre.3.fix.1
cargo fmt --all PASS à réexécuter
audit Rust workspace PASS / clean audit local PASS / clean
cargo check --workspace PASS inchangé
cargo clippy --workspace --all-targets FAIL : 11 implicit_return dans unit_tests/grpc_unary.rs corrigé ; à réexécuter
Transport unit 354/354 PASS inchangé
Transport public_api 43/43 PASS inchangé
Transport release_completeness 36/36 PASS inchangé
Transport doctests 4/4 PASS inchangé
Core dependency canary 3/3 PASS inchangé
cargo test --workspace PASS inchangé fonctionnellement

Correction :

9 diagnostics proviennent de l'expansion #[tonic::async_trait] sur la fixture serveur,
alors que les corps source ont déjà des return explicites.
=> allow(clippy::implicit_return) strictement local à cette implémentation de test, avec justification.

2 diagnostics concernent les closures metadata and_then.
=> return explicite dans les closures.

aucun changement N1/N2 runtime
aucune dépendance/feature modifiée
aucun Subscribe/PublicNode/Config V3 anticipé

Verdict pre.003-fix.001 : correctif Clippy minimal prêt ; fermeture de pre.003 après réexécution verte des gates habituels et inspection des graphes Cargo demandée par la tranche.

18.2 Gate final opérateur pre.003-fix.001

Gate Résultat final
cargo fmt --all PASS
audit Rust workspace PASS / clean
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS
Transport unit 354/354 PASS
Transport public_api 43/43 PASS
Transport release_completeness 36/36 PASS
Transport doctests 4/4 PASS
cargo test --workspace PASS
cargo tree -p ... fourni/relu
cargo tree -p ... -e features fourni/relu
cargo tree -p ... --duplicates fourni/relu
cargo tree --duplicates fourni/relu

Graphe pertinent confirmé : tonic 0.14.6, tonic-prost 0.14.6, prost/prost-types 0.14.4, yellowstone-grpc-proto 12.6.0, solana-pubkey 4.3.0. Les features serveur/codegen et yellowstone-grpc-proto/tonic restent liées à la fixture dev/test ; aucune seconde version Tonic/Prost/Solana n'est introduite par la tranche.

Verdict : pre.003 fermée.

19. Gate pre.004 — candidate

Surface État candidate
workspace version 0.2.9-pre.4
sept maps SubscribeRequest SOURCE PASS
map vide / entrée nommée vide SOURCE+TEST
commitment optional exact SOURCE+TEST
account-data slices ordonnées SOURCE+TEST
ping optional exact SOURCE+TEST
from_slot optional exact SOURCE+TEST
filter names <=128 octets / unicité globale SOURCE+TEST
filter groups <=1024 total SOURCE+TEST
slices <=128 / length <=64 MiB / overflow rejeté SOURCE+TEST
request Debug sans noms/payloads de filtres SOURCE+TEST
filtres Accounts/Slots détaillés OUT pre.004
filtres Transactions/Blocks détaillés OUT pre.004
stream bidi / lifecycle / updates OUT pre.004
PublicNode / Config V3 OUT pre.004
audit Rust workspace local PASS / clean
fmt/check/Clippy/tests opérateur TODO

Le proto publié yellowstone-grpc-proto 12.6.0 a été recontrôlé avant implémentation : les onze champs top-level retenus restent accounts, slots, transactions, transactions_status, blocks, blocks_meta, entry, commitment, accounts_data_slice, ping, from_slot. Aucun SubscribeDeshred n'entre dans la surface KSP.

Verdict pre.004 : candidate source prête ; fermeture après gate Cargo opérateur.