Files
2026-08-23 08:58:03 +02:00

215 lines
6.9 KiB
Markdown

<!-- file: deltas/0.2.7/pre.011.md -->
<!-- version: 1 -->
# Delta `0.2.7-pre.011` — familles WebSocket unstable : block + slotsUpdates + vote
## Base
Base requise :
```text
0.2.7-pre.010-fix.001
workspace.package.version = 0.2.7-pre.10.fix.1
```
Le checkpoint opérateur reçu sur cette base est vert et permet de poursuivre la série. Le correctif `pre.010-fix.001` a supprimé le helper typed devenu mort sans modifier le lifecycle WebSocket.
## Signal technique
```text
livraison = 0.2.7-pre.011
workspace.package.version = 0.2.7-pre.11
commit = v0.2.7-pre.011
tag = aucun
```
## Objectif
Compléter les neuf familles standard Solana avec les trois paires officiellement instables :
```text
blockSubscribe / blockUnsubscribe
slotsUpdatesSubscribe / slotsUpdatesUnsubscribe
voteSubscribe / voteUnsubscribe
```
La surface promise par `0.2.7` atteint ainsi :
```text
9/9 subscribe wrappers publics typed
9/9 unsubscribe via WsSubscription::unsubscribe()
18/18 opérations standard représentées
```
La compliance finale et les canaris transverses 18/18 restent le scope de `pre.012`.
## `blockSubscribe`
Nouveaux contrats publics :
```text
SolanaBlockSubscribeFilter
All
MentionsAccountOrProgram(Pubkey)
SolanaBlockSubscribeConfig
commitment
encoding
transaction_details
max_supported_transaction_version
show_rewards
SolanaBlockNotification
slot
block : Option<SolanaConfirmedBlock>
err : Option<serde_json::Value>
```
Le config sérialise les noms wire exacts : `commitment`, `encoding`, `transactionDetails`, `maxSupportedTransactionVersion`, `showRewards`.
Un commitment `processed` explicitement fourni est rejeté avant I/O. `confirmed` et `finalized` sont acceptés. Les cinq encodings documentés et les quatre niveaux de transaction details réutilisent les enums HTTP déjà acquis.
`maxSupportedTransactionVersion` reste un `u8` numérique générique : KSP ne durcit pas la valeur à `0` et reste compatible avec de futures versions numériques supportées par le runtime ciblé.
La notification réutilise `SolanaConfirmedBlock::decode_wire`, ce qui conserve les formes `full`, `accounts`, `signatures`, `none`, les encodings modern/legacy déjà acquis, les rewards et les extensions SIMD déjà couvertes côté HTTP. `block` et `err` restent indépendamment nullables.
Un fixture couvre un payload de notification supérieur à 1232 octets tout en restant sous la limite WebSocket KSP, conformément à la décision de ne jamais dériver la taille maximale WS de l'ancienne limite transaction legacy.
Une erreur RPC applicative simulant un validator sans capability block est renvoyée au caller sans teardown ni reconnect de la session physique.
## `slotsUpdatesSubscribe`
Nouveaux contrats publics :
```text
SolanaSlotUpdateStats
SolanaSlotUpdate
FirstShredReceived
Completed
CreatedBank
Frozen
Dead
OptimisticConfirmation
Root
Unknown
```
Les sept variantes courantes conservent leurs champs spécifiques. `createdBank` exige `parent`, `frozen` exige `stats`, `dead` exige `err`.
Une nouvelle valeur upstream du champ `type` devient :
```text
Unknown { update_type, raw }
```
au lieu de faire échouer la subscription. Le `raw` est déjà borné par `WsSessionSettings.max_message_size_bytes` avant le parse JSON. Le fallback ne masque pas les violations d'une variante déjà connue : une forme connue mais structurellement invalide reste `invalid_response` pour la subscription concernée.
## `voteSubscribe`
Nouveau DTO public :
```text
SolanaVoteNotification
vote_pubkey : Pubkey
slots : Vec<u64>
hash : String
timestamp : Option<i64>
signature : String
```
`timestamp` conserve de manière tolérante les trois formes wire retenues par l'audit : omitted, null et valeur `i64`. Omission et null deviennent `None`; une valeur devient `Some(i64)`.
Les votes restent des observations gossip pre-consensus. Transport ne leur attribue aucune sémantique de confirmation ledger.
## Warning unstable centralisé
`WsSubscriptionKind` connaît désormais exactement la partition unstable :
```text
Block
SlotsUpdates
Vote
```
Le point commun `WsSession::subscribe_typed_with_completion` appelle `WsSubscriptionKind::warn_if_unstable()` avant la création logique. Le warning passe exclusivement par `ksp-logging-lib` et contient seulement :
```text
rpc_method
subscription_kind
documentation_status = unstable
```
Il n'inclut jamais filtre, pubkey, signature, payload, remote subscription ID, URL ou credential. Le warning n'est pas répété à chaque notification.
## Tests
Neuf tests unitaires supplémentaires couvrent :
```text
block config complet + processed rejeté
block notification null/block + shared SolanaConfirmedBlock
block payload > 1232 octets sous borne WS
block request exact + notification + blockUnsubscribe
block RPC capability error sans échec session
7 variantes slotsUpdates + Unknown raw
champs obligatoires createdBank/frozen/dead
vote timestamp omitted/null/value
slotsUpdates + vote end-to-end + unsubscribe
partition unstable exacte
```
Le nombre de fonctions `#[test]` supplémentaires est neuf parce que le test block notification agrège aussi la preuve de payload >1232 et le test lifecycle agrège la partition warning. Un canari d'API publique supplémentaire vérifie les nouveaux wrappers et DTOs depuis la racine de crate.
Comptages attendus après compilation :
```text
Transport unit tests = 309
Transport public API tests = 35
release completeness = 22
```
## Fichiers ajoutés
```text
crates/ksp-onchain-transport-lib/src/ws_blocks.rs
crates/ksp-onchain-transport-lib/unit_tests/ws_blocks.rs
deltas/0.2.7/pre.011.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/src/ws_cluster.rs
crates/ksp-onchain-transport-lib/src/ws_lifecycle.rs
crates/ksp-onchain-transport-lib/src/ws_session.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
crates/ksp-onchain-transport-lib/unit_tests/ws_cluster.rs
crates/ksp-onchain-transport-lib/unit_tests/ws_lifecycle.rs
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.
## Validation de préparation
Le sandbox de préparation ne dispose pas de Cargo/rustc. Les contrôles statiques KSP sont exécutés avant packaging ; les gates compilées restent opérateur.
## Validation opérateur requise
```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 ce checkpoint est vert, `pre.012` réalise la compliance WebSocket **18/18**, les canaris de composition Config et les régressions HTTP finales prévues par le plan.