494 lines
31 KiB
Markdown
494 lines
31 KiB
Markdown
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
|
||
<!-- version: 6 -->
|
||
|
||
# Validation `0.2.9` — moteur Yellowstone + standard Solana + PublicNode
|
||
|
||
> **Statut : matrice ouverte par `0.2.9-pre.001`, corrigée par `pre.001-fix.002`, avancée par `pre.002` puis corrigée par `pre.002-fix.001`. Le premier gate opérateur a validé fmt/audit/check et le graphe, puis a révélé un retour Clippy implicite et l'exigence de runtime Tokio de `connect_lazy()` ; le fix borne désormais ce cas sans panic et attend la réexécution Cargo complète. Le scope distingue moteur Yellowstone, façade Solana standard et première intégration PublicNode. OrbitFlare et Helius sont les seules releases provider suivantes actuellement planifiées ; les autres providers restent en TODO/IDEAS sans numéro réservé.**
|
||
|
||
## 1. Autorités du gate
|
||
|
||
Base interne :
|
||
|
||
```text
|
||
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` :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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 | TODO |
|
||
| `SubscribeDeshred` | bidi | Triton extension/pré-exécution malgré présence proto | OUT | canari d'absence/API | TODO |
|
||
| `SubscribeReplayInfo` | unary | standard | IN | fixture unary | TODO |
|
||
| `Ping` | unary | standard | IN | fixture unary | TODO |
|
||
| `GetLatestBlockhash` | unary | standard | IN | fixture unary | TODO |
|
||
| `GetBlockHeight` | unary | standard | IN | fixture unary | TODO |
|
||
| `GetSlot` | unary | standard | IN | fixture unary | TODO |
|
||
| `IsBlockhashValid` | unary | standard | IN | fixture unary | TODO |
|
||
| `GetVersion` | unary | standard | IN | fixture unary | TODO |
|
||
|
||
## 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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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?` | TODO |
|
||
| Ping | `count` | `count` | TODO |
|
||
| LatestBlockhash | `commitment?` | slot/hash/last_valid_height | TODO |
|
||
| BlockHeight | `commitment?` | block_height | TODO |
|
||
| Slot | `commitment?` | slot | TODO |
|
||
| IsBlockhashValid | blockhash + `commitment?` | slot + bool | TODO |
|
||
| Version | empty | version | TODO |
|
||
|
||
## 8. Dépendances / licence
|
||
|
||
| Gate | Décision / matérialisation `pre.002` | 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 et matérialisée** | source PASS / Cargo pending |
|
||
| `yellowstone-grpc-proto` | `^12.6`, `default-features = false`, aucune feature KSP | Cargo tree pending |
|
||
| `tonic` | `^0.14`, `default-features = false`, feature `channel` locale | Cargo tree pending |
|
||
| `yellowstone-grpc-client` | absent | manifest canary ajouté |
|
||
| `prost/prost-types` direct KSP | absent | manifest / 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 :
|
||
|
||
```text
|
||
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.002` |
|
||
|--------------------------------------------------------------------------------|--------------------------------|---------------------------------|
|
||
| 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 | TODO `pre.003+` |
|
||
| 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.002` :
|
||
|
||
```text
|
||
DONE/source+tests ajoutés endpoint schemes http/https validés ; TLS réel reporté pre.003
|
||
DONE/source+tests ajoutés endpoint URL, descripteurs et nombre d’endpoints 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
|
||
TODO pre.004 filter-group count
|
||
TODO pre.004 filter-name length/uniqueness
|
||
TODO pre.003 metadata key/value count/size
|
||
TODO pre.005+ account/owner/include/exclude/required counts
|
||
TODO pre.004+ memcmp/data slice bounds
|
||
TODO pre.005+ Cuckoo dimensions/data bounds
|
||
```
|
||
|
||
Security canaries :
|
||
|
||
```text
|
||
DONE/source+tests ajoutés endpoint URL Debug redacted
|
||
TODO pre.003 secret metadata Debug/Display absent
|
||
TODO pre.003 Status message/details distants non recopiés aveuglément en context
|
||
PARTIAL pre.002 URI Tonic invalide mappée sans recopier l'erreur ; TLS/connect réel pre.003
|
||
TODO pre.004+ request/update Debug sans payload arbitraire sensible
|
||
PARTIAL pre.002 channel Debug ne contient ni URL ni raw Tonic ; snapshot lifecycle 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 | 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 :
|
||
|
||
```text
|
||
exactly-once
|
||
lossless
|
||
historical replay complet
|
||
ordre global sans gap
|
||
```
|
||
|
||
## 12. Config V3
|
||
|
||
Décision de gate :
|
||
|
||
```text
|
||
V1 HTTP reste lisible
|
||
V2 HTTP+WS reste lisible
|
||
V3 ajoute gRPC explicitement
|
||
```
|
||
|
||
Shape conceptuelle à matérialiser :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
solana-yellowstone-grpc.publicnode.com:443
|
||
```
|
||
|
||
Gates :
|
||
|
||
```text
|
||
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 — **15–20 min max ; release <= une session**
|
||
|
||
```text
|
||
pre.001 DONE audit/sizing/architecture 15–20 min nominal
|
||
pre.002 FIX.001 CANDIDATE moteur: deps/settings/errors/channel 15–20 min
|
||
pre.003 TODO moteur: TLS/metadata + fixture + 7 unary 15–20 min
|
||
pre.004 TODO standard: Subscribe common/from_slot/bounds 15–20 min
|
||
pre.005 TODO standard: accounts + slots 15–20 min
|
||
pre.006 TODO standard: transactions + transaction_status 15–20 min
|
||
pre.007 TODO standard: blocks + block_meta + entry 15–20 min
|
||
pre.008 TODO moteur: bidi/backpressure/half-close/shutdown 15–20 min
|
||
pre.009 TODO moteur: reconnect/replay/gap/duplicate 15–20 min
|
||
pre.010 TODO Config V3 + protocol/provider + profils PublicNode 15–20 min
|
||
pre.011 TODO PublicNode live + compliance + docs/prompt 0.2.10 15–20 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` :
|
||
|
||
```text
|
||
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 :
|
||
|
||
```text
|
||
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.**
|