v0.2.7-pre.014
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
|
||||
<!-- version: 18 -->
|
||||
<!-- version: 19 -->
|
||||
|
||||
# `ksp-onchain-transport-lib`
|
||||
|
||||
`ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Sa première surface est le transport HTTP JSON-RPC ; les extensions WebSocket et gRPC sont introduites séparément lorsque leur release les cible.
|
||||
`ksp-onchain-transport-lib` est la bibliothèque KSP propriétaire du transport on-chain Solana. Elle fournit le transport HTTP JSON-RPC complet et le moteur WebSocket Solana standard ; les extensions provider-specific et gRPC sont ajoutées séparément lorsqu’une release les cible.
|
||||
|
||||
## Responsabilités
|
||||
|
||||
@@ -19,7 +19,8 @@ La crate possède :
|
||||
- les enveloppes JSON-RPC 2.0 et leur validation ;
|
||||
- le registre audité des méthodes Solana HTTP ;
|
||||
- l'exécution générique des méthodes standard supportées ;
|
||||
- les wrappers typés explicitement livrés par KSP ;
|
||||
- les wrappers typés HTTP et WebSocket explicitement livrés par KSP ;
|
||||
- les sessions physiques WebSocket, subscriptions logiques, reconnect/resubscribe et backpressure bornés ;
|
||||
- les snapshots runtime sûrs ;
|
||||
- l'observabilité Transport via `ksp-logging-lib`.
|
||||
|
||||
@@ -70,23 +71,23 @@ Le registre porte notamment :
|
||||
- remplacement historique éventuel ;
|
||||
- release de couverture typée KSP.
|
||||
|
||||
La release stable `0.2.4` complète la surface typée des **52 méthodes courantes** :
|
||||
La surface HTTP typée couvre les **52 méthodes courantes** :
|
||||
|
||||
```text
|
||||
0.2.1 foundation : 4
|
||||
0.2.2 Accounts/Tokens/Cluster : 22
|
||||
0.2.3 Transactions : 11
|
||||
0.2.4 Blocks/Economics : 15
|
||||
total : 52
|
||||
foundation : 4
|
||||
Accounts/Tokens/Cluster : 22
|
||||
Transactions : 11
|
||||
Blocks/Economics : 15
|
||||
total : 52
|
||||
```
|
||||
|
||||
`0.2.4` ajoute les dix wrappers Blocks et les cinq wrappers Economics. Les points sensibles restent notamment `getBlock` moderne + bare encoding legacy deprecated, les quatre `transactionDetails`, les versions transaction numériques génériques, `numRewardPartitions`, `commissionBps`, les overloads de `getBlocks`, les ranges de production, les valeurs d'inflation/minimum de délégation fournies par le runtime et les `null` positionnels de `getInflationReward`.
|
||||
Les dix wrappers Blocks et les cinq wrappers Economics couvrent notamment `getBlock` moderne + bare encoding legacy deprecated, les quatre `transactionDetails`, les versions transaction numériques génériques, `numRewardPartitions`, `commissionBps`, les overloads de `getBlocks`, les ranges de production, les valeurs d'inflation/minimum de délégation fournies par le runtime et les `null` positionnels de `getInflationReward`.
|
||||
|
||||
`KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Le réaudit final `0.2.4` agrège le réaudit 37/37 de `0.2.3` avec les 15 nouveaux wrappers et porte la preuve stable à **52/52**.
|
||||
`KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Les canaris de release portent la preuve globale à **52/52** méthodes courantes typées.
|
||||
|
||||
Les 14 méthodes historiques restent découvrables pour la compliance mais sont `Removed` et ne sont pas simulées comme appelables.
|
||||
|
||||
## Foundation WebSocket `0.2.7-pre.004`
|
||||
## Moteur WebSocket standard
|
||||
|
||||
La première session physique WebSocket est matérialisée sans introduire de pool/scheduler automatique ni de registry de subscriptions anticipé.
|
||||
|
||||
@@ -99,25 +100,25 @@ La première session physique WebSocket est matérialisée sans introduire de po
|
||||
- publie `WsSessionSnapshot` via un état compact `watch` ;
|
||||
- applique aux sockets les plafonds KSP de message, frame et write buffer ;
|
||||
- ne projette jamais l'URL dans `Debug`, snapshot, erreurs KSP ou logs ;
|
||||
- répond aux `Ping` reçus et tolère les `Pong`; le lifecycle complet `Close`/shutdown a été durci ensuite en `pre.005`.
|
||||
- répond aux `Ping` reçus et tolère les `Pong`; le lifecycle `Close`/shutdown est borné et explicite.
|
||||
|
||||
Le chemin JSON-RPC générique reste `pub(crate)`. Il sert de primitive au moteur typed de subscriptions et **ne constitue pas une API publique raw provider-extension**. Le registry subscriptions et le mapping remote/local sont matérialisés en `pre.006`, reconnect/resubscribe est actif depuis `pre.007` et le backpressure borné par subscription est effectif depuis `pre.008`.
|
||||
Le chemin JSON-RPC générique reste `pub(crate)`. Il sert de primitive au moteur typed de subscriptions et **ne constitue pas une API publique raw provider-extension**. Le registry de subscriptions et le mapping remote/local, le reconnect/resubscribe et le backpressure borné par subscription font partie du moteur standard.
|
||||
|
||||
Les tests déterministes utilisent un serveur WebSocket local et prouvent le handshake, le round-trip JSON-RPC, le dispatch de réponses hors ordre, l'isolation des erreurs RPC applicatives, deux sessions physiques distinctes sur la même URL et la redaction des erreurs de connexion.
|
||||
|
||||
### Durcissement `0.2.7-pre.005`
|
||||
### Limites, control frames et shutdown
|
||||
|
||||
La session physique dispose désormais de `WsSession::close().await`. Le signal de shutdown est distinct de la command queue, passe l'état en `Closing`, annule les requests JSON-RPC en attente, envoie un Close WebSocket best-effort sous `close_timeout`, puis publie `Closed`. Un peer qui ne répond pas au Close ne peut donc pas bloquer indéfiniment le shutdown.
|
||||
|
||||
Les limites `max_message_size`, `max_frame_size`, `max_write_buffer_size` et `max_pending_requests` sont couvertes par des fixtures adversariales locales. Les requests outbound qui dépassent les bornes message/frame sont rejetées avant écriture ; les frames/messages inbound surdimensionnés sont rejetés par Tungstenite avant parse JSON. Les timeouts pending libèrent leur capacité sans faire tomber une session encore saine.
|
||||
|
||||
Ping/Pong/Close sont traités comme control frames : le Pong automatique Tungstenite est flushé et aucun heartbeat applicatif périodique n'est ajouté. Depuis `pre.007`, un Close distant inattendu, EOF, erreur I/O/TLS/WebSocket ou violation protocolaire structurelle entre dans le reconnect borné ; `Closed` reste réservé au shutdown local explicite ou à la disparition des handles.
|
||||
Ping/Pong/Close sont traités comme control frames : le Pong automatique Tungstenite est flushé et aucun heartbeat applicatif périodique n'est ajouté. Un Close distant inattendu, EOF, erreur I/O/TLS/WebSocket ou violation protocolaire structurelle entre dans le reconnect borné ; `Closed` reste réservé au shutdown local explicite ou à la disparition des handles.
|
||||
|
||||
### Registry de subscriptions `0.2.7-pre.006`
|
||||
### Registry de subscriptions
|
||||
|
||||
Le même actor possède maintenant le registre des subscriptions logiques, sans exposer les IDs numériques distants. Chaque subscription reçoit un `WsSubscriptionId` local stable, et le mapping `remote_subscription_id -> WsSubscriptionId` reste strictement runtime/interne.
|
||||
|
||||
La création générique typed reste `pub(crate)` et n'est jamais exposée comme API raw provider-extension. À partir de `pre.009`, les wrappers standard publics l'utilisent derrière leurs DTOs et paramètres typés. Le handle public `WsSubscription<T>` expose uniquement :
|
||||
La création générique typed reste `pub(crate)` et n'est jamais exposée comme API raw provider-extension. Les wrappers standard publics l’utilisent derrière leurs DTOs et paramètres typés. Le handle public `WsSubscription<T>` expose uniquement :
|
||||
|
||||
- `id()` et `kind()` ;
|
||||
- `state()` ;
|
||||
@@ -126,7 +127,7 @@ La création générique typed reste `pub(crate)` et n'est jamais exposée comme
|
||||
|
||||
L'ACK de subscribe est traité atomiquement dans l'actor : le remote ID est lié au local ID avant que la notification suivante puisse être dispatchée. Les notifications inconnues/stale sont ignorées avec un diagnostic sûr. Un mismatch de méthode de notification ou un échec de décodage typed termine uniquement la subscription concernée ; la session physique reste `Active`.
|
||||
|
||||
### Reconnect et resubscribe `0.2.7-pre.007`
|
||||
### Reconnect et resubscribe
|
||||
|
||||
Une perte de connexion physique invalide immédiatement les remote subscription IDs et incrémente `continuity_gap_count`. Le runtime utilise `WsReconnectSettings` pour appliquer un nombre fini de tentatives avec backoff exponentiel borné et sans jitter. Le shutdown surveille les phases de backoff et de handshake et interrompt la reprise sans reconnecter uniquement pour nettoyer des subscriptions.
|
||||
|
||||
@@ -136,7 +137,7 @@ Avec `WsResubscribePolicy::Never`, la session physique peut se reconnecter mais
|
||||
|
||||
Le compteur de continuity gaps est un signal d'observabilité, pas une garantie de livraison. Transport n'ajoute aucun backfill HTTP et ne promet aucune continuité lossless pendant l'intervalle de déconnexion.
|
||||
|
||||
### Backpressure et libération de capacité `0.2.7-pre.008`
|
||||
### Backpressure et libération de capacité
|
||||
|
||||
Chaque subscription dispose de sa propre queue typed bornée par `notification_queue_capacity`. Le runtime ne droppe jamais silencieusement une notification lorsque cette queue est pleine : il incrémente `WsSessionSnapshot::overflow_count()`, fait passer uniquement le handle lent à `Failed`, publie `ERROR_CODE_WS_BACKPRESSURE_OVERFLOW` via `WsSubscription::terminal_error_code()` et programme un `*Unsubscribe` distant best-effort. Les autres subscriptions et la session physique restent utilisables.
|
||||
|
||||
@@ -146,7 +147,7 @@ Les autres terminaisons en échec publient également un code KSP sûr sur le ha
|
||||
|
||||
Les fixtures adversariales prouvent l'isolation d'un consumer lent, la survie d'une subscription saine, le cleanup distant best-effort, la réutilisation de capacité après unsubscribe ou abandon du receiver et la conservation du compteur d'overflow à travers les snapshots. Aucune promesse de livraison lossless n'est ajoutée.
|
||||
|
||||
### Wrappers stables lot A `0.2.7-pre.009`
|
||||
### Wrappers stables : account, program et logs
|
||||
|
||||
Les trois premiers wrappers WebSocket standards sont publics sur `WsSession` :
|
||||
|
||||
@@ -162,9 +163,9 @@ logs_subscribe -> WsSubscription<SolanaRpcResponse<SolanaLogsNotification>>
|
||||
|
||||
`SolanaLogsSubscribeFilter` rend les trois filtres upstream explicites : `All`, `AllWithVotes` et `Mentions(Pubkey)`. La variante `Mentions` encode par construction exactement une adresse. `SolanaLogsNotification` conserve la signature opaque, le `err` nullable et l'ordre des messages `logs`, enveloppés dans `SolanaRpcResponse`.
|
||||
|
||||
L'unsubscribe de ces trois familles passe toujours par `WsSubscription::unsubscribe()`: le caller ne voit ni ne fournit l'ID serveur. Les paramètres initiaux restent conservés par l'actor pour le resubscribe déterministe acquis en `pre.007`, et toutes les règles de backpressure/terminal error acquises en `pre.008` s'appliquent sans branche spéciale aux nouveaux DTOs publics.
|
||||
L'unsubscribe de ces trois familles passe toujours par `WsSubscription::unsubscribe()`: le caller ne voit ni ne fournit l'ID serveur. Les paramètres initiaux restent conservés par l’actor pour le resubscribe déterministe, et toutes les règles de backpressure/terminal error s’appliquent sans branche spéciale aux DTOs publics.
|
||||
|
||||
### Wrappers stables lot B `0.2.7-pre.010`
|
||||
### Wrappers stables : signature, slot et root
|
||||
|
||||
Le second lot stable complète les subscriptions standard non instables :
|
||||
|
||||
@@ -178,9 +179,9 @@ root_subscribe -> WsSubscription<u64>
|
||||
|
||||
Une cancellation effectuée avant cette terminaison continue d'utiliser `WsSubscription::unsubscribe()` et émet `signatureUnsubscribe` avec le remote ID détenu uniquement par l'actor. Après la notification terminale, `unsubscribe()` devient local-only et retourne `false`, puisque la subscription est déjà fermée côté serveur et côté KSP.
|
||||
|
||||
`slot_subscribe()` et `root_subscribe()` n'acceptent aucun paramètre. `SolanaSlotNotification` conserve exactement `slot`, `parent` et `root`; `root_subscribe()` délivre directement le root `u64`. Ces deux subscriptions restent continues et utilisent donc le reconnect/resubscribe standard de `pre.007`.
|
||||
`slot_subscribe()` et `root_subscribe()` n'acceptent aucun paramètre. `SolanaSlotNotification` conserve exactement `slot`, `parent` et `root`; `root_subscribe()` délivre directement le root `u64`. Ces deux subscriptions restent continues et utilisent donc le reconnect/resubscribe standard.
|
||||
|
||||
### Wrappers unstable `0.2.7-pre.011`
|
||||
### Wrappers unstable : block, slotsUpdates et vote
|
||||
|
||||
Les trois familles standard restantes complètent désormais l'inventaire **9/9 subscribe + 9/9 unsubscribe via handles** :
|
||||
|
||||
@@ -264,9 +265,9 @@ Les trois tests sont `ignored` par défaut. Les deux smokes Transport appartienn
|
||||
- [`USAGE.md`](USAGE.md) — consommation directe, Config -> Transport, API typed/raw, smokes et inspection runtime ;
|
||||
- [`../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](../../docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md) — foundation HTTP stable ;
|
||||
- [`../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](../../docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) — extension typed Accounts/Tokens/Cluster ;
|
||||
- [`../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — matrice finale validée `0.2.2` ;
|
||||
- [`../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de `0.2.3` ;
|
||||
- [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée `0.2.3` ;
|
||||
- [`../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — matrice finale validée Accounts/Tokens/Cluster ;
|
||||
- [`../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé Transactions ;
|
||||
- [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée Transactions ;
|
||||
- [`../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan Blocks/Economics et compliance HTTP finale ;
|
||||
- [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ;
|
||||
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard HTTP + WebSocket V2, avec lecture backward V1 HTTP-only.
|
||||
|
||||
Reference in New Issue
Block a user