Files
khadhroony-solana-project/deltas/0.2.3/pre.004.md
2026-08-18 12:14:59 +02:00

347 lines
9.9 KiB
Markdown

<!-- file: deltas/0.2.3/pre.004.md -->
<!-- version: 1 -->
# Delta `0.2.3-pre.004` — lectures Transaction avec cardinalités et statuts positionnels
## Base requise
Livraison précédente validée localement par l'opérateur :
```text
0.2.3-pre.003
workspace.package.version = "0.2.3-pre.3"
```
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
152 unit tests
15 public API tests
9 release completeness tests
0 warning signalé par check/clippy
```
Le plan canonique reste `docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md` version 3.
## Objectif
Implémenter les trois wrappers Transaction `Read / RetrySafe` prévus par la tranche `pre.004` :
```text
getRecentPrioritizationFees
getSignaturesForAddress
getSignatureStatuses
```
Ils rejoignent les quatre reads de `pre.003`, portant la surface Transaction typée exécutée à :
```text
7 / 11 wrappers
```
Les quatre méthodes restantes restent volontairement différées :
```text
getTransaction
requestAirdrop
sendTransaction
simulateTransaction
```
## Version Cargo
Conformément à `VER-ID-009` :
```text
0.2.3-pre.3 -> 0.2.3-pre.4
```
Aucune dépendance ni feature Cargo n'est ajoutée.
## `getRecentPrioritizationFees`
Surface publique conceptuelle :
```text
role + Option<&[Pubkey]>
-> Vec<SolanaPrioritizationFee>
```
Le tableau d'adresses reste optionnel :
- `None` omet entièrement le paramètre ;
- `Some(slice)` sérialise exactement un tableau d'adresses ;
- l'ordre des adresses caller est conservé ;
- les résultats restent dans l'ordre renvoyé par le provider.
La cardinalité runtime documentée est appliquée avant I/O :
```text
0..=128 accepté
129+ ERROR_CODE_INVALID_RPC_PARAMETERS
```
Le test couvre explicitement la borne `128` puis le rejet de `129`.
Aucune règle locale n'est créée à partir de la profondeur actuelle de cache des prioritization fees : la valeur d'environ 150 blocs est une
caractéristique runtime du noeud et non une cardinalité client.
## `getSignaturesForAddress`
Surface publique conceptuelle :
```text
role + Pubkey + Option<SolanaSignaturesForAddressConfig>
-> Vec<SolanaSignatureInfo>
```
La config préparée en `pre.002` devient production-live pour cette méthode :
```text
before
until
limit
commitment
minContextSlot
```
Une config absente ou entièrement vide est omise. La limite est validée avant I/O exactement selon le runtime audité :
```text
1..=1000 accepté quand limit est fourni
0 rejeté
1001+ rejeté
```
La fixture de succès utilise explicitement `limit = 1000`, puis les tests rejettent `0` et `1001`.
Le résultat conserve notamment :
```text
signature
slot
err nullable
memo nullable
blockTime nullable
confirmationStatus nullable
transactionIndex optionnel
```
L'ordre `newest -> oldest` du provider n'est jamais retrié côté KSP. Les signatures restent des chaînes wire opaques dans cette release.
Une fixture JSON-RPC d'erreur vérifie qu'une indisponibilité de transaction history reste une `RPC_APPLICATION_ERROR`, sans être transformée en
retry Transport.
## `getSignatureStatuses`
Surface publique conceptuelle :
```text
role + &[String] + Option<SolanaSignatureStatusesConfig>
-> SolanaRpcResponse<Vec<Option<SolanaSignatureStatus>>>
```
La config `searchTransactionHistory` préparée en `pre.002` devient production-live. Une config vide est omise.
Le tableau d'entrée suit exactement la borne Agave auditée :
```text
0..=256 accepté
257+ ERROR_CODE_INVALID_RPC_PARAMETERS
```
Le tableau vide reste volontairement accepté, conformément au runtime `v4.2.1` audité en `pre.001`. La borne `256` est exercée par une fixture
contenant 256 positions `null` et `257` est rejeté avant I/O.
Le résultat conserve strictement la correspondance positionnelle :
```text
entrée[i] <-> value[i]
null -> None
objet -> Some(SolanaSignatureStatus)
```
KSP vérifie maintenant que le provider retourne exactement autant de positions que de signatures demandées. Une longueur différente produit
`ERROR_CODE_INVALID_RESPONSE`, car continuer masquerait la correspondance signature/statut.
Pour un statut présent, les champs suivants restent préservés :
```text
slot
confirmations nullable
status legacy lossless JSON
err nullable
confirmationStatus nullable
```
La forme `status` demeure un champ legacy du wire courant ; elle n'est pas confondue avec les anciennes méthodes RPC Deprecated.
## Helpers activés en production
Seuls les helpers nécessaires à cette tranche quittent `#[cfg(test)]` :
```text
SolanaSignaturesForAddressConfig::{is_empty,to_json_value}
SolanaSignatureStatusesConfig::{is_empty,to_json_value}
SolanaPrioritizationFee::decode_wire
SolanaSignatureInfo::decode_wire
SolanaSignatureStatus::decode_wire
decode_confirmation_status
WirePrioritizationFee
WireSignatureInfo
WireSignatureStatus
```
Les helpers de `getTransaction`, `requestAirdrop`, `sendTransaction` et `simulateTransaction` restent staged/test-only jusqu'à leur tranche
propriétaire. Aucun `#[allow(dead_code)]` n'est introduit.
## Fixtures HTTP déterministes ajoutées
```text
crates/ksp-onchain-transport-lib/fixtures/http/get_recent_prioritization_fees.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signatures_for_address.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signatures_for_address.error.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.empty.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.max_256.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.count_mismatch.json
```
Les tests HTTP utilisent uniquement un serveur loopback local.
## Couverture de tests ajoutée
Neuf tests unitaires HTTP supplémentaires couvrent :
- paramètres exacts de `getRecentPrioritizationFees` et ordre serveur ;
- omission du paramètre optionnel ;
- acceptation de 128 adresses et rejet local de 129 ;
- pagination/config complète de `getSignaturesForAddress` avec `limit = 1000` ;
- rejet local de `limit = 0` et `limit = 1001` ;
- propagation d'une erreur JSON-RPC applicative ;
- `getSignatureStatuses` avec `searchTransactionHistory = true` et positions `null` ;
- tableau vide + config vide omise ;
- borne 256 acceptée, 257 rejetée et longueur de réponse incohérente rejetée.
Un test public compile les trois nouveaux wrappers depuis la crate root.
Une nouvelle canarie release fige le sous-ensemble Read exécuté cumulé de `pre.003 + pre.004` :
```text
getFeeForMessage
getLatestBlockhash
getRecentPrioritizationFees
getSignaturesForAddress
getSignatureStatuses
getTransactionCount
isBlockhashValid
```
Chaque descriptor reste :
```text
Transactions / V0_2_3 / Read / RetrySafe
```
La canarie confirme aussi que les quatre méthodes différées restent enregistrées dans `V0_2_3` sans les compter comme surface typée achevée.
Après application, la cible Transport attendue devient :
```text
161 unit tests
16 public API tests
10 release completeness tests
```
## Fichiers ajoutés
```text
crates/ksp-onchain-transport-lib/fixtures/http/get_recent_prioritization_fees.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signatures_for_address.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signatures_for_address.error.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.success.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.empty.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.max_256.json
crates/ksp-onchain-transport-lib/fixtures/http/get_signature_statuses.count_mismatch.json
deltas/0.2.3/pre.004.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/src/rpc_transactions.rs
crates/ksp-onchain-transport-lib/unit_tests/rpc_transactions.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
```
Restent inchangés dans cette tranche :
```text
CHANGELOG.md
ROADMAP.md
docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md
crates/ksp-onchain-transport-lib/Cargo.toml
crates/ksp-onchain-transport-lib/src/executor.rs
crates/ksp-onchain-transport-lib/src/resilience.rs
crates/ksp-onchain-transport-lib/src/rpc_method.rs
```
## Contrôles statiques effectués dans l'environnement d'échange
- les sept nouvelles fixtures sont du JSON valide ;
- aucune dépendance n'est ajoutée ;
- aucun `reqwest`, `tracing`, retry local ou client parallèle n'est introduit par le diff ;
- aucun `#[allow(dead_code)]` n'est introduit ;
- les helpers des tranches futures restent `#[cfg(test)]` ;
- aucune ligne Rust modifiée ne dépasse 160 colonnes ;
- `CHANGELOG.md`, `ROADMAP.md`, le plan `010`, `executor.rs`, `resilience.rs` et `rpc_method.rs` restent identiques à `pre.003`.
`cargo`, `rustc` et `rustfmt` ne sont pas installés dans l'environnement d'échange. Aucune validation Cargo de `pre.004` n'est donc déclarée
réussie ici.
## Validation opérateur requise
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
```
La validation doit notamment confirmer :
```text
0 warning check/clippy
161 unit tests
16 public API tests
10 release completeness tests
```
Le smoke Devnet reste opt-in et n'est pas requis pour cette tranche locale déterministe.
## Hors scope maintenu
`pre.004` ne traite pas :
- `getTransaction` moderne/legacy ;
- `requestAirdrop` ;
- `sendTransaction` ;
- la preuve end-to-end no-resend des writes ;
- `simulateTransaction` ;
- les 15 méthodes `0.2.4` Blocks/Economics ;
- un nouveau smoke cross-crates.
La prochaine tranche reste `pre.005` : `getTransaction` moderne, compatibilité legacy et wire transaction/meta/version.