v0.2.4-pre.002-fix.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 132
|
||||
# version: 133
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.2.4-pre.2"
|
||||
version = "0.2.4-pre.2.fix.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Transaction detail level accepted by modern `getBlock` requests.
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
|
||||
@@ -82,6 +82,7 @@ impl SolanaGetBlockConfig {
|
||||
}
|
||||
|
||||
/// Returns whether this config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none()
|
||||
&& self.encoding.is_none()
|
||||
@@ -92,6 +93,7 @@ impl SolanaGetBlockConfig {
|
||||
|
||||
/// Serializes this config to the exact Solana JSON-RPC object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(commitment) = self.commitment {
|
||||
@@ -141,6 +143,7 @@ impl SolanaBlockProductionRange {
|
||||
|
||||
/// Serializes this range to the exact Solana JSON-RPC object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
object.insert("firstSlot".to_owned(), serde_json::Value::Number(self.first_slot.into()));
|
||||
@@ -189,12 +192,14 @@ impl SolanaBlockProductionConfig {
|
||||
}
|
||||
|
||||
/// Returns whether this config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none() && self.identity.is_none() && self.range.is_none();
|
||||
}
|
||||
|
||||
/// Serializes this config to the exact Solana JSON-RPC object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(&self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(commitment) = self.commitment {
|
||||
@@ -231,6 +236,7 @@ impl SolanaBlockCommitment {
|
||||
}
|
||||
|
||||
/// Decodes a block-commitment result from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireBlockCommitment>(method, value);
|
||||
return match decoded {
|
||||
@@ -282,6 +288,7 @@ impl SolanaBlockProduction {
|
||||
}
|
||||
|
||||
/// Decodes a block-production result from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireBlockProduction>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -352,6 +359,7 @@ impl SolanaBlockReward {
|
||||
return &self.commission_bps;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireBlockReward>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -400,6 +408,7 @@ impl SolanaBlockTransaction {
|
||||
return &self.version;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireBlockTransaction>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -489,6 +498,7 @@ impl SolanaConfirmedBlock {
|
||||
}
|
||||
|
||||
/// Decodes a confirmed block from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireConfirmedBlock>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -561,6 +571,7 @@ impl SolanaPerformanceSample {
|
||||
}
|
||||
|
||||
/// Decodes one performance sample from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WirePerformanceSample>(method, value);
|
||||
return match decoded {
|
||||
@@ -576,6 +587,7 @@ impl SolanaPerformanceSample {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_block_transaction_version(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<serde_json::Value>,
|
||||
@@ -593,6 +605,7 @@ fn decode_block_transaction_version(
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_block_transactions(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<std::vec::Vec<serde_json::Value>>,
|
||||
@@ -613,6 +626,7 @@ fn decode_block_transactions(
|
||||
return std::result::Result::Ok(crate::SolanaWireField::Value(transactions));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_block_rewards(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<std::vec::Vec<serde_json::Value>>,
|
||||
@@ -633,6 +647,7 @@ fn decode_block_rewards(
|
||||
return std::result::Result::Ok(crate::SolanaWireField::Value(rewards));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireBlockCommitment {
|
||||
@@ -640,6 +655,7 @@ struct WireBlockCommitment {
|
||||
total_stake: u64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireBlockProductionRange {
|
||||
@@ -647,6 +663,7 @@ struct WireBlockProductionRange {
|
||||
last_slot: u64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireBlockProduction {
|
||||
@@ -654,6 +671,7 @@ struct WireBlockProduction {
|
||||
range: WireBlockProductionRange,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireBlockReward {
|
||||
@@ -668,6 +686,7 @@ struct WireBlockReward {
|
||||
commission_bps: crate::SolanaWireField<u16>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireBlockTransaction {
|
||||
@@ -678,6 +697,7 @@ struct WireBlockTransaction {
|
||||
version: crate::SolanaWireField<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireConfirmedBlock {
|
||||
@@ -696,6 +716,7 @@ struct WireConfirmedBlock {
|
||||
block_height: std::option::Option<u64>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WirePerformanceSample {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_economics.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Inflation-governor values returned by `getInflationGovernor`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@@ -43,6 +43,7 @@ impl SolanaInflationGovernor {
|
||||
}
|
||||
|
||||
/// Decodes an inflation-governor result from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireInflationGovernor>(method, value);
|
||||
return match decoded {
|
||||
@@ -93,6 +94,7 @@ impl SolanaInflationRate {
|
||||
}
|
||||
|
||||
/// Decodes an inflation-rate result from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireInflationRate>(method, value);
|
||||
return match decoded {
|
||||
@@ -142,12 +144,14 @@ impl SolanaInflationRewardConfig {
|
||||
}
|
||||
|
||||
/// Returns whether this config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.epoch.is_none() && self.commitment.is_none() && self.min_context_slot.is_none();
|
||||
}
|
||||
|
||||
/// Serializes this config to the exact Solana JSON-RPC object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(epoch) = self.epoch {
|
||||
@@ -212,6 +216,7 @@ impl SolanaInflationReward {
|
||||
}
|
||||
|
||||
/// Decodes one non-null inflation reward from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireInflationReward>(method, value);
|
||||
return match decoded {
|
||||
@@ -255,12 +260,14 @@ impl SolanaSupplyConfig {
|
||||
}
|
||||
|
||||
/// Returns whether this config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none() && self.exclude_non_circulating_accounts_list.is_none();
|
||||
}
|
||||
|
||||
/// Serializes this config to the exact Solana JSON-RPC object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(commitment) = self.commitment {
|
||||
@@ -308,6 +315,7 @@ impl SolanaSupply {
|
||||
}
|
||||
|
||||
/// Decodes a supply result from its Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireSupply>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -331,6 +339,7 @@ impl SolanaSupply {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireInflationGovernor {
|
||||
@@ -341,6 +350,7 @@ struct WireInflationGovernor {
|
||||
foundation_term: f64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireInflationRate {
|
||||
@@ -350,6 +360,7 @@ struct WireInflationRate {
|
||||
epoch: u64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireInflationReward {
|
||||
@@ -363,6 +374,7 @@ struct WireInflationReward {
|
||||
commission_bps: crate::SolanaWireField<u16>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireSupply {
|
||||
|
||||
159
deltas/0.2.4/pre.002-fix.001.md
Normal file
159
deltas/0.2.4/pre.002-fix.001.md
Normal file
@@ -0,0 +1,159 @@
|
||||
<!-- file: deltas/0.2.4/pre.002-fix.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.2.4-pre.002-fix.001` — suppression du code interne prématurément actif
|
||||
|
||||
## Base requise
|
||||
|
||||
Livraison précédente :
|
||||
|
||||
```text
|
||||
0.2.4-pre.002
|
||||
workspace.package.version = "0.2.4-pre.2"
|
||||
```
|
||||
|
||||
Ce fix corrige uniquement les warnings `dead_code` introduits par `pre.002` dans les nouveaux modules Blocks/Economics. Il ne redéfinit pas le périmètre fonctionnel de la prerelease et ne modifie ni les DTOs publics, ni les fixtures, ni les tests, ni le registre RPC.
|
||||
|
||||
## Problème observé
|
||||
|
||||
Les validations locales de `pre.002` ont montré que la tranche est fonctionnellement verte :
|
||||
|
||||
```text
|
||||
cargo fmt --all -> terminé
|
||||
cargo check --workspace -> terminé avec 29 warnings dead_code
|
||||
cargo clippy --workspace --all-targets -> terminé avec les mêmes 29 warnings dead_code
|
||||
cargo test -p ksp-onchain-transport-lib -> 196 unit tests OK
|
||||
20 public API tests OK
|
||||
15 release-completeness tests OK
|
||||
1 smoke Devnet ignoré comme prévu
|
||||
0 échec
|
||||
```
|
||||
|
||||
Les warnings proviennent exclusivement de helpers internes d'encodage/décodage et de structs `Wire*` préparés en `pre.002` pour les futurs wrappers, alors qu'aucun wrapper `V0_2_4` ne les consomme encore dans une compilation normale de la bibliothèque.
|
||||
|
||||
Le choix `#[allow(dead_code)]` est rejeté : le lint est correct et signale du code de production activé trop tôt.
|
||||
|
||||
## Correction
|
||||
|
||||
Les 17 contrats publics ajoutés par `pre.002` restent compilés et exportés normalement.
|
||||
|
||||
Seuls les éléments internes qui n'ont encore aucun consommateur runtime sont placés sous `#[cfg(test)]` :
|
||||
|
||||
- helpers `is_empty` des configs Blocks/Economics ;
|
||||
- helpers `to_json_value` des configs/ranges Blocks/Economics ;
|
||||
- décodeurs internes `decode_wire` des résultats Blocks/Economics ;
|
||||
- helpers privés de décodage des transactions/rewards de bloc ;
|
||||
- structs privées `WireBlock*`, `WirePerformanceSample` et `WireInflation*`/`WireSupply`.
|
||||
|
||||
Ils restent donc compilés par les unit tests de `pre.002`, qui continuent à valider les formes wire et les fixtures déterministes, mais ils ne participent plus au build normal de la crate tant qu'un wrapper runtime ne les utilise pas.
|
||||
|
||||
Cette approche garde le découpage des prereleases strict :
|
||||
|
||||
```text
|
||||
pre.002 -> contrats publics + fixtures + validation test-only des helpers wire
|
||||
pre.003+ -> activation progressive des helpers internes au moment où leur wrapper runtime existe
|
||||
```
|
||||
|
||||
À partir de `pre.003`, `SolanaBlockCommitment::decode_wire` sera sorti de `#[cfg(test)]` avec l'implémentation de `getBlockCommitment`. Les autres encodeurs/décodeurs seront activés uniquement dans la prerelease qui introduit leur consommateur.
|
||||
|
||||
Aucun `#[allow(dead_code)]` n'est ajouté.
|
||||
|
||||
## Version Cargo
|
||||
|
||||
Ce correctif modifie des sources Rust participant au build. Conformément à `VER-ID-007` et `VER-ID-010` :
|
||||
|
||||
```text
|
||||
0.2.4-pre.2 -> 0.2.4-pre.2.fix.1
|
||||
```
|
||||
|
||||
Aucune dépendance ni feature Cargo n'est modifiée.
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
|
||||
crates/ksp-onchain-transport-lib/src/rpc_economics.rs
|
||||
```
|
||||
|
||||
## Fichiers ajoutés
|
||||
|
||||
```text
|
||||
deltas/0.2.4/pre.002-fix.001.md
|
||||
```
|
||||
|
||||
## Fichiers supprimés
|
||||
|
||||
Aucun.
|
||||
|
||||
## Fichiers volontairement inchangés
|
||||
|
||||
```text
|
||||
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_blocks.rs
|
||||
crates/ksp-onchain-transport-lib/unit_tests/rpc_economics.rs
|
||||
crates/ksp-onchain-transport-lib/tests/public_api.rs
|
||||
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
||||
crates/ksp-onchain-transport-lib/fixtures/http/**
|
||||
docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md
|
||||
ROADMAP.md
|
||||
CHANGELOG.md
|
||||
deltas/0.2.4/pre.002.md
|
||||
```
|
||||
|
||||
Aucun delta historique n'est réécrit.
|
||||
|
||||
## Validations exécutées dans le sandbox
|
||||
|
||||
- contrôle différentiel contre la livraison `pre.002` ;
|
||||
- vérification que seuls les trois fichiers de production listés ci-dessus sont modifiés ;
|
||||
- contrôle que les 17 types publics de `pre.002` restent hors `#[cfg(test)]` ;
|
||||
- contrôle que tous les helpers et structs privés signalés `dead_code` par les validations locales sont maintenant test-only ;
|
||||
- contrôle de l'absence de `#[allow(dead_code)]` ;
|
||||
- contrôle de l'absence de `unwrap`, `expect`, `panic!` et `unsafe` dans les lignes modifiées ;
|
||||
- `git diff --check` sur le fix ;
|
||||
- contrôle des versions de fichiers modifiés.
|
||||
|
||||
## Validations Cargo non exécutées dans le sandbox
|
||||
|
||||
Le sandbox ne fournit pas `cargo`, `rustc` ni `rustfmt`. Les validations du fix doivent donc être rejouées sur le checkout de développement :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-onchain-transport-lib
|
||||
```
|
||||
|
||||
Le critère de clôture du fix est plus strict que pour la tentative initiale : `cargo check` et `cargo clippy` doivent terminer sans les 29 warnings `dead_code` introduits par `pre.002`.
|
||||
|
||||
Le commit attendu après validation est :
|
||||
|
||||
```text
|
||||
v0.2.4-pre.002-fix.001
|
||||
```
|
||||
|
||||
## Décisions prises
|
||||
|
||||
- conserver les DTOs publics actifs en production ;
|
||||
- rendre test-only uniquement l'infrastructure wire interne sans consommateur runtime ;
|
||||
- ne pas masquer les warnings avec `allow(dead_code)` ;
|
||||
- activer progressivement les helpers lors de l'arrivée de chaque wrapper ;
|
||||
- ne pas modifier le plan `011`, le périmètre fonctionnel restant identique.
|
||||
|
||||
## Questions ouvertes
|
||||
|
||||
Aucune.
|
||||
|
||||
## Suite
|
||||
|
||||
Après validation du fix, `0.2.4-pre.003` reste inchangé :
|
||||
|
||||
```text
|
||||
getBlockCommitment
|
||||
getBlockHeight
|
||||
getBlockTime
|
||||
getFirstAvailableBlock
|
||||
minimumLedgerSlot
|
||||
```
|
||||
Reference in New Issue
Block a user