v0.3.6-pre.005-fix.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 400
|
||||
# version: 401
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-solprices-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-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.3.6-pre.5"
|
||||
version = "0.3.6-pre.5.fix.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-job-backfill-lib/src/discovery.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Network-scoped identity of one discovered transaction candidate before canonical signature decoding.
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -262,7 +262,7 @@ where
|
||||
std::option::Option::None => return std::result::Result::Err(discovery_invalid("scope.address")),
|
||||
};
|
||||
let mut before = match request.scope().kind() {
|
||||
crate::BackfillScopeKind::BeforeAddress => request.scope().anchor().map(|value| value.as_str().to_owned()),
|
||||
crate::BackfillScopeKind::BeforeAddress => request.scope().anchor().map(|value| return value.as_str().to_owned()),
|
||||
crate::BackfillScopeKind::LatestAddress => std::option::Option::None,
|
||||
crate::BackfillScopeKind::AfterAddress | crate::BackfillScopeKind::ExplicitSignatures => {
|
||||
return std::result::Result::Err(discovery_invalid("scope.kind"));
|
||||
@@ -434,8 +434,7 @@ fn discovery_invalid(field: &'static str) -> ksp_core_lib::Error {
|
||||
}
|
||||
|
||||
fn discovery_stalled() -> ksp_core_lib::Error {
|
||||
return ksp_core_lib::Error::new(crate::ERROR_CODE_BACKFILL_DISCOVERY_STALLED, "Backfill discovery cursor did not advance")
|
||||
.with_context("field", "before");
|
||||
return ksp_core_lib::Error::new(crate::ERROR_CODE_BACKFILL_DISCOVERY_STALLED, "Backfill discovery cursor did not advance").with_context("field", "before");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -51,10 +51,10 @@ pub use self::request::BackfillSignature;
|
||||
pub use self::request::MAX_BACKFILL_CANDIDATES;
|
||||
/// Maximum number of concurrent transaction hydrations admitted by one Backfill request.
|
||||
pub use self::request::MAX_BACKFILL_HYDRATION_CONCURRENCY;
|
||||
/// Maximum number of `getSignaturesForAddress` pages admitted by one address Backfill request.
|
||||
pub use self::request::MAX_BACKFILL_PAGES;
|
||||
/// Maximum page size admitted for one `getSignaturesForAddress` request.
|
||||
pub use self::request::MAX_BACKFILL_PAGE_SIZE;
|
||||
/// Maximum number of `getSignaturesForAddress` pages admitted by one address Backfill request.
|
||||
pub use self::request::MAX_BACKFILL_PAGES;
|
||||
/// Maximum Base58 text length possible for one canonical 64-byte Solana signature.
|
||||
pub use self::request::MAX_BACKFILL_SIGNATURE_TEXT_BYTES;
|
||||
/// Minimum Base58 text length possible for one canonical 64-byte Solana signature.
|
||||
|
||||
@@ -43,16 +43,9 @@ fn pre_005_production_sources_keep_transport_and_store_in_their_owned_layers() {
|
||||
include_str!("../src/request.rs"),
|
||||
];
|
||||
for source in sources {
|
||||
for forbidden in [
|
||||
"ksp_config_lib::",
|
||||
"ksp_interface_lib::",
|
||||
"ksp_store_api::",
|
||||
"ksp_store_postgres_lib::",
|
||||
"reqwest::",
|
||||
"serde_json::",
|
||||
"std::env",
|
||||
"tonic::",
|
||||
] {
|
||||
for forbidden in
|
||||
["ksp_config_lib::", "ksp_interface_lib::", "ksp_store_api::", "ksp_store_postgres_lib::", "reqwest::", "serde_json::", "std::env", "tonic::"]
|
||||
{
|
||||
assert!(!source.contains(forbidden), "forbidden concrete Backfill path detected: {forbidden}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,14 +63,13 @@ impl super::SignaturePageSource for FakeSource {
|
||||
},
|
||||
std::result::Result::Err(_) => {
|
||||
return std::boxed::Box::pin(async {
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_BACKFILL_DISCOVERY_INVALID,
|
||||
"test page queue lock poisoned",
|
||||
));
|
||||
return std::result::Result::Err(ksp_core_lib::Error::new(crate::ERROR_CODE_BACKFILL_DISCOVERY_INVALID, "test page queue lock poisoned"));
|
||||
});
|
||||
},
|
||||
};
|
||||
return std::boxed::Box::pin(async move { return std::result::Result::Ok(page); });
|
||||
return std::boxed::Box::pin(async move {
|
||||
return std::result::Result::Ok(page);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,10 +222,7 @@ async fn pre_005_after_page_bound_is_partial_and_does_not_claim_anchor_completio
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let source = FakeSource::new(std::vec![
|
||||
std::vec![page_entry('7', 70), page_entry('6', 60)],
|
||||
std::vec![page_entry('5', 50), page_entry('4', 40)],
|
||||
]);
|
||||
let source = FakeSource::new(std::vec![std::vec![page_entry('7', 70), page_entry('6', 60)], std::vec![page_entry('5', 50), page_entry('4', 40)],]);
|
||||
let result = super::discover_with_source(&source, &request).await;
|
||||
let discovery = match result {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -127,18 +127,8 @@ fn pre_005_request_bounds_are_exact_and_explicit_context_is_rejected() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let explicit_with_context = crate::BackfillRequest::new(
|
||||
job_id,
|
||||
network,
|
||||
role,
|
||||
crate::BackfillCommitment::Confirmed,
|
||||
explicit_scope,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
std::option::Option::Some(10),
|
||||
);
|
||||
let explicit_with_context =
|
||||
crate::BackfillRequest::new(job_id, network, role, crate::BackfillCommitment::Confirmed, explicit_scope, 1, 1, 1, 1, std::option::Option::Some(10));
|
||||
assert!(explicit_with_context.is_err());
|
||||
return;
|
||||
}
|
||||
|
||||
129
deltas/0.3.6/pre.005-fix.001.md
Normal file
129
deltas/0.3.6/pre.005-fix.001.md
Normal file
@@ -0,0 +1,129 @@
|
||||
<!-- file: deltas/0.3.6/pre.005-fix.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.6-pre.005-fix.001` — return explicite du curseur Before
|
||||
|
||||
## Base requise
|
||||
|
||||
```text
|
||||
0.3.6-pre.005 appliquée
|
||||
workspace.package.version = 0.3.6-pre.5
|
||||
```
|
||||
|
||||
Le gate opérateur fourni pour `pre.005` confirme :
|
||||
|
||||
```text
|
||||
cargo fmt --all PASS
|
||||
python3 scripts/audit_rust_workspace_rules.py PASS / clean
|
||||
python3 scripts/audit_markdown_tables.py ... PASS / clean (264 tables / 147 fichiers)
|
||||
cargo check --workspace PASS
|
||||
cargo clippy --workspace --all-targets FAIL / clippy::implicit_return
|
||||
cargo test -p ksp-job-backfill-lib PASS
|
||||
unitaires 11 PASS
|
||||
dependency_boundary 2 PASS
|
||||
public_api 2 PASS
|
||||
release_completeness 2 PASS
|
||||
cargo tree -p ksp-job-backfill-lib --edges normal exécuté
|
||||
cargo tree -p ksp-job-backfill-lib -e features exécuté
|
||||
```
|
||||
|
||||
## Objectif
|
||||
|
||||
Corriger exclusivement l'écart Clippy `implicit_return` dans la closure privée qui construit le curseur initial `before` du scope `BeforeAddress`, sans modifier la sémantique de découverte de `pre.005`.
|
||||
|
||||
## Cause exacte
|
||||
|
||||
Dans `crates/ksp-job-backfill-lib/src/discovery.rs`, `discover_older` initialise le curseur optionnel à partir de l'ancre du scope :
|
||||
|
||||
```rust
|
||||
crate::BackfillScopeKind::BeforeAddress => request.scope().anchor().map(|value| value.as_str().to_owned()),
|
||||
```
|
||||
|
||||
Le workspace interdit les retours implicites via `-D clippy::implicit-return`. La closure de `Option::map` doit donc rendre son résultat avec un `return` explicite.
|
||||
|
||||
Le correctif est strictement syntaxique :
|
||||
|
||||
```rust
|
||||
crate::BackfillScopeKind::BeforeAddress => request.scope().anchor().map(|value| return value.as_str().to_owned()),
|
||||
```
|
||||
|
||||
La valeur obtenue, l'exclusivité de l'ancre, l'ordre de pagination, la déduplication, les bornes et tous les contrats publics restent identiques.
|
||||
|
||||
## Version
|
||||
|
||||
Le fix modifie un fichier Rust. Conformément au workflow de version :
|
||||
|
||||
```text
|
||||
workspace.package.version = 0.3.6-pre.5.fix.1
|
||||
delivery = 0.3.6-pre.005-fix.001
|
||||
commit = v0.3.6-pre.005-fix.001
|
||||
```
|
||||
|
||||
Aucun tag prerelease.
|
||||
|
||||
## Fichiers ajoutés
|
||||
|
||||
```text
|
||||
deltas/0.3.6/pre.005-fix.001.md
|
||||
```
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-job-backfill-lib/src/discovery.rs
|
||||
docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md
|
||||
docs/validation/023-V0_3_6_JOB_API_BACKFILL.md
|
||||
```
|
||||
|
||||
## Fichiers supprimés
|
||||
|
||||
Aucun.
|
||||
|
||||
## Invariants préservés
|
||||
|
||||
- identité transactionnelle/candidate toujours `(RawNetworkId, signature)` ;
|
||||
- provider, endpoint, protocole et rôle Transport restent hors identité ;
|
||||
- aucune modification des quatre scopes, de leurs bornes ou du fingerprint ;
|
||||
- aucune modification du chemin `HttpTransportPool::get_signatures_for_address` ;
|
||||
- aucune nouvelle dépendance, feature, crate, API publique ou test ;
|
||||
- aucune ouverture de RAW, persistance, checkpoint, runtime, README, USAGE, CHANGELOG, ROADMAP ou prompt.
|
||||
|
||||
## Validations exécutées pour l'assemblage du fix
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
-> General Rust rule audit: clean
|
||||
-> Rust export completeness audit: 0 candidate(s)
|
||||
-> KSP workspace Rust rule audit: clean
|
||||
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.6
|
||||
-> Markdown table audit: clean (264 tables / 148 fichiers)
|
||||
```
|
||||
|
||||
Le diff par rapport à `pre.005` est limité aux quatre fichiers modifiés ci-dessus et au présent delta.
|
||||
|
||||
## Validations non exécutées
|
||||
|
||||
L'environnement d'assemblage ne fournit ni `cargo` ni `rustfmt`. Le gate Rust du fix n'est donc pas annoncé comme vert localement.
|
||||
|
||||
Aucun smoke réseau ou PostgreSQL n'est pertinent pour ce correctif Clippy.
|
||||
|
||||
## Gate opérateur demandé
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
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.6
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-job-backfill-lib
|
||||
cargo tree -p ksp-job-backfill-lib --edges normal
|
||||
cargo tree -p ksp-job-backfill-lib -e features
|
||||
```
|
||||
|
||||
Résultat attendu : les onze tests unitaires et six canaries d'intégration restent verts, Clippy devient vert et le graphe de dépendances reste inchangé.
|
||||
|
||||
## Questions ouvertes
|
||||
|
||||
Aucune. `pre.006` reste interdit tant que ce gate de fix n'est pas intégralement vert.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Plan v0.3.6 — Job API et premier backfill RAW
|
||||
|
||||
@@ -434,13 +434,19 @@ Les tests couvrent le succès direct `null`, la surface publique et surtout un r
|
||||
|
||||
### `pre.005` — Fondation Backfill et découverte
|
||||
|
||||
**Statut : matérialisé ; gate opérateur à rejouer.**
|
||||
**Statut : réalisé ; corrigé par `pre.005-fix.001`, gate opérateur du fix à rejouer.**
|
||||
|
||||
Budget cible : **15-20 min**. Entrée : Transport observé stable et gate `pre.004` vert. La tranche crée `ksp-job-backfill-lib` avec dépendances directes Job API, Core, Logging, Onchain Transport, Store façade sans feature backend imposée et SHA-256 déjà centralisé au workspace ; Tokio reste uniquement une dev-dependency pour les tests async de cette tranche.
|
||||
|
||||
La requête impose explicitement `JobId`, `RawNetworkId`, rôle HTTP, engagement `Confirmed|Finalized`, scope, page size `1..=1000`, pages `1..=10000`, candidats `1..=10000`, future concurrence d'hydratation `1..=64` et `min_context_slot` seulement pour les scopes adresse. Les quatre scopes sont matérialisés. Les signatures explicites sont bornées, Base58-shaped et dédupliquées à première occurrence ; le décodage exact vers 64 octets reste volontairement `pre.006`.
|
||||
|
||||
`BackfillCandidateIdentity` est explicitement `(RawNetworkId, BackfillSignature)` ; rôle/provider/endpoint/protocole sont exclus du fingerprint de scope et ne peuvent donc pas devenir une identité transactionnelle. La découverte réelle appelle uniquement `HttpTransportPool::get_signatures_for_address`, sans client, retry, pacing ou endpoint policy dans Job. Latest/Before paginent par `before`, After conserve la fenêtre plus récente la plus proche de l'ancre via `until`, et les limites de pages produisent un résultat partiel observable plutôt qu'une fausse complétion. Les doubles déterministes restent privés aux tests. La tranche matérialise 11 tests unitaires et 6 canaries d’intégration ; leur exécution Cargo reste une preuve opérateur. Sortie attendue après gate : latest, before, after et explicite, déduplication stable, frontières partielles et firewall de dépendances verts.
|
||||
`BackfillCandidateIdentity` est explicitement `(RawNetworkId, BackfillSignature)` ; rôle/provider/endpoint/protocole sont exclus du fingerprint de scope et ne peuvent donc pas devenir une identité transactionnelle. La découverte réelle appelle uniquement `HttpTransportPool::get_signatures_for_address`, sans client, retry, pacing ou endpoint policy dans Job. Latest/Before paginent par `before`, After conserve la fenêtre plus récente la plus proche de l'ancre via `until`, et les limites de pages produisent un résultat partiel observable plutôt qu'une fausse complétion. Les doubles déterministes restent privés aux tests. Le gate opérateur exécute avec succès les 11 tests unitaires et les 6 canaries d’intégration, ainsi que `cargo check`; Clippy `--all-targets` révèle toutefois un unique écart de style `implicit_return` dans une closure privée de `discover_older`, corrigé par `pre.005-fix.001`.
|
||||
|
||||
#### `pre.005-fix.001` — Return explicite dans la closure du curseur Before
|
||||
|
||||
**Statut : matérialisé ; gate opérateur à rejouer.**
|
||||
|
||||
Le gate opérateur de `pre.005` confirme `cargo fmt`, les audits Rust/Markdown, `cargo check --workspace`, les 11 tests unitaires, les 6 canaries d’intégration et les arbres Cargo. `cargo clippy --workspace --all-targets` échoue uniquement sur `clippy::implicit_return` à la construction optionnelle du curseur `before` dans `discover_older`. Le fix remplace l'expression implicite de la closure par `return value.as_str().to_owned()` sans modifier la valeur produite, les branches de scope, la pagination ou le contrat public. Comme un fichier Rust est corrigé, la version workspace devient `0.3.6-pre.5.fix.1`.
|
||||
|
||||
### `pre.006` — Conversion RAW v1 et provenance
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/023-V0_3_6_JOB_API_BACKFILL.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Validation v0.3.6 — Job API et premier backfill RAW
|
||||
|
||||
@@ -57,6 +57,9 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
- [X] Gate opérateur de `pre.003-fix.001` : `cargo fmt`, audits Rust/Markdown, `cargo check`, Clippy, treize unitaires + quatorze canaries `ksp-job-api` et arbres Cargo normal/features verts.
|
||||
- [X] `pre.004` matérialise une voie observée additive de `getTransaction` sans modifier le client, les settings, le routage ni la politique de retry Transport ; gate opérateur vert.
|
||||
- [X] Le workspace comptait 14 crates avant `pre.005`; `ksp-job-backfill-lib` devient la 15e crate membre sans créer d'exécutable ni de Worker.
|
||||
- [X] Gate opérateur de `pre.005` : `cargo fmt`, audits Rust/Markdown et `cargo check --workspace` verts ; les 11 tests unitaires et 6 canaries `ksp-job-backfill-lib` sont verts.
|
||||
- [X] Le même gate révèle un unique échec Clippy `clippy::implicit_return` dans la closure privée qui dérive le curseur `before`; les arbres Cargo normal/features sont néanmoins exécutés et cohérents avec le graphe prévu.
|
||||
- [X] `pre.005-fix.001` ajoute uniquement le `return` explicite exigé dans cette closure et ne modifie ni valeur, ni pagination, ni identité réseau, ni dépendance, ni API publique.
|
||||
|
||||
## 4. Autorités et cohérence documentaire
|
||||
|
||||
@@ -97,7 +100,7 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
|
||||
## 7. Admission et portées
|
||||
|
||||
`pre.005` matérialise les contrats et leurs tests, mais les critères comportementaux ci-dessous restent ouverts jusqu'au gate Cargo opérateur. L'identité candidate est auditée statiquement comme `(RawNetworkId, signature)` ; rôle HTTP, provider, endpoint et protocole ne participent ni à cette identité ni au fingerprint sémantique du scope.
|
||||
`pre.005` matérialise les contrats et leurs tests. Le gate opérateur confirme les 11 unitaires et 6 canaries, tandis que Clippy impose un fix syntaxique sans effet comportemental avant clôture complète. L'identité candidate est `(RawNetworkId, signature)` ; rôle HTTP, provider, endpoint et protocole ne participent ni à cette identité ni au fingerprint sémantique du scope.
|
||||
|
||||
- [ ] `LatestAddress`, `BeforeAddress`, `AfterAddress` et `ExplicitSignatures` couverts.
|
||||
- [ ] Adresse validée par le type Core existant.
|
||||
@@ -190,12 +193,12 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique
|
||||
- [X] `ksp-job-backfill-lib` ne dépend pas de Config, App, Wallet, Program, Interface ou backend Store ; `ksp-store-lib` est consommée avec `default-features = false`.
|
||||
- [ ] Aucun retour de dépendance vers Job depuis les couches basses.
|
||||
- [X] Versions/features auditées : aucune nouvelle version externe ; `sha2` et `tokio` réutilisent les entrées workspace existantes, Tokio étant dev-only en `pre.005`.
|
||||
- [X] `pre.005` matérialise 11 tests unitaires et 6 canaries d’intégration ; leur exécution Cargo reste ouverte jusqu’au gate opérateur.
|
||||
- [X] `pre.005` matérialise 11 tests unitaires et 6 canaries d’intégration ; le gate opérateur les exécute tous avec succès.
|
||||
- [ ] `cargo fmt --all -- --check` vert.
|
||||
- [X] `scripts/audit_rust_workspace_rules.py` vert sur `pre.005` dans l'environnement d'assemblage.
|
||||
- [X] `scripts/audit_markdown_tables.py` vert sur `pre.005` dans l'environnement d'assemblage (264 tables / 147 fichiers, delta inclus).
|
||||
- [X] `scripts/audit_rust_workspace_rules.py` vert sur `pre.005` dans l'environnement d'assemblage et dans le gate opérateur.
|
||||
- [X] `scripts/audit_markdown_tables.py` vert sur `pre.005` dans le gate opérateur (264 tables / 147 fichiers, delta inclus).
|
||||
- [X] Contrats de fichiers de `FILE_CONTRACTS.md` vérifiés sur chaque ajout de `pre.001`.
|
||||
- [ ] `cargo check --workspace` vert.
|
||||
- [X] `cargo check --workspace` vert sur `pre.005`; le fix ne change qu'une closure privée refusée par Clippy.
|
||||
- [ ] `cargo clippy --workspace --all-targets --all-features -- -D warnings` vert.
|
||||
- [ ] `cargo test --workspace --all-targets --all-features` vert.
|
||||
- [ ] `cargo tree -d` examiné et doublons justifiés.
|
||||
|
||||
Reference in New Issue
Block a user