334 lines
11 KiB
Markdown
334 lines
11 KiB
Markdown
<!-- 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.
|