v0.2.7-pre.001-fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Plan `0.2.7` — WebSocket Solana standard
|
||||
|
||||
@@ -131,15 +131,20 @@ Shape cible minimale :
|
||||
```text
|
||||
format_version = 2
|
||||
retry # HTTP existant, conservé
|
||||
ws_defaults # defaults de session WS KSP, non provider-specific
|
||||
ws_defaults # defaults de session WS KSP, communs aux familles WS
|
||||
default_profile
|
||||
profiles[]
|
||||
profile_id
|
||||
endpoints[] # HTTP existant, conservé
|
||||
ws_endpoints[] # endpoints WebSocket explicites
|
||||
kind # discriminateur de famille/protocole WS
|
||||
```
|
||||
|
||||
`ws_endpoints[]` porte seulement les données nécessaires à Transport : nom logique, enabled, provider, cluster, URL et overrides de session éventuellement nécessaires. Les credentials restent résolus par Config comme aujourd'hui ; Transport reçoit un endpoint déjà résolu et doit redacter l'URL dans `Debug`/logs/errors.
|
||||
`ws_endpoints[]` porte seulement les données nécessaires à Transport : nom logique, enabled, provider, cluster, URL, `kind` et overrides de session éventuellement nécessaires. Les credentials restent résolus par Config comme aujourd'hui ; Transport reçoit un endpoint déjà résolu et doit redacter l'URL dans `Debug`/logs/errors.
|
||||
|
||||
Décision d'extensibilité : **le conteneur V2 ne doit pas supposer qu'il n'existera qu'un seul type de WebSocket**. `0.2.7` matérialise uniquement `kind = solana_standard`; toute valeur inconnue ou future est rejetée explicitement comme non supportée. Le discriminateur est mappé vers un type Transport public non exhaustif, afin qu'une release ultérieure puisse ajouter une famille telle que Helius Enhanced WebSocket sans réécrire le conteneur `profiles[].ws_endpoints[]` ni contaminer les settings Solana standard avec des champs provider-specific.
|
||||
|
||||
Cette préparation ne promet aucune option Helius dans `0.2.7`. L'audit provider-specific de la release suivante décidera la relation exacte entre Helius Enhanced WebSocket, LaserStream et le moteur standard avant d'ajouter des variantes/configurations concrètes.
|
||||
|
||||
Le V1 chargé sous `0.2.7` produit une configuration HTTP valide et une collection WebSocket vide. Le V2 devient le format livré par les fixtures Config dès la tranche qui matérialise le WebSocket.
|
||||
|
||||
@@ -216,19 +221,73 @@ Règles générales documentées : JSON-RPC 2.0 sur connexion persistante ; rés
|
||||
|
||||
La matrice détaillée initiale est conservée dans `docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`.
|
||||
|
||||
### 6.1 Baseline à trois niveaux : docs Solana, Git Agave, SIMD
|
||||
|
||||
La compliance WebSocket reprend la méthode utilisée pour la clôture HTTP et ne traite pas le site documentaire comme unique vérité technique :
|
||||
|
||||
```text
|
||||
1. documentation Solana actuelle
|
||||
-> surface publique annoncée, paramètres, statuts et formes documentées
|
||||
|
||||
2. Git Agave, tag courant audité v4.2.1
|
||||
-> parité d'implémentation réelle, types wire, options ignorées, variantes et handlers
|
||||
|
||||
3. solana-improvement-documents main
|
||||
-> SIMDs Activated, Review, Draft ou Idea susceptibles de modifier le wire,
|
||||
la sémantique des notifications ou les hypothèses de taille/lifecycle
|
||||
```
|
||||
|
||||
Au 2026-08-22, le tag Git **Agave `v4.2.1`** est disponible et constitue la baseline d'implémentation de cette release, même lorsque des liens de la documentation publique pointent encore vers une révision Agave plus ancienne. Le cross-check `v4.2.1` confirme les 9 familles subscribe/unsubscribe actuelles et ne révèle aucune méthode PubSub standard supplémentaire à ajouter aux 18 méthodes de l'index Solana.
|
||||
|
||||
Les constats ciblés déjà retenus restent valides sous `v4.2.1` : `accountSubscribe.minContextSlot` est toujours ignoré par le handler PubSub, `programSubscribe.withContext` reste un paramètre réel à préserver, `RpcVote.timestamp` reste optionnel et `SlotUpdate` conserve les sept variantes connues de la matrice actuelle.
|
||||
|
||||
### 6.2 Audit SIMD WebSocket ciblé
|
||||
|
||||
L'audit SIMD ne consiste pas à implémenter des propositions par anticipation. Il sert à éviter de figer dans KSP des hypothèses déjà fragilisées par l'évolution upstream.
|
||||
|
||||
| SIMD | Statut au 2026-08-22 | Conséquence WebSocket KSP |
|
||||
|-----------------------------------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `0118` Partitioned Epoch Rewards Distribution | Activated | réutiliser les DTOs bloc/rewards déjà lossless acquis par HTTP, notamment `numRewardPartitions` omitted, `null` ou valeur |
|
||||
| `0291` Commission Rate in Basis Points | Review | préserver les champs de commission déjà exposés par Agave et les DTOs partagés, sans dérivation locale entre représentations |
|
||||
| `0296` Larger Transaction Size | Review | proposition jusqu'à 4096 octets : ne jamais dimensionner frames/messages sur l'ancienne limite transaction de 1232 ; surveiller `blockSubscribe` |
|
||||
| `0298` Bank Hash in Block Footer | Idea | ne pas inventer `bankHash` dans le wire actuel ; surveiller l'évolution du DTO bloc partagé |
|
||||
| `0301` parent bank hash | PR fermé, non mergé | aucun `parentBankHash` spéculatif ; conserver le contrôle déjà appliqué à la compliance HTTP |
|
||||
| `0307` Add Block Footer | Review | ne pas ajouter `footer` avant exposition réelle par Agave ; réauditer `blockSubscribe` si le DTO bloc partagé évolue |
|
||||
| `0326` Alpenglow | Review | `voteSubscribe` et `slotsUpdatesSubscribe.optimisticConfirmation` sont unstable ; ne pas coder de sémantique durable TowerBFT autour de ces flux |
|
||||
| `0337` Alpenglow Fast Leader Handover Markers | Review | nouveaux block markers potentiels : risque futur de shape/taille pour les blocs, sans nouveau champ WS courant |
|
||||
| `0384` Alpenglow migration | Review | la migration peut suspendre des notifications RPC de commitment/optimistic confirmation ; aucun flux KSP ne doit supposer une séquence complète |
|
||||
| `0385` Transaction V1 | Review | conserver `maxSupportedTransactionVersion` et les versions transaction comme contrats génériques ; ne pas caper localement à v0 |
|
||||
|
||||
Conséquence de sizing : les bornes WebSocket KSP sont des protections runtime configurables et finies, **pas** des constantes dérivées de l'ancienne taille de transaction Solana. Les tests `blockSubscribe` devront inclure des payloads sensiblement supérieurs aux transactions legacy tout en restant sous les limites KSP configurées.
|
||||
|
||||
Sources SIMD auditées :
|
||||
|
||||
```text
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0118-partitioned-epoch-reward-distribution.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0291-commission-rate-in-basis-points.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0296-larger-transactions.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0298-bank-hash-in-block-footer.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/pull/301
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0307-add-block-footer.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0326-alpenglow.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0337-parent-ready-update-marker.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0384-alpenglow-migration.md
|
||||
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md
|
||||
```
|
||||
|
||||
## 7. Points wire sensibles sous `KSP-TRANSPORT-007`
|
||||
|
||||
### `accountSubscribe`
|
||||
|
||||
Conserver : pubkey ; `commitment` ; encodings `base58|base64|base64+zstd|binary|jsonParsed` ; `dataSlice` ; notification `accountNotification` contextualisée.
|
||||
|
||||
Le type partagé Agave `RpcAccountInfoConfig` contient aussi `min_context_slot`, mais le handler PubSub `v3.1.8` l'ignore explicitement. KSP ne doit donc pas promettre `minContextSlot` comme option WebSocket effective tant que l'upstream ne lui donne pas une sémantique réelle ; cette non-promise doit rester visible dans la compliance pour éviter qu'une option ignorée soit comptée comme supportée.
|
||||
Le type partagé Agave `RpcAccountInfoConfig` contient aussi `min_context_slot`, mais le handler PubSub `v4.2.1` l'ignore explicitement. KSP ne doit donc pas promettre `minContextSlot` comme option WebSocket effective tant que l'upstream ne lui donne pas une sémantique réelle ; cette non-promise doit rester visible dans la compliance pour éviter qu'une option ignorée soit comptée comme supportée.
|
||||
|
||||
### `programSubscribe`
|
||||
|
||||
Conserver : program pubkey ; `commitment` ; `filters` ; mêmes encodings account ; `dataSlice` ; **`withContext` default false**.
|
||||
|
||||
La documentation actuelle expose `withContext`, mais le code Agave `v3.1.8` lié par la page stocke bien `with_context` alors que le chemin générique de notification audité sérialise un `RpcResponse` contexté. KSP ne doit ni ignorer le paramètre, ni convertir cette incohérence amont en hypothèse stricte. Décision : exposer le flag et rendre le décodeur capable d'accepter la forme documentée non-contextée comme la forme contextée observée.
|
||||
La documentation actuelle expose `withContext`, mais le code Agave `v4.2.1` lié par la page stocke bien `with_context` alors que le chemin générique de notification audité sérialise un `RpcResponse` contexté. KSP ne doit ni ignorer le paramètre, ni convertir cette incohérence amont en hypothèse stricte. Décision : exposer le flag et rendre le décodeur capable d'accepter la forme documentée non-contextée comme la forme contextée observée.
|
||||
|
||||
### `logsSubscribe`
|
||||
|
||||
@@ -274,13 +333,13 @@ Le runtime doit prévoir une forme `Unknown`/raw bornée pour qu'une variante aj
|
||||
|
||||
### `voteSubscribe` — Unstable
|
||||
|
||||
Aucun paramètre. La méthode nécessite le flag validator documenté et observe des votes gossip pre-consensus. Conserver `votePubkey`, `slots`, `hash`, `timestamp`, `signature`. Agave `v3.1.8` définit `timestamp` comme `Option<i64>` : le décodeur KSP doit donc préserver cette optionalité et accepter de manière tolérante les formes wire `omitted/null/value`, sans inventer une valeur.
|
||||
Aucun paramètre. La méthode nécessite le flag validator documenté et observe des votes gossip pre-consensus. Conserver `votePubkey`, `slots`, `hash`, `timestamp`, `signature`. Agave `v4.2.1` définit `timestamp` comme `Option<i64>` : le décodeur KSP doit donc préserver cette optionalité et accepter de manière tolérante les formes wire `omitted/null/value`, sans inventer une valeur.
|
||||
|
||||
### `*Unsubscribe`
|
||||
|
||||
Chaque unsubscribe reçoit l'ID serveur et retourne `true` quand la subscription est supprimée ; le handler Agave audité retourne `InvalidParams` pour un ID inconnu. Cette réalité wire ne devient pas l'API publique KSP : le caller utilise l'ID local/handle stable et la session traduit vers l'ID serveur courant.
|
||||
|
||||
Le cross-check Agave `v3.1.8` confirme également que `logsSubscribe` impose exactement une adresse pour `mentions`, que `signatureSubscribe` ne consomme que `commitment` et `enableReceivedNotification`, et que `blockSubscribe` applique bien le jeu d'options documenté avec un commitment au moins `confirmed`. Ces constats renforcent la matrice normative sans ajouter d'options non documentées à KSP.
|
||||
Le cross-check Agave `v4.2.1` confirme également que `logsSubscribe` impose exactement une adresse pour `mentions`, que `signatureSubscribe` ne consomme que `commitment` et `enableReceivedNotification`, et que `blockSubscribe` applique bien le jeu d'options documenté avec un commitment au moins `confirmed`. Ces constats renforcent la matrice normative sans ajouter d'options non documentées à KSP.
|
||||
|
||||
## 8. Dépendances WebSocket candidates
|
||||
|
||||
@@ -332,6 +391,7 @@ Noms cibles :
|
||||
WsEndpointUrl
|
||||
WsProviderName
|
||||
WsClusterName
|
||||
WsProtocolKind
|
||||
WsReconnectSettings
|
||||
WsResubscribePolicy
|
||||
WsSessionSettings
|
||||
@@ -341,6 +401,8 @@ WsTransportSettings
|
||||
|
||||
Les wrappers `WsProviderName`/`WsClusterName` sont parallèles aux `Http*` pour éviter une migration publique HTTP dans cette release. Une généralisation future n'est justifiée que si un troisième backend démontre un type commun réellement utile.
|
||||
|
||||
`WsProtocolKind` est un discriminateur public `#[non_exhaustive]`. `0.2.7` n'expose concrètement que `SolanaStandard`. Ajouter plus tard une famille provider-specific ne doit donc ni casser les matches externes ni forcer une nouvelle forme de `WsEndpointSettings`. Les options spécifiques restent portées par leurs contrats dédiés et ne sont jamais ajoutées arbitrairement à `WsSessionSettings`.
|
||||
|
||||
`WsEndpointUrl` :
|
||||
|
||||
- accepte seulement `ws://`/`wss://` après validation ;
|
||||
@@ -645,9 +707,11 @@ Pour unstable/évolutif, préférer des enums avec fallback `Unknown { type_name
|
||||
|
||||
## 17. API générique provider-specific
|
||||
|
||||
Le moteur interne doit encoder une spec générique `subscribe_method + unsubscribe_method + params + decoder`, afin que `0.2.8` puisse réutiliser la session.
|
||||
Le moteur interne doit encoder une spec générique `subscribe_method + unsubscribe_method + params + decoder`, afin qu'une release provider-specific puisse réutiliser la session.
|
||||
|
||||
**Aucune API publique raw provider-extension n'est promise dans `0.2.7`.** Elle sera décidée après audit Helius de `0.2.8`. Cela évite de figer trop tôt une escape hatch qui deviendrait le contrat principal et contournerait les wrappers typés standards.
|
||||
La préparation Config/Transport de `0.2.7` se limite au discriminateur `WsProtocolKind` et au conteneur commun `ws_endpoints[]`. Elle doit permettre d'ajouter ultérieurement au moins une famille comme **Helius Enhanced WebSocket**, tout en laissant l'audit de la release suivante décider si Helius Enhanced WebSocket, LaserStream WebSocket et d'autres surfaces Helius partagent exactement le même moteur, les mêmes credentials et les mêmes paramètres.
|
||||
|
||||
**Aucune API publique raw provider-extension et aucun paramètre Helius ne sont promis dans `0.2.7`.** Ils seront décidés après audit Helius. Cela évite de figer trop tôt une escape hatch qui deviendrait le contrat principal et contournerait les wrappers typés standards.
|
||||
|
||||
## 18. Tests déterministes attendus
|
||||
|
||||
@@ -719,7 +783,8 @@ Un rate-limit, refus provider ou indisponibilité externe ne constitue pas autom
|
||||
## 21. Hors périmètre confirmé
|
||||
|
||||
```text
|
||||
Helius LaserStream / provider params -> 0.2.8
|
||||
Helius Enhanced WS / provider params -> audit provider-specific futur
|
||||
Helius LaserStream WebSocket -> 0.2.8 selon séquence courante
|
||||
Yellowstone gRPC -> 0.2.9
|
||||
provider Yellowstone commercial -> plus tard
|
||||
shred/deshred/pre-execution -> plus tard
|
||||
@@ -741,7 +806,7 @@ L'inventaire officiel n'impose que 9 familles de subscriptions, mais le lifecycl
|
||||
```text
|
||||
pre.001 audit interne/externe + matrice 18 méthodes + bot3 + dependencies + threat model + plan/sizing
|
||||
pre.002 settings WS Transport + URL redaction + IDs/states/snapshots + tests de settings
|
||||
pre.003 std.transport V2 HTTP+WS + backward V1 + schema/fixtures + Config -> WsTransportSettings
|
||||
pre.003 std.transport V2 HTTP+WS + backward V1 + discriminateur WS + schema/fixtures + Config -> WsTransportSettings
|
||||
pre.004 deps tokio-tungstenite/futures-util + actor physique + handshake/read/write + pending JSON-RPC + serveur local
|
||||
pre.005 limites frame/message/request + control frames + cancellation/close/shutdown + adversarial socket tests
|
||||
pre.006 registry subscriptions + IDs locaux + generic subscribe/unsubscribe engine + channels typed bounded
|
||||
|
||||
Reference in New Issue
Block a user