# Delta `0.2.2-pre.006` — cinq wrappers HTTP Cluster restants typés ## Base requise Livraison précédente validée localement par l'opérateur : ```text 0.2.2-pre.005 workspace.package.version = "0.2.2-pre.5" ``` La validation opérateur du 2026-08-18 a confirmé : ```text cargo fmt --all OK cargo check --workspace OK cargo clippy --workspace --all-targets OK cargo test -p ksp-onchain-transport-lib OK ``` Résultats Transport de cette base : ```text 116 unit tests 12 public API tests 5 release completeness tests 0 warning signalé par check/clippy ``` Le plan canonique reste `docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md` version 3. ## Contrôle documentaire avant nouvelle tranche Le découpage durable reste cohérent : - `ROADMAP.md` conserve `0.2.2` en cours `[/]` ; - le plan `009` attribue exactement à `pre.006` les cinq méthodes Cluster restantes ; - les 5 Accounts de `pre.003`, les 5 Tokens de `pre.004` et les 7 Cluster simples de `pre.005` restent inchangés ; - `pre.007` reste la tranche de complétude/smoke/docs/préparation stable prévue ; - aucun index documentaire durable ne nécessite de modification à cette étape. ## Objectif Implémenter les cinq wrappers publics typés Cluster restants : ```text getLeaderSchedule getSlot getSlotLeader getSlotLeaders getVoteAccounts ``` Après cette tranche, les 22 méthodes HTTP Accounts + Tokens + Cluster attribuées à `0.2.2` possèdent toutes leur wrapper typé KSP. Tous les wrappers passent par la foundation HTTP commune : ```text wrapper typé -> descriptor audité -> execute_standard_rpc -> pool/admission/retry/deadline -> reqwest HTTP -> JSON-RPC validation -> décodage DTO KSP ``` Aucun wrapper Cluster ne contacte `reqwest` directement. ## Version Cargo Conformément au cycle prerelease KSP : ```text 0.2.2-pre.5 -> 0.2.2-pre.6 ``` Aucune dépendance ni feature Cargo n'est ajoutée ou retirée. ## Réaudit ciblé du contrat courant Le contrat préparé dans le plan `009` a été recroisé avec la source primaire Agave `v4.2.1`, notamment : ```text rpc-client-types/src/config.rs rpc/src/rpc.rs ``` Les invariants utiles à cette tranche restent : - `getLeaderSchedule` accepte l'overload slot/config déjà modélisé par `SolanaLeaderScheduleRequest` ; - `RpcLeaderScheduleConfig` contient `identity` et `commitment` ; - le résultat de `getLeaderSchedule` reste nullable ; - `getSlot` et `getSlotLeader` utilisent la config commune `commitment/minContextSlot` ; - `getSlotLeaders` prend `startSlot + limit`, avec la limite `1..=5000` retenue par le plan ; - `RpcGetVoteAccountsConfig` contient `votePubkey`, `commitment`, `keepUnstakedDelinquents`, `delinquentSlotDistance` ; - `getVoteAccounts` renvoie les groupes `current` et `delinquent` ; - `inflationRewardsCommissionBps` reste optionnel pour compatibilité avec les noeuds antérieurs ; - l'historique `epochCredits` reste exposé comme historique RPC borné, sans être interprété comme historique complet du vote account. ## Surface typée Cluster finale ### `getLeaderSchedule` ```text role + SolanaLeaderScheduleRequest -> Option ``` `SolanaLeaderScheduleRequest` conserve les deux formes cohérentes : ```text CurrentEpoch(config?) Slot { slot, config? } ``` Un config vide est omis. Un résultat JSON `null` devient `None`. Une map non nulle valide chaque identité et la convertit en `ksp_core_lib::Pubkey`. ### `getSlot` ```text role + Option -> u64 ``` La config commune est sérialisée uniquement lorsqu'elle contient `commitment` et/ou `minContextSlot`. Une erreur distante `MinContextSlotNotReached` reste une erreur RPC applicative. ### `getSlotLeader` ```text role + Option -> Pubkey ``` La valeur texte du leader est validée avant exposition comme `Pubkey`, sans recopier une valeur wire invalide dans le diagnostic. ### `getSlotLeaders` ```text role + startSlot u64 + limit u64 -> Vec ``` KSP rejette localement avant I/O : ```text limit == 0 limit > 5000 ``` L'ordre du tableau retourné est conservé, car chaque position correspond aux slots successifs demandés. ### `getVoteAccounts` ```text role + Option -> SolanaVoteAccountStatus ``` Un config vide est omis. Les deux groupes `current` et `delinquent` sont conservés, ainsi que : ```text votePubkey nodePubkey activatedStake commission inflationRewardsCommissionBps Option epochVoteAccount epochCredits Vec lastVote rootSlot ``` Aucune conversion métier staking/rewards n'est introduite dans Transport. ## Activation finale des helpers préparés en `pre.002` Les helpers spécifiques aux cinq méthodes de cette tranche deviennent production-live maintenant qu'ils ont des consommateurs runtime : - `SolanaLeaderScheduleConfig::{is_empty,to_json_value}` ; - `SolanaLeaderScheduleRequest::to_json_params` ; - `SolanaLeaderSchedule::decode_wire` ; - `SolanaVoteAccountsConfig::{is_empty,to_json_value}` ; - `SolanaVoteAccountInfo::decode_wire` ; - `SolanaVoteAccountStatus::decode_wire` ; - `WireVoteAccountInfo` et `WireVoteAccountStatus`. Aucun `#[allow(dead_code)]` n'est ajouté. Le helper privé d'exécution Cluster est renommé de `execute_cluster_simple_rpc` vers `execute_cluster_rpc`, car il dessert désormais les douze wrappers Cluster. ## Fixtures HTTP déterministes ajoutées ```text crates/ksp-onchain-transport-lib/fixtures/http/get_leader_schedule.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_leader_schedule.null.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leader.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leader.invalid_pubkey.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leaders.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leaders.invalid_pubkey.json crates/ksp-onchain-transport-lib/fixtures/http/get_vote_accounts.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_vote_accounts.invalid_pubkey.json ``` Les tests utilisent uniquement un serveur HTTP loopback local. ## Couverture de tests ajoutée Les tests couvrent notamment : - sérialisation slot + config de `getLeaderSchedule` ; - résultat nullable de `getLeaderSchedule` ; - sérialisation `commitment/minContextSlot` de `getSlot` et `getSlotLeader` ; - omission d'un `SolanaContextConfig` vide ; - validation de la `Pubkey` de `getSlotLeader` ; - conservation de l'ordre de `getSlotLeaders` ; - rejet local des limites `0` et `5001` avant I/O ; - rejet d'une identité invalide dans la liste `getSlotLeaders` ; - sérialisation complète de `SolanaVoteAccountsConfig` ; - omission d'un config vote accounts vide ; - conservation de `inflationRewardsCommissionBps` présent et absent ; - conservation des triples `epochCredits` ; - rejet d'une `votePubkey` invalide. Le test public compile explicitement les cinq nouvelles méthodes depuis `HttpTransportPool`. Un canari release fige désormais les douze méthodes Cluster exactes de `0.2.2` et vérifie `Read + RetrySafe` sur tout le sous-ensemble. Après application, la cible Transport attendue devient : ```text 127 unit tests 13 public API tests 6 release completeness tests ``` ## Rustdoc de crate La documentation de tête de `ksp-onchain-transport-lib` est ajustée pour ne plus présenter Cluster comme une famille encore staged : après `pre.006`, les 22 wrappers `0.2.2` sont implémentés. Les familles `0.2.3` et `0.2.4` restent staged. ## Fichiers ajoutés ```text crates/ksp-onchain-transport-lib/fixtures/http/get_leader_schedule.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_leader_schedule.null.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leader.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leader.invalid_pubkey.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leaders.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_slot_leaders.invalid_pubkey.json crates/ksp-onchain-transport-lib/fixtures/http/get_vote_accounts.success.json crates/ksp-onchain-transport-lib/fixtures/http/get_vote_accounts.invalid_pubkey.json deltas/0.2.2/pre.006.md ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/src/rpc_cluster.rs crates/ksp-onchain-transport-lib/unit_tests/rpc_cluster.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs ``` ## Fichiers supprimés Aucun. ## Documentation durable Aucune modification de ROADMAP/plan/index n'est requise dans cette tranche : le plan existant décrit déjà ce découpage et `pre.007` reste la tranche de clôture prerelease/documentation. `CHANGELOG.md` reste réservé à la clôture stable. ## Validation à exécuter sur le checkout opérateur ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-onchain-transport-lib ``` La livraison n'affirme pas que ces commandes ont été exécutées dans l'environnement de génération. ## Critères de validation de `pre.006` `pre.006` est validable lorsque : - les quatre commandes ci-dessus passent sans warning nouveau ; - les 127 unit tests passent ; - les 13 tests public API passent ; - les 6 tests release completeness passent ; - aucun helper Cluster production-live n'est `dead_code` ; - les douze wrappers Cluster `0.2.2` sont accessibles depuis `HttpTransportPool` ; - le total `0.2.2` reste exactement 5 Accounts + 5 Tokens + 12 Cluster = 22 wrappers ; - aucune méthode `0.2.3`/`0.2.4` n'est activée prématurément.