Files
2026-08-18 08:27:42 +02:00

299 lines
9.7 KiB
Markdown

<!-- file: deltas/0.2.2/pre.006.md -->
<!-- version: 1 -->
# 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<SolanaLeaderSchedule>
```
`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<SolanaContextConfig> -> 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<SolanaContextConfig> -> 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<Pubkey>
```
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<SolanaVoteAccountsConfig> -> SolanaVoteAccountStatus
```
Un config vide est omis. Les deux groupes `current` et `delinquent` sont conservés, ainsi que :
```text
votePubkey
nodePubkey
activatedStake
commission
inflationRewardsCommissionBps Option<u16>
epochVoteAccount
epochCredits Vec<SolanaEpochCredits>
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.