332 lines
14 KiB
Markdown
332 lines
14 KiB
Markdown
<!-- file: deltas/0.2.4/pre.002.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.2.4-pre.002` — primitives Blocks/Economics et fixtures wire partagées
|
|
|
|
## Base requise
|
|
|
|
Livraison précédente :
|
|
|
|
```text
|
|
0.2.4-pre.001-fix.001
|
|
workspace.package.version = "0.2.4-pre.1"
|
|
```
|
|
|
|
Le plan canonique est `docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md` version 2. Le fix `pre.001-fix.001` est appliqué avant cette tranche ; les deltas historiques `pre.001.md` et `pre.001-fix.001.md` restent inchangés.
|
|
|
|
## Objectif
|
|
|
|
Installer les primitives, configurations et résultats partagés nécessaires aux 10 wrappers Blocks et 5 wrappers Economics de `0.2.4`, ainsi que leurs fixtures wire locales déterministes, sans encore implémenter les wrappers prévus à partir de `pre.003` et sans déclarer la couverture typed `V0_2_4` complète.
|
|
|
|
Cette tranche matérialise dès maintenant les exigences `KSP-TRANSPORT-007` qui appartiennent au wire partagé : omissions/null explicites, versions de transaction numériques génériques, reward partitions SIMD-0118, commissions basis-points SIMD-0291, adresses RPC typées en `Pubkey` et sous-arbres Transaction riches conservés losslessly.
|
|
|
|
## Version Cargo
|
|
|
|
Conformément à `VER-ID-009`, la nouvelle prerelease synchronise le signal technique :
|
|
|
|
```text
|
|
0.2.4-pre.1 -> 0.2.4-pre.2
|
|
```
|
|
|
|
Aucune dépendance ni feature Cargo n'est ajoutée ou modifiée.
|
|
|
|
## Implémentation
|
|
|
|
### Module Blocks partagé
|
|
|
|
Le nouveau module privé `rpc_blocks` ajoute les types publics suivants, réexportés explicitement depuis la racine de crate :
|
|
|
|
```text
|
|
SolanaTransactionDetails
|
|
SolanaGetBlockConfig
|
|
SolanaBlockProductionRange
|
|
SolanaBlockProductionConfig
|
|
SolanaBlockCommitment
|
|
SolanaBlockProductionResultRange
|
|
SolanaBlockProduction
|
|
SolanaBlockReward
|
|
SolanaBlockTransaction
|
|
SolanaConfirmedBlock
|
|
SolanaPerformanceSample
|
|
```
|
|
|
|
`SolanaTransactionDetails` couvre exactement les quatre valeurs wire modernes :
|
|
|
|
```text
|
|
full
|
|
signatures
|
|
none
|
|
accounts
|
|
```
|
|
|
|
`SolanaGetBlockConfig` conserve indépendamment les cinq options du contrat moderne :
|
|
|
|
```text
|
|
commitment
|
|
encoding
|
|
transactionDetails
|
|
maxSupportedTransactionVersion
|
|
rewards
|
|
```
|
|
|
|
Aucune validation de commitment ni aucun choix de forme legacy n'est encore exécuté ici : ces responsabilités appartiennent au wrapper `getBlock` de `pre.006`.
|
|
|
|
`SolanaBlockProductionConfig` conserve `commitment`, une `identity` typée `Pubkey` et une range `firstSlot/lastSlot?`. La validation `lastSlot >= firstSlot` reste volontairement réservée au wrapper `getBlockProduction` de `pre.005`.
|
|
|
|
`SolanaBlockProduction` décode les clés dynamiques de `byIdentity` en `Pubkey` et conserve les couples `(leader slots, blocks produced)` ainsi que la range effective retournée par le runtime. Le futur wrapper appliquera le `SolanaRpcResponse<T>` partagé autour de ce résultat.
|
|
|
|
### Wire `getBlock`
|
|
|
|
`SolanaConfirmedBlock` est un DTO bloc dédié et ne réutilise pas `SolanaConfirmedTransaction`, dont `slot` et `blockTime` sont propres au top-level de `getTransaction`.
|
|
|
|
Le bloc conserve :
|
|
|
|
```text
|
|
previousBlockhash
|
|
blockhash
|
|
parentSlot
|
|
transactions
|
|
signatures
|
|
rewards
|
|
numRewardPartitions
|
|
blockTime
|
|
blockHeight
|
|
```
|
|
|
|
Les champs conditionnels `transactions`, `signatures`, `rewards` et `numRewardPartitions` utilisent `SolanaWireField<T>` afin de préserver les trois états :
|
|
|
|
```text
|
|
Omitted
|
|
Null
|
|
Value(T)
|
|
```
|
|
|
|
`numRewardPartitions` couvre explicitement le wire associé à SIMD-0118 sans synthétiser une valeur `0` en cas d'omission ou de `null`.
|
|
|
|
`SolanaBlockTransaction` compose les primitives Transaction déjà acquises :
|
|
|
|
```text
|
|
SolanaEncodedTransaction
|
|
SolanaWireField<serde_json::Value> pour meta
|
|
SolanaWireField<SolanaTransactionVersion> pour version
|
|
```
|
|
|
|
Le décodeur interne `SolanaTransactionVersion::decode_wire` passe donc de privé à `pub(crate)` pour être réutilisé sans dupliquer la logique `legacy | u8`. Son comportement public reste inchangé. Une fixture `getBlock` porte volontairement la version numérique `1` afin d'empêcher une future régression qui bornerait artificiellement cette primitive à V0, conformément au watchpoint SIMD-0385.
|
|
|
|
`SolanaBlockReward` conserve :
|
|
|
|
```text
|
|
pubkey: Pubkey
|
|
lamports: i64
|
|
postBalance: u64
|
|
rewardType: String ou null
|
|
commission: u8 ou null
|
|
commissionBps: SolanaWireField<u16>
|
|
```
|
|
|
|
`commissionBps` couvre l'extension stable déjà exposée par le runtime pour SIMD-0291. `commission` et `commissionBps` restent indépendants ; Transport ne dérive jamais l'un depuis l'autre.
|
|
|
|
`rewardType` reste volontairement une chaîne nullable au niveau Transport. Cette tranche n'introduit pas une taxonomie économique KSP spéculative alors que les évolutions de reward semantics restent dans la watchlist, notamment SIMD-0123.
|
|
|
|
### Module Economics partagé
|
|
|
|
Le nouveau module privé `rpc_economics` ajoute et réexporte :
|
|
|
|
```text
|
|
SolanaInflationGovernor
|
|
SolanaInflationRate
|
|
SolanaInflationRewardConfig
|
|
SolanaInflationReward
|
|
SolanaSupplyConfig
|
|
SolanaSupply
|
|
```
|
|
|
|
`SolanaInflationGovernor` et `SolanaInflationRate` conservent directement les valeurs runtime `f64`/epoch sans reproduire localement les formules d'inflation.
|
|
|
|
`SolanaInflationRewardConfig` sérialise uniquement les options fournies :
|
|
|
|
```text
|
|
epoch
|
|
commitment
|
|
minContextSlot
|
|
```
|
|
|
|
`SolanaInflationReward` conserve `commission: Option<u8>` et `commissionBps: SolanaWireField<u16>` pour couvrir SIMD-0291 sans perdre la différence omission/null/présent du champ basis-points. La cardinalité et les `null` positionnels de la liste `getInflationReward` seront pris en charge par le wrapper de `pre.008`; le DTO de cette tranche représente uniquement une entrée non-null.
|
|
|
|
`SolanaSupplyConfig` utilise `Option<bool>` pour `excludeNonCirculatingAccountsList`. Cela distingue un champ omis d'un `false` explicitement envoyé, tout en laissant le runtime appliquer son défaut lorsque l'option est absente.
|
|
|
|
`SolanaSupply` convertit la liste ordonnée `nonCirculatingAccounts` en `Vec<Pubkey>` et échoue proprement si une clé retournée n'est pas une public key valide. Le futur wrapper réutilisera `SolanaRpcResponse<SolanaSupply>`.
|
|
|
|
### Frontières conservées
|
|
|
|
Cette prerelease n'ajoute aucun `impl HttpTransportPool` pour les 15 méthodes `V0_2_4`. Les nouveaux types sont donc uniquement des contrats wire/config/result partagés.
|
|
|
|
Le flux d'exécution reste inchangé :
|
|
|
|
```text
|
|
wrapper typed futur
|
|
-> descriptor central
|
|
-> execute_standard_rpc
|
|
-> pool/admission
|
|
-> executor HTTP
|
|
-> validation JSON-RPC
|
|
-> decode typed
|
|
```
|
|
|
|
Aucun client HTTP parallèle, aucune boucle de retry locale et aucune dépendance Solana RPC haut niveau ne sont introduits.
|
|
|
|
## Fixtures déterministes ajoutées
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/fixtures/http/block_commitment.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/block_production.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/confirmed_block.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/confirmed_block.omissions.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/performance_sample.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_governor.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_rate.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_reward.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/supply.v4_2_1.json
|
|
```
|
|
|
|
Elles couvrent notamment :
|
|
|
|
- block commitment présent et `null` ;
|
|
- `getBlockProduction.byIdentity` et la range effective ;
|
|
- bloc riche avec transaction version numérique `1` ;
|
|
- `meta` explicite `null` et version omise ;
|
|
- reward `commissionBps` présent puis omis ;
|
|
- `numRewardPartitions` présent, omis et explicitement `null` ;
|
|
- performance sample courant puis ancien sans `numNonVoteTransactions` ;
|
|
- inflation governor/rate ;
|
|
- liste inflation reward avec un `null` positionnel et les variantes `commissionBps` ;
|
|
- supply avec liste ordonnée de public keys.
|
|
|
|
## Tests ajoutés
|
|
|
|
`unit_tests/rpc_blocks.rs` ajoute **8 tests déterministes** couvrant configs, résultats, omissions/null, version transaction non nulle, extensions SIMD et validation des public keys.
|
|
|
|
`unit_tests/rpc_economics.rs` ajoute **6 tests déterministes** couvrant configs, inflation values, reward basis-points, `null` positionnel de fixture, supply ordonnée et invalid pubkey.
|
|
|
|
Les tests d'intégration ajoutent aussi :
|
|
|
|
- une canarie de surface publique qui vérifie que les 17 nouveaux types sont disponibles depuis la racine de crate ;
|
|
- une canarie de registre qui confirme que `V0_2_4` reste exactement composé des **10 Blocks + 5 Economics**, tous `Read / RetrySafe`, et que `getBlock` conserve son marqueur de forme legacy dépréciée sans prétendre que les wrappers existent déjà.
|
|
|
|
La canarie typed-complete `V0_2_4 == 15` reste volontairement fermée jusqu'aux tranches d'implémentation des wrappers.
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_economics.rs
|
|
crates/ksp-onchain-transport-lib/unit_tests/rpc_blocks.rs
|
|
crates/ksp-onchain-transport-lib/unit_tests/rpc_economics.rs
|
|
crates/ksp-onchain-transport-lib/fixtures/http/block_commitment.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/block_production.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/confirmed_block.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/confirmed_block.omissions.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/performance_sample.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_governor.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_rate.v4_2_1.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/inflation_reward.variants.json
|
|
crates/ksp-onchain-transport-lib/fixtures/http/supply.v4_2_1.json
|
|
deltas/0.2.4/pre.002.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/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/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md
|
|
crates/ksp-onchain-transport-lib/Cargo.toml
|
|
crates/ksp-onchain-transport-lib/README.md
|
|
crates/ksp-onchain-transport-lib/USAGE.md
|
|
crates/ksp-onchain-transport-lib/src/executor.rs
|
|
crates/ksp-onchain-transport-lib/src/rpc_method.rs
|
|
crates/ksp-config-lib/**
|
|
config/**
|
|
deltas/0.2.4/pre.001.md
|
|
deltas/0.2.4/pre.001-fix.001.md
|
|
```
|
|
|
|
Aucun ancien delta n'est réécrit. Aucun wrapper Blocks/Economics n'est avancé prématurément.
|
|
|
|
## Validations exécutées dans le sandbox
|
|
|
|
- reconstruction exacte de la base `v0.2.3` puis application des overlays `0.2.4-pre.001` et `0.2.4-pre.001-fix.001` ;
|
|
- contrôle différentiel de la tranche `pre.002` contre cette base ;
|
|
- recoupement ciblé des configs/résultats avec la baseline Agave `v4.2.1` retenue par le plan ;
|
|
- parse JSON local des neuf nouvelles fixtures ;
|
|
- contrôle statique des 17 réexports crate-root ;
|
|
- contrôle statique que chaque nouveau item `pub`/`pub(crate)` de production possède sa documentation ;
|
|
- contrôle statique de l'absence de `impl HttpTransportPool` dans les nouveaux modules ;
|
|
- contrôle statique de l'absence de `use`, `unwrap`, `expect`, `panic!` et opérateur `?` dans les deux nouvelles sources de production ;
|
|
- contrôle statique des lignes Rust modifiées à `<= 160` colonnes ;
|
|
- contrôle différentiel de `Cargo.toml` : seul `workspace.package.version` change ;
|
|
- contrôle différentiel de `rpc_transactions.rs` : seule la version de fichier et la visibilité interne documentée de `SolanaTransactionVersion::decode_wire` changent ;
|
|
- contrôle que `CHANGELOG.md`, `ROADMAP.md`, le plan `011` version 2 et les deltas historiques restent inchangés.
|
|
|
|
## Validations Cargo non exécutées
|
|
|
|
Le sandbox courant ne fournit pas `cargo`, `rustc` ni `rustfmt`. Les commandes suivantes ne sont donc pas déclarées comme réussies et doivent être exécutées sur le checkout de développement avant commit :
|
|
|
|
```bash
|
|
cargo fmt --all
|
|
cargo check --workspace
|
|
cargo clippy --workspace --all-targets
|
|
cargo test -p ksp-onchain-transport-lib
|
|
```
|
|
|
|
Aucun `cargo tree` supplémentaire n'est requis par cette tranche puisqu'aucune dépendance ni feature n'a changé. Les graphes complets restent obligatoires à la clôture `pre.009`.
|
|
|
|
Le commit attendu après application et validations suit `VER-GIT-001` :
|
|
|
|
```text
|
|
v0.2.4-pre.002
|
|
```
|
|
|
|
## Décisions prises
|
|
|
|
- séparer physiquement les primitives Blocks et Economics dans deux modules Transport dédiés ;
|
|
- ne pas avancer de wrapper avant sa tranche propriétaire ;
|
|
- réutiliser `SolanaWireField<T>`, `SolanaEncodedTransaction` et `SolanaTransactionVersion` plutôt que dupliquer le wire Transaction ;
|
|
- ouvrir uniquement la visibilité interne de `SolanaTransactionVersion::decode_wire` sans modifier son API publique ;
|
|
- typer les identités/adresses RPC en `Pubkey` lorsqu'elles sont structurelles ;
|
|
- garder les sous-arbres Transaction/meta riches lossless via `serde_json::Value` ;
|
|
- garder `rewardType` ouvert au niveau Transport au lieu d'introduire une taxonomie économique prématurée ;
|
|
- distinguer `excludeNonCirculatingAccountsList` omis d'un `false` explicite ;
|
|
- intégrer dès les fixtures partagées SIMD-0118, SIMD-0291 et la canarie future-compatible SIMD-0385 ;
|
|
- ne pas modifier le plan `011`, aucune capacité stable additive n'ayant été découverte pendant cette tranche.
|
|
|
|
## Questions ouvertes
|
|
|
|
Aucune question bloquante pour `pre.003`.
|
|
|
|
## Suite
|
|
|
|
`0.2.4-pre.003` : implémenter les cinq wrappers Blocks simples avec requêtes JSON exactes et réponses typed :
|
|
|
|
```text
|
|
getBlockCommitment
|
|
getBlockHeight
|
|
getBlockTime
|
|
getFirstAvailableBlock
|
|
minimumLedgerSlot
|
|
```
|