v0.3.14-pre.002-fix.001

This commit is contained in:
2026-09-11 20:00:56 +02:00
parent b2068e9ef2
commit 5932250314
4 changed files with 210 additions and 7 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 567
# version: 568
[workspace]
resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
[workspace.package]
version = "0.3.14-pre.2"
version = "0.3.14-pre.2.fix.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
// version: 1
// version: 2
/// Maximum number of simultaneously retained non-repaired run-local gaps.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS: usize = 64;
@@ -206,8 +206,9 @@ impl RawTransactionIngestGapLedger {
if !RawTransactionIngestGapReason::ALL.contains(&gap.reason) || !RawTransactionIngestGapState::ALL.contains(&gap.state) {
return std::result::Result::Err(crate::runtime_error("continuity.gap_catalog_invalid"));
}
if gap.range.start_slot() > gap.range.end_slot() {
return std::result::Result::Err(crate::runtime_error("continuity.gap_range_reversed"));
let range_validation = RawTransactionIngestGapRange::new(gap.range.start_slot(), gap.range.end_slot());
if let std::result::Result::Err(error) = range_validation {
return std::result::Result::Err(error);
}
}
if open_gap_count > crate::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
// version: 27
// version: 28
use sha2::Digest; // rust-rules: trait-import
@@ -2794,7 +2794,6 @@ fn standard_logs_live_source_key(
fn yellowstone_coverage_scope_fingerprint(request: &ksp_onchain_transport_lib::YellowstoneSubscribeRequest) -> ksp_core_lib::Result<[u8; 32]> {
let mut normalized = request.clone();
normalized.set_commitment(std::option::Option::None);
normalized.set_from_slot(std::option::Option::None);
normalized.set_ping(std::option::Option::None);
let identity = match normalized.identity() {
std::result::Result::Ok(value) => value,

View File

@@ -0,0 +1,203 @@
<!-- file: deltas/0.3.14/pre.002-fix.001.md -->
<!-- version: 1 -->
# Delta `0.3.14-pre.002-fix.001` — correction frontières replay et dead-code continuity
## Base requise
```text
0.3.14-pre.002
workspace.package.version = 0.3.14-pre.2
deltas/0.3.14/pre.002.md présent
```
## Objectif
Corriger strictement la tranche `pre.002` après le gate opérateur, sans étendre son périmètre fonctionnel :
```text
supprimer la mutation Worker du cursor Yellowstone from_slot
préserver la propriété Transport-owned replay
supprimer le dead_code de RawTransactionIngestGapRange::new sans suppression de validation ni lint bypass
conserver pre.002 sans repair I/O
```
## Défauts observés
Le gate opérateur sur `0.3.14-pre.2` a produit :
```text
cargo check --workspace : PASS avec 1 warning dead_code
cargo clippy --workspace --all-targets --all-features -- -D warnings : FAIL
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features : FAIL
```
Clippy :
```text
associated function `new` is never used
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs:102
-D dead-code implied by -D warnings
```
Test d'intégration :
```text
v0_3_12_pre_008_worker_observes_transport_reconnect_replay_and_faults_only_on_proven_retention_gap : FAIL
Worker took ownership of replay/repair responsibility: set_from_slot(
```
Les 114 unit tests du crate passaient avant l'échec du test de frontière.
## Cause
`pre.002` construisait le fingerprint de coverage Yellowstone en clonant la requête puis en supprimant :
```text
commitment
from_slot
ping
```
La suppression de `from_slot` appelait `YellowstoneSubscribeRequest::set_from_slot(None)` depuis `runtime_resources.rs`. Même sans I/O, cette mutation viole la frontière durable établie en `0.3.12-pre.008` : le Worker observe le replay Yellowstone mais ne possède ni ne modifie son cursor ; la responsabilité `from_slot` reste dans Transport.
Le constructeur privé `RawTransactionIngestGapRange::new` était par ailleurs appelé uniquement depuis les unit tests de `pre.002`, donc considéré mort dans la compilation normale de la bibliothèque.
## Correction
### Yellowstone coverage fingerprint
Le Worker continue de neutraliser uniquement les éléments communs qu'il peut traiter sans absorber la responsabilité replay :
```text
commitment -> retiré du fingerprint opaque, car porté séparément par TargetCoverage
ping -> retiré du fingerprint opaque, car non métier
from_slot -> conservé dans l'identité opaque Transport
```
Le Worker n'appelle plus `set_from_slot`.
Conserver `from_slot` dans l'identité rend la comparaison de deux scopes Yellowstone volontairement plus conservative : deux requêtes identiques métier mais portant des cursors replay différents peuvent rester distinctes. Cette différence ne peut pas broaden la coverage ni produire une fausse preuve de complétude. Une éventuelle identité Transport spécifiquement dédiée au scope métier relève d'une tranche Transport ultérieure, pas de ce fix.
Cette correction remplace donc la décision trop agressive de `pre.002` qui annonçait l'exclusion du cursor replay du fingerprint Worker.
### Gap range validation
`RawTransactionIngestGapLedger::validate_invariants()` réutilise maintenant `RawTransactionIngestGapRange::new(start_slot, end_slot)` pour revalider chaque plage retenue.
Cela :
```text
rend le constructeur vivant dans le code de production
conserve le rejet reversed
conserve le contrôle checked du span inclusif
ajoute au recheck du ledger la borne MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS
n'introduit aucun allow/expect dead_code
```
## Fichiers ajoutés
```text
deltas/0.3.14/pre.002-fix.001.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
```
## Fichiers supprimés
```text
aucun
```
## Version Cargo
Le fix modifie du code Rust ; conformément à `VER-ID-007` et `VER-ID-010` :
```text
header Cargo.toml : 567 -> 568
workspace.package.version : 0.3.14-pre.2 -> 0.3.14-pre.2.fix.1
```
Versions de fichiers :
```text
continuity.rs : 1 -> 2
runtime_resources.rs : 27 -> 28
```
## Frontières préservées
```text
aucun repair I/O
aucune nouvelle tâche
aucune nouvelle socket
aucun retry Worker
aucune nouvelle dépendance
aucune nouvelle feature
aucun accès Config depuis Worker
aucun accès Job Backfill depuis Worker
aucun backend Store physique depuis Worker
aucune mutation Worker de Yellowstone from_slot
```
## Validations exécutées
Dans le sandbox de préparation :
```text
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.14
scan statique de la frontière set_from_slot dans runtime_resources.rs
scan du constructeur RawTransactionIngestGapRange::new dans le chemin production
comparaison exacte pre.002 -> pre.002-fix.001
contrôle contenu archive delta
unzip -t archive delta
```
## Validations non exécutées
Le sandbox de préparation ne fournit pas le toolchain Cargo/Rust. Les gates suivants restent à exécuter côté opérateur :
```text
cargo fmt --all
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
```
Le test de frontière existant qui a détecté la régression n'est ni modifié ni assoupli.
## Décisions prises
```text
fix strict de pre.002, sans nouvelle responsabilité fonctionnelle
Transport reste propriétaire de from_slot/replay
le Worker privilégie une identité Yellowstone conservative plutôt qu'une normalisation interdite
le ledger revalide ses ranges via le constructeur canonique
aucun lint bypass n'est accepté pour dead_code
```
## Questions ouvertes
```text
aucune pour ce fix
```
## Gate opérateur après application
```bash
cargo fmt --all
cargo fmt --all -- --check
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
```