v0.3.15-pre.006-fix.002

This commit is contained in:
2026-09-13 16:34:18 +02:00
parent f3ed86e54c
commit f12e67bdc7
10 changed files with 180 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-config-lib/USAGE.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Utilisation de ksp-config-lib
@@ -164,7 +164,7 @@ L'accesseur historique `into_transport_settings()` conserve volontairement son t
Les protocoles WebSocket restent `kind = "solana_standard"` et `kind = "helius_laserstream"`. Chaque endpoint peut en plus déclarer `capabilities`, liste de descriptors `WsSubscriptionKind` (`account`, `block`, `logs`, `program`, `root`, `signature`, `slot`, `slots_updates`, `vote`, `helius_transaction`). L'absence de cette liste reste backward-compatible mais ne constitue aucune preuve de support ; une liste présente est mappée explicitement vers Transport puis validée contre le protocole. Config ne déduit jamais une capability depuis `provider`.
Les profils Solana standard versionnés déclarent conservativement les six familles stables `account/logs/program/root/signature/slot` et ne déclarent donc pas `block`. Le profil `testnet_public` fournit le socle HTTP + WS standard Testnet sans credential ; `publicnode_testnet` reste une source Yellowstone optionnelle séparée. Les profils `helius_devnet` et `helius_mainnet` déclarent les sept familles Helius déjà supportées par la façade (`account/logs/program/root/signature/slot/slots_updates`) plus `helius_transaction`, sans `block` ni `vote`. Helius LaserStream WebSocket conserve ses URLs Config-owned et sa clé `KSP_SECRET_HELIUS_API_KEY`; cette surface est indépendante de Yellowstone gRPC.
Les profils Solana standard publics versionnés déclarent `account/block/logs/program/root/signature/slot`. `block` reste une capability explicite, instable et validator/provider-gated : Config ne linfère jamais du protocol kind ni du provider, mais les endpoints publics committés lannoncent désormais explicitement pour rendre la route Standard Block composable. Le profil `testnet_public` fournit le socle HTTP + WS standard Testnet sans credential ; `publicnode_testnet` reste une source Yellowstone optionnelle séparée. Les profils `helius_devnet` et `helius_mainnet` déclarent les sept familles Helius déjà supportées par la façade (`account/logs/program/root/signature/slot/slots_updates`) plus `helius_transaction`, sans `block` ni `vote`. Helius LaserStream WebSocket conserve ses URLs Config-owned et sa clé `KSP_SECRET_HELIUS_API_KEY`; cette surface est indépendante de Yellowstone gRPC.
Les scalaires `*_ms` restent des valeurs Config et sont convertis en `std::time::Duration` par l'adapter. La dépendance reste unidirectionnelle : Config connaît les contrats Transport pour les construire ; Transport ne connaît ni Config, ni `.env`, ni les variables KSP.

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-config-lib/unit_tests/transport.rs
// version: 15
// version: 16
#[test]
fn fixture_transport_profile_maps_complete_runtime_contract() {
@@ -146,7 +146,7 @@ fn committed_transport_document_maps_default_and_explicit_profiles() {
assert_eq!(ws.endpoints()[0].url().as_str(), "wss://api.devnet.solana.com");
assert_eq!(ws.endpoints()[0].protocol(), ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard);
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs));
assert!(!ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
}
}
if let std::result::Result::Ok(mainnet) = mainnet {
@@ -160,7 +160,7 @@ fn committed_transport_document_maps_default_and_explicit_profiles() {
if let std::option::Option::Some(ws) = ws {
assert_eq!(ws.endpoints()[0].url().as_str(), "wss://api.mainnet.solana.com");
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs));
assert!(!ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
}
}
}
@@ -232,7 +232,7 @@ fn v0_3_15_pre_006_fix_001_testnet_public_is_keyless_standard_transport_without_
assert_eq!(ws.endpoints()[0].cluster().as_str(), "testnet");
assert_eq!(ws.endpoints()[0].protocol(), ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard);
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs));
assert!(!ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
assert!(ws.endpoints()[0].supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
}
assert!(resolved.grpc_settings().is_none(), "keyless Testnet base profile must not conflate PublicNode Yellowstone with the network itself");
}
@@ -588,6 +588,35 @@ fn helius_laserstream_mainnet_and_devnet_api_key_map_to_protocol_and_safe_redact
assert!(devnet_debug.contains(crate::REDACTED_CONFIG_VALUE));
}
#[test]
fn v0_3_15_pre_006_fix_002_committed_public_standard_profiles_declare_block_capability() {
let engine = committed_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let environment = crate::ConfigEnvironment::from_maps(std::collections::BTreeMap::new(), std::collections::BTreeMap::new());
for (profile_id, cluster) in [("devnet_public", "devnet"), ("mainnet_public", "mainnet"), ("testnet_public", "testnet")] {
let resolved = engine.load_resolved_transport_config(std::option::Option::Some(profile_id), &environment);
assert!(resolved.is_ok(), "committed public standard profile {profile_id} should resolve: {resolved:?}");
let resolved = match resolved {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => continue,
};
let ws = resolved.ws_settings();
assert!(ws.is_some(), "committed public standard profile {profile_id} should expose WebSocket settings");
if let std::option::Option::Some(ws) = ws {
assert_eq!(ws.endpoints().len(), 1);
let endpoint = &ws.endpoints()[0];
assert_eq!(endpoint.provider().as_str(), "solana-public");
assert_eq!(endpoint.cluster().as_str(), cluster);
assert_eq!(endpoint.protocol(), ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard);
assert!(endpoint.supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs));
assert!(endpoint.supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block));
}
}
}
#[test]
fn v0_3_15_pre_003_committed_helius_profiles_map_transaction_capability_without_block_or_vote() {
let engine = committed_engine();