v0.2.1-pre.002

This commit is contained in:
2026-08-17 18:02:18 +02:00
parent d98d152f08
commit 0cff0406ab
15 changed files with 2989 additions and 10 deletions

333
deltas/0.2.1/pre.002.md Normal file
View File

@@ -0,0 +1,333 @@
<!-- file: deltas/0.2.1/pre.002.md -->
<!-- version: 1 -->
# Delta `0.2.1-pre.002` — fondation crate/settings/JSON-RPC/descriptors
## Base requise
```text
release : 0.2.1
prerelease : pre.002
identifiant de commit attendu : v0.2.1-pre.002
workspace.package.version : 0.2.1-pre.2
base : v0.2.1-pre.001-fix.001
```
Le user a confirmé avoir commité `v0.2.1-pre.001` puis `v0.2.1-pre.001-fix.001` avant l'ouverture de cette tranche.
## Objectif
Matérialiser la fondation Rust de `ksp-onchain-transport-lib` sans ouvrir encore le client/pool HTTP :
- ajouter la crate au workspace ;
- stabiliser les codes d'erreur Transport ;
- posséder les settings runtime publics et leur validation ;
- posséder les envelopes JSON-RPC 2.0 HTTP ;
- matérialiser le registre central des méthodes/statuts issu de la matrice `pre.001` ;
- installer la base de warnings KSP de statut sans dépendance directe à `tracing` ;
- ajouter les tests unitaires/intégration correspondant à ces contrats.
## Version Cargo
Conformément à `VER-ID-009` :
```text
0.2.1-pre.1 -> 0.2.1-pre.2
```
Toutes les crates membres continuent d'hériter `version.workspace = true`.
## Workspace et dépendances
Nouveau membre :
```text
crates/ksp-onchain-transport-lib
```
Dépendances directes de la crate :
```text
ksp-core-lib
ksp-logging-lib
reqwest.workspace = true
serde.workspace = true
serde_json.workspace = true
```
`reqwest` reste centralisé au workspace :
```toml
reqwest = { version = "^0.13", default-features = false }
```
Le `pre.001` avait vérifié le 2026-08-17 la génération `reqwest 0.13` et observé `0.13.4`. Cette tranche n'active volontairement aucune feature TLS/JSON/client : `reqwest` est utilisé uniquement pour `Url::parse` dans la validation de `HttpEndpointUrl`. Conformément à `RUST-DEP-001` / `RUST-DEP-003`, les features réseau et Tokio seront ajoutés seulement lorsque `pre.003` introduira un vrai client HTTP async.
Aucune dépendance directe vers :
```text
ksp-config-lib
ksp-store-api
ksp-store-lib
ksp-program-api
ksp-program-lib
tracing
```
## Contrats publics Transport
### Settings runtime
La crate expose :
```text
HttpTransportSettings
HttpEndpointSettings
HttpEndpointRoleSettings
HttpRoleLimits
HttpRetrySettings
HttpEndpointUrl
HttpProviderName
HttpClusterName
HttpRoleName
HttpRequestKind
```
Décisions :
- Transport reste totalement constructible/testable sans Config ;
- `provider`, `cluster`, `role` et `request_kind` sont des descriptors ouverts, pas des enums fermées ;
- `HttpEndpointUrl` accepte uniquement HTTP/HTTPS, conserve la valeur runtime réelle mais redacted systématiquement son `Debug` ;
- `HttpTransportSettings::validate()` vérifie notamment endpoints activés, identités/roles uniques, timeouts positifs, request kinds, wildcard, limites et backoff cohérents ;
- `NonZeroU32` empêche structurellement les zéros sur RPS/burst/concurrence lorsqu'ils sont configurés ;
- aucun accès direct à `.env` ou `std::env::var*` n'existe dans Transport.
### Codes d'erreur
Le domaine unique reste :
```text
onchain_transport
```
Codes stabilisés/réservés :
```text
invalid_settings
endpoint_selection_failed
http_connection_failed
http_request_failed
timeout
rate_limited
json_encode_failed
json_decode_failed
json_rpc_protocol_invalid
rpc_application_error
method_removed
invalid_response
```
Ils utilisent exclusivement `ksp_core_lib::Error` / `ErrorCode`.
## JSON-RPC HTTP
La fondation expose :
```text
JsonRpcRequest
JsonRpcSuccessResponse
JsonRpcErrorObject
JsonRpcErrorResponse
JsonRpcResponse
parse_json_rpc_response_text
parse_json_rpc_response_value
```
Invariants :
- request ids KSP numériques `u64` ;
- `jsonrpc` exactement `"2.0"` ;
- id de réponse exactement égal à celui de la requête ;
- présence exclusive de `result` ou `error` ;
- JSON `null` conservé comme résultat valide ;
- erreur JSON syntaxique distincte d'une violation protocolaire ;
- application error RPC préservée dans `JsonRpcResponse::Error`, puis mappable vers `rpc_application_error` ;
- le mapping KSP ne copie pas le message/data distant dans le contexte générique ;
- `Debug` des requests masque les paramètres ; `Debug` des succès masque le résultat ; `Debug` des erreurs masque message/data distants.
Ce dernier point empêche un log/debug accidentel d'une transaction, d'un token provider ou d'une réponse massive tout en laissant les getters explicites accessibles au consumer légitime.
## Registre central des méthodes
`rpc_method.rs` matérialise exactement :
```text
52 méthodes current
14 méthodes historiques Deprecated / Removed
```
Chaque descriptor possède :
```text
method
category
request_kind
documentation_status
runtime_status
request_form_status
operation_kind
transport_retry_class
replacement
coverage_release
```
La distribution de couverture est encodée et testée :
```text
0.2.1 : 4
0.2.2 : 22
0.2.3 : 11
0.2.4 : 15
----
52 current
```
Cas structurants déjà encodés :
```text
getTransaction -> StableWithDeprecatedLegacy
getBlock -> StableWithDeprecatedLegacy
sendTransaction -> WriteSubmission / NeverAfterDispatch
requestAirdrop -> WriteSubmission / NeverAfterDispatch
simulateTransaction -> Simulation / RetrySafe
14 historiques -> Deprecated / Removed / NotApplicable
```
`HttpRpcMethodDescriptor::ensure_runtime_supported()` centralise le comportement de statut :
- Stable + Supported : succès silencieux ;
- Deprecated/Unstable + Supported : `warn` via `ksp-logging-lib` ;
- Removed : `warn` puis erreur `method_removed`, sans simuler un appel supporté.
Le target utilisé est toujours le nom Cargo réel via `env!("CARGO_PKG_NAME")`; aucune dépendance directe `tracing` n'est introduite.
## Tests ajoutés
40 tests Rust sont définis :
- validation des settings et erreurs structurées ;
- HTTP/HTTPS uniquement ;
- redaction URL et `Debug` global settings ;
- endpoint enabled, doublons endpoint/rôle, wildcard, burst/RPS, timeouts, backoff ;
- sérialisation JSON-RPC request ;
- parse success/error/null ;
- id mismatch, version, `result xor error`, invalid JSON ;
- redaction des payloads request/result/error dans `Debug` ;
- mapping RPC application error ;
- registre 52 + 14 et unicité ;
- distribution 4/22/11/15 ;
- canaris exacts `getBalance/getGenesisHash/getHealth/getVersion` ;
- request forms deprecated de `getTransaction/getBlock` ;
- no-resend descriptors write ;
- warning path Unstable supporté ;
- erreur `method_removed` ;
- tests d'intégration de la façade publique ;
- canary de firewall des dépendances directes du manifest.
Les vrais tests unitaires sont physiquement sous `unit_tests/` et rattachés aux modules de production via `#[cfg(test)]` + `#[path = ...]`. `tests/` est réservé aux tests d'intégration publics.
## Fichiers ajoutés
```text
crates/ksp-onchain-transport-lib/Cargo.toml
crates/ksp-onchain-transport-lib/src/error.rs
crates/ksp-onchain-transport-lib/src/json_rpc.rs
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/src/rpc_method.rs
crates/ksp-onchain-transport-lib/src/settings.rs
crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs
crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs
crates/ksp-onchain-transport-lib/unit_tests/settings.rs
crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
deltas/0.2.1/pre.002.md
```
## Fichiers modifiés
```text
Cargo.toml
ROADMAP.md
docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md
```
## Fichiers supprimés
Aucun.
## Validations exécutées dans l'environnement d'échange
Le conteneur ne fournit ni `cargo`, ni `rustc`, ni `rustfmt`. Les validations exécutables disponibles ont donc été limitées aux contrôles statiques suivants :
- parsing TOML du `Cargo.toml` racine et du manifest de la nouvelle crate ;
- contrôle `workspace.package.version = 0.2.1-pre.2` ;
- contrôle présence du nouveau membre workspace ;
- contrôle des headers `file:` et newline finale sur tous les nouveaux fichiers ;
- scan production : aucun `use`, `?`, `unwrap`, `expect`, `panic!`, `pub mod` ;
- scan manifest : aucune dépendance directe Config/Store/Program/`tracing` ;
- scan production : aucune lecture directe `std::env::var*` ;
- audit heuristique de rustdoc sur les éléments publics ;
- comparaison automatique du registre Rust avec la matrice `008` : 52 current identiques, dans le même ordre, et 14 historiques identiques ;
- contrôle de distribution de release : `4 / 22 / 11 / 15` ;
- contrôle des deux seuls marqueurs `StableWithDeprecatedLegacy` : `getTransaction`, `getBlock` ;
- contrôle des fences Markdown et headers des documents modifiés ;
- contrôle des lignes Rust > 160 colonnes après formatage manuel : aucune.
## Validations non exécutées
Obligatoires sur le checkout de développement avant commit :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
cargo test --workspace
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib -d
cargo tree -p ksp-onchain-transport-lib -e features
cargo tree -p ksp-onchain-transport-lib -e normal
```
Les `cargo tree` sont désormais obligatoires parce que `reqwest` entre réellement dans le graphe à cette tranche. Les doublons significatifs doivent être examinés avant validation du commit.
Aucun build Tauri n'est requis : aucune application Tauri/frontend n'est modifiée.
## Décisions prises
- conserver un identifiant JSON-RPC KSP numérique `u64` pour les requêtes émises ;
- préserver les payloads JSON dynamiques via `serde_json::Value` sans introduire de DTO Solana SDK massif ;
- redacter les `Debug` wire susceptibles de contenir des secrets/payloads massifs ;
- encoder dès maintenant la couverture release et la retry class dans le registre central ;
- ne pas activer de features réseau `reqwest` ni Tokio avant leur premier usage réel ;
- ne pas introduire Config, Store, Program, Solana SDK haut niveau, base64, bs58, WebSocket ou gRPC.
## Questions ouvertes / reports explicites
Aucune question bloquante pour `pre.003`.
À décider avec l'implémentation réelle de `pre.003` :
- features `reqwest 0.13` exactes nécessaires au client async/TLS ;
- ownership précis du `reqwest::Client` par endpoint logique ;
- structures runtime du pool, fairness et snapshots ;
- première utilisation effective de Tokio et des primitives `sync` si nécessaires.
## Suite
```text
0.2.1-pre.003
```
Mission prévue : endpoint client + pool logique + rôles/capabilities + priorité/fairness/fallback + snapshots sûrs, sans encore ouvrir rate-limit/concurrence/retry effectif de `pre.004` au-delà des structures strictement nécessaires.