v0.2.9-pre.010-fix.001

This commit is contained in:
2026-08-24 18:53:10 +02:00
parent 4568d94a62
commit 3198cc5666
6 changed files with 169 additions and 19 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 251
# version: 252
[workspace]
resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
[workspace.package]
version = "0.2.9-pre.10"
version = "0.2.9-pre.10.fix.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/src/grpc_stream.rs
// version: 2
// version: 3
use tonic_prost::prost::Message; // rust-rules: trait-import
@@ -488,14 +488,14 @@ impl ContinuityTracker {
}
if self.recent_set.insert(identity.clone()) {
self.recent_order.push_back(identity);
if self.recent_order.len() > MAX_RECENT_UPDATE_IDENTITIES {
if let std::option::Option::Some(oldest) = self.recent_order.pop_front() {
if self.recent_order.len() > MAX_RECENT_UPDATE_IDENTITIES
&& let std::option::Option::Some(oldest) = self.recent_order.pop_front()
{
self.recent_set.remove(&oldest);
}
}
}
}
}
#[allow(clippy::too_many_arguments)]
async fn run_subscribe_actor(
@@ -534,12 +534,12 @@ async fn run_subscribe_actor(
return;
},
};
if matches!(&update, crate::YellowstoneSubscribeUpdate::Ping(_)) {
if let std::result::Result::Err(code) = send_automatic_ping(&request_state, settings.max_outbound_message_size_bytes()) {
if matches!(&update, crate::YellowstoneSubscribeUpdate::Ping(_))
&& let std::result::Result::Err(code) = send_automatic_ping(&request_state, settings.max_outbound_message_size_bytes())
{
fail_actor(code, &request_state, &mut snapshot, &snapshot_tx);
return;
}
}
tracker.observe(&update, &mut snapshot);
snapshot_tx.send_replace(snapshot);
match update_tx.try_send(std::result::Result::Ok(update)) {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/src/lib.rs
// version: 43
// version: 44
#![warn(missing_docs)]
#![deny(unreachable_pub)]
@@ -42,8 +42,9 @@
//! JSON-RPC, error and constants modules.
//! `0.2.9-pre.007` completes the standard transaction/transaction-status filters and storage-wire projections; `pre.008` completes Blocks, block-meta and
//! entry projections. `0.2.9-pre.009` promotes those protobuf bridges into runtime and opens one KSP-owned bounded bidirectional `Subscribe` session with
//! request mutation, automatic server-Ping reply, observable Pong, normal server half-close, terminal backpressure and bounded graceful shutdown. Reconnect and
//! replay policy remain outside this tranche.
//! request mutation, automatic server-Ping reply, observable Pong, normal server half-close, terminal backpressure and bounded graceful shutdown.
//! `0.2.9-pre.010` activates the bounded KSP-owned reconnect policy, deterministic replay from the latest accepted request and highest observed slot,
//! conservative ReplayInfo-based continuity-gap observability and bounded duplicate observation without claiming exactly-once or lossless delivery.
mod constants;
mod error;

View File

@@ -0,0 +1,101 @@
<!-- file: deltas/0.2.9/pre.010-fix.001.md -->
<!-- version: 1 -->
# Delta `0.2.9-pre.010-fix.001` — Clippy reconnect + cohérence crate-root
## 1. Base
```text
0.2.9-pre.010
workspace.package.version = 0.2.9-pre.10
```
Le gate opérateur fourni confirme :
```text
cargo fmt --all PASS
python3 scripts/audit_rust_workspace_rules.py PASS / clean
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS + 2 warnings
Transport unit 383/383 PASS
Transport public_api 49/49 PASS
Transport release_completeness 43/43 PASS
Transport doctests 4/4 PASS
cargo test --workspace PASS
```
## 2. Motif
Deux `clippy::collapsible_if` subsistent dans `grpc_stream.rs` :
```text
ContinuityTracker::observe() éviction du cache borné
run_subscribe_actor() Ping -> send_automatic_ping
```
La revue de code détecte également une incohérence documentaire dans `src/lib.rs` : le commentaire crate-root reste au niveau `pre.009` et affirme encore que reconnect/replay sont hors tranche, alors que `pre.010` les a matérialisés.
## 3. Correctifs
### 3.1 Clippy
Les deux `if` imbriqués sont convertis en let-chains équivalentes. Aucun `#[allow(clippy::...)]` n'est ajouté.
Aucune sémantique n'est modifiée :
```text
cache duplicate toujours borné à 512 identités
Ping automatique même send_automatic_ping, mêmes erreurs terminales
reconnect inchangé
ReplayInfo/from_slot inchangés
gaps/duplicates compteurs inchangés
backpressure/shutdown inchangés
```
### 3.2 Documentation crate-root
`ksp-onchain-transport-lib/src/lib.rs` décrit maintenant explicitement `0.2.9-pre.010` : reconnect borné KSP-owned, reprise depuis le dernier request/slot observé, gap prudent via ReplayInfo et duplicates observables sans promesse exactly-once/lossless.
### 3.3 Signal de version
Le correctif touche du Rust ; conformément à `VER-ID-007`/`VER-ID-010` :
```text
workspace.package.version = 0.2.9-pre.10.fix.1
commit attendu = v0.2.9-pre.010-fix.001
```
## 4. Documentation de release
Mise à jour :
```text
docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md
docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md
```
Le premier gate opérateur et le statut du fix y sont enregistrés. `pre.011` reste explicitement non commencée avant fermeture sans warning du présent fix.
## 5. Frontières inchangées
```text
OUT fix.001 : Config V3 / PublicNode / provider facade
OUT 0.2.9 : SubscribeDeshred
aucune dépendance / feature Cargo ajoutée
aucun wire protobuf modifié
aucun contrat public reconnect/replay modifié
```
## 6. Gate opérateur attendu
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-core-lib --test workspace_dependencies
cargo test --workspace
```
Attendu : Clippy sans warning, Transport 383 unit / 49 public API / 43 release-completeness / 4 doctests et workspace vert. Aucun `cargo tree` supplémentaire n'est requis, le graphe Cargo étant inchangé.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 20 -->
<!-- version: 21 -->
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
> **Statut : `0.2.9-pre.009-fix.001` est fermé sur gate opérateur intégralement vert : fmt/audit/check/Clippy sans warning, Transport 379 unit + 48 public API + 42 completeness + 4 doctests, dependency canary et workspace PASS. `0.2.9-pre.010` est candidate pour le reconnect/replay KSP-owned, les gaps de couverture replay prouvés par ReplayInfo et les duplicates observables sans promesse lossless.**
> **Statut : `0.2.9-pre.010` a passé fmt/audit/check, Transport 383 unit + 49 public API + 43 completeness + 4 doctests et le workspace complet, mais le gate Clippy a remonté deux `collapsible_if`. `0.2.9-pre.010-fix.001` est candidate de fermeture : hygiène Clippy + correction de la description crate-root obsolète, sans changement de sémantique reconnect/replay. `pre.011` reste hors application tant que ce fix n'a pas repassé le gate opérateur sans warning.**
## 1. Objet, base et état d'ouverture
@@ -1418,3 +1418,20 @@ De même, KSP ne supprime pas les duplicates : il les observe autour du replay,
Couverture de divergence : les identités Block/BlockMeta incluent le blockhash ; deux histoires de même slot avec blockhash différent ne sont donc pas prises pour un duplicate. Aucune généralisation dequivocation nest annoncée pour les familles sans preuve de blockhash.
**Gate candidat :** fixture locale reconnect/replay, duplicate, gap de couverture replay, budget épuisé, mutation rejetée pendant reconnect et shutdown pendant backoff ; audit statique clean. Aucun changement de dépendance ou feature.
## 29. `pre.010-fix.001` — hygiène Clippy + synchronisation crate-root
Le premier gate opérateur de `pre.010` confirme le contrat reconnect/replay : fmt, audit Rust, check, Transport 383/383 unit, 49/49 public API, 43/43 release-completeness, 4/4 doctests et `cargo test --workspace` passent. Clippy termine avec succès mais remonte deux `collapsible_if` dans `grpc_stream.rs`.
Le correctif fusionne uniquement les deux conditions imbriquées signalées par Clippy : éviction du cache borné d'identités et réponse automatique au Ping Yellowstone. Aucun branchement, code d'erreur, borne, compteur, ordre de replay ou état lifecycle ne change.
La revue de code relève aussi une description crate-root restée au niveau `pre.009`, affirmant à tort que reconnect/replay sont encore hors tranche. `src/lib.rs` est synchronisé avec `pre.010` pour décrire le reconnect borné, la reprise `from_slot`, les gaps ReplayInfo et les duplicates observables sans promesse exactly-once/lossless.
Signal technique :
```text
workspace.package.version = 0.2.9-pre.10.fix.1
```
**Gate fix attendu :** fmt + audit + check + Clippy sans warning + Transport 383/49/43/4 + dependency canary + workspace. Aucune dépendance/feature n'ayant changé, aucun nouveau `cargo tree` n'est requis. `pre.011` ne commence qu'après ce gate.

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
<!-- version: 21 -->
<!-- version: 22 -->
# Validation `0.2.9` — moteur Yellowstone + standard Solana + PublicNode
> **Statut : `pre.009-fix.001` est fermé : fmt/audit/check/Clippy sans warning, Transport 379 unit + 48 public API + 42 completeness + 4 doctests, dependency canary et workspace PASS. `pre.010` est candidate reconnect/replay avec observabilité prudente des gaps/duplicates.**
> **Statut : `pre.010` est fonctionnellement vert sur le gate opérateur (383 unit + 49 public API + 43 completeness + 4 doctests, workspace PASS), avec deux warnings Clippy `collapsible_if`. `pre.010-fix.001` corrige ces warnings et la description crate-root restée au niveau `pre.009`; aucun changement reconnect/replay n'est introduit. Fermeture requise sans warning avant `pre.011`.**
## 1. Autorités du gate
@@ -979,3 +979,34 @@ La détection de gap n'utilise pas les sauts entre slots d'updates filtrés : un
Le cache de duplicates retient des identités minimales Account/Slot/Transaction/TransactionStatus/Block/BlockMeta/Entry. Il ne retient pas les payloads complets et ne supprime jamais un update. Pour Block/BlockMeta, le blockhash fait partie de l'identité afin de ne pas classer deux histoires divergentes de même slot comme un simple duplicate ; aucune détection globale d'equivocation n'est prétendue.
**Gate candidate attendu :** audit statique clean ; après exécution opérateur, Transport attendu autour de 383 unit / 49 public API / 43 release-completeness / 4 doctests. Aucune dépendance/feature changée, donc pas de `cargo tree` supplémentaire.
## 30. Gate `pre.010-fix.001` — Clippy + cohérence crate-root
Premier gate opérateur de `pre.010` :
| Gate | Résultat avant fix | Correctif `fix.001` |
|------------------------------------------|--------------------|----------------------------------------------|
| `cargo fmt --all` | PASS | à réexécuter |
| audit Rust workspace | PASS / clean | à réexécuter |
| `cargo check --workspace` | PASS | contrat inchangé |
| `cargo clippy --workspace --all-targets` | PASS + 2 warnings | deux `collapsible_if` fusionnés |
| Transport unit | 383/383 PASS | contrat attendu inchangé |
| Transport `public_api` | 49/49 PASS | contrat attendu inchangé |
| Transport `release_completeness` | 43/43 PASS | contrat attendu inchangé |
| Transport doctests | 4/4 PASS | contrat attendu inchangé |
| `cargo test --workspace` | PASS | contrat attendu inchangé |
| description crate-root | stale `pre.009` | synchronisée avec reconnect/replay `pre.010` |
Warnings observés :
```text
crates/ksp-onchain-transport-lib/src/grpc_stream.rs:491 clippy::collapsible_if
crates/ksp-onchain-transport-lib/src/grpc_stream.rs:537 clippy::collapsible_if
```
Le premier concerne uniquement l'éviction lorsque le cache d'identités dépasse 512 entrées ; le second uniquement le chemin `Ping -> send_automatic_ping`. Les let-chains produisent les mêmes conditions et les mêmes sorties qu'avant fix. Aucun `allow` Clippy n'est ajouté.
La revue de la sémantique `pre.010` ne révèle pas d'écart supplémentaire avec le contrat retenu : `from_slot = max(explicite, last_observed)`, ReplayInfo reste informatif, le clamp n'a lieu que si `first_available > requested`, les duplicates sont comptés mais livrés, et les non-promesses exactly-once/lossless restent explicites.
**Verdict candidate :** `pre.010-fix.001` est prête pour gate opérateur. `pre.011` reste TODO jusqu'à PASS sans warning.