0.3.15-pre.012-fix.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 622
|
# version: 623
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-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"]
|
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-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]
|
[workspace.package]
|
||||||
version = "0.3.15-pre.12"
|
version = "0.3.15-pre.12.fix.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-raw-transaction-ingest-desk/src/app_state.rs
|
// file: crates/ksp-app-raw-transaction-ingest-desk/src/app_state.rs
|
||||||
// version: 8
|
// version: 9
|
||||||
|
|
||||||
//! Shared backend state owned by the Raw Transaction Ingest Desk Tauri application.
|
//! Shared backend state owned by the Raw Transaction Ingest Desk Tauri application.
|
||||||
|
|
||||||
@@ -121,6 +121,7 @@ impl crate::AppState {
|
|||||||
if let std::result::Result::Err(error) = admission {
|
if let std::result::Result::Err(error) = admission {
|
||||||
return std::result::Result::Err(error);
|
return std::result::Result::Err(error);
|
||||||
}
|
}
|
||||||
|
let prepared = {
|
||||||
let generation = self.inventory_generation.lock();
|
let generation = self.inventory_generation.lock();
|
||||||
let generation = match generation {
|
let generation = match generation {
|
||||||
std::result::Result::Ok(value) => value,
|
std::result::Result::Ok(value) => value,
|
||||||
@@ -132,11 +133,11 @@ impl crate::AppState {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let prepared = crate::prepare_route_start(&self.config_management, *generation, request);
|
let prepared = crate::prepare_route_start(&self.config_management, *generation, request);
|
||||||
let prepared = match prepared {
|
match prepared {
|
||||||
std::result::Result::Ok(value) => value,
|
std::result::Result::Ok(value) => value,
|
||||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
std::mem::drop(generation);
|
|
||||||
return crate::start_route_runtime(std::sync::Arc::clone(&self.route_runtime), prepared).await;
|
return crate::start_route_runtime(std::sync::Arc::clone(&self.route_runtime), prepared).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-raw-transaction-ingest-desk/tests/desktop_contract.rs
|
// file: crates/ksp-app-raw-transaction-ingest-desk/tests/desktop_contract.rs
|
||||||
// version: 10
|
// version: 11
|
||||||
|
|
||||||
//! Desktop scaffold contract canaries for Raw Transaction Ingest Desk.
|
//! Desktop scaffold contract canaries for Raw Transaction Ingest Desk.
|
||||||
|
|
||||||
@@ -303,7 +303,8 @@ fn pre_012_window_shutdown_and_start_stop_races_are_bounded_backend_owned() {
|
|||||||
assert!(runtime.contains(required), "missing pre.012 route-race marker {required}");
|
assert!(runtime.contains(required), "missing pre.012 route-race marker {required}");
|
||||||
}
|
}
|
||||||
let app_state = read_text(app_root().join("src/app_state.rs").as_path());
|
let app_state = read_text(app_root().join("src/app_state.rs").as_path());
|
||||||
|
assert!(app_state.contains("let prepared = {"));
|
||||||
assert!(app_state.contains("let generation = self.inventory_generation.lock()"));
|
assert!(app_state.contains("let generation = self.inventory_generation.lock()"));
|
||||||
assert!(app_state.contains("std::mem::drop(generation)"));
|
assert!(!app_state.contains("std::mem::drop(generation)"));
|
||||||
assert!(app_state.contains("self.route_runtime.ensure_start_admission_open()"));
|
assert!(app_state.contains("self.route_runtime.ensure_start_admission_open()"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-raw-transaction-ingest-desk/unit_tests/route_runtime.rs
|
// file: crates/ksp-app-raw-transaction-ingest-desk/unit_tests/route_runtime.rs
|
||||||
// version: 4
|
// version: 5
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pre_009_multi_route_runtime_starts_without_workers_or_shared_store_material() {
|
fn pre_009_multi_route_runtime_starts_without_workers_or_shared_store_material() {
|
||||||
@@ -130,3 +130,14 @@ fn pre_012_application_shutdown_is_one_shot_and_marks_starting_routes_before_act
|
|||||||
assert!(matches!(inner.routes.first(), std::option::Option::Some(super::RouteRuntimeSlot::Starting { stop_requested: true, .. })));
|
assert!(matches!(inner.routes.first(), std::option::Option::Some(super::RouteRuntimeSlot::Starting { stop_requested: true, .. })));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_012_fix_001_start_route_future_is_send_for_tauri_command() {
|
||||||
|
fn assert_send_future<'a>(
|
||||||
|
state: &'a crate::AppState,
|
||||||
|
request: &'a crate::RawIngestRouteStartRequestDto,
|
||||||
|
) -> impl std::future::Future<Output = ksp_core_lib::Result<crate::RouteRuntimeLaunch>> + std::marker::Send + 'a {
|
||||||
|
return state.start_route(request);
|
||||||
|
}
|
||||||
|
let _assertion = assert_send_future;
|
||||||
|
}
|
||||||
|
|||||||
86
deltas/0.3.15/pre.012-fix.001.md
Normal file
86
deltas/0.3.15/pre.012-fix.001.md
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<!-- file: deltas/0.3.15/pre.012-fix.001.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.3.15-pre.012-fix.001`
|
||||||
|
|
||||||
|
## Base
|
||||||
|
|
||||||
|
```text
|
||||||
|
base archive : ksp-general-0.3.15-pre.012.zip
|
||||||
|
base SHA-256 : 627a1152e3c5d97517dfbe7de630ca47dc52fd2c3b7683a325b52cfea7291331
|
||||||
|
base version : 0.3.15-pre.12
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motif du fix
|
||||||
|
|
||||||
|
Le gate opérateur du 16 septembre 2026 a révélé un défaut de compilation dans la nouvelle protection stale-inventory de `pre.012`. `AppState::start_route` gardait un `std::sync::MutexGuard<u32>` dans la portée du futur jusqu'au `await` de `start_route_runtime`. Tauri exige un futur `Send` pour une commande async ; le Desk échouait donc à compiler avec :
|
||||||
|
|
||||||
|
```text
|
||||||
|
future returned by `start_route` is not `Send`
|
||||||
|
std::sync::MutexGuard<'_, u32> is not `Send`
|
||||||
|
```
|
||||||
|
|
||||||
|
Les audits Rust/Markdown étaient propres et les tests Worker continuaient de passer, mais `cargo check`, Clippy, les tests Desk/workspace et `cargo tauri dev` étaient bloqués par cette erreur.
|
||||||
|
|
||||||
|
## Correction
|
||||||
|
|
||||||
|
La préparation Start synchrone est maintenant enfermée dans une portée lexicale :
|
||||||
|
|
||||||
|
```text
|
||||||
|
let prepared = {
|
||||||
|
lock generation
|
||||||
|
revalidate + reconstruct Config/Transport
|
||||||
|
return prepared value
|
||||||
|
};
|
||||||
|
await start_route_runtime(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
Le guard de génération est ainsi détruit structurellement avant le premier `await`. La protection stale-inventory de `pre.012` est conservée : aucune nouvelle génération ne peut être publiée entre le contrôle et la reconstruction synchrones.
|
||||||
|
|
||||||
|
Un canari de compilation impose désormais `Future + Send` au futur `AppState::start_route`, et le canari desktop vérifie la portée lexicale au lieu d'accepter `std::mem::drop(generation)` comme preuve suffisante.
|
||||||
|
|
||||||
|
## Version
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version : 0.3.15-pre.12.fix.1
|
||||||
|
root Cargo header counter : 623
|
||||||
|
```
|
||||||
|
|
||||||
|
## Frontières
|
||||||
|
|
||||||
|
Aucun changement de comportement pour :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Start / Stop / shutdown
|
||||||
|
Config / Transport / Store
|
||||||
|
Worker / Common RAW
|
||||||
|
monitoring frontend
|
||||||
|
acquisition / replay / repair
|
||||||
|
IPC security contract
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation d'assemblage
|
||||||
|
|
||||||
|
Exécuté dans l'environnement d'assemblage : contrôles statiques ciblés du diff, inventaire du delta, intégrité ZIP et reconstruction byte-exact à partir de `pre.012`.
|
||||||
|
|
||||||
|
Cargo/rustfmt ne sont pas disponibles dans cet environnement. Les gates Cargo de ce fix restent à confirmer par l'opérateur.
|
||||||
|
|
||||||
|
## Inventaire exact du delta
|
||||||
|
|
||||||
|
Ajout :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.3.15/pre.012-fix.001.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Modifications :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
crates/ksp-app-raw-transaction-ingest-desk/src/app_state.rs
|
||||||
|
crates/ksp-app-raw-transaction-ingest-desk/tests/desktop_contract.rs
|
||||||
|
crates/ksp-app-raw-transaction-ingest-desk/unit_tests/route_runtime.rs
|
||||||
|
docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Suppressions : aucune.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
|
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
|
||||||
<!-- version: 22 -->
|
<!-- version: 23 -->
|
||||||
|
|
||||||
# Validation v0.3.15 — Raw Transaction Ingest Desk
|
# Validation v0.3.15 — Raw Transaction Ingest Desk
|
||||||
|
|
||||||
@@ -794,4 +794,13 @@ pre_012_race_shutdown_and_ipc_hardening_adds_no_production_module_or_lower_layer
|
|||||||
```
|
```
|
||||||
|
|
||||||
Non-claims : `pre.012` ne modifie ni Config, ni Transport, ni Store, ni `ksp-worker-raw-transaction-ingest-lib`, ni Common RAW. Il n'ajoute aucune orchestration Backfill, aucun scheduler, aucune route et aucune nouvelle donnée frontend. `pre.013` reste propriétaire de la fermeture completeness/security cross-layer.
|
Non-claims : `pre.012` ne modifie ni Config, ni Transport, ni Store, ni `ksp-worker-raw-transaction-ingest-lib`, ni Common RAW. Il n'ajoute aucune orchestration Backfill, aucun scheduler, aucune route et aucune nouvelle donnée frontend. `pre.013` reste propriétaire de la fermeture completeness/security cross-layer.
|
||||||
|
### `pre.012-fix.001` — future Tauri Start `Send`
|
||||||
|
|
||||||
|
Le gate opérateur de `pre.012` a arrêté la tranche sur un défaut de compilation déterministe dans `AppState::start_route` : le `std::sync::MutexGuard<u32>` de `inventory_generation` restait considéré vivant au franchissement du `await` final, malgré `std::mem::drop(generation)`. Le futur exposé par la commande Tauri `start_route` ne satisfaisait donc plus la borne `Send` imposée par `tauri::ipc::ResultFutureTag::future`. Les audits Rust/Markdown étaient propres et les suites Worker indépendantes restaient vertes, mais `cargo check`, Clippy, les tests Desk/workspace et `cargo tauri dev` ne pouvaient pas compiler le Desk.
|
||||||
|
|
||||||
|
Le fix ne change aucune sémantique Start/Stop. Lock + revalidation/préparation synchrones sont désormais enfermés dans une portée lexicale `let prepared = { ... };`. Le `MutexGuard` est donc détruit structurellement à la fin du bloc avant tout `await`. Le contrat stale-inventory de `pre.012` reste inchangé : la génération demeure verrouillée pendant toute la reconstruction synchrone, mais aucun guard non-`Send` ne traverse une suspension asynchrone.
|
||||||
|
|
||||||
|
Un canari de compilation `pre_012_fix_001_start_route_future_is_send_for_tauri_command` impose explicitement le type `Future<...> + Send` au futur retourné par `AppState::start_route`. Le canari desktop vérifie également la portée lexicale et interdit le retour au simple `std::mem::drop(generation)` comme preuve de lifetime.
|
||||||
|
|
||||||
|
Non-claims : aucune modification de route, Config, Transport, Store, Worker, Common RAW, monitoring, shutdown ou sécurité IPC.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user