v0.2.7-pre.004
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Plan `0.2.7` — WebSocket Solana standard
|
||||
|
||||
> **Statut : actif, `0.2.7-pre.003`.** Les gates `pre.001` et `pre.002` sont clos. `pre.003` matérialise `std.transport` V2 HTTP + WebSocket, la lecture backward V1 HTTP-only et l'adapter `Config -> WsTransportSettings`. Le socket physique reste différé à `pre.004`.
|
||||
> **Statut : actif, `0.2.7-pre.004`.** `pre.003` est validé opérateur. `pre.004` matérialise les dépendances WebSocket, la première session physique actor-owned, le handshake/read/write JSON-RPC, la map bornée de requests en attente et les fixtures serveur local. Les subscriptions typed restent différées.
|
||||
|
||||
## 1. Objet et base vérifiée
|
||||
|
||||
@@ -366,7 +366,7 @@ Audit au 2026-08-22 :
|
||||
| `tokio-websockets` | `0.13.3` | alternative viable, non retenue | strict/minimal et performant, mais exige davantage d'assemblage/features et n'apporte pas de besoin fonctionnel supérieur démontré pour cette foundation |
|
||||
| `fastwebsockets` | `0.10.0` | non retenue | plus bas niveau ; peut déléguer davantage de compliance au caller, inutile pour la première foundation KSP |
|
||||
|
||||
Landing prévu, **pas dans `pre.001`** :
|
||||
Landing matérialisé par **`pre.004`** :
|
||||
|
||||
```toml
|
||||
# root [workspace.dependencies]
|
||||
@@ -379,7 +379,7 @@ futures-util = { workspace = true, features = ["std", "sink"] }
|
||||
tokio = { workspace = true, features = ["macros", "rt", "sync", "time"] }
|
||||
```
|
||||
|
||||
Le serveur de test local pourra activer `tokio/net` en dev si KSP utilise directement `TcpListener`.
|
||||
Le serveur de test local active `tokio/net` en dev et utilise directement `TcpListener`.
|
||||
|
||||
`url` n'est pas retenu a priori : l'endpoint KSP peut être validé et passé comme chaîne/request sans ajouter la feature uniquement par habitude bot3. `handshake`/`stream` sont déjà requis transitivement par `connect`/TLS et ne doivent pas être listés sans nécessité directe.
|
||||
|
||||
@@ -486,6 +486,8 @@ Une tâche actor possède exclusivement :
|
||||
|
||||
Le handle public `WsSession` communique avec cet actor par canal bounded. Aucun caller ne split/manipule directement le socket.
|
||||
|
||||
`pre.004` matérialise cette foundation : `WsSession::connect` ouvre une connexion physique explicite, le socket reste exclusivement dans l'actor, les commandes passent par `mpsc` borné, les réponses JSON-RPC sont dispatchées par ID KSP dans une map bornée et les snapshots sûrs sont publiés par `watch`. La primitive JSON-RPC reste `pub(crate)` afin de ne pas créer une API publique raw provider-extension avant les wrappers typed. Le registry des subscriptions et le mapping remote/local restent `pre.006`.
|
||||
|
||||
### 9.4 Identités
|
||||
|
||||
```text
|
||||
@@ -868,7 +870,7 @@ L'inventaire officiel n'impose que 9 familles de subscriptions, mais le lifecycl
|
||||
pre.001 audit interne/externe + matrice 18 méthodes + bot3 + dependencies + threat model + plan/sizing
|
||||
pre.002 DONE — settings WS Transport + URL redaction + IDs/states/snapshots + tests de settings
|
||||
pre.003 DONE — 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.004 DONE — 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
|
||||
pre.007 reconnect borné + resubscribe déterministe + continuity gap + races unsubscribe/reconnect
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Validation `0.2.7` — WebSocket Solana standard
|
||||
|
||||
> **Statut : matrice active, `0.2.7-pre.003`.** Les settings/lifecycle `pre.002` et la composition Config V2 `pre.003` sont matérialisés. Les preuves runtime socket/subscription restent ouvertes.
|
||||
> **Statut : matrice active, `0.2.7-pre.004`.** Settings/lifecycle `pre.002`, Config V2 `pre.003` et première session physique actor-owned `pre.004` sont matérialisés. Registry subscriptions, shutdown complet, reconnect et wrappers typed restent ouverts.
|
||||
|
||||
## 1. Baseline normative
|
||||
|
||||
@@ -189,39 +189,39 @@ Les votes observés sont gossip/pre-consensus ; aucune garantie d'entrée dans l
|
||||
|
||||
## 6. Lifecycle compliance initiale
|
||||
|
||||
| Contrat | Décision `pre.001` | Gate cible |
|
||||
|-------------------------------|-------------------------------------------------------------------|----------------------|
|
||||
| plusieurs sessions / même URL | création physique explicite ; aucun singleton/pool automatique | `pre.004`, `pre.012` |
|
||||
| plusieurs subs / session | registry actor par session | `pre.006` |
|
||||
| ID public subscription | local KSP stable | `pre.006` |
|
||||
| ID serveur | éphémère interne et remappé | `pre.006`/`pre.007` |
|
||||
| session states | Disconnected/Connecting/Active/Reconnecting/Closing/Closed/Failed | **Done `pre.002`** |
|
||||
| subscription states | Requested/Active/Resubscribing/Cancelling/Closed/Failed | **Done `pre.002`** |
|
||||
| reconnect | physique uniquement, budget/backoff finis | `pre.007` |
|
||||
| resubscribe | policy `Never` ou `ActiveSubscriptions`, ordre local déterministe | `pre.007` |
|
||||
| continuity | gap observable, aucune promesse lossless | `pre.007` |
|
||||
| backpressure | queue par sub bounded ; overflow => fail local explicite | `pre.008` |
|
||||
| shutdown | explicite, bounded, annule reconnect et subscriptions | `pre.005` |
|
||||
| keepalive | pas de ping applicatif périodique sans besoin démontré | `pre.005` |
|
||||
| Contrat | Décision `pre.001` | Gate cible |
|
||||
|-------------------------------|-------------------------------------------------------------------|--------------------------------------------|
|
||||
| plusieurs sessions / même URL | création physique explicite ; aucun singleton/pool automatique | **Done `pre.004`**, canary final `pre.012` |
|
||||
| plusieurs subs / session | registry actor par session | `pre.006` |
|
||||
| ID public subscription | local KSP stable | `pre.006` |
|
||||
| ID serveur | éphémère interne et remappé | `pre.006`/`pre.007` |
|
||||
| session states | Disconnected/Connecting/Active/Reconnecting/Closing/Closed/Failed | **Done `pre.002`** |
|
||||
| subscription states | Requested/Active/Resubscribing/Cancelling/Closed/Failed | **Done `pre.002`** |
|
||||
| reconnect | physique uniquement, budget/backoff finis | `pre.007` |
|
||||
| resubscribe | policy `Never` ou `ActiveSubscriptions`, ordre local déterministe | `pre.007` |
|
||||
| continuity | gap observable, aucune promesse lossless | `pre.007` |
|
||||
| backpressure | queue par sub bounded ; overflow => fail local explicite | `pre.008` |
|
||||
| shutdown | explicite, bounded, annule reconnect et subscriptions | `pre.005` |
|
||||
| keepalive | pas de ping applicatif périodique sans besoin démontré | `pre.005` |
|
||||
|
||||
## 7. Threat/security compliance initiale
|
||||
|
||||
| Invariant | Preuve attendue | Statut |
|
||||
|---------------------------------------------------|---------------------------------------------|--------------------|
|
||||
| URL/credentials absents de `Debug` | unit tests URL wrapper | **Done `pre.002`** |
|
||||
| URL/credentials absents des erreurs | validation URL + future connection errors | Partial `pre.002` |
|
||||
| URL/credentials absents des logs | safe fields `pre.002`, capture actor future | Partial `pre.002` |
|
||||
| snapshots sans URL/raw payload | unit shape + public contract | **Done `pre.002`** |
|
||||
| frame/message finis | settings bornés, enforcement socket futur | Partial `pre.002` |
|
||||
| JSON borné indirectement par message | oversized + malformed fixture | Planned |
|
||||
| queues notifications bornées | capacité settings, channel futur | Partial `pre.002` |
|
||||
| pending RPC borné + timeout | settings bornés, runtime futur | Partial `pre.002` |
|
||||
| reconnect loop bornée | repeated disconnect fixture | Planned |
|
||||
| unsubscribe pendant reconnect ne resubscribe pas | race fixture | Planned |
|
||||
| signature terminale ne resubscribe pas | terminal fixture | Planned |
|
||||
| shutdown ne bloque pas | peer hostile/no close ack fixture | Planned |
|
||||
| no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | Planned |
|
||||
| no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** |
|
||||
| Invariant | Preuve attendue | Statut |
|
||||
|---------------------------------------------------|----------------------------------------------|------------------------------------------|
|
||||
| URL/credentials absents de `Debug` | unit tests URL wrapper | **Done `pre.002`** |
|
||||
| URL/credentials absents des erreurs | validation URL + connection errors safe | **Done through `pre.004`** |
|
||||
| URL/credentials absents des logs | actor logs only safe endpoint metadata | Partial `pre.004`, capture finale future |
|
||||
| snapshots sans URL/raw payload | unit shape + public contract | **Done `pre.002`** |
|
||||
| frame/message finis | settings bornés + `WebSocketConfig` raccordé | Partial `pre.004`, adversarial `pre.005` |
|
||||
| JSON borné indirectement par message | oversized + malformed fixture | Planned |
|
||||
| queues notifications bornées | capacité settings, channel futur | Partial `pre.002` |
|
||||
| pending RPC borné + timeout | map actor bornée + timeout request | **Done `pre.004`** |
|
||||
| reconnect loop bornée | repeated disconnect fixture | Planned |
|
||||
| unsubscribe pendant reconnect ne resubscribe pas | race fixture | Planned |
|
||||
| signature terminale ne resubscribe pas | terminal fixture | Planned |
|
||||
| shutdown ne bloque pas | peer hostile/no close ack fixture | Planned |
|
||||
| no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | Planned |
|
||||
| no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** |
|
||||
|
||||
## 8. Dependency compliance initiale
|
||||
|
||||
@@ -249,7 +249,7 @@ https://docs.rs/crate/futures-util/0.3.34
|
||||
|
||||
Alternatives auditées mais non retenues : `tokio-websockets 0.13.3`, `fastwebsockets 0.10.0`.
|
||||
|
||||
Aucune de ces dependencies n'est ajoutée par `pre.001`; le graphe Cargo stable ne change pas dans ce gate hors signal de version workspace.
|
||||
`pre.004` matérialise `tokio-tungstenite` et `futures-util` dans `[workspace.dependencies]` sans features consumer au root. Transport active seulement `connect`, `rustls-tls-webpki-roots`, `std` et `sink`; `tokio/net` est ajouté côté dev fixture local.
|
||||
|
||||
## 9. Config compliance initiale
|
||||
|
||||
@@ -330,6 +330,34 @@ Logging : `TRACING_TARGET` reste défini dans `constants.rs`; les nouveaux évé
|
||||
|
||||
Les defaults de taille/queue sont des **policies KSP locales**, pas des limites Solana. Leur enforcement réel et leurs tests oversized/slow-consumer restent attendus dans les tranches socket/backpressure.
|
||||
|
||||
## 9.2 Checkpoint runtime physique `pre.004`
|
||||
|
||||
Surface matérialisée :
|
||||
|
||||
```text
|
||||
WsSession::connect(endpoint) public, une connexion physique par appel
|
||||
actor socket propriétaire exclusif du WebSocket
|
||||
command queue tokio mpsc bounded
|
||||
pending JSON-RPC BTreeMap bounded par max_pending_requests
|
||||
request timeout command_timeout
|
||||
response dispatch par id numérique KSP
|
||||
state snapshot watch + WsSessionSnapshot
|
||||
raw JSON-RPC public non, primitive pub(crate)
|
||||
reconnect/resubscribe non, gates futurs
|
||||
```
|
||||
|
||||
Fixtures déterministes `pre.004` :
|
||||
|
||||
```text
|
||||
handshake local + JSON-RPC round-trip
|
||||
deux sessions physiques distinctes sur la même URL
|
||||
deux requests concurrentes + réponses inversées
|
||||
erreur RPC applicative sans teardown de session
|
||||
erreur de connexion sans URL/credential dans Error Debug
|
||||
```
|
||||
|
||||
Les limites `max_message_size`, `max_frame_size` et `max_write_buffer_size` sont raccordées à `tungstenite::WebSocketConfig`. Les fixtures oversized et le shutdown/control-frame hostile restent explicitement `pre.005`.
|
||||
|
||||
## 10. Validation du gate `pre.001`
|
||||
|
||||
Exécuté dans le sandbox :
|
||||
|
||||
Reference in New Issue
Block a user