424 lines
12 KiB
Markdown
424 lines
12 KiB
Markdown
<!-- file: deltas/0.2.4/pre.004.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.4-pre.004` — ranges Blocks et performance samples
|
|
|
|
## Base requise
|
|
|
|
Livraison précédente :
|
|
|
|
```text
|
|
0.2.4-pre.003
|
|
workspace.package.version = "0.2.4-pre.3"
|
|
```
|
|
|
|
Les validations locales fournies pour cette base sont propres :
|
|
|
|
```text
|
|
cargo fmt --all -> terminé
|
|
cargo check --workspace -> terminé sans warning
|
|
cargo clippy --workspace --all-targets -> terminé sans warning
|
|
cargo test -p ksp-onchain-transport-lib -> 202 unit tests OK
|
|
21 public API tests OK
|
|
16 release-completeness tests OK
|
|
1 smoke Devnet ignoré comme prévu
|
|
0 échec
|
|
```
|
|
|
|
Le plan canonique `docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md` passe de la version 2 à la version 3 dans cette livraison afin de corriger explicitement la config runtime stable de `getBlocks` / `getBlocksWithLimit` : Agave `v4.2.1` utilise `RpcContextConfig` avec `commitment` et `minContextSlot`.
|
|
|
|
## Objectif
|
|
|
|
Implémenter exactement la tranche `pre.004` prévue :
|
|
|
|
```text
|
|
getBlocks
|
|
getBlocksWithLimit
|
|
getRecentPerformanceSamples
|
|
```
|
|
|
|
Les trois méthodes sont déjà enregistrées dans la partition `V0_2_4 / Blocks` et classées `Read / RetrySafe`. Cette prerelease ne modifie donc pas le registre central.
|
|
|
|
Après cette tranche, huit des dix wrappers Blocks de `0.2.4` sont matérialisés :
|
|
|
|
```text
|
|
pre.003
|
|
getBlockCommitment
|
|
getBlockHeight
|
|
getBlockTime
|
|
getFirstAvailableBlock
|
|
minimumLedgerSlot
|
|
|
|
pre.004
|
|
getBlocks
|
|
getBlocksWithLimit
|
|
getRecentPerformanceSamples
|
|
```
|
|
|
|
Restent volontairement différés :
|
|
|
|
```text
|
|
pre.005 getBlockProduction
|
|
pre.006 getBlock
|
|
```
|
|
|
|
Les cinq méthodes Economics restent également hors scope.
|
|
|
|
## Réaudit RPC de la tranche
|
|
|
|
Le contrat HTTP courant a été revérifié avant implémentation et reste conforme au plan `pre.001` :
|
|
|
|
- `getBlocks` accepte `start_slot`, un second paramètre qui peut être soit `end_slot`, soit un `RpcContextConfig`, puis éventuellement ce même type de config en troisième position ; la config stable contient `commitment` et `minContextSlot`, et la plage maximale est de `500_000` slots ;
|
|
- `getBlocksWithLimit` accepte `start_slot`, `limit` puis un `RpcContextConfig` optionnel `{commitment,minContextSlot}` ; `limit` ne doit pas dépasser `500_000` ;
|
|
- `getRecentPerformanceSamples` accepte un `limit` optionnel avec maximum `720`; l'absence du paramètre laisse le runtime appliquer son défaut ;
|
|
- les résultats `getBlocks` / `getBlocksWithLimit` restent des listes ordonnées de slots `u64` ;
|
|
- `getRecentPerformanceSamples` reste une liste dans l'ordre fourni par le serveur et expose `slot`, `numTransactions`, `numSlots`, `samplePeriodSecs`, avec `numNonVoteTransactions` conservé comme champ optionnel pour compatibilité avec les anciens wires.
|
|
|
|
Aucun nouvel overload ni nouvelle limite n'a été identifié. En revanche, le cross-audit source Agave a clarifié un champ stable que la page publique n'affiche pas : `minContextSlot` fait partie du `RpcContextConfig` accepté par `getBlocks` et `getBlocksWithLimit`. Le plan vivant est corrigé en conséquence sous sa version 3.
|
|
|
|
## Version Cargo
|
|
|
|
Nouvelle prerelease technique :
|
|
|
|
```text
|
|
0.2.4-pre.3 -> 0.2.4-pre.4
|
|
```
|
|
|
|
Aucune dépendance ni feature Cargo n'est ajoutée ou modifiée.
|
|
|
|
## `getBlocks`
|
|
|
|
Signature publique :
|
|
|
|
```text
|
|
HttpTransportPool::get_blocks(
|
|
role,
|
|
start_slot,
|
|
Option<end_slot>,
|
|
Option<&SolanaContextConfig>,
|
|
) -> Result<Vec<u64>>
|
|
```
|
|
|
|
Le wrapper préserve les quatre formes retenues par `KSP-TRANSPORT-007` :
|
|
|
|
```json
|
|
[430000100]
|
|
[430000100, 430000109]
|
|
[430000100, {"commitment":"confirmed", "minContextSlot":429999999}]
|
|
[430000100, 430000109, {"commitment":"confirmed", "minContextSlot":429999999}]
|
|
```
|
|
|
|
Un `Some(SolanaContextConfig::default())` reste un overload config explicite :
|
|
|
|
```json
|
|
[430000100, {}]
|
|
```
|
|
|
|
Il n'est pas réécrit silencieusement en `[430000100]`.
|
|
|
|
Validation déterministe avant I/O :
|
|
|
|
```text
|
|
commitment = processed -> rejet
|
|
end >= start et end - start > 500_000 -> rejet
|
|
```
|
|
|
|
La borne est inclusive :
|
|
|
|
```text
|
|
end - start = 500_000 -> valide
|
|
```
|
|
|
|
Le cas :
|
|
|
|
```text
|
|
end < start
|
|
```
|
|
|
|
reste valide et est envoyé au runtime ; KSP accepte alors le tableau vide retourné sans fabriquer une erreur locale ni synthétiser une autre réponse.
|
|
|
|
Le résultat `Vec<u64>` est conservé dans l'ordre exact retourné par le serveur ; aucun tri ni remplissage des slots absents n'est effectué.
|
|
|
|
## `getBlocksWithLimit`
|
|
|
|
Signature publique :
|
|
|
|
```text
|
|
HttpTransportPool::get_blocks_with_limit(
|
|
role,
|
|
start_slot,
|
|
limit,
|
|
Option<&SolanaContextConfig>,
|
|
) -> Result<Vec<u64>>
|
|
```
|
|
|
|
Validation déterministe avant I/O :
|
|
|
|
```text
|
|
commitment = processed -> rejet
|
|
limit > 500_000 -> rejet
|
|
```
|
|
|
|
Les deux bornes importantes sont couvertes explicitement :
|
|
|
|
```text
|
|
limit = 0 -> valide
|
|
limit = 500_000 -> valide
|
|
limit = 500_001 -> rejet avant I/O
|
|
```
|
|
|
|
Aucune borne minimale artificielle `1` n'est ajoutée.
|
|
|
|
Comme pour `getBlocks`, l'ordre et les éventuels trous de slots de la réponse sont laissés au runtime et préservés par Transport.
|
|
|
|
## `getRecentPerformanceSamples`
|
|
|
|
Signature publique :
|
|
|
|
```text
|
|
HttpTransportPool::get_recent_performance_samples(
|
|
role,
|
|
Option<limit>,
|
|
) -> Result<Vec<SolanaPerformanceSample>>
|
|
```
|
|
|
|
Wire sans limite explicite :
|
|
|
|
```json
|
|
[]
|
|
```
|
|
|
|
Wire avec maximum explicite :
|
|
|
|
```json
|
|
[720]
|
|
```
|
|
|
|
Validation déterministe :
|
|
|
|
```text
|
|
limit <= 720 -> valide
|
|
limit > 720 -> rejet avant I/O
|
|
```
|
|
|
|
Le wrapper n'introduit aucune borne minimale locale et ne remplace pas l'absence de limite par une valeur synthétique `720` dans la requête.
|
|
|
|
`SolanaPerformanceSample`, introduit en `pre.002`, est désormais consommé par un wrapper runtime. Son décodeur interne et `WirePerformanceSample` sortent donc de `#[cfg(test)]`.
|
|
|
|
Le décodage conserve :
|
|
|
|
```text
|
|
slot
|
|
numTransactions
|
|
numNonVoteTransactions présent ou omis
|
|
numSlots
|
|
samplePeriodSecs
|
|
```
|
|
|
|
L'ordre retourné par le serveur est conservé sans tri local.
|
|
|
|
## Discipline `#[cfg(test)]`
|
|
|
|
La règle introduite par `pre.002-fix.001` reste appliquée strictement.
|
|
|
|
Nouveaux éléments devenus runtime en `pre.004` :
|
|
|
|
```text
|
|
SolanaPerformanceSample::decode_wire
|
|
WirePerformanceSample
|
|
```
|
|
|
|
Éléments déjà runtime en `pre.003` :
|
|
|
|
```text
|
|
SolanaBlockCommitment::decode_wire
|
|
WireBlockCommitment
|
|
```
|
|
|
|
Restent test-only jusqu'à leur tranche :
|
|
|
|
```text
|
|
SolanaGetBlockConfig::{is_empty,to_json_value}
|
|
SolanaBlockProductionRange::to_json_value
|
|
SolanaBlockProductionConfig::{is_empty,to_json_value}
|
|
SolanaBlockProduction::decode_wire
|
|
SolanaBlockReward::decode_wire
|
|
SolanaBlockTransaction::decode_wire
|
|
SolanaConfirmedBlock::decode_wire
|
|
helpers privés transaction/reward de bloc
|
|
WireBlockProduction*
|
|
WireBlockReward
|
|
WireBlockTransaction
|
|
WireConfirmedBlock
|
|
helpers/wires Economics
|
|
```
|
|
|
|
Aucun `#[allow(dead_code)]` n'est introduit.
|
|
|
|
## Fixtures HTTP ajoutées
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks.empty.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks_with_limit.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks_with_limit.empty.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_recent_performance_samples.success.json
|
|
```
|
|
|
|
Les réponses de blocs utilisent volontairement des slots non continus afin de prouver que Transport ne synthétise pas les slots absents.
|
|
|
|
La fixture performance contient un échantillon courant avec `numNonVoteTransactions` et un échantillon compatible ancien wire sans ce champ.
|
|
|
|
## Tests unitaires ajoutés
|
|
|
|
`unit_tests/rpc_blocks.rs` ajoute six tests async :
|
|
|
|
```text
|
|
typed_get_blocks_covers_all_four_overloads_and_preserves_server_order
|
|
typed_get_blocks_allows_reversed_and_boundary_ranges_but_rejects_oversized_before_io
|
|
typed_block_range_wrappers_reject_processed_commitment_before_io
|
|
typed_get_blocks_with_limit_accepts_zero_and_maximum_and_rejects_above_maximum
|
|
typed_get_recent_performance_samples_preserves_default_explicit_limit_order_and_older_shape
|
|
typed_get_recent_performance_samples_rejects_above_720_before_io
|
|
```
|
|
|
|
Ils couvrent notamment :
|
|
|
|
```text
|
|
getBlocks [start]
|
|
getBlocks [start,end]
|
|
getBlocks [start,config]
|
|
getBlocks [start,end,config]
|
|
getBlocks [start,{}]
|
|
getBlocks end < start
|
|
getBlocks différence = 500_000
|
|
autorejet getBlocks différence = 500_001
|
|
commitment processed rejeté avant I/O
|
|
getBlocksWithLimit 0
|
|
getBlocksWithLimit 500_000
|
|
getBlocksWithLimit 500_001 rejeté avant I/O
|
|
getRecentPerformanceSamples sans limite
|
|
getRecentPerformanceSamples 720
|
|
getRecentPerformanceSamples 721 rejeté avant I/O
|
|
ordre des résultats conservé
|
|
ancien sample sans numNonVoteTransactions accepté
|
|
```
|
|
|
|
## Canaries d'intégration
|
|
|
|
`tests/public_api.rs` ajoute :
|
|
|
|
```text
|
|
public_v0_2_4_pre_004_range_and_performance_wrappers_are_available_from_crate_root
|
|
```
|
|
|
|
La canarie référence directement :
|
|
|
|
```text
|
|
HttpTransportPool::get_blocks
|
|
HttpTransportPool::get_blocks_with_limit
|
|
HttpTransportPool::get_recent_performance_samples
|
|
```
|
|
|
|
`tests/release_completeness.rs` ajoute :
|
|
|
|
```text
|
|
release_v0_2_4_pre_004_range_performance_subset_is_exact_and_retry_safe
|
|
```
|
|
|
|
Elle verrouille le sous-ensemble exact :
|
|
|
|
```text
|
|
getBlocks
|
|
getBlocksWithLimit
|
|
getRecentPerformanceSamples
|
|
```
|
|
|
|
et leur classification commune :
|
|
|
|
```text
|
|
HttpRpcCoverageRelease::V0_2_4
|
|
HttpRpcCategory::Blocks
|
|
RpcOperationKind::Read
|
|
TransportRetryClass::RetrySafe
|
|
```
|
|
|
|
## Frontières architecturales
|
|
|
|
Cette tranche ne modifie pas les frontières établies :
|
|
|
|
```text
|
|
Transport -X-> Config
|
|
Transport -X-> Store
|
|
Transport -X-> Program
|
|
Transport -X-> tracing direct
|
|
```
|
|
|
|
Les wrappers passent exclusivement par `execute_standard_rpc` et la politique centrale de retry.
|
|
|
|
Aucun client RPC Solana haut niveau, aucun retry local, aucune lecture d'environnement/configuration et aucune dépendance externe nouvelle ne sont introduits.
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
|
|
crates/ksp-onchain-transport-lib/unit_tests/rpc_blocks.rs
|
|
crates/ksp-onchain-transport-lib/tests/public_api.rs
|
|
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
|
docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md
|
|
```
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks.empty.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks_with_limit.success.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_blocks_with_limit.empty.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/get_recent_performance_samples.success.json
|
|
deltas/0.2.4/pre.004.md
|
|
```
|
|
|
|
Aucun fichier n'est supprimé.
|
|
|
|
## Validation à exécuter après application
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-onchain-transport-lib
|
|
```
|
|
|
|
Compteurs attendus si aucun test existant n'est ajouté/supprimé localement entre-temps :
|
|
|
|
```text
|
|
208 unit tests
|
|
22 public API tests
|
|
17 release-completeness tests
|
|
1 smoke Devnet ignoré comme prévu
|
|
0 échec
|
|
```
|
|
|
|
Le sandbox de génération ne possède pas le toolchain Rust ; aucune compilation locale n'est revendiquée dans ce delta.
|
|
|
|
## Suite
|
|
|
|
La tranche suivante reste celle prévue par le plan :
|
|
|
|
```text
|
|
0.2.4-pre.005
|
|
getBlockProduction
|
|
```
|
|
|
|
Elle devra activer uniquement les helpers runtime nécessaires à `SolanaBlockProductionConfig`, `SolanaBlockProductionRange` et `SolanaBlockProduction`, puis couvrir `identity`, `range`, le résultat contextualisé et la validation `lastSlot >= firstSlot`.
|
|
|
|
## Commit attendu
|
|
|
|
Après validation locale réussie :
|
|
|
|
```text
|
|
v0.2.4-pre.004
|
|
```
|