Files
2026-08-22 18:21:20 +02:00

7.1 KiB

Delta 0.2.7-pre.004 — runtime WebSocket physique + actor JSON-RPC

1. Base requise

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 :

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 :

tokio-tungstenite 0.30.0
futures-util       0.3.34

Le root déclare sans features consumer :

tokio-tungstenite = { version = "^0.30", default-features = false }
futures-util = { version = "^0.3", default-features = false }

Transport active seulement :

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 :

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 :

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 :

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 :

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 :

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 :

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 :

crates/ksp-onchain-transport-lib/src/constants.rs
TRACING_TARGET = "ksp-onchain-transport-lib"

Répartition principale :

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 :

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 :

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 :

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

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 :

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.