diff --git a/Cargo.toml b/Cargo.toml index 8fd257b..342c786 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 97 +# version: 98 [workspace] resolver = "3" members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib"] [workspace.package] -version = "0.2.1-pre.2" +version = "0.2.1-pre.2.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/ROADMAP.md b/ROADMAP.md index 297e994..5cb90fe 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # Roadmap KSP @@ -48,6 +48,7 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U - [X] `0.2.1-pre.001` — Audit HTTP officiel/bot3, matrice exhaustive, architecture et gate de sizing : scope monolithique refusé, premier split de la couverture HTTP sur `0.2.1`–`0.2.6`, `0.2.1` réduite déclarée raisonnablement clôturable. - [X] `0.2.1-pre.001-fix.001` — Recalibrer le split HTTP sur `0.2.1`–`0.2.4` : `0.2.2` Accounts + Tokens + Cluster, `0.2.3` Transactions, `0.2.4` Blocks + Economics + compliance finale ; autoriser l'enchaînement de plusieurs releases complètement clôturées dans une même session lorsque le sizing le permet. - [X] `0.2.1-pre.002` — Créer la crate `ksp-onchain-transport-lib`, fixer ses settings runtime publics/validation, les envelopes JSON-RPC HTTP, les codes d'erreur, le registre central 52 current + 14 historiques et la base de warnings KSP de statut. +- [X] `0.2.1-pre.002-fix.001` — Nettoyer les warnings Clippy/missing-docs révélés par la validation locale de `pre.002`, sans changer son périmètre fonctionnel ni ses contrats publics. ### Releases fonctionnelles décidées/pressenties diff --git a/crates/ksp-onchain-transport-lib/src/settings.rs b/crates/ksp-onchain-transport-lib/src/settings.rs index 21cbfcb..3e746fd 100644 --- a/crates/ksp-onchain-transport-lib/src/settings.rs +++ b/crates/ksp-onchain-transport-lib/src/settings.rs @@ -1,5 +1,5 @@ // file: crates/ksp-onchain-transport-lib/src/settings.rs -// version: 1 +// version: 2 /// Runtime HTTP endpoint URL owned by Transport. /// @@ -475,13 +475,13 @@ fn validate_endpoint(endpoint: &crate::HttpEndpointSettings, endpoint_index: usi if endpoint.request_timeout().is_zero() { return invalid_settings("HTTP request timeout must be greater than zero", format!("endpoints[{endpoint_index}].request_timeout").as_str()); } - if let std::option::Option::Some(max_idle) = endpoint.max_idle_connections_per_host() { - if max_idle == 0 { - return invalid_settings( - "max idle connections per host must be greater than zero when configured", - format!("endpoints[{endpoint_index}].max_idle_connections_per_host").as_str(), - ); - } + if let std::option::Option::Some(max_idle) = endpoint.max_idle_connections_per_host() + && max_idle == 0 + { + return invalid_settings( + "max idle connections per host must be greater than zero when configured", + format!("endpoints[{endpoint_index}].max_idle_connections_per_host").as_str(), + ); } if endpoint.roles().is_empty() { return invalid_settings("HTTP endpoint must declare at least one role", format!("endpoints[{endpoint_index}].roles").as_str()); @@ -548,13 +548,13 @@ fn validate_role(role: &crate::HttpEndpointRoleSettings, endpoint_index: usize, format!("endpoints[{endpoint_index}].roles[{role_index}].limits.burst_capacity").as_str(), ); } - if let std::option::Option::Some(pause) = role.limits().pause_after_rate_limit() { - if pause.is_zero() { - return invalid_settings( - "rate-limit cooldown must be greater than zero when configured", - format!("endpoints[{endpoint_index}].roles[{role_index}].limits.pause_after_rate_limit").as_str(), - ); - } + if let std::option::Option::Some(pause) = role.limits().pause_after_rate_limit() + && pause.is_zero() + { + return invalid_settings( + "rate-limit cooldown must be greater than zero when configured", + format!("endpoints[{endpoint_index}].roles[{role_index}].limits.pause_after_rate_limit").as_str(), + ); } return std::result::Result::Ok(()); } diff --git a/crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs b/crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs index 900b413..9907098 100644 --- a/crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs +++ b/crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs @@ -1,5 +1,7 @@ // file: crates/ksp-onchain-transport-lib/tests/dependency_boundary.rs -// version: 1 +// version: 2 + +//! Integration canary for the direct dependency firewall of `ksp-onchain-transport-lib`. #[test] fn transport_manifest_preserves_ksp_dependency_firewall() { diff --git a/crates/ksp-onchain-transport-lib/tests/public_api.rs b/crates/ksp-onchain-transport-lib/tests/public_api.rs index af6dd24..337db31 100644 --- a/crates/ksp-onchain-transport-lib/tests/public_api.rs +++ b/crates/ksp-onchain-transport-lib/tests/public_api.rs @@ -1,5 +1,7 @@ // file: crates/ksp-onchain-transport-lib/tests/public_api.rs -// version: 1 +// version: 2 + +//! Integration tests for the public `ksp-onchain-transport-lib` consumer contract. #[test] fn public_settings_contract_is_constructible_without_config_dependency() { diff --git a/crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs b/crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs index 887da22..7112edc 100644 --- a/crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs +++ b/crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs @@ -1,5 +1,5 @@ // file: crates/ksp-onchain-transport-lib/unit_tests/json_rpc.rs -// version: 1 +// version: 2 #[test] fn request_serialization_matches_json_rpc_2_0_shape() { @@ -22,9 +22,9 @@ fn request_rejects_empty_or_untrimmed_method() { #[test] fn response_parser_preserves_null_success_result() { let response = super::parse_json_rpc_response_text(r#"{"jsonrpc":"2.0","result":null,"id":9}"#, 9).expect("null result is a valid success payload"); - match response { - super::JsonRpcResponse::Success(success) => assert!(success.result().is_null()), - super::JsonRpcResponse::Error(_) => assert!(false, "success response must not parse as error"), + assert!(matches!(&response, super::JsonRpcResponse::Success(_)), "success response must not parse as error"); + if let super::JsonRpcResponse::Success(success) = response { + assert!(success.result().is_null()); } } @@ -35,13 +35,11 @@ fn response_parser_preserves_rpc_error_payload() { 4, ) .expect("valid JSON-RPC error envelope must parse"); - match response { - super::JsonRpcResponse::Error(error_response) => { - assert_eq!(error_response.error().code(), -32005); - assert_eq!(error_response.error().message(), "Node is unhealthy"); - assert_eq!(error_response.error().data(), std::option::Option::Some(&serde_json::json!({"numSlotsBehind":12}))); - }, - super::JsonRpcResponse::Success(_) => assert!(false, "RPC error response must not parse as success"), + assert!(matches!(&response, super::JsonRpcResponse::Error(_)), "RPC error response must not parse as success"); + if let super::JsonRpcResponse::Error(error_response) = response { + assert_eq!(error_response.error().code(), -32005); + assert_eq!(error_response.error().message(), "Node is unhealthy"); + assert_eq!(error_response.error().data(), std::option::Option::Some(&serde_json::json!({"numSlotsBehind":12}))); } } diff --git a/crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs b/crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs index 541a5fe..dfd3f06 100644 --- a/crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs +++ b/crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs @@ -1,5 +1,5 @@ // file: crates/ksp-onchain-transport-lib/unit_tests/rpc_method.rs -// version: 1 +// version: 2 #[test] fn audited_registry_has_expected_current_and_historical_counts() { @@ -25,15 +25,17 @@ fn coverage_release_counts_match_recalibrated_matrix() { let mut accounts_tokens_cluster = 0_usize; let mut transactions = 0_usize; let mut blocks_economics = 0_usize; + let mut historical = 0_usize; for descriptor in super::current_http_rpc_methods() { match descriptor.coverage_release() { super::HttpRpcCoverageRelease::V0_2_1 => foundation += 1, super::HttpRpcCoverageRelease::V0_2_2 => accounts_tokens_cluster += 1, super::HttpRpcCoverageRelease::V0_2_3 => transactions += 1, super::HttpRpcCoverageRelease::V0_2_4 => blocks_economics += 1, - super::HttpRpcCoverageRelease::Historical => assert!(false, "current method must not be historical"), + super::HttpRpcCoverageRelease::Historical => historical += 1, } } + assert_eq!(historical, 0); assert_eq!(foundation, 4); assert_eq!(accounts_tokens_cluster, 22); assert_eq!(transactions, 11); diff --git a/deltas/0.2.1/pre.002-fix.001.md b/deltas/0.2.1/pre.002-fix.001.md new file mode 100644 index 0000000..966ac21 --- /dev/null +++ b/deltas/0.2.1/pre.002-fix.001.md @@ -0,0 +1,171 @@ + + + +# Delta `0.2.1-pre.002-fix.001` — nettoyage Clippy et documentation des tests + +## Base requise + +```text +release : 0.2.1 +prerelease corrigée : pre.002 +identifiant de commit attendu : v0.2.1-pre.002-fix.001 +workspace.package.version : 0.2.1-pre.2.fix.1 +base : v0.2.1-pre.002 +``` + +Le correctif est ouvert à partir de la validation locale transmise après application de `pre.002`. + +## Objectif + +Corriger exclusivement les warnings révélés par `cargo clippy --workspace --all-targets` et `cargo test`, sans modifier le périmètre fonctionnel ni les contrats publics introduits par `pre.002` : + +- supprimer trois usages de `assert!(false, ...)` signalés par `clippy::assertions_on_constants` dans les tests unitaires ; +- appliquer les deux simplifications `clippy::collapsible_if` dans la validation des settings ; +- documenter les deux crates de tests d'intégration afin de satisfaire `missing_docs` ; +- conserver inchangés le registre 52 current + 14 historiques, les settings publics, les envelopes JSON-RPC, les codes d'erreur, les descriptors et le firewall de dépendances. + +## Version Cargo + +Le correctif touche du Rust de production et de test. Conformément à `VER-ID-007` et `VER-ID-010` : + +```text +0.2.1-pre.2 -> 0.2.1-pre.2.fix.1 +``` + +Toutes les crates membres continuent d'hériter `version.workspace = true`. + +## Corrections Rust + +### Validation des settings + +Les deux validations imbriquées suivantes sont exprimées sous forme de let-chain Rust 2024 : + +```text +max_idle_connections_per_host = Some(0) +pause_after_rate_limit = Some(Duration::ZERO) +``` + +La sémantique reste strictement identique : les valeurs nulles configurées restent rejetées avec `ERROR_CODE_INVALID_SETTINGS`. + +### Tests JSON-RPC + +Les tests qui validaient la variante attendue avec un `match` et `assert!(false, ...)` utilisent désormais : + +1. une assertion `matches!` sur la variante attendue ; +2. un `if let` pour vérifier le payload de cette variante. + +Aucun `panic!`/`unreachable!` explicite n'est introduit. + +### Test de matrice de couverture + +Le cas `HttpRpcCoverageRelease::Historical` rencontré dans `current_http_rpc_methods()` est désormais comptabilisé dans un compteur local puis vérifié avec : + +```text +historical == 0 +``` + +La preuve reste donc explicite sans assertion constante fausse. + +### Tests d'intégration + +Les targets Cargo : + +```text +tests/public_api.rs +tests/dependency_boundary.rs +``` + +possèdent maintenant une documentation de crate `//!`, ce qui satisfait le lint workspace `missing_docs` sans masquer le warning global. + +## Graphe de dépendances + +Les quatre commandes `cargo tree` ont été exécutées localement sur `pre.002` avant ce fix. + +Constats : + +- aucune dépendance directe interdite Transport -> Config/Store/Program/tracing n'apparaît ; +- `reqwest 0.13.4` reste la dépendance HTTP retenue par `pre.002` ; +- `cargo tree -d` ne rapporte comme duplication que `syn 2.0.119` / `syn 3.0.3`, issue des chaînes proc-macro/ICU/Serde et ne justifiant pas une modification du graphe KSP dans ce correctif ; +- aucune dépendance n'est ajoutée ou retirée par `fix.001`. + +## Fichiers ajoutés + +```text +deltas/0.2.1/pre.002-fix.001.md +``` + +## Fichiers modifiés + +```text +Cargo.toml +ROADMAP.md +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/tests/dependency_boundary.rs +crates/ksp-onchain-transport-lib/tests/public_api.rs +``` + +## Fichiers supprimés + +Aucun. + +## Validation de `pre.002` ayant déclenché le correctif + +Les commandes suivantes ont été exécutées par le user sur `v0.2.1-pre.002` avant création du fix : + +```text +cargo fmt --all : exécuté +cargo check --workspace : OK +cargo clippy --workspace --all-targets : terminé avec warnings +cargo test -p ksp-onchain-transport-lib : OK, 40 tests passés +cargo test --workspace : OK ; 1 test diagnostic ignoré comme prévu +cargo tree -p ksp-onchain-transport-lib : exécuté +cargo tree -p ksp-onchain-transport-lib -d : exécuté +cargo tree -p ksp-onchain-transport-lib -e features : exécuté +cargo tree -p ksp-onchain-transport-lib -e normal : exécuté +``` + +Warnings observés et ciblés par ce fix : + +```text +3 x clippy::assertions_on_constants +2 x clippy::collapsible_if +2 x missing documentation for integration-test crate +``` + +## Validations du correctif + +Le sandbox de préparation ne possède pas `cargo`, `rustc` ni `rustfmt`. Les validations Rust du correctif ne peuvent donc pas y être exécutées et ne sont pas déclarées réussies. + +Après application du delta, exécuter dans cet ordre : + +```bash +cargo fmt --all +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-onchain-transport-lib +cargo test --workspace +``` + +Les quatre `cargo tree` ne sont pas obligatoires à répéter pour ce fix puisqu'aucune dépendance n'a changé. Ils peuvent être relancés si une vérification de non-régression du graphe est souhaitée. + +## Contrôles statiques effectués pendant la préparation + +- aucune occurrence restante de `assert!(false` dans la crate Transport ; +- les deux blocs signalés `collapsible_if` ont été remplacés ; +- les deux tests d'intégration possèdent une rustdoc de crate ; +- les headers/version des fichiers modifiés ont été incrémentés ; +- `pre.002.md` n'est pas modifié ; +- le périmètre public de `pre.002` reste inchangé. + +## Décisions prises + +- ne pas masquer les lints par `#[allow(...)]` ; corriger leur cause ; +- ne pas remplacer `assert!(false)` par `panic!()` ou `unreachable!()` ; +- ne pas modifier le graphe de dépendances pour le seul doublon `syn 2/3` ; +- conserver ce travail sous un vrai `pre.002-fix.001`, conformément à l'historique Git KSP. + +## Questions ouvertes + +Aucune pour ce correctif. Après validation et commit, `0.2.1` peut reprendre avec la prerelease suivante prévue par le plan `008`.