diff --git a/Cargo.toml b/Cargo.toml index 63d5e03..b5255a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 116 +# version: 117 [workspace] resolver = "3" members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib"] [workspace.package] -version = "0.2.2-pre.7" +version = "0.2.2-pre.7.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/crates/ksp-onchain-transport-lib/README.md b/crates/ksp-onchain-transport-lib/README.md index c44f2ef..22f4d2f 100644 --- a/crates/ksp-onchain-transport-lib/README.md +++ b/crates/ksp-onchain-transport-lib/README.md @@ -1,5 +1,5 @@ - + # `ksp-onchain-transport-lib` @@ -122,7 +122,7 @@ Deux smokes Devnet opt-in sont séparés par responsabilité : ```text Transport pur : settings programmatiques -> HttpTransportPool - -> getAccountInfo/getTokenSupply/getEpochInfo/getVoteAccounts + -> getAccountInfo/getTokenAccountsByOwner/getEpochInfo/getVoteAccounts Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool -> getHealth/getGenesisHash/getVersion/getBalance diff --git a/crates/ksp-onchain-transport-lib/USAGE.md b/crates/ksp-onchain-transport-lib/USAGE.md index 2305706..c32c1d8 100644 --- a/crates/ksp-onchain-transport-lib/USAGE.md +++ b/crates/ksp-onchain-transport-lib/USAGE.md @@ -1,5 +1,5 @@ - + # Utilisation de `ksp-onchain-transport-lib` @@ -161,7 +161,7 @@ Le smoke **Transport pur** construit ses settings programmatiquement et exerce u cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture ``` -Il appelle `getAccountInfo`, `getTokenSupply`, `getEpochInfo` et `getVoteAccounts`. Le mint utilisé par `getTokenSupply` est celui de l'exemple Devnet de la documentation officielle courante ; si cet état externe disparaît, le smoke doit être réaudité plutôt que transformé en test déterministe. +Il appelle `getAccountInfo`, `getTokenAccountsByOwner`, `getEpochInfo` et `getVoteAccounts`. La branche Token utilise le selector `programId` avec l'ID canonique du programme SPL Token et `System Program` comme owner valide ; une réponse vide reste acceptable. Le smoke valide ainsi la route Token sans dépendre de la persistance d'un mint ou d'un token account Devnet particulier. Le smoke historique de **composition Config -> Transport** reste également disponible : diff --git a/crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs b/crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs index f085654..609f8f5 100644 --- a/crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs +++ b/crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs @@ -1,9 +1,9 @@ // file: crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs -// version: 1 +// version: 2 //! Opt-in live Devnet smoke for the pure Transport Accounts/Tokens/Cluster path. -fn devnet_pool() -> ksp_onchain_transport_lib::HttpTransportPool { +fn devnet_pool() -> ksp_core_lib::Result { let role = ksp_onchain_transport_lib::HttpRoleName::new("default"); let role_settings = ksp_onchain_transport_lib::HttpEndpointRoleSettings::new( role, @@ -17,8 +17,11 @@ fn devnet_pool() -> ksp_onchain_transport_lib::HttpTransportPool { std::option::Option::None, ), ); - let endpoint_url = - ksp_onchain_transport_lib::HttpEndpointUrl::parse("https://api.devnet.solana.com").expect("official Solana Devnet endpoint URL must remain valid"); + let endpoint_url_result = ksp_onchain_transport_lib::HttpEndpointUrl::parse("https://api.devnet.solana.com"); + let endpoint_url = match endpoint_url_result { + std::result::Result::Ok(endpoint_url) => endpoint_url, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; let endpoint = ksp_onchain_transport_lib::HttpEndpointSettings::new( "solana_devnet_public", true, @@ -34,13 +37,13 @@ fn devnet_pool() -> ksp_onchain_transport_lib::HttpTransportPool { std::vec![endpoint], ksp_onchain_transport_lib::HttpRetrySettings::new(1, std::time::Duration::from_millis(250), std::time::Duration::from_secs(2)), ); - return ksp_onchain_transport_lib::HttpTransportPool::new(settings).expect("programmatic Devnet Transport settings must construct a pool"); + return ksp_onchain_transport_lib::HttpTransportPool::new(settings); } #[tokio::test(flavor = "current_thread")] #[ignore = "opt-in live Solana Devnet smoke; performs external network requests"] async fn programmatic_devnet_transport_reaches_accounts_tokens_and_cluster_wrappers() { - let pool = devnet_pool(); + let pool = devnet_pool().expect("programmatic Devnet Transport settings must construct a pool"); let role = ksp_onchain_transport_lib::HttpRoleName::new("default"); let account_config = ksp_onchain_transport_lib::SolanaAccountInfoConfig::new( @@ -56,16 +59,17 @@ async fn programmatic_devnet_transport_reaches_accounts_tokens_and_cluster_wrapp assert!(account.context().slot() > 0); assert!(account.value().is_some()); - // Current official getTokenSupply documentation uses this Devnet mint in its example. - let token_mint = "3wyAj7Rt1TWVPZVteFJPLa26JmLvdb1CAKEFZm3NY75E" + // Use the stable SPL Token program selector with a valid owner that need not own any token account. + // The smoke therefore validates the Token RPC path without depending on one mutable Devnet mint/account fixture. + let token_program = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" .parse::() - .expect("official Devnet token mint example must remain a valid Pubkey literal"); - let token_supply = pool - .get_token_supply(&role, &token_mint, std::option::Option::None) + .expect("canonical SPL Token program id must remain a valid Pubkey literal"); + let token_selector = ksp_onchain_transport_lib::SolanaTokenAccountSelector::ProgramId(token_program); + let token_accounts = pool + .get_token_accounts_by_owner(&role, &ksp_core_lib::PRGIDPK_SOLANA_SYSTEM, &token_selector, std::option::Option::None) .await - .expect("Devnet getTokenSupply smoke must succeed for the documented mint"); - assert!(token_supply.context().slot() > 0); - assert!(!token_supply.value().amount().is_empty()); + .expect("Devnet getTokenAccountsByOwner smoke must succeed with the canonical SPL Token program selector"); + assert!(token_accounts.context().slot() > 0); let epoch = pool .get_epoch_info( diff --git a/deltas/0.2.2/pre.007-fix.001.md b/deltas/0.2.2/pre.007-fix.001.md new file mode 100644 index 0000000..2c98432 --- /dev/null +++ b/deltas/0.2.2/pre.007-fix.001.md @@ -0,0 +1,162 @@ + + + +# Delta `v0.2.2-pre.007-fix.001` + +## Base + +Base attendue : + +```text +v0.2.2-pre.007 +``` + +Version Cargo de la base : + +```text +0.2.2-pre.7 +``` + +Ce fix modifie du Rust de test et synchronise donc le signal technique Cargo conformément à `VER-ID-007` / `VER-ID-010` : + +```text +0.2.2-pre.7.fix.1 +``` + +Le delta historique `deltas/0.2.2/pre.007.md` reste inchangé conformément à `KSP-REL-003` et `VER-DELTA-007`. + +## Motif du fix + +La validation opérateur du 2026-08-18 a révélé deux défauts du nouveau smoke Transport de `pre.007`. + +### 1. Clippy `expect_used` hors corps de test + +`cargo clippy --workspace --all-targets` échoue sur deux `expect()` placés dans le helper `devnet_pool()` : + +```text +HttpEndpointUrl::parse(...).expect(...) +HttpTransportPool::new(...).expect(...) +``` + +Le workspace autorise les assertions/`expect` dans les corps de tests via sa configuration Clippy, mais le helper non annoté comme test reste soumis à `expect_used = deny`. + +Correction : `devnet_pool()` retourne désormais `ksp_core_lib::Result` et propage explicitement l'erreur par `match`, sans `?`, `unwrap` ni `expect` dans le helper. + +### 2. Fixture live Token trop fragile + +L'exécution opt-in du smoke Transport a atteint Devnet mais `getTokenSupply` a renvoyé : + +```text +onchain_transport.rpc_application_error +rpc_code = -32602 +``` + +Le mint utilisé reste affiché par la documentation officielle courante, mais son état réel n'est donc pas une dépendance live suffisamment durable pour une gate de candidate KSP. + +Correction : la branche Token du smoke utilise désormais : + +```text +getTokenAccountsByOwner +owner = System Program (Pubkey valide et stable) +selector = programId +programId = SPL Token canonique (Tokenkeg...) +config = absent +``` + +Une liste vide est acceptable. Le test vérifie le contexte RPC et la traversée du wrapper Token sans dépendre de l'existence d'un mint ou d'un token account Devnet particulier. + +La documentation officielle `getTokenAccountsByOwner` confirme que le selector accepte `programId` et que la méthode cible Devnet. + +## Résultats opérateur de la base + +Avant ce fix, l'opérateur a communiqué : + +- `cargo fmt --all` : OK ; +- `cargo check --workspace` : OK ; +- `cargo clippy --workspace --all-targets` : **FAIL**, uniquement les deux `expect_used` ci-dessus ; +- `cargo test -p ksp-onchain-transport-lib` : 127 unit + 13 public API + 7 release completeness, OK ; smoke ignoré par défaut ; +- `cargo test -p ksp-config-lib` : OK ; +- `cargo test -p ksp-core-lib` : OK ; +- `cargo test -p ksp-app-config-desk` : OK ; +- `cargo test --workspace` : OK ; +- inspections `cargo tree` demandées : exécutées ; +- smoke Config -> Transport live : OK ; +- smoke Transport live : **FAIL** uniquement sur `getTokenSupply` avec RPC `-32602`. + +Ces échecs empêchent `pre.007` de devenir la base de `rel.001` sans fix. + +## Fichiers modifiés + +```text +Cargo.toml +crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs +crates/ksp-onchain-transport-lib/README.md +crates/ksp-onchain-transport-lib/USAGE.md +docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md +docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md +``` + +## Fichier ajouté + +```text +deltas/0.2.2/pre.007-fix.001.md +``` + +Aucun fichier supprimé. + +## Inchangé + +Ce fix ne modifie pas : + +- les 22 wrappers `0.2.2` ; +- les DTOs publics ; +- les descriptors ou politiques retry ; +- Config ; +- les fixtures HTTP déterministes ; +- les canaries de complétude ; +- les dépendances/features Cargo ; +- `ROADMAP.md` ; +- `CHANGELOG.md` ; +- le prompt `0.2.3` ; +- le delta historique `pre.007.md`. + +Le périmètre reste strictement la correction de la candidate `pre.007`. + +## Validations exécutées pendant la préparation + +Contrôles statiques exécutés : + +- version Cargo `0.2.2-pre.7.fix.1` ; +- versions de tous les fichiers modifiés incrémentées ; +- aucun `expect()` dans `devnet_pool()` ; +- absence du mint d'exemple `3wyAj7...` dans le smoke corrigé ; +- présence de `getTokenAccountsByOwner` + selector `ProgramId` ; +- aucune dépendance/feature ajoutée ; +- payload du fix limité aux sept fichiers listés ; +- archive réextraite et comparée au payload préparé. + +Cargo n'est pas disponible dans l'environnement de préparation. + +## Validations opérateur à rejouer + +```bash +cargo fmt --all +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-onchain-transport-lib +cargo test --workspace + +cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture +cargo test -p ksp-config-lib --test transport_devnet_smoke -- --ignored --nocapture +``` + +Résultat attendu : + +```text +clippy propre +127 unit + 13 public API + 7 release completeness OK +smoke Transport live OK +smoke Config -> Transport live OK +``` + +Si ces gates passent, `0.2.2-rel.001` peut rester strictement publicationnel comme prévu. diff --git a/docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md b/docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md index ade2ea5..cb409b6 100644 --- a/docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md +++ b/docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md @@ -1,5 +1,5 @@ - + # Plan `0.2.2` — HTTP Accounts + Tokens + Cluster @@ -478,7 +478,9 @@ future : 11 Transactions + 15 Blocks/Economics Le réaudit final du 2026-08-18 de `https://solana.com/docs/rpc/http` confirme toujours les 52 méthodes HTTP courantes et la même répartition des familles. La navigation Deprecated conserve les 14 méthodes historiques déjà enregistrées. Aucune méthode de `0.2.2` n'est déplacée ou reclassée. -Un smoke Devnet opt-in **propre à Transport** est ajouté sous `crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs`. Il construit ses settings programmatiquement et exerce `getAccountInfo`, `getTokenSupply`, `getEpochInfo` et `getVoteAccounts`. Le smoke historique `Config -> Transport` reste distinct et transitoirement hébergé dans Config. Les fixtures HTTP locales restent les preuves reproductibles par défaut. +Un smoke Devnet opt-in **propre à Transport** est ajouté sous `crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs`. Il construit ses settings programmatiquement et exerce `getAccountInfo`, `getTokenAccountsByOwner`, `getEpochInfo` et `getVoteAccounts`. La branche Token utilise le programme SPL Token canonique comme selector `programId` et n'exige aucun mint/token account Devnet persistant. Le smoke historique `Config -> Transport` reste distinct et transitoirement hébergé dans Config. Les fixtures HTTP locales restent les preuves reproductibles par défaut. + +`pre.007-fix.001` corrige la première exécution opérateur de ce smoke : le mint repris de l'exemple officiel `getTokenSupply` a renvoyé RPC `-32602` sur Devnet, et deux `expect()` dans le helper de construction violaient le gate Clippy. Le nouveau chemin Token évite cette dépendance d'état externe et le helper retourne explicitement le `Result` de construction. La matrice durable de clôture est `docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md` et le prompt suivant est `prompts/008-V0_2_3_START_PROMPT.md`. `CHANGELOG.md` reste réservé à `rel.001`. diff --git a/docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md b/docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md index beeb45b..b5a2337 100644 --- a/docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md +++ b/docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md @@ -1,5 +1,5 @@ - + # Validation finale `0.2.2` — HTTP Accounts + Tokens + Cluster @@ -143,7 +143,7 @@ Il construit `HttpTransportSettings` programmatiquement, sans Config ni environn ```text https://api.devnet.solana.com -> getAccountInfo(System Program) - -> getTokenSupply(mint de l'exemple Devnet officiel courant) + -> getTokenAccountsByOwner(System Program, selector programId = SPL Token) -> getEpochInfo -> getVoteAccounts ``` @@ -154,7 +154,9 @@ Exécution explicite : cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture ``` -Le test est `ignored` par défaut. Un incident réseau/rate-limit ou la disparition d'un état externe documenté doit être analysé séparément ; il ne remplace jamais les fixtures HTTP locales. +Le test est `ignored` par défaut. Sa branche Token ne dépend plus d'un mint d'exemple : elle accepte naturellement une liste vide et vérifie seulement qu'un appel Token structurellement valide atteint Devnet. Un incident réseau/rate-limit doit être analysé séparément ; le smoke ne remplace jamais les fixtures HTTP locales. + +Correction `pre.007-fix.001` : lors de la première passe opérateur de `pre.007`, `getTokenSupply` sur le mint d'exemple de la documentation a échoué avec le code RPC `-32602`. Le smoke Config -> Transport, lui, a réussi. La branche Token est donc volontairement passée à `getTokenAccountsByOwner` avec selector `programId`, qui ne requiert aucun mint mutable pour prouver la traversée live du wrapper Token. ## Smoke de composition Config -> Transport