336 lines
11 KiB
Markdown
336 lines
11 KiB
Markdown
<!-- file: deltas/0.2.2/pre.003.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.2-pre.003` — cinq wrappers HTTP Accounts typés
|
|
|
|
## Base requise
|
|
|
|
Livraison précédente corrigée et validée localement par l'opérateur :
|
|
|
|
```text
|
|
0.2.2-pre.002-fix.002
|
|
workspace.package.version = "0.2.2-pre.2.fix.2"
|
|
```
|
|
|
|
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
|
|
85 unit tests
|
|
9 public API tests
|
|
2 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.
|
|
|
|
## Objectif
|
|
|
|
Clôturer la famille Accounts attribuée à `0.2.2` avec cinq wrappers publics typés :
|
|
|
|
```text
|
|
getAccountInfo
|
|
getLargestAccounts
|
|
getMinimumBalanceForRentExemption
|
|
getMultipleAccounts
|
|
getProgramAccounts
|
|
```
|
|
|
|
Tous passent par la foundation HTTP `0.2.1` :
|
|
|
|
```text
|
|
wrapper typé
|
|
-> descriptor audité
|
|
-> execute_standard_rpc
|
|
-> pool/admission/retry/deadline
|
|
-> reqwest HTTP
|
|
-> JSON-RPC validation
|
|
-> décodage DTO KSP
|
|
```
|
|
|
|
Aucun wrapper ne contacte `reqwest` directement.
|
|
|
|
## Version Cargo
|
|
|
|
Conformément à `VER-ID-009` :
|
|
|
|
```text
|
|
0.2.2-pre.2.fix.2 -> 0.2.2-pre.3
|
|
```
|
|
|
|
Aucune dépendance ni feature Cargo n'est ajoutée.
|
|
|
|
## Surface typée Accounts
|
|
|
|
### `getAccountInfo`
|
|
|
|
Signature publique conceptuelle :
|
|
|
|
```text
|
|
role + Pubkey + Option<SolanaAccountInfoConfig>
|
|
-> SolanaRpcResponse<Option<SolanaAccount>>
|
|
```
|
|
|
|
Le wrapper :
|
|
|
|
- sérialise `encoding`, `dataSlice`, `commitment` et `minContextSlot` ;
|
|
- omet l'objet config lorsqu'il est vide ;
|
|
- conserve l'absence du compte sous `None` ;
|
|
- conserve les formes Account data legacy, tuple encodé et `jsonParsed` ;
|
|
- convertit l'owner en `ksp_core_lib::Pubkey` sans recopier une valeur invalide dans le diagnostic.
|
|
|
|
### `getLargestAccounts`
|
|
|
|
Signature publique conceptuelle :
|
|
|
|
```text
|
|
role + Option<SolanaLargestAccountsConfig>
|
|
-> SolanaRpcResponse<Vec<SolanaAccountBalance>>
|
|
```
|
|
|
|
Le wrapper conserve l'ordre du wire et sérialise les champs KSP déjà audités dans `pre.002`, y compris `filter` et `sortResults` lorsqu'ils sont
|
|
explicitement renseignés.
|
|
|
|
### `getMinimumBalanceForRentExemption`
|
|
|
|
Signature publique conceptuelle :
|
|
|
|
```text
|
|
role + usize data_len + Option<SolanaCommitmentConfig>
|
|
-> u64 lamports
|
|
```
|
|
|
|
Le wrapper encode la longueur de données sans valeur sentinelle et conserve les erreurs JSON-RPC applicatives comme telles.
|
|
|
|
### `getMultipleAccounts`
|
|
|
|
Signature publique conceptuelle :
|
|
|
|
```text
|
|
role + &[Pubkey] + Option<SolanaAccountInfoConfig>
|
|
-> SolanaRpcResponse<Vec<Option<SolanaAccount>>>
|
|
```
|
|
|
|
Le wrapper :
|
|
|
|
- refuse localement plus de 100 public keys ;
|
|
- sérialise les adresses dans l'ordre fourni ;
|
|
- conserve les `null` individuels ;
|
|
- vérifie que le nombre d'éléments retournés correspond au nombre d'adresses demandées, afin de ne pas fabriquer silencieusement un mapping
|
|
positionnel incohérent.
|
|
|
|
### `getProgramAccounts`
|
|
|
|
Signature publique conceptuelle :
|
|
|
|
```text
|
|
role + program Pubkey + Option<SolanaProgramAccountsConfig>
|
|
-> SolanaProgramAccountsResult
|
|
```
|
|
|
|
Le résultat préserve les deux formes wire :
|
|
|
|
```text
|
|
Accounts(Vec<SolanaKeyedAccount>)
|
|
Context(SolanaRpcResponse<Vec<SolanaKeyedAccount>>)
|
|
```
|
|
|
|
Le wrapper sérialise `dataSize`, `memcmp`, `tokenAccountState`, `withContext`, `sortResults` et la config Account commune.
|
|
|
|
## Validation locale des paramètres
|
|
|
|
Nouveau code d'erreur public Transport :
|
|
|
|
```text
|
|
ERROR_CODE_INVALID_RPC_PARAMETERS
|
|
onchain_transport.invalid_rpc_parameters
|
|
```
|
|
|
|
Il distingue une requête KSP localement invalide d'une erreur JSON-RPC distante ou d'une réponse invalide.
|
|
|
|
Les invariants appliqués avant I/O sont :
|
|
|
|
```text
|
|
getMultipleAccounts : <= 100 public keys
|
|
getProgramAccounts : <= 4 filters
|
|
memcmp raw bytes : <= 128 bytes
|
|
```
|
|
|
|
Pour `memcmp` encodé sous forme base58/base64, KSP ne décode toujours pas localement la chaîne : la limite des 128 octets décodés reste donc
|
|
contrôlée par le serveur. Cette décision évite d'ajouter `bs58` ou `base64` uniquement pour une validation anticipée.
|
|
|
|
## Wire Account activé en production
|
|
|
|
Les helpers privés préparés par `pre.002` et réellement nécessaires à ces wrappers deviennent production-live :
|
|
|
|
- sérialisation des configs Account/Largest/Program ;
|
|
- conversion des encodings Account ;
|
|
- décodage `SolanaAccountData` ;
|
|
- décodage Account/KeyedAccount/AccountBalance ;
|
|
- conversion `Pubkey` wire ;
|
|
- construction interne de `SolanaRpcResponse<T>`.
|
|
|
|
Les helpers Cluster/Token préparatoires restent inchangés et ne deviennent pas production-live avant leurs tranches respectives.
|
|
|
|
## Fixtures HTTP déterministes ajoutées
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.null.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.invalid_owner.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_largest_accounts.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_largest_accounts.invalid_address.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_minimum_balance_for_rent_exemption.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_minimum_balance_for_rent_exemption.error.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_multiple_accounts.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_program_accounts.bare.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_program_accounts.context.success.json
|
|
```
|
|
|
|
Les tests locaux utilisent un serveur HTTP loopback et n'accèdent pas à Internet.
|
|
|
|
## Couverture de tests ajoutée
|
|
|
|
Les tests Accounts couvrent :
|
|
|
|
- request exacte pour chaque méthode ;
|
|
- config et omission de config vide ;
|
|
- succès typé ;
|
|
- account absent ;
|
|
- `null` dans `getMultipleAccounts` ;
|
|
- ordre de `getMultipleAccounts` ;
|
|
- résultat bare et contextualisé de `getProgramAccounts` ;
|
|
- invalid owner/address ;
|
|
- erreur JSON-RPC applicative ;
|
|
- limite des 100 comptes ;
|
|
- limite des 4 filtres ;
|
|
- limite raw `memcmp` de 128 octets ;
|
|
- mismatch cardinalité request/result de `getMultipleAccounts`.
|
|
|
|
Le test public compile explicitement les cinq méthodes sur `HttpTransportPool` et vérifie le nouveau code d'erreur.
|
|
|
|
Un canari release supplémentaire fige l'ensemble Accounts `0.2.2` exact :
|
|
|
|
```text
|
|
getAccountInfo
|
|
getLargestAccounts
|
|
getMinimumBalanceForRentExemption
|
|
getMultipleAccounts
|
|
getProgramAccounts
|
|
```
|
|
|
|
Il vérifie aussi que ces descriptors restent `Read + RetrySafe`. Aucune famille Tokens/Cluster n'est déclarée typed-complete par cette tranche.
|
|
|
|
Après application, la cible Transport attendue devient :
|
|
|
|
```text
|
|
98 unit tests
|
|
10 public API tests
|
|
3 release completeness tests
|
|
```
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.null.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_account_info.invalid_owner.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_largest_accounts.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_largest_accounts.invalid_address.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_minimum_balance_for_rent_exemption.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_minimum_balance_for_rent_exemption.error.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_multiple_accounts.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_program_accounts.bare.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_program_accounts.context.success.json
|
|
deltas/0.2.2/pre.003.md
|
|
```
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-onchain-transport-lib/src/error.rs
|
|
crates/ksp-onchain-transport-lib/src/lib.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_accounts.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_common.rs
|
|
crates/ksp-onchain-transport-lib/unit_tests/rpc_accounts.rs
|
|
crates/ksp-onchain-transport-lib/tests/public_api.rs
|
|
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
|
```
|
|
|
|
## Fichiers supprimés
|
|
|
|
Aucun.
|
|
|
|
## Fichiers volontairement inchangés
|
|
|
|
```text
|
|
CHANGELOG.md
|
|
ROADMAP.md
|
|
docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md
|
|
crates/ksp-onchain-transport-lib/Cargo.toml
|
|
crates/ksp-onchain-transport-lib/src/executor.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_method.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_tokens.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_cluster.rs
|
|
crates/ksp-config-lib/**
|
|
config/**
|
|
```
|
|
|
|
La tranche suivante reste `pre.004 — cinq wrappers Tokens`.
|
|
|
|
## Validations exécutées
|
|
|
|
- prise en compte de la validation opérateur propre de `pre.002-fix.002` comme base ;
|
|
- relecture des règles `VERSION_WORKFLOW.md` et `RULES_RUST.md` applicables ;
|
|
- revérification de la documentation HTTP Solana actuelle pour les cinq méthodes Accounts ;
|
|
- recoupement des signatures/limites avec la source Agave `v4.2.1` auditée par le plan ;
|
|
- validation JSON syntaxique des dix nouvelles fixtures ;
|
|
- contrôle statique de l'absence de `unwrap`, `expect`, `panic!` et `#[allow(dead_code)]` dans le code de production modifié ;
|
|
- contrôle statique que les cinq wrappers utilisent `execute_standard_rpc` et aucun appel `reqwest` direct ;
|
|
- contrôle statique de l'absence de nouvelle dépendance/feature ;
|
|
- contrôle exact des fichiers inclus dans l'archive d'échange.
|
|
|
|
## Validations non exécutées
|
|
|
|
Le sandbox d'échange ne fournit pas `cargo`, `rustc` ou `rustfmt`. Les commandes suivantes doivent être exécutées sur le checkout opérateur avant
|
|
commit :
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-onchain-transport-lib
|
|
```
|
|
|
|
`cargo test --workspace` reste réservé au checkpoint de clôture/session conformément au workflow KSP. Aucun `cargo tree` n'est requis par cette
|
|
tranche puisqu'aucune dépendance ni feature n'a changé.
|
|
|
|
## Décisions prises
|
|
|
|
- utiliser les DTOs `pre.002` sans créer de seconde couche RPC ;
|
|
- conserver `execute_standard_rpc()` comme unique entrée d'exécution HTTP standard ;
|
|
- introduire un code d'erreur dédié aux paramètres typed invalides plutôt que détourner `invalid_settings` ;
|
|
- vérifier localement les limites dont KSP peut connaître la violation sans dépendance de décodage supplémentaire ;
|
|
- préserver les `null`, l'ordre et la dualité bare/context au lieu de normaliser artificiellement les réponses ;
|
|
- ne pas modifier Config ;
|
|
- ne pas ajouter de logging spécifique par méthode.
|
|
|
|
## Questions ouvertes
|
|
|
|
Aucune question bloquante pour `pre.004`.
|
|
|
|
## Suite
|
|
|
|
`0.2.2-pre.004` : implémenter les cinq wrappers Tokens (`getTokenAccountBalance`, `getTokenAccountsByDelegate`, `getTokenAccountsByOwner`,
|
|
`getTokenLargestAccounts`, `getTokenSupply`) avec les DTOs préparés, selector `Mint | ProgramId`, fixtures HTTP déterministes et conservation de
|
|
`uiAmount: null`.
|