v0.2.8-pre.009
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/lib.rs
|
||||
// version: 33
|
||||
// version: 34
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -26,9 +26,11 @@
|
||||
//! `0.2.7-pre.009` opens the first stable typed WebSocket wrappers for account, program-account and transaction-log subscriptions without exposing a raw
|
||||
//! provider-extension subscription API. `0.2.8-pre.002` adds a Helius LaserStream WebSocket protocol discriminator and two typed protocol facades while
|
||||
//! keeping the `WsSession` actor/socket implementation unique and the historical generic constructor standard-only.
|
||||
//! `0.2.8-pre.003` exposes the six standard families Helius supports through the provider facade, while `0.2.8-pre.005` adds the typed Helius
|
||||
//! `transactionSubscribe` request contract and provider filter/options validation. `0.2.8-pre.006` integrates the live transaction handle and typed
|
||||
//! `transactionNotification` union into the same actor-owned registry, remote-ID remap, unsubscribe-race handling and per-subscription backpressure path.
|
||||
//! `0.2.8-pre.003` initially exposed the six standard families unambiguously supported by the audited Helius pages; `0.2.8-pre.009` reconciles the current
|
||||
//! Helius documentation and adds the now-documented unstable `slotsUpdatesSubscribe` pair while keeping explicitly unsupported block/vote pairs absent.
|
||||
//! `0.2.8-pre.005` adds the typed Helius `transactionSubscribe` request contract and provider filter/options validation. `0.2.8-pre.006` integrates the live
|
||||
//! transaction handle and typed `transactionNotification` union into the same actor-owned registry, remote-ID remap, unsubscribe-race handling and
|
||||
//! per-subscription backpressure path.
|
||||
|
||||
mod client;
|
||||
mod constants;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/ws_cluster.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
/// Slot relationship reported by the standard Solana `slotNotification` WebSocket method.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
@@ -433,6 +433,12 @@ impl crate::HeliusLaserStreamWsSession {
|
||||
pub async fn root_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<u64>> {
|
||||
return self.physical_session().root_subscribe().await;
|
||||
}
|
||||
|
||||
/// Subscribes to unstable slot-lifecycle notifications through the standard `slotsUpdatesSubscribe` wire currently documented by Helius LaserStream
|
||||
/// WebSocket.
|
||||
pub async fn slots_updates_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotUpdate>> {
|
||||
return self.physical_session().slots_updates_subscribe().await;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
/// Typed facade for one standard Solana WebSocket physical session.
|
||||
///
|
||||
@@ -67,7 +67,8 @@ impl std::fmt::Debug for SolanaStandardWsSession {
|
||||
|
||||
/// Typed facade for one Helius LaserStream WebSocket physical session.
|
||||
///
|
||||
/// The facade exposes the six standard Solana subscription families that Helius documents as supported plus the Helius-specific typed
|
||||
/// The facade exposes the seven standard Solana subscription families that the current Helius method pages support or document as available plus the
|
||||
/// Helius-specific typed
|
||||
/// `transactionSubscribe` lifecycle. Transaction notifications, reconnect/resubscribe, unsubscribe races and bounded backpressure all delegate to the same
|
||||
/// shared [`crate::WsSession`] actor; the facade owns no second socket, registry or queue. No public inner handle is exposed, so callers cannot bypass the
|
||||
/// provider-specific surface by recovering a generic [`crate::WsSession`].
|
||||
@@ -79,12 +80,6 @@ impl std::fmt::Debug for SolanaStandardWsSession {
|
||||
/// ```
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// async fn unsupported_slots_updates(session: &ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
||||
/// let _ = session.slots_updates_subscribe().await;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// async fn unsupported_vote(session: &ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
||||
/// let _ = session.vote_subscribe().await;
|
||||
/// }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/tests/public_api.rs
|
||||
// version: 37
|
||||
// version: 38
|
||||
|
||||
//! Integration tests for the public `ksp-onchain-transport-lib` consumer contract.
|
||||
|
||||
@@ -753,3 +753,10 @@ fn public_v0_2_8_pre_006_helius_transaction_live_handle_and_notification_types_a
|
||||
let _signature = std::any::type_name::<ksp_onchain_transport_lib::HeliusTransactionSignatureNotification>();
|
||||
assert_eq!(ksp_onchain_transport_lib::WsSubscriptionKind::HeliusTransaction.as_str(), "helius_transaction");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public_v0_2_8_pre_009_helius_slots_updates_surface_reuses_shared_typed_contract() {
|
||||
let _slots_updates = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::slots_updates_subscribe;
|
||||
let _shared_slot_update = std::any::type_name::<ksp_onchain_transport_lib::SolanaSlotUpdate>();
|
||||
assert_eq!(ksp_onchain_transport_lib::WsSubscriptionKind::SlotsUpdates.as_str(), "slots_updates");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
||||
// version: 30
|
||||
// version: 31
|
||||
|
||||
//! Release-level completeness canaries for staged HTTP and WebSocket Transport coverage.
|
||||
|
||||
@@ -797,7 +797,7 @@ fn release_v0_2_8_pre_002_protocol_facades_preserve_the_standard_partition() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_v0_2_8_pre_003_helius_surface_is_exactly_six_standard_families_before_transaction_extension() {
|
||||
fn release_v0_2_8_pre_003_original_six_standard_families_remain_available_after_provider_evolution() {
|
||||
let _account = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::account_subscribe;
|
||||
let _program = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::program_subscribe;
|
||||
let _logs = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::logs_subscribe;
|
||||
@@ -806,7 +806,6 @@ fn release_v0_2_8_pre_003_helius_surface_is_exactly_six_standard_families_before
|
||||
let _root = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::root_subscribe;
|
||||
let source = include_str!("../src/ws_protocol_session.rs");
|
||||
assert!(source.contains("unsupported_block"));
|
||||
assert!(source.contains("unsupported_slots_updates"));
|
||||
assert!(source.contains("unsupported_vote"));
|
||||
assert!(!source.contains("pub async fn transaction_subscribe"));
|
||||
assert_eq!(ksp_onchain_transport_lib::WsProtocolKind::HeliusLaserStream.as_str(), "helius_laserstream");
|
||||
@@ -847,7 +846,6 @@ fn release_v0_2_8_pre_006_helius_transaction_lifecycle_is_actor_integrated_witho
|
||||
assert!(!source.contains("tokio_tungstenite::connect_async"));
|
||||
let protocol_source = include_str!("../src/ws_protocol_session.rs");
|
||||
assert!(protocol_source.contains("unsupported_block"));
|
||||
assert!(protocol_source.contains("unsupported_slots_updates"));
|
||||
assert!(protocol_source.contains("unsupported_vote"));
|
||||
}
|
||||
|
||||
@@ -871,7 +869,6 @@ fn release_v0_2_8_pre_008_adversarial_guards_preserve_provider_isolation_and_saf
|
||||
let protocol_source = include_str!("../src/ws_protocol_session.rs");
|
||||
assert!(protocol_source.contains("unsupported_helius_transaction"));
|
||||
assert!(protocol_source.contains("unsupported_block"));
|
||||
assert!(protocol_source.contains("unsupported_slots_updates"));
|
||||
assert!(protocol_source.contains("unsupported_vote"));
|
||||
let helius_source = include_str!("../src/ws_helius_transactions.rs");
|
||||
assert!(helius_source.contains("impl std::fmt::Debug for HeliusFullTransactionNotification"));
|
||||
@@ -886,3 +883,94 @@ fn release_v0_2_8_pre_008_adversarial_guards_preserve_provider_isolation_and_saf
|
||||
assert!(actor_source.contains("ERROR_CODE_WS_BACKPRESSURE_OVERFLOW"));
|
||||
assert!(actor_source.contains("remote_to_local.remove"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_v0_2_8_pre_009_http_and_standard_websocket_inventories_remain_exact() {
|
||||
assert_eq!(ksp_onchain_transport_lib::current_http_rpc_methods().len(), 52);
|
||||
assert_eq!(ksp_onchain_transport_lib::historical_http_rpc_methods().len(), 14);
|
||||
let standard = [
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Account,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Block,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Logs,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Program,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Root,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Signature,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Slot,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::SlotsUpdates,
|
||||
ksp_onchain_transport_lib::WsSubscriptionKind::Vote,
|
||||
];
|
||||
assert_eq!(standard.len(), 9);
|
||||
let lifecycle_source = include_str!("../src/ws_lifecycle.rs");
|
||||
for method in [
|
||||
"accountSubscribe",
|
||||
"accountUnsubscribe",
|
||||
"blockSubscribe",
|
||||
"blockUnsubscribe",
|
||||
"logsSubscribe",
|
||||
"logsUnsubscribe",
|
||||
"programSubscribe",
|
||||
"programUnsubscribe",
|
||||
"rootSubscribe",
|
||||
"rootUnsubscribe",
|
||||
"signatureSubscribe",
|
||||
"signatureUnsubscribe",
|
||||
"slotSubscribe",
|
||||
"slotUnsubscribe",
|
||||
"slotsUpdatesSubscribe",
|
||||
"slotsUpdatesUnsubscribe",
|
||||
"voteSubscribe",
|
||||
"voteUnsubscribe",
|
||||
] {
|
||||
assert!(lifecycle_source.contains(method), "missing standard WebSocket method mapping: {method}");
|
||||
}
|
||||
let _account = ksp_onchain_transport_lib::SolanaStandardWsSession::account_subscribe;
|
||||
let _block = ksp_onchain_transport_lib::SolanaStandardWsSession::block_subscribe;
|
||||
let _logs = ksp_onchain_transport_lib::SolanaStandardWsSession::logs_subscribe;
|
||||
let _program = ksp_onchain_transport_lib::SolanaStandardWsSession::program_subscribe;
|
||||
let _root = ksp_onchain_transport_lib::SolanaStandardWsSession::root_subscribe;
|
||||
let _signature = ksp_onchain_transport_lib::SolanaStandardWsSession::signature_subscribe;
|
||||
let _slot = ksp_onchain_transport_lib::SolanaStandardWsSession::slot_subscribe;
|
||||
let _slots_updates = ksp_onchain_transport_lib::SolanaStandardWsSession::slots_updates_subscribe;
|
||||
let _vote = ksp_onchain_transport_lib::SolanaStandardWsSession::vote_subscribe;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_v0_2_8_pre_009_helius_surface_is_seven_standard_families_plus_transaction() {
|
||||
let _account = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::account_subscribe;
|
||||
let _program = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::program_subscribe;
|
||||
let _logs = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::logs_subscribe;
|
||||
let _signature = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::signature_subscribe;
|
||||
let _slot = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::slot_subscribe;
|
||||
let _root = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::root_subscribe;
|
||||
let _slots_updates = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::slots_updates_subscribe;
|
||||
let _transaction = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::transaction_subscribe;
|
||||
let protocol_source = include_str!("../src/ws_protocol_session.rs");
|
||||
assert!(protocol_source.contains("unsupported_block"));
|
||||
assert!(protocol_source.contains("unsupported_vote"));
|
||||
assert!(!protocol_source.contains("unsupported_slots_updates"));
|
||||
let cluster_source = include_str!("../src/ws_cluster.rs");
|
||||
assert!(cluster_source.contains("impl crate::HeliusLaserStreamWsSession"));
|
||||
assert!(cluster_source.contains("pub async fn slots_updates_subscribe"));
|
||||
assert_eq!(ksp_onchain_transport_lib::WsSubscriptionKind::SlotsUpdates.as_str(), "slots_updates");
|
||||
assert_eq!(ksp_onchain_transport_lib::WsSubscriptionKind::HeliusTransaction.as_str(), "helius_transaction");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_v0_2_8_pre_009_config_secret_and_dependency_boundaries_remain_wired() {
|
||||
let manifest_directory = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
let workspace = manifest_directory.parent().and_then(std::path::Path::parent).expect("Transport integration test must resolve the workspace root");
|
||||
let transport_manifest = std::fs::read_to_string(manifest_directory.join("Cargo.toml")).expect("Transport manifest must be readable");
|
||||
for forbidden in ["ksp-config-lib", "ksp-store-api", "ksp-store-lib", "ksp-program-api", "ksp-program-lib", "tracing =", "tracing."] {
|
||||
assert!(!transport_manifest.contains(forbidden), "forbidden direct Transport dependency detected: {forbidden}");
|
||||
}
|
||||
let config_manifest = std::fs::read_to_string(workspace.join("crates/ksp-config-lib/Cargo.toml")).expect("Config manifest must be readable");
|
||||
assert!(config_manifest.contains("ksp-onchain-transport-lib"));
|
||||
let config_transport =
|
||||
std::fs::read_to_string(workspace.join("crates/ksp-config-lib/src/transport.rs")).expect("Config Transport adapter source must be readable");
|
||||
assert!(config_transport.contains("WsProtocolKind::HeliusLaserStream"));
|
||||
let transport_example = std::fs::read_to_string(workspace.join("config/examples/std.transport.example.json")).expect("Transport example must be readable");
|
||||
assert!(transport_example.contains("\"kind\": \"helius_laserstream\""));
|
||||
assert!(transport_example.contains("${KSP_SECRET_HELIUS_API_KEY"));
|
||||
let env_example = std::fs::read_to_string(workspace.join(".env.example")).expect(".env.example must be readable");
|
||||
assert!(env_example.contains("KSP_SECRET_HELIUS_API_KEY"));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_helius_standard.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
use futures_util::SinkExt; // rust-rules: trait-import
|
||||
use futures_util::StreamExt; // rust-rules: trait-import
|
||||
@@ -63,7 +63,7 @@ async fn wait_for_close_frame(websocket: &mut tokio_tungstenite::WebSocketStream
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn helius_facade_reuses_exact_standard_wire_for_all_six_supported_families() {
|
||||
async fn helius_facade_reuses_exact_standard_wire_for_all_seven_currently_supported_families() {
|
||||
let (listener, url) = bind_local_listener().await;
|
||||
let server = tokio::spawn(async move {
|
||||
let (stream, _) = listener.accept().await.expect("local server must accept client");
|
||||
@@ -95,6 +95,7 @@ async fn helius_facade_reuses_exact_standard_wire_for_all_six_supported_families
|
||||
.await;
|
||||
expect_pair(&mut websocket, "slotSubscribe", serde_json::json!([]), "slotUnsubscribe", 105).await;
|
||||
expect_pair(&mut websocket, "rootSubscribe", serde_json::json!([]), "rootUnsubscribe", 106).await;
|
||||
expect_pair(&mut websocket, "slotsUpdatesSubscribe", serde_json::json!([]), "slotsUpdatesUnsubscribe", 107).await;
|
||||
wait_for_close_frame(&mut websocket).await;
|
||||
});
|
||||
let session = crate::HeliusLaserStreamWsSession::connect(helius_endpoint(url.as_str())).await.expect("Helius facade must connect");
|
||||
@@ -134,6 +135,8 @@ async fn helius_facade_reuses_exact_standard_wire_for_all_six_supported_families
|
||||
assert!(slot.unsubscribe().await.expect("Helius slotUnsubscribe must complete"));
|
||||
let mut root = session.root_subscribe().await.expect("Helius rootSubscribe must register");
|
||||
assert!(root.unsubscribe().await.expect("Helius rootUnsubscribe must complete"));
|
||||
let mut slots_updates = session.slots_updates_subscribe().await.expect("Helius slotsUpdatesSubscribe must register");
|
||||
assert!(slots_updates.unsubscribe().await.expect("Helius slotsUpdatesUnsubscribe must complete"));
|
||||
session.close().await.expect("Helius facade close must complete");
|
||||
server.await.expect("local Helius peer task must complete");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user