From 3198cc566633148bf5c8cbedfdc5bfee7815b79f Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Mon, 24 Aug 2026 18:53:10 +0200 Subject: [PATCH] v0.2.9-pre.010-fix.001 --- Cargo.toml | 4 +- .../src/grpc_stream.rs | 20 ++-- crates/ksp-onchain-transport-lib/src/lib.rs | 7 +- deltas/0.2.9/pre.010-fix.001.md | 101 ++++++++++++++++++ .../plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md | 21 +++- .../validation/012-V0_2_9_YELLOWSTONE_GRPC.md | 35 +++++- 6 files changed, 169 insertions(+), 19 deletions(-) create mode 100644 deltas/0.2.9/pre.010-fix.001.md diff --git a/Cargo.toml b/Cargo.toml index 9f1aca3..13c58e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/crates/ksp-onchain-transport-lib/src/grpc_stream.rs b/crates/ksp-onchain-transport-lib/src/grpc_stream.rs index 49fe019..b74d55a 100644 --- a/crates/ksp-onchain-transport-lib/src/grpc_stream.rs +++ b/crates/ksp-onchain-transport-lib/src/grpc_stream.rs @@ -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,10 +488,10 @@ 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() { - self.recent_set.remove(&oldest); - } + 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); } } } @@ -534,11 +534,11 @@ 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()) { - fail_actor(code, &request_state, &mut snapshot, &snapshot_tx); - return; - } + 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); diff --git a/crates/ksp-onchain-transport-lib/src/lib.rs b/crates/ksp-onchain-transport-lib/src/lib.rs index 2470882..f8a8fdd 100644 --- a/crates/ksp-onchain-transport-lib/src/lib.rs +++ b/crates/ksp-onchain-transport-lib/src/lib.rs @@ -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; diff --git a/deltas/0.2.9/pre.010-fix.001.md b/deltas/0.2.9/pre.010-fix.001.md new file mode 100644 index 0000000..9ab17c3 --- /dev/null +++ b/deltas/0.2.9/pre.010-fix.001.md @@ -0,0 +1,101 @@ + + + +# 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é. diff --git a/docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md b/docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md index e78ac92..6ad96a9 100644 --- a/docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md +++ b/docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md @@ -1,9 +1,9 @@ - + # 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 d’equivocation n’est 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. + diff --git a/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md b/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md index 7dda050..106a04a 100644 --- a/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md +++ b/docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md @@ -1,9 +1,9 @@ - + # 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. +