241 lines
7.1 KiB
Markdown
241 lines
7.1 KiB
Markdown
<!-- file: deltas/0.2.7/pre.004.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.7-pre.004` — runtime WebSocket physique + actor JSON-RPC
|
|
|
|
## 1. Base requise
|
|
|
|
```text
|
|
0.2.7-pre.003 appliquée
|
|
workspace.package.version = 0.2.7-pre.3
|
|
```
|
|
|
|
Le checkpoint opérateur reçu avant cette tranche est vert : `cargo fmt --all`, audit Python, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, tests Transport, tests Config et `cargo test --workspace`.
|
|
|
|
## 2. Signal technique
|
|
|
|
Cette prerelease non-fix modifie dépendances, runtime Rust et tests. Conformément au workflow KSP :
|
|
|
|
```text
|
|
livraison = 0.2.7-pre.004
|
|
workspace.package.version = 0.2.7-pre.4
|
|
commit = v0.2.7-pre.004
|
|
```
|
|
|
|
Aucun tag prerelease.
|
|
|
|
## 3. Dépendances WebSocket matérialisées
|
|
|
|
Le réaudit du 22 août 2026 confirme les versions retenues depuis `pre.001` :
|
|
|
|
```text
|
|
tokio-tungstenite 0.30.0
|
|
futures-util 0.3.34
|
|
```
|
|
|
|
Le root déclare sans features consumer :
|
|
|
|
```toml
|
|
tokio-tungstenite = { version = "^0.30", default-features = false }
|
|
futures-util = { version = "^0.3", default-features = false }
|
|
```
|
|
|
|
Transport active seulement :
|
|
|
|
```text
|
|
tokio-tungstenite : connect + rustls-tls-webpki-roots
|
|
futures-util : sink + std
|
|
tokio : macros + rt + sync + time
|
|
```
|
|
|
|
Le fixture serveur local ajoute `tokio/net` côté dev.
|
|
|
|
Aucune dépendance Config, Store, Program, Wallet ou `tracing` direct n'est introduite.
|
|
|
|
## 4. `WsSession` physique
|
|
|
|
Nouvelle surface publique :
|
|
|
|
```text
|
|
WsSession::connect(WsEndpointSettings)
|
|
WsSession::id()
|
|
WsSession::state()
|
|
WsSession::snapshot()
|
|
```
|
|
|
|
Un appel de `connect` crée exactement une connexion physique. Deux appels avec le même endpoint créent deux sockets indépendants ; aucun singleton, pool ou scheduler automatique n'est ajouté.
|
|
|
|
Le caller ne reçoit jamais le socket brut.
|
|
|
|
## 5. Actor propriétaire du socket
|
|
|
|
Une tâche actor unique possède :
|
|
|
|
```text
|
|
WebSocketStream
|
|
compteur JSON-RPC request id
|
|
map pending requests
|
|
bounded command receiver
|
|
publication WsSessionSnapshot
|
|
```
|
|
|
|
Le handle communique avec l'actor par `tokio::sync::mpsc` borné selon `command_queue_capacity`.
|
|
|
|
Les snapshots sont publiés via `tokio::sync::watch` et conservent seulement les metadata sûres prévues en `pre.002`.
|
|
|
|
## 6. Handshake et `WebSocketConfig`
|
|
|
|
`WsSession::connect` attend le handshake sous `command_timeout` et configure explicitement :
|
|
|
|
```text
|
|
write_buffer_size = 0
|
|
max_write_buffer_size = WsSessionSettings.max_write_buffer_size_bytes
|
|
max_message_size = WsSessionSettings.max_message_size_bytes
|
|
max_frame_size = WsSessionSettings.max_frame_size_bytes
|
|
```
|
|
|
|
Le `write_buffer_size = 0` évite de rendre la validité de la configuration KSP dépendante du buffer par défaut interne de Tungstenite et garantit que le plafond configuré reste strictement supérieur au target buffer.
|
|
|
|
Les tests oversized et les recalibrages éventuels restent le gate `pre.005`.
|
|
|
|
## 7. Pending JSON-RPC
|
|
|
|
La primitive interne actor :
|
|
|
|
```text
|
|
execute_json_rpc(method, params)
|
|
```
|
|
|
|
reste **`pub(crate)`**. Elle n'est volontairement pas exposée comme API raw provider-extension publique.
|
|
|
|
Comportement :
|
|
|
|
- ID numérique KSP monotone par session ;
|
|
- sérialisation via `JsonRpcRequest` existant ;
|
|
- map `BTreeMap` bornée par `max_pending_requests` ;
|
|
- deadline par request issue de `command_timeout` ;
|
|
- dispatch des réponses par `id`, y compris si elles arrivent hors ordre ;
|
|
- erreurs JSON-RPC applicatives renvoyées au caller concerné sans teardown de la connexion ;
|
|
- ID réponse inconnu/stale ignoré avec diagnostic sûr ;
|
|
- JSON structurellement invalide classé erreur protocole session.
|
|
|
|
Cette primitive sera consommée par le moteur de subscriptions à partir de `pre.006`.
|
|
|
|
## 8. Lifecycle limité à la tranche
|
|
|
|
`pre.004` matérialise :
|
|
|
|
```text
|
|
Connecting -> Active
|
|
connection/read/write failure -> Failed
|
|
last handle dropped -> cleanup best-effort -> Closed
|
|
```
|
|
|
|
Le reconnect/resubscribe reste `pre.007`.
|
|
|
|
Le shutdown async public, les budgets de Close et les fixtures peer hostile restent `pre.005`.
|
|
|
|
Ping reçu est répondu par Pong afin de conserver l'interopérabilité du socket. Aucun heartbeat applicatif périodique n'est ajouté.
|
|
|
|
## 9. Erreurs
|
|
|
|
Nouveaux codes publics :
|
|
|
|
```text
|
|
ws_backpressure_overflow
|
|
ws_connection_failed
|
|
ws_protocol_error
|
|
ws_session_closed
|
|
```
|
|
|
|
Les erreurs de connexion WebSocket ne conservent volontairement pas la source Tungstenite brute : celle-ci pourrait contenir une request/URI ou d'autres détails provider. Les erreurs KSP exposent uniquement `session_id`, endpoint logique, provider et cluster.
|
|
|
|
## 10. Logging / tracing
|
|
|
|
Toutes les émissions passent exclusivement par `ksp-logging-lib` et réutilisent :
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/src/constants.rs
|
|
TRACING_TARGET = "ksp-onchain-transport-lib"
|
|
```
|
|
|
|
Répartition principale :
|
|
|
|
```text
|
|
trace -> ouverture socket, send/dispatch JSON-RPC, Ping/Pong, notification prématurée ignorée
|
|
debug -> actor start, handshake actif, réponse stale, timeout pending, remote close
|
|
warn -> handshake/read/write failure, malformed wire, capacité pending épuisée
|
|
```
|
|
|
|
Ne sont jamais loggés : URL complète, credentials, query token, payload JSON-RPC complet ou notification brute.
|
|
|
|
## 11. Serveur local déterministe
|
|
|
|
Nouveaux tests runtime sans Internet :
|
|
|
|
```text
|
|
handshake local + round-trip JSON-RPC
|
|
deux sessions physiques distinctes sur la même URL
|
|
deux requests concurrentes + réponses inversées
|
|
application error sans teardown de session
|
|
connection error sans fuite URL/credential
|
|
```
|
|
|
|
Le serveur utilise `tokio::net::TcpListener` + `tokio_tungstenite::accept_async`.
|
|
|
|
## 12. Canaris workspace/public API
|
|
|
|
Le canari workspace dependencies est synchronisé avec les nouvelles dépendances/features et continue de vérifier le firewall Transport.
|
|
|
|
Le canari public API vérifie la disponibilité de `WsSession` et les quatre nouveaux codes d'erreur.
|
|
|
|
## 13. Documentation synchronisée
|
|
|
|
Mis à jour :
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/README.md
|
|
crates/ksp-onchain-transport-lib/USAGE.md
|
|
docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md
|
|
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
|
|
```
|
|
|
|
`ROADMAP.md` et `CHANGELOG.md` restent inchangés conformément à la politique de série prerelease.
|
|
|
|
## 14. Validation de préparation
|
|
|
|
Exécuté dans le sandbox :
|
|
|
|
```text
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
General Rust rule audit: clean
|
|
Rust export completeness audit: 0 candidate(s)
|
|
KSP workspace Rust rule audit: clean
|
|
|
|
inspection absence tracing direct OK
|
|
inspection TRACING_TARGET OK
|
|
inspection dépendances workspace/member OK
|
|
inspection Markdown tables OK
|
|
```
|
|
|
|
Cargo n'est pas disponible dans le sandbox de génération ; aucun résultat Cargo local n'est revendiqué.
|
|
|
|
## 15. Gates opérateur avant commit
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
python3 scripts/audit_rust_workspace_rules.py
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-onchain-transport-lib
|
|
cargo test --workspace
|
|
```
|
|
|
|
Si le checkpoint est vert :
|
|
|
|
```text
|
|
commit = v0.2.7-pre.004
|
|
```
|
|
|
|
La tranche suivante est `0.2.7-pre.005` : adversarial limits frame/message/request, control frames, cancellation, close/shutdown explicite et peer hostile.
|