v0.2.8-pre.003
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 219
|
# version: 220
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
|
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.2.8-pre.2.fix.1"
|
version = "0.2.8-pre.3"
|
||||||
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-onchain-transport-lib/src/ws_accounts.rs
|
// file: crates/ksp-onchain-transport-lib/src/ws_accounts.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
const MAX_PROGRAM_SUBSCRIBE_FILTERS: usize = 4;
|
const MAX_PROGRAM_SUBSCRIBE_FILTERS: usize = 4;
|
||||||
const MAX_PROGRAM_SUBSCRIBE_RAW_MEMCMP_BYTES: usize = 128;
|
const MAX_PROGRAM_SUBSCRIBE_RAW_MEMCMP_BYTES: usize = 128;
|
||||||
@@ -277,6 +277,46 @@ fn validate_program_subscribe_filters(filters: &[crate::SolanaProgramAccountFilt
|
|||||||
return std::result::Result::Ok(());
|
return std::result::Result::Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::SolanaStandardWsSession {
|
||||||
|
/// Subscribes to changes for one Solana account through standard `accountSubscribe`.
|
||||||
|
pub async fn account_subscribe(
|
||||||
|
&self,
|
||||||
|
account: &ksp_core_lib::Pubkey,
|
||||||
|
config: std::option::Option<&crate::SolanaAccountSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaAccount>>> {
|
||||||
|
return self.physical_session().account_subscribe(account, config).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to account changes owned by one Solana program through standard `programSubscribe`.
|
||||||
|
pub async fn program_subscribe(
|
||||||
|
&self,
|
||||||
|
program_id: &ksp_core_lib::Pubkey,
|
||||||
|
config: std::option::Option<&crate::SolanaProgramSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaProgramNotification>> {
|
||||||
|
return self.physical_session().program_subscribe(program_id, config).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::HeliusLaserStreamWsSession {
|
||||||
|
/// Subscribes to account changes through the standard `accountSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn account_subscribe(
|
||||||
|
&self,
|
||||||
|
account: &ksp_core_lib::Pubkey,
|
||||||
|
config: std::option::Option<&crate::SolanaAccountSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaAccount>>> {
|
||||||
|
return self.physical_session().account_subscribe(account, config).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to program-owned account changes through the standard `programSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn program_subscribe(
|
||||||
|
&self,
|
||||||
|
program_id: &ksp_core_lib::Pubkey,
|
||||||
|
config: std::option::Option<&crate::SolanaProgramSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaProgramNotification>> {
|
||||||
|
return self.physical_session().program_subscribe(program_id, config).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "../unit_tests/ws_accounts.rs"]
|
#[path = "../unit_tests/ws_accounts.rs"]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/src/ws_blocks.rs
|
// file: crates/ksp-onchain-transport-lib/src/ws_blocks.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
/// Filter accepted by unstable Solana `blockSubscribe`.
|
/// Filter accepted by unstable Solana `blockSubscribe`.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
@@ -210,6 +210,17 @@ struct WireRpcResponse {
|
|||||||
value: WireBlockNotification,
|
value: WireBlockNotification,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::SolanaStandardWsSession {
|
||||||
|
/// Subscribes to unstable standard Solana block notifications through `blockSubscribe`.
|
||||||
|
pub async fn block_subscribe(
|
||||||
|
&self,
|
||||||
|
filter: &crate::SolanaBlockSubscribeFilter,
|
||||||
|
config: std::option::Option<&crate::SolanaBlockSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaBlockNotification>>> {
|
||||||
|
return self.physical_session().block_subscribe(filter, config).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "../unit_tests/ws_blocks.rs"]
|
#[path = "../unit_tests/ws_blocks.rs"]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/src/ws_cluster.rs
|
// file: crates/ksp-onchain-transport-lib/src/ws_cluster.rs
|
||||||
// version: 3
|
// version: 4
|
||||||
|
|
||||||
/// Slot relationship reported by the standard Solana `slotNotification` WebSocket method.
|
/// Slot relationship reported by the standard Solana `slotNotification` WebSocket method.
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
@@ -401,6 +401,40 @@ fn decode_vote_notification(method: &str, value: serde_json::Value) -> ksp_core_
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::SolanaStandardWsSession {
|
||||||
|
/// Subscribes to standard Solana slot-processing notifications through `slotSubscribe`.
|
||||||
|
pub async fn slot_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotNotification>> {
|
||||||
|
return self.physical_session().slot_subscribe().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to standard Solana root-slot notifications through `rootSubscribe`.
|
||||||
|
pub async fn root_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<u64>> {
|
||||||
|
return self.physical_session().root_subscribe().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to unstable standard Solana slot-lifecycle notifications through `slotsUpdatesSubscribe`.
|
||||||
|
pub async fn slots_updates_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotUpdate>> {
|
||||||
|
return self.physical_session().slots_updates_subscribe().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to unstable pre-consensus gossip vote notifications through `voteSubscribe`.
|
||||||
|
pub async fn vote_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaVoteNotification>> {
|
||||||
|
return self.physical_session().vote_subscribe().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::HeliusLaserStreamWsSession {
|
||||||
|
/// Subscribes to slot-processing notifications through the standard `slotSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn slot_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotNotification>> {
|
||||||
|
return self.physical_session().slot_subscribe().await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to root-slot notifications through the standard `rootSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn root_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<u64>> {
|
||||||
|
return self.physical_session().root_subscribe().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "../unit_tests/ws_cluster.rs"]
|
#[path = "../unit_tests/ws_cluster.rs"]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs
|
// file: crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
/// Typed facade for one standard Solana WebSocket physical session.
|
/// Typed facade for one standard Solana WebSocket physical session.
|
||||||
///
|
///
|
||||||
/// The facade delegates to the same [`crate::WsSession`] actor used by the compatibility API. It owns no socket, registry, reconnect loop or queue of its
|
/// The facade delegates to the same [`crate::WsSession`] actor used by the compatibility API. It owns no socket, registry, reconnect loop or queue of its
|
||||||
/// own and therefore does not duplicate the physical WebSocket runtime.
|
/// own and therefore does not duplicate the physical WebSocket runtime. Subscription wrappers are implemented beside their wire owners in the
|
||||||
|
/// `ws_accounts`, `ws_blocks`, `ws_cluster` and `ws_transactions` modules.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct SolanaStandardWsSession {
|
pub struct SolanaStandardWsSession {
|
||||||
inner: crate::WsSession,
|
inner: crate::WsSession,
|
||||||
@@ -43,69 +44,9 @@ impl SolanaStandardWsSession {
|
|||||||
return self.inner.close().await;
|
return self.inner.close().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subscribes to changes for one Solana account through standard `accountSubscribe`.
|
/// Returns the crate-private shared physical session used by domain-specific facade wrappers.
|
||||||
pub async fn account_subscribe(
|
pub(crate) fn physical_session(&self) -> &crate::WsSession {
|
||||||
&self,
|
return &self.inner;
|
||||||
account: &ksp_core_lib::Pubkey,
|
|
||||||
config: std::option::Option<&crate::SolanaAccountSubscribeConfig>,
|
|
||||||
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaAccount>>> {
|
|
||||||
return self.inner.account_subscribe(account, config).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to unstable standard Solana block notifications through `blockSubscribe`.
|
|
||||||
pub async fn block_subscribe(
|
|
||||||
&self,
|
|
||||||
filter: &crate::SolanaBlockSubscribeFilter,
|
|
||||||
config: std::option::Option<&crate::SolanaBlockSubscribeConfig>,
|
|
||||||
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaBlockNotification>>> {
|
|
||||||
return self.inner.block_subscribe(filter, config).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to Solana transaction logs through standard `logsSubscribe`.
|
|
||||||
pub async fn logs_subscribe(
|
|
||||||
&self,
|
|
||||||
filter: &crate::SolanaLogsSubscribeFilter,
|
|
||||||
config: std::option::Option<&crate::SolanaCommitmentConfig>,
|
|
||||||
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaLogsNotification>>> {
|
|
||||||
return self.inner.logs_subscribe(filter, config).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to account changes owned by one Solana program through standard `programSubscribe`.
|
|
||||||
pub async fn program_subscribe(
|
|
||||||
&self,
|
|
||||||
program_id: &ksp_core_lib::Pubkey,
|
|
||||||
config: std::option::Option<&crate::SolanaProgramSubscribeConfig>,
|
|
||||||
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaProgramNotification>> {
|
|
||||||
return self.inner.program_subscribe(program_id, config).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to standard Solana root-slot notifications through `rootSubscribe`.
|
|
||||||
pub async fn root_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<u64>> {
|
|
||||||
return self.inner.root_subscribe().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to one Solana transaction signature through standard `signatureSubscribe`.
|
|
||||||
pub async fn signature_subscribe(
|
|
||||||
&self,
|
|
||||||
signature: &str,
|
|
||||||
config: std::option::Option<&crate::SolanaSignatureSubscribeConfig>,
|
|
||||||
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaSignatureNotification>>> {
|
|
||||||
return self.inner.signature_subscribe(signature, config).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to standard Solana slot-processing notifications through `slotSubscribe`.
|
|
||||||
pub async fn slot_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotNotification>> {
|
|
||||||
return self.inner.slot_subscribe().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to unstable standard Solana slot-lifecycle notifications through `slotsUpdatesSubscribe`.
|
|
||||||
pub async fn slots_updates_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaSlotUpdate>> {
|
|
||||||
return self.inner.slots_updates_subscribe().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Subscribes to unstable pre-consensus gossip vote notifications through `voteSubscribe`.
|
|
||||||
pub async fn vote_subscribe(&self) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaVoteNotification>> {
|
|
||||||
return self.inner.vote_subscribe().await;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,17 +58,29 @@ impl std::fmt::Debug for SolanaStandardWsSession {
|
|||||||
|
|
||||||
/// Typed facade for one Helius LaserStream WebSocket physical session.
|
/// Typed facade for one Helius LaserStream WebSocket physical session.
|
||||||
///
|
///
|
||||||
/// `0.2.8-pre.002` intentionally exposes only physical-session lifecycle through this facade. The six Helius-supported standard subscription wrappers are
|
/// The facade exposes only the six standard Solana subscription families that Helius documents as supported. Provider-specific transaction subscription
|
||||||
/// added in the next tranche after exact delegation and API-absence canaries are established. No public inner handle is exposed, so callers cannot bypass
|
/// support is intentionally deferred to a later tranche. No public inner handle is exposed, so callers cannot bypass the provider-specific surface by
|
||||||
/// the provider-specific surface by recovering a generic [`crate::WsSession`].
|
/// recovering a generic [`crate::WsSession`].
|
||||||
///
|
///
|
||||||
/// ```compile_fail
|
/// ```compile_fail
|
||||||
/// async fn unsupported(session: &ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
/// async fn unsupported_block(session: &ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
||||||
/// let _ = session.block_subscribe().await;
|
/// let _ = session.block_subscribe().await;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// ```compile_fail
|
/// ```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;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ```compile_fail
|
||||||
/// fn no_escape_hatch(session: ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
/// fn no_escape_hatch(session: ksp_onchain_transport_lib::HeliusLaserStreamWsSession) {
|
||||||
/// let _ = session.into_inner();
|
/// let _ = session.into_inner();
|
||||||
/// }
|
/// }
|
||||||
@@ -169,6 +122,11 @@ impl HeliusLaserStreamWsSession {
|
|||||||
pub async fn close(&self) -> ksp_core_lib::Result<()> {
|
pub async fn close(&self) -> ksp_core_lib::Result<()> {
|
||||||
return self.inner.close().await;
|
return self.inner.close().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the crate-private shared physical session used by domain-specific facade wrappers.
|
||||||
|
pub(crate) fn physical_session(&self) -> &crate::WsSession {
|
||||||
|
return &self.inner;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for HeliusLaserStreamWsSession {
|
impl std::fmt::Debug for HeliusLaserStreamWsSession {
|
||||||
@@ -177,6 +135,10 @@ impl std::fmt::Debug for HeliusLaserStreamWsSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[path = "../unit_tests/ws_helius_standard.rs"]
|
||||||
|
mod helius_standard_tests;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "../unit_tests/ws_protocol_session.rs"]
|
#[path = "../unit_tests/ws_protocol_session.rs"]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/src/ws_transactions.rs
|
// file: crates/ksp-onchain-transport-lib/src/ws_transactions.rs
|
||||||
// version: 3
|
// version: 4
|
||||||
|
|
||||||
/// Optional configuration accepted by standard Solana `signatureSubscribe`.
|
/// Optional configuration accepted by standard Solana `signatureSubscribe`.
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
||||||
@@ -246,6 +246,46 @@ fn decode_logs_notification(method: &str, value: serde_json::Value) -> ksp_core_
|
|||||||
return std::result::Result::Ok(crate::SolanaRpcResponse::new(context, notification));
|
return std::result::Result::Ok(crate::SolanaRpcResponse::new(context, notification));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl crate::SolanaStandardWsSession {
|
||||||
|
/// Subscribes to one Solana transaction signature through standard `signatureSubscribe`.
|
||||||
|
pub async fn signature_subscribe(
|
||||||
|
&self,
|
||||||
|
signature: &str,
|
||||||
|
config: std::option::Option<&crate::SolanaSignatureSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaSignatureNotification>>> {
|
||||||
|
return self.physical_session().signature_subscribe(signature, config).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to Solana transaction logs through standard `logsSubscribe`.
|
||||||
|
pub async fn logs_subscribe(
|
||||||
|
&self,
|
||||||
|
filter: &crate::SolanaLogsSubscribeFilter,
|
||||||
|
config: std::option::Option<&crate::SolanaCommitmentConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaLogsNotification>>> {
|
||||||
|
return self.physical_session().logs_subscribe(filter, config).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::HeliusLaserStreamWsSession {
|
||||||
|
/// Subscribes to one transaction signature through the standard `signatureSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn signature_subscribe(
|
||||||
|
&self,
|
||||||
|
signature: &str,
|
||||||
|
config: std::option::Option<&crate::SolanaSignatureSubscribeConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaSignatureNotification>>> {
|
||||||
|
return self.physical_session().signature_subscribe(signature, config).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subscribes to transaction logs through the standard `logsSubscribe` wire supported by Helius LaserStream WebSocket.
|
||||||
|
pub async fn logs_subscribe(
|
||||||
|
&self,
|
||||||
|
filter: &crate::SolanaLogsSubscribeFilter,
|
||||||
|
config: std::option::Option<&crate::SolanaCommitmentConfig>,
|
||||||
|
) -> ksp_core_lib::Result<crate::WsSubscription<crate::SolanaRpcResponse<crate::SolanaLogsNotification>>> {
|
||||||
|
return self.physical_session().logs_subscribe(filter, config).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[path = "../unit_tests/ws_transactions.rs"]
|
#[path = "../unit_tests/ws_transactions.rs"]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/tests/public_api.rs
|
// file: crates/ksp-onchain-transport-lib/tests/public_api.rs
|
||||||
// version: 34
|
// version: 35
|
||||||
|
|
||||||
//! Integration tests for the public `ksp-onchain-transport-lib` consumer contract.
|
//! Integration tests for the public `ksp-onchain-transport-lib` consumer contract.
|
||||||
|
|
||||||
@@ -698,3 +698,18 @@ fn public_v0_2_8_pre_002_protocol_facades_are_available_without_replacing_the_st
|
|||||||
let _helius_close = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::close;
|
let _helius_close = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::close;
|
||||||
let _helius_snapshot = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::snapshot;
|
let _helius_snapshot = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn public_v0_2_8_pre_003_helius_standard_surface_reuses_shared_typed_contracts() {
|
||||||
|
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 _shared_account_config = std::any::type_name::<ksp_onchain_transport_lib::SolanaAccountSubscribeConfig>();
|
||||||
|
let _shared_program_config = std::any::type_name::<ksp_onchain_transport_lib::SolanaProgramSubscribeConfig>();
|
||||||
|
let _shared_logs_filter = std::any::type_name::<ksp_onchain_transport_lib::SolanaLogsSubscribeFilter>();
|
||||||
|
let _shared_signature_config = std::any::type_name::<ksp_onchain_transport_lib::SolanaSignatureSubscribeConfig>();
|
||||||
|
let _shared_slot_notification = std::any::type_name::<ksp_onchain_transport_lib::SolanaSlotNotification>();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
// file: crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
||||||
// version: 25
|
// version: 26
|
||||||
|
|
||||||
//! Release-level completeness canaries for staged HTTP and WebSocket Transport coverage.
|
//! Release-level completeness canaries for staged HTTP and WebSocket Transport coverage.
|
||||||
|
|
||||||
@@ -795,3 +795,19 @@ fn release_v0_2_8_pre_002_protocol_facades_preserve_the_standard_partition() {
|
|||||||
std::option::Option::Some("HeliusLaserStreamWsSession")
|
std::option::Option::Some("HeliusLaserStreamWsSession")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn release_v0_2_8_pre_003_helius_surface_is_exactly_six_standard_families_before_transaction_extension() {
|
||||||
|
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 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("transaction_subscribe"));
|
||||||
|
assert_eq!(ksp_onchain_transport_lib::WsProtocolKind::HeliusLaserStream.as_str(), "helius_laserstream");
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_helius_standard.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
use futures_util::SinkExt; // rust-rules: trait-import
|
||||||
|
use futures_util::StreamExt; // rust-rules: trait-import
|
||||||
|
|
||||||
|
fn helius_endpoint(url: &str) -> crate::WsEndpointSettings {
|
||||||
|
return crate::WsEndpointSettings::new(
|
||||||
|
"local_helius_standard_fixture",
|
||||||
|
true,
|
||||||
|
crate::WsProviderName::new("helius"),
|
||||||
|
crate::WsClusterName::new("local"),
|
||||||
|
crate::WsProtocolKind::HeliusLaserStream,
|
||||||
|
crate::WsEndpointUrl::parse(url).expect("local Helius WebSocket URL must parse"),
|
||||||
|
crate::WsSessionSettings::default(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn bind_local_listener() -> (tokio::net::TcpListener, std::string::String) {
|
||||||
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.expect("local listener must bind");
|
||||||
|
let address = listener.local_addr().expect("local listener must expose address");
|
||||||
|
return (listener, format!("ws://{address}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn read_request(websocket: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>) -> serde_json::Value {
|
||||||
|
let message = websocket.next().await.expect("request message must exist").expect("request message must decode");
|
||||||
|
let text = message.to_text().expect("request must be text");
|
||||||
|
return serde_json::from_str(text).expect("request must contain JSON");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_result(websocket: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>, request: &serde_json::Value, result: serde_json::Value) {
|
||||||
|
let id = request.get("id").and_then(serde_json::Value::as_u64).expect("request id must be numeric");
|
||||||
|
let response = serde_json::json!({"jsonrpc":"2.0","id":id,"result":result});
|
||||||
|
websocket.send(tokio_tungstenite::tungstenite::Message::Text(response.to_string().into())).await.expect("local response must send");
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn expect_pair(
|
||||||
|
websocket: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>,
|
||||||
|
subscribe_method: &str,
|
||||||
|
expected_params: serde_json::Value,
|
||||||
|
unsubscribe_method: &str,
|
||||||
|
remote_id: u64,
|
||||||
|
) {
|
||||||
|
let subscribe = read_request(websocket).await;
|
||||||
|
assert_eq!(subscribe["method"], serde_json::Value::String(subscribe_method.to_owned()));
|
||||||
|
assert_eq!(subscribe["params"], expected_params);
|
||||||
|
send_result(websocket, &subscribe, serde_json::json!(remote_id)).await;
|
||||||
|
let unsubscribe = read_request(websocket).await;
|
||||||
|
assert_eq!(unsubscribe["method"], serde_json::Value::String(unsubscribe_method.to_owned()));
|
||||||
|
assert_eq!(unsubscribe["params"], serde_json::json!([remote_id]));
|
||||||
|
send_result(websocket, &unsubscribe, serde_json::json!(true)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn wait_for_close_frame(websocket: &mut tokio_tungstenite::WebSocketStream<tokio::net::TcpStream>) {
|
||||||
|
loop {
|
||||||
|
let message = websocket.next().await;
|
||||||
|
match message {
|
||||||
|
std::option::Option::Some(std::result::Result::Ok(tokio_tungstenite::tungstenite::Message::Close(_))) => return,
|
||||||
|
std::option::Option::Some(std::result::Result::Ok(_)) => {},
|
||||||
|
std::option::Option::Some(std::result::Result::Err(_)) | std::option::Option::None => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "current_thread")]
|
||||||
|
async fn helius_facade_reuses_exact_standard_wire_for_all_six_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");
|
||||||
|
let mut websocket = tokio_tungstenite::accept_async(stream).await.expect("local WebSocket handshake must succeed");
|
||||||
|
expect_pair(
|
||||||
|
&mut websocket,
|
||||||
|
"accountSubscribe",
|
||||||
|
serde_json::json!(["11111111111111111111111111111111", {"encoding":"base64","commitment":"confirmed"}]),
|
||||||
|
"accountUnsubscribe",
|
||||||
|
101,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
expect_pair(
|
||||||
|
&mut websocket,
|
||||||
|
"programSubscribe",
|
||||||
|
serde_json::json!(["11111111111111111111111111111111", {"encoding":"jsonParsed","filters":[{"dataSize":80}],"withContext":true}]),
|
||||||
|
"programUnsubscribe",
|
||||||
|
102,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
expect_pair(&mut websocket, "logsSubscribe", serde_json::json!(["all", {"commitment":"finalized"}]), "logsUnsubscribe", 103).await;
|
||||||
|
expect_pair(
|
||||||
|
&mut websocket,
|
||||||
|
"signatureSubscribe",
|
||||||
|
serde_json::json!(["fixture-signature", {"commitment":"confirmed","enableReceivedNotification":true}]),
|
||||||
|
"signatureUnsubscribe",
|
||||||
|
104,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
expect_pair(&mut websocket, "slotSubscribe", serde_json::json!([]), "slotUnsubscribe", 105).await;
|
||||||
|
expect_pair(&mut websocket, "rootSubscribe", serde_json::json!([]), "rootUnsubscribe", 106).await;
|
||||||
|
wait_for_close_frame(&mut websocket).await;
|
||||||
|
});
|
||||||
|
let session = crate::HeliusLaserStreamWsSession::connect(helius_endpoint(url.as_str())).await.expect("Helius facade must connect");
|
||||||
|
let pubkey = "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>().expect("fixture pubkey must parse");
|
||||||
|
let account_config = crate::SolanaAccountSubscribeConfig::new(
|
||||||
|
std::option::Option::Some(crate::SolanaAccountEncoding::Base64),
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::Some(crate::SolanaCommitment::Confirmed),
|
||||||
|
);
|
||||||
|
let mut account = session.account_subscribe(&pubkey, std::option::Option::Some(&account_config)).await.expect("Helius accountSubscribe must register");
|
||||||
|
assert!(account.unsubscribe().await.expect("Helius accountUnsubscribe must complete"));
|
||||||
|
let program_config = crate::SolanaProgramSubscribeConfig::new(
|
||||||
|
crate::SolanaAccountSubscribeConfig::new(
|
||||||
|
std::option::Option::Some(crate::SolanaAccountEncoding::JsonParsed),
|
||||||
|
std::option::Option::None,
|
||||||
|
std::option::Option::None,
|
||||||
|
),
|
||||||
|
std::vec![crate::SolanaProgramAccountFilter::DataSize(80)],
|
||||||
|
std::option::Option::Some(true),
|
||||||
|
);
|
||||||
|
let mut program = session.program_subscribe(&pubkey, std::option::Option::Some(&program_config)).await.expect("Helius programSubscribe must register");
|
||||||
|
assert!(program.unsubscribe().await.expect("Helius programUnsubscribe must complete"));
|
||||||
|
let logs_config = crate::SolanaCommitmentConfig::new(std::option::Option::Some(crate::SolanaCommitment::Finalized));
|
||||||
|
let mut logs = session
|
||||||
|
.logs_subscribe(&crate::SolanaLogsSubscribeFilter::All, std::option::Option::Some(&logs_config))
|
||||||
|
.await
|
||||||
|
.expect("Helius logsSubscribe must register");
|
||||||
|
assert!(logs.unsubscribe().await.expect("Helius logsUnsubscribe must complete"));
|
||||||
|
let signature_config =
|
||||||
|
crate::SolanaSignatureSubscribeConfig::new(std::option::Option::Some(crate::SolanaCommitment::Confirmed), std::option::Option::Some(true));
|
||||||
|
let mut signature = session
|
||||||
|
.signature_subscribe("fixture-signature", std::option::Option::Some(&signature_config))
|
||||||
|
.await
|
||||||
|
.expect("Helius signatureSubscribe must register");
|
||||||
|
assert!(signature.unsubscribe().await.expect("Helius signatureUnsubscribe must complete"));
|
||||||
|
let mut slot = session.slot_subscribe().await.expect("Helius slotSubscribe must register");
|
||||||
|
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"));
|
||||||
|
session.close().await.expect("Helius facade close must complete");
|
||||||
|
server.await.expect("local Helius peer task must complete");
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_protocol_session.rs
|
// file: crates/ksp-onchain-transport-lib/unit_tests/ws_protocol_session.rs
|
||||||
// version: 2
|
// version: 3
|
||||||
|
|
||||||
use futures_util::StreamExt; // rust-rules: trait-import
|
use futures_util::StreamExt; // rust-rules: trait-import
|
||||||
|
|
||||||
@@ -92,4 +92,13 @@ fn protocol_facades_define_no_second_actor_socket_or_public_inner_escape_hatch()
|
|||||||
assert!(!source.contains("WsSessionCommand"));
|
assert!(!source.contains("WsSessionCommand"));
|
||||||
assert!(!source.contains("pub fn inner("));
|
assert!(!source.contains("pub fn inner("));
|
||||||
assert!(!source.contains("pub fn into_inner("));
|
assert!(!source.contains("pub fn into_inner("));
|
||||||
|
assert!(!source.contains("pub async fn account_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn block_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn logs_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn program_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn root_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn signature_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn slot_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn slots_updates_subscribe"));
|
||||||
|
assert!(!source.contains("pub async fn vote_subscribe"));
|
||||||
}
|
}
|
||||||
|
|||||||
259
deltas/0.2.8/pre.003.md
Normal file
259
deltas/0.2.8/pre.003.md
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
<!-- file: deltas/0.2.8/pre.003.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.2.8-pre.003` — Surface standard Helius WebSocket
|
||||||
|
|
||||||
|
## 1. Objet
|
||||||
|
|
||||||
|
Cette tranche expose sur `HeliusLaserStreamWsSession` uniquement les six familles WebSocket standard que l'audit Helius courant classe comme supportées, sans ajouter de wire provider parallèle et sans ouvrir encore Config Helius, `transactionSubscribe` ou le heartbeat.
|
||||||
|
|
||||||
|
Le checkpoint opérateur de `pre.002-fix.001` est intégralement vert ; aucune dette de gate n'est reportée dans cette tranche.
|
||||||
|
|
||||||
|
Version workspace :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.2.8-pre.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Livraison / commit attendu :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.2.8-pre.003
|
||||||
|
v0.2.8-pre.003
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun tag prerelease.
|
||||||
|
|
||||||
|
## 2. Surface Helius ajoutée
|
||||||
|
|
||||||
|
`HeliusLaserStreamWsSession` expose désormais :
|
||||||
|
|
||||||
|
```text
|
||||||
|
account_subscribe
|
||||||
|
program_subscribe
|
||||||
|
logs_subscribe
|
||||||
|
signature_subscribe
|
||||||
|
slot_subscribe
|
||||||
|
root_subscribe
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque wrapper délègue au `WsSession` physique partagé et réutilise exactement les DTOs, encoders, decoders, `WsSubscriptionKind` et méthodes d'unsubscribe standard acquis en `0.2.7`.
|
||||||
|
|
||||||
|
Aucun type suivant n'est créé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
HeliusAccountSubscribeConfig
|
||||||
|
HeliusAccountNotification
|
||||||
|
HeliusProgramSubscribeConfig
|
||||||
|
HeliusProgramNotification
|
||||||
|
HeliusLogsSubscribeFilter
|
||||||
|
HeliusLogsNotification
|
||||||
|
HeliusSignatureSubscribeConfig
|
||||||
|
HeliusSignatureNotification
|
||||||
|
HeliusSlotNotification
|
||||||
|
HeliusRootNotification
|
||||||
|
```
|
||||||
|
|
||||||
|
L'absence de ces copies est volontaire : aucun écart de wire Helius courant ne les justifie.
|
||||||
|
|
||||||
|
## 3. Surface Helius explicitement absente
|
||||||
|
|
||||||
|
La façade Helius continue de ne pas exposer :
|
||||||
|
|
||||||
|
```text
|
||||||
|
block_subscribe
|
||||||
|
slots_updates_subscribe
|
||||||
|
vote_subscribe
|
||||||
|
transaction_subscribe
|
||||||
|
```
|
||||||
|
|
||||||
|
Les trois familles standard non supportées sont verrouillées par des rustdocs `compile_fail` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
blockSubscribe
|
||||||
|
slotsUpdatesSubscribe
|
||||||
|
voteSubscribe
|
||||||
|
```
|
||||||
|
|
||||||
|
`transactionSubscribe` reste réservé à la tranche provider-specific dédiée du forecast.
|
||||||
|
|
||||||
|
## 4. Organisation du code
|
||||||
|
|
||||||
|
`ws_protocol_session.rs` reste limité au lifecycle des façades et à l'accès crate-private au moteur partagé. Les wrappers sont rangés auprès du propriétaire de leur wire :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ws_accounts.rs
|
||||||
|
SolanaStandardWsSession : account / program
|
||||||
|
HeliusLaserStreamWsSession : account / program
|
||||||
|
|
||||||
|
ws_transactions.rs
|
||||||
|
SolanaStandardWsSession : logs / signature
|
||||||
|
HeliusLaserStreamWsSession : logs / signature
|
||||||
|
|
||||||
|
ws_cluster.rs
|
||||||
|
SolanaStandardWsSession : root / slot / slotsUpdates / vote
|
||||||
|
HeliusLaserStreamWsSession : root / slot
|
||||||
|
|
||||||
|
ws_blocks.rs
|
||||||
|
SolanaStandardWsSession : block uniquement
|
||||||
|
|
||||||
|
ws_protocol_session.rs
|
||||||
|
connect / id / snapshot / state / close
|
||||||
|
physical_session() crate-private
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette répartition évite de transformer le module de façade en fichier fourre-tout tout en conservant un seul actor/socket/registry.
|
||||||
|
|
||||||
|
Aucun accès public `inner()` / `into_inner()` / `physical_session()` n'est ajouté.
|
||||||
|
|
||||||
|
## 5. Fixture Helius standard
|
||||||
|
|
||||||
|
Une fixture locale dédiée couvre les six familles contre un peer WebSocket local Helius-typed.
|
||||||
|
|
||||||
|
Elle vérifie pour chaque paire :
|
||||||
|
|
||||||
|
```text
|
||||||
|
nom subscribe exact
|
||||||
|
params exacts
|
||||||
|
remote subscription id
|
||||||
|
nom unsubscribe exact
|
||||||
|
params [remote_id]
|
||||||
|
result true
|
||||||
|
```
|
||||||
|
|
||||||
|
Couverture :
|
||||||
|
|
||||||
|
```text
|
||||||
|
accountSubscribe / accountUnsubscribe
|
||||||
|
programSubscribe / programUnsubscribe
|
||||||
|
logsSubscribe / logsUnsubscribe
|
||||||
|
signatureSubscribe / signatureUnsubscribe
|
||||||
|
slotSubscribe / slotUnsubscribe
|
||||||
|
rootSubscribe / rootUnsubscribe
|
||||||
|
```
|
||||||
|
|
||||||
|
Les tests standard historiques restent propriétaires du décodage exact des notifications ; la nouvelle fixture prouve que la façade Helius traverse le même wire plutôt que de créer une seconde pile de décodage.
|
||||||
|
|
||||||
|
## 6. Canaries publiques et release completeness
|
||||||
|
|
||||||
|
Ajouts :
|
||||||
|
|
||||||
|
```text
|
||||||
|
public API : les six wrappers Helius sont accessibles depuis le crate-root
|
||||||
|
public API : les types de paramètres/résultats restent les types Solana partagés
|
||||||
|
release completeness : surface Helius courante = six familles standard, avant extension transaction
|
||||||
|
source canary : ws_protocol_session.rs ne redevient pas propriétaire des wrappers métier
|
||||||
|
```
|
||||||
|
|
||||||
|
Les neuf familles de `SolanaStandardWsSession` et les 18 opérations standard acquises restent inchangées.
|
||||||
|
|
||||||
|
## 7. Hors périmètre préservé
|
||||||
|
|
||||||
|
Cette tranche ne modifie pas :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ksp-config-lib
|
||||||
|
config/std.transport.json
|
||||||
|
config/schemas/std.transport.schema.json
|
||||||
|
.env.example
|
||||||
|
WsSubscriptionKind
|
||||||
|
transactionSubscribe / transactionUnsubscribe
|
||||||
|
notification transaction Helius
|
||||||
|
heartbeat/idle timer
|
||||||
|
HTTP 52/14
|
||||||
|
Store / Program / Wallet
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucune dépendance Rust n'est ajoutée.
|
||||||
|
|
||||||
|
## 8. Preuve opérateur héritée avant ouverture
|
||||||
|
|
||||||
|
Le checkpoint fourni après `pre.002-fix.001` est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
cargo fmt --all OK
|
||||||
|
python3 scripts/audit_rust_workspace_rules.py clean
|
||||||
|
cargo check --workspace OK
|
||||||
|
cargo clippy --workspace --all-targets OK
|
||||||
|
cargo test -p ksp-onchain-transport-lib OK
|
||||||
|
cargo test --workspace OK
|
||||||
|
```
|
||||||
|
|
||||||
|
`pre.002` + `pre.002-fix.001` sont donc considérés `DONE` avant ce delta.
|
||||||
|
|
||||||
|
## 9. Fichiers de la livraison
|
||||||
|
|
||||||
|
Nouveau :
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/ksp-onchain-transport-lib/unit_tests/ws_helius_standard.rs
|
||||||
|
deltas/0.2.8/pre.003.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Modifiés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
crates/ksp-onchain-transport-lib/src/ws_protocol_session.rs
|
||||||
|
crates/ksp-onchain-transport-lib/src/ws_accounts.rs
|
||||||
|
crates/ksp-onchain-transport-lib/src/ws_blocks.rs
|
||||||
|
crates/ksp-onchain-transport-lib/src/ws_cluster.rs
|
||||||
|
crates/ksp-onchain-transport-lib/src/ws_transactions.rs
|
||||||
|
crates/ksp-onchain-transport-lib/unit_tests/ws_protocol_session.rs
|
||||||
|
crates/ksp-onchain-transport-lib/tests/public_api.rs
|
||||||
|
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
|
||||||
|
docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
|
||||||
|
docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 10. Validation exécutée dans le sandbox de préparation
|
||||||
|
|
||||||
|
Exécuté après modification :
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
Le sandbox ne fournit pas Cargo/rustfmt ; les nouvelles fixtures et doctests ne sont donc pas déclarés compilés avant le checkpoint opérateur.
|
||||||
|
|
||||||
|
## 11. Gate opérateur
|
||||||
|
|
||||||
|
Après application :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --all
|
||||||
|
python3 scripts/audit_rust_workspace_rules.py
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets
|
||||||
|
cargo test -p ksp-onchain-transport-lib
|
||||||
|
cargo test --workspace
|
||||||
|
```
|
||||||
|
|
||||||
|
Attendu :
|
||||||
|
|
||||||
|
```text
|
||||||
|
nouvelle fixture Helius six familles verte
|
||||||
|
4 doctests compile_fail de HeliusLaserStreamWsSession verts
|
||||||
|
public API pre.003 verte
|
||||||
|
release completeness pre.003 verte
|
||||||
|
aucun warning/clippy
|
||||||
|
standard WebSocket 9/9 non régressé
|
||||||
|
workspace complet vert
|
||||||
|
```
|
||||||
|
|
||||||
|
## 12. Suite
|
||||||
|
|
||||||
|
Si le checkpoint est vert, `pre.004` ouvre uniquement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Config V2 kind = helius_laserstream
|
||||||
|
schema / fixtures
|
||||||
|
mapping Config -> Transport
|
||||||
|
secret Helius dans URL résolue par Config
|
||||||
|
redaction api-key
|
||||||
|
```
|
||||||
|
|
||||||
|
`transactionSubscribe` reste hors `pre.004` conformément au forecast courant.
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<!-- file: docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md -->
|
<!-- file: docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md -->
|
||||||
<!-- version: 7 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Plan `0.2.8` — Helius LaserStream WebSocket
|
# Plan `0.2.8` — Helius LaserStream WebSocket
|
||||||
|
|
||||||
> **Statut : `0.2.8-pre.002` est appliqué et testé, mais son gate Clippy requiert `pre.002-fix.001`.** Les tests Transport et workspace sont verts ; le fix corrige cinq `clippy::implicit_return` dans la nouvelle fixture protocolaire, passe Cargo à `0.2.8-pre.2.fix.1` et réorganise les documents actifs pour garder une séparation nette entre plan, validation et delta. Le moteur physique `WsSession` reste unique et partagé.
|
> **Statut : `0.2.8-pre.002` + `pre.002-fix.001` sont validés ; `0.2.8-pre.003` est préparé.** La façade `HeliusLaserStreamWsSession` expose désormais uniquement les six familles standard documentées comme supportées par Helius (`account`, `logs`, `program`, `root`, `signature`, `slot`) en réutilisant le wire standard existant. `block`, `slotsUpdates` et `vote` restent absents de la façade Helius. Le checkpoint Cargo opérateur de `pre.003` reste à exécuter.
|
||||||
|
|
||||||
## 1. Objet, base et état courant
|
## 1. Objet, base et état courant
|
||||||
|
|
||||||
@@ -24,15 +24,16 @@ prompts/013-V0_2_8_START_PROMPT.md présent
|
|||||||
pre.001 gate audit/sizing Helius
|
pre.001 gate audit/sizing Helius
|
||||||
pre.001-fix.001 séparation des façades + fermeture gate Cargo
|
pre.001-fix.001 séparation des façades + fermeture gate Cargo
|
||||||
pre.001-fix.002 forecast compact + namespace LaserStream WS/gRPC
|
pre.001-fix.002 forecast compact + namespace LaserStream WS/gRPC
|
||||||
pre.002 socle protocolaire appliqué ; tests verts, Clippy en échec ciblé
|
pre.002 socle protocolaire validé
|
||||||
pre.002-fix.001 correction Clippy + audit/normalisation structure documentaire
|
pre.002-fix.001 correction Clippy + normalisation structure documentaire validées
|
||||||
|
pre.003 six familles standard Helius préparées ; checkpoint opérateur pending
|
||||||
|
|
||||||
workspace.package.version courant = 0.2.8-pre.2.fix.1
|
workspace.package.version courant = 0.2.8-pre.3
|
||||||
commit attendu = v0.2.8-pre.002-fix.001
|
commit attendu = v0.2.8-pre.003
|
||||||
aucun tag prerelease
|
aucun tag prerelease
|
||||||
```
|
```
|
||||||
|
|
||||||
Le log opérateur de `pre.002` confirme : `cargo fmt`, audit Rust et `cargo check --workspace` verts ; `cargo test -p ksp-onchain-transport-lib` et `cargo test --workspace` verts ; `cargo clippy --workspace --all-targets` bloque uniquement sur cinq `clippy::implicit_return` dans `unit_tests/ws_protocol_session.rs`. Les résultats détaillés restent dans la matrice de validation et le delta du fix, pas dans le plan.
|
Le checkpoint opérateur de `pre.002-fix.001` est intégralement vert : `cargo fmt`, audit Rust, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, tests Transport et `cargo test --workspace`. `pre.003` peut donc ouvrir la surface standard Helius sans reporter de dette de gate.
|
||||||
|
|
||||||
## 2. Forecast souple courant
|
## 2. Forecast souple courant
|
||||||
|
|
||||||
@@ -43,10 +44,10 @@ pre.001 DONE — audit Helius actuel + matrice + architecture + threat model +
|
|||||||
fix.001 DONE — séparation des façades standard/Helius + moteur unique + gate Cargo fermé
|
fix.001 DONE — séparation des façades standard/Helius + moteur unique + gate Cargo fermé
|
||||||
fix.002 DONE — forecast normalisé + namespace LaserStream WebSocket/gRPC clarifié
|
fix.002 DONE — forecast normalisé + namespace LaserStream WebSocket/gRPC clarifié
|
||||||
|
|
||||||
pre.002 FIX REQUIRED — socle protocolaire : WsProtocolKind::HeliusLaserStream + façades standard/Helius
|
pre.002 DONE — socle protocolaire : WsProtocolKind::HeliusLaserStream + façades standard/Helius
|
||||||
+ connexion physique partagée + guards, sans duplication de l'actor
|
+ connexion physique partagée + guards, sans duplication de l'actor
|
||||||
fix.001 PREPARED — correction Clippy `implicit_return` + audit/normalisation structure docs
|
fix.001 DONE — correction Clippy `implicit_return` + audit/normalisation structure docs
|
||||||
pre.003 surface Helius standard supportée : account/logs/program/root/signature/slot
|
pre.003 PREPARED — surface Helius standard supportée : account/logs/program/root/signature/slot
|
||||||
+ absence typée de block/slotsUpdates/vote sur Helius + non-régression standard 9/9
|
+ absence typée de block/slotsUpdates/vote sur Helius + non-régression standard 9/9
|
||||||
pre.004 Config V2 helius_laserstream + schema/fixtures + mapping Config -> Transport
|
pre.004 Config V2 helius_laserstream + schema/fixtures + mapping Config -> Transport
|
||||||
+ stratégie de secret Helius et redaction URL
|
+ stratégie de secret Helius et redaction URL
|
||||||
@@ -454,7 +455,7 @@ Les 18 opérations standard restent donc présentes et testées : 9 subscribe +
|
|||||||
|
|
||||||
### 7.2 Surface cible `HeliusLaserStreamWsSession`
|
### 7.2 Surface cible `HeliusLaserStreamWsSession`
|
||||||
|
|
||||||
À partir de `pre.003`, la façade Helius doit exposer uniquement les familles de subscription suivantes :
|
À terme dans `0.2.8`, la façade Helius doit exposer uniquement les familles de subscription suivantes :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
account
|
account
|
||||||
@@ -466,7 +467,9 @@ slot
|
|||||||
transaction
|
transaction
|
||||||
```
|
```
|
||||||
|
|
||||||
Même après `pre.003`, elle **n'expose pas** :
|
`pre.003` matérialise exactement les six familles standard ; `transaction` reste réservé aux tranches provider-specific ultérieures du forecast.
|
||||||
|
|
||||||
|
La façade Helius **n'expose jamais dans le scope courant** :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
block
|
block
|
||||||
@@ -591,7 +594,34 @@ account block logs program root signature slot slotsUpdates vote
|
|||||||
|
|
||||||
La façade Helius ne recevra les six délégations communes qu'en `pre.003`, afin de garder la tranche actuelle limitée au socle protocolaire et aux guards.
|
La façade Helius ne recevra les six délégations communes qu'en `pre.003`, afin de garder la tranche actuelle limitée au socle protocolaire et aux guards.
|
||||||
|
|
||||||
### 7.7 Protocol kind et namespace LaserStream
|
### 7.7 Réalisation de `pre.003`
|
||||||
|
|
||||||
|
`pre.003` ajoute uniquement les six wrappers standard que la matrice Helius autorise :
|
||||||
|
|
||||||
|
```text
|
||||||
|
accountSubscribe / accountUnsubscribe
|
||||||
|
programSubscribe / programUnsubscribe
|
||||||
|
logsSubscribe / logsUnsubscribe
|
||||||
|
signatureSubscribe / signatureUnsubscribe
|
||||||
|
slotSubscribe / slotUnsubscribe
|
||||||
|
rootSubscribe / rootUnsubscribe
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun encoder, decoder ou DTO Helius parallèle n'est créé : chaque méthode de `HeliusLaserStreamWsSession` délègue au même wrapper `WsSession` standard déjà validé en `0.2.7`. Pour éviter que le module de façade devienne un fichier fourre-tout, les implémentations sont rangées auprès de leur propriétaire wire :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ws_accounts.rs -> account / program, façades standard + Helius
|
||||||
|
ws_transactions.rs -> logs / signature, façades standard + Helius
|
||||||
|
ws_cluster.rs -> root / slot, plus unstable standard uniquement
|
||||||
|
ws_blocks.rs -> block, façade standard uniquement
|
||||||
|
ws_protocol_session.rs -> lifecycle des façades + accès crate-private au moteur partagé
|
||||||
|
```
|
||||||
|
|
||||||
|
`block_subscribe`, `slots_updates_subscribe` et `vote_subscribe` restent absents du type Helius et sont verrouillés par doctests `compile_fail`. L'accès interne au `WsSession` physique est `pub(crate)` seulement ; aucun `inner()`/`into_inner()` public n'est introduit. Une fixture locale Helius dédiée vérifie les six méthodes subscribe/unsubscribe et leurs paramètres exacts ; les tests standard existants restent propriétaires du décodage des notifications.
|
||||||
|
|
||||||
|
`transactionSubscribe`, Config Helius et heartbeat restent hors scope de `pre.003`.
|
||||||
|
|
||||||
|
### 7.8 Protocol kind et namespace LaserStream
|
||||||
|
|
||||||
Retenir pour **WebSocket uniquement** :
|
Retenir pour **WebSocket uniquement** :
|
||||||
|
|
||||||
@@ -609,7 +639,7 @@ Le futur **Helius LaserStream gRPC** reste un backend/provider distinct, hors `0
|
|||||||
|
|
||||||
Cette règle permet de conserver le code court `helius_laserstream` dans son conteneur WS sans créer d'ambiguïté future entre les deux produits portant le nom LaserStream.
|
Cette règle permet de conserver le code court `helius_laserstream` dans son conteneur WS sans créer d'ambiguïté future entre les deux produits portant le nom LaserStream.
|
||||||
|
|
||||||
### 7.8 Connexion et propriété du moteur
|
### 7.9 Connexion et propriété du moteur
|
||||||
|
|
||||||
Cible de `pre.002` :
|
Cible de `pre.002` :
|
||||||
|
|
||||||
@@ -629,7 +659,7 @@ pas de second snapshot model
|
|||||||
pas de public escape hatch Helius -> raw standard WsSession
|
pas de public escape hatch Helius -> raw standard WsSession
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7.9 Capability validation defense-in-depth
|
### 7.10 Capability validation defense-in-depth
|
||||||
|
|
||||||
La séparation de façade est la première barrière. Une matrice interne reste utile :
|
La séparation de façade est la première barrière. Une matrice interne reste utile :
|
||||||
|
|
||||||
@@ -645,7 +675,7 @@ HeliusLaserStream:
|
|||||||
|
|
||||||
Cette matrice sert aux guards de constructor/descriptor, aux canaries et à la protection interne ; elle ne remplace plus la séparation de l'API publique.
|
Cette matrice sert aux guards de constructor/descriptor, aux canaries et à la protection interne ; elle ne remplace plus la séparation de l'API publique.
|
||||||
|
|
||||||
### 7.10 Heartbeat/idle ownership
|
### 7.11 Heartbeat/idle ownership
|
||||||
|
|
||||||
Helius annonce un timeout d'inactivité de 10 minutes et recommande des pings périodiques.
|
Helius annonce un timeout d'inactivité de 10 minutes et recommande des pings périodiques.
|
||||||
|
|
||||||
@@ -663,7 +693,7 @@ write failure = chemin disconnect/reconnect existant
|
|||||||
budget reconnect = fini, inchangé
|
budget reconnect = fini, inchangé
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7.11 Config V2
|
### 7.12 Config V2
|
||||||
|
|
||||||
Évolution :
|
Évolution :
|
||||||
|
|
||||||
@@ -675,7 +705,7 @@ profiles[].ws_endpoints[].kind:
|
|||||||
|
|
||||||
Les paramètres de `transactionSubscribe` restent runtime et n'appartiennent pas au profil endpoint Config.
|
Les paramètres de `transactionSubscribe` restent runtime et n'appartiennent pas au profil endpoint Config.
|
||||||
|
|
||||||
### 7.12 Credentials
|
### 7.13 Credentials
|
||||||
|
|
||||||
L'api-key reste uniquement dans l'URL résolue :
|
L'api-key reste uniquement dans l'URL résolue :
|
||||||
|
|
||||||
@@ -854,35 +884,37 @@ validation finale fermée
|
|||||||
prompt 0.2.9 prêt
|
prompt 0.2.9 prêt
|
||||||
```
|
```
|
||||||
|
|
||||||
## 13. Checkpoint `pre.002` / `pre.002-fix.001`
|
## 13. Checkpoint `pre.003`
|
||||||
|
|
||||||
Le socle `pre.002` est matériellement en place :
|
Le checkpoint précédent est fermé par preuve opérateur :
|
||||||
|
|
||||||
```text
|
|
||||||
WsProtocolKind::HeliusLaserStream -> helius_laserstream
|
|
||||||
SolanaStandardWsSession
|
|
||||||
HeliusLaserStreamWsSession
|
|
||||||
WsSession::connect historique standard-only
|
|
||||||
connect_for_protocol / connect_physical partagés
|
|
||||||
aucun second actor/socket/registry
|
|
||||||
aucun Config Helius / transactionSubscribe / heartbeat anticipé
|
|
||||||
```
|
|
||||||
|
|
||||||
Preuves opérateur déjà reçues pour `pre.002` :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
pre.002 + pre.002-fix.001
|
||||||
cargo fmt --all OK
|
cargo fmt --all OK
|
||||||
python3 scripts/audit_rust_workspace_rules.py clean
|
python3 scripts/audit_rust_workspace_rules.py clean
|
||||||
cargo check --workspace OK
|
cargo check --workspace OK
|
||||||
cargo clippy --workspace --all-targets FAIL ciblé : 5 implicit_return dans ws_protocol_session.rs
|
cargo clippy --workspace --all-targets OK
|
||||||
cargo test -p ksp-onchain-transport-lib OK
|
cargo test -p ksp-onchain-transport-lib OK
|
||||||
313 unit tests + 37 public API + 25 release completeness + 2 doctests compile_fail
|
|
||||||
cargo test --workspace OK
|
cargo test --workspace OK
|
||||||
```
|
```
|
||||||
|
|
||||||
`pre.002-fix.001` corrige uniquement ce défaut Clippy dans la fixture, sans modifier le runtime protocolaire. Le fix réorganise aussi les deux documents actifs : le **plan** conserve décisions, audit, forecast et stratégie ; la **validation** conserve matrices, critères et preuves exécutées ; les détails de livraison restent dans les **deltas**.
|
`pre.003` prépare maintenant :
|
||||||
|
|
||||||
Après application du fix, le gate opérateur à rejouer est :
|
```text
|
||||||
|
HeliusLaserStreamWsSession::account_subscribe
|
||||||
|
HeliusLaserStreamWsSession::program_subscribe
|
||||||
|
HeliusLaserStreamWsSession::logs_subscribe
|
||||||
|
HeliusLaserStreamWsSession::signature_subscribe
|
||||||
|
HeliusLaserStreamWsSession::slot_subscribe
|
||||||
|
HeliusLaserStreamWsSession::root_subscribe
|
||||||
|
|
||||||
|
block / slotsUpdates / vote -> toujours absents de la façade Helius
|
||||||
|
transactionSubscribe -> toujours absent
|
||||||
|
moteur/actor -> inchangé et partagé
|
||||||
|
new dependency -> aucune
|
||||||
|
```
|
||||||
|
|
||||||
|
La validation locale disponible au moment de préparer l'overlay est l'audit Rust workspace, qui reste `clean`. Le checkpoint opérateur requis avant de déclarer `pre.003` `DONE` est :
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo fmt --all
|
cargo fmt --all
|
||||||
@@ -893,4 +925,4 @@ cargo test -p ksp-onchain-transport-lib
|
|||||||
cargo test --workspace
|
cargo test --workspace
|
||||||
```
|
```
|
||||||
|
|
||||||
Si ce checkpoint est vert, `pre.002` + `fix.001` peuvent être considérés `DONE` et `pre.003` ouvre les six familles standard supportées sur `HeliusLaserStreamWsSession`.
|
Si ce checkpoint est vert, `pre.004` ouvre uniquement Config V2 `helius_laserstream`, schema/fixtures, mapping Config -> Transport et stratégie de secret/redaction.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
|
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
|
||||||
<!-- version: 7 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Validation `0.2.8` — Helius LaserStream WebSocket
|
# Validation `0.2.8` — Helius LaserStream WebSocket
|
||||||
|
|
||||||
> **Statut : `pre.002` testé avec succès sauf Clippy ; `pre.002-fix.001` préparé.** La matrice conserve les critères et preuves exécutées ; le forecast détaillé reste exclusivement dans le plan actif afin que ce fichier ne devienne pas un second plan.
|
> **Statut : `pre.002` + `pre.002-fix.001` validés ; `pre.003` préparé.** La façade Helius contient les six wrappers standard supportés sans DTO/wire provider parallèle. Les nouvelles fixtures et canaries doivent encore passer le checkpoint Cargo opérateur avant que `pre.003` soit marqué `DONE`.
|
||||||
|
|
||||||
## 1. Références
|
## 1. Références
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ fix architecture deltas/0.2.8/pre.001-fix.001.md
|
|||||||
fix forecast/nomenclature deltas/0.2.8/pre.001-fix.002.md
|
fix forecast/nomenclature deltas/0.2.8/pre.001-fix.002.md
|
||||||
pre.002 deltas/0.2.8/pre.002.md
|
pre.002 deltas/0.2.8/pre.002.md
|
||||||
pre.002 Clippy/docs fix deltas/0.2.8/pre.002-fix.001.md
|
pre.002 Clippy/docs fix deltas/0.2.8/pre.002-fix.001.md
|
||||||
|
pre.003 deltas/0.2.8/pre.003.md
|
||||||
validation standard WS docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
|
validation standard WS docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
|
||||||
HTTP compliance docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
|
HTTP compliance docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
|
||||||
KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
|
KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
|
||||||
@@ -86,7 +87,7 @@ Verdict : doublons transitifs, aucune nouvelle dépendance Helius, aucune anomal
|
|||||||
[x] doublons ciblés analysés comme transitifs/non bloquants
|
[x] doublons ciblés analysés comme transitifs/non bloquants
|
||||||
```
|
```
|
||||||
|
|
||||||
Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` testé par l’opérateur avec un unique échec Clippy ciblé, corrigé par `pre.002-fix.001`.**
|
Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` + `pre.002-fix.001` sont entièrement verts et fermés. `pre.003` est ouvert.**
|
||||||
|
|
||||||
## 3. Matrice provider normative
|
## 3. Matrice provider normative
|
||||||
|
|
||||||
@@ -138,8 +139,8 @@ Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` testé par l’opérateur a
|
|||||||
| LaserStream gRPC | backend/type/Config distincts, hors `0.2.8` | absence de réutilisation WS | décidé |
|
| LaserStream gRPC | backend/type/Config distincts, hors `0.2.8` | absence de réutilisation WS | décidé |
|
||||||
| escape hatch Helius | aucun `inner()`/`into_inner()` public | compile-fail/source canary | pre.002 implémenté |
|
| escape hatch Helius | aucun `inner()`/`into_inner()` public | compile-fail/source canary | pre.002 implémenté |
|
||||||
| generic Helius `WsSession::connect` | ne doit pas permettre de contourner la façade | invalid protocol pre-I/O canary | pre.002 implémenté |
|
| generic Helius `WsSession::connect` | ne doit pas permettre de contourner la façade | invalid protocol pre-I/O canary | pre.002 implémenté |
|
||||||
| Helius unsupported | absent de la façade | compile-fail/API absence canary | décidé |
|
| Helius unsupported | absent de la façade | compile-fail/API absence canary | pre.003 implémenté, checkpoint pending |
|
||||||
| standard Helius commun | délégation vers le même wire/actor | exact fixture | décidé |
|
| standard Helius commun | délégation vers le même wire/actor | exact fixture | pre.003 implémenté, checkpoint pending |
|
||||||
| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé |
|
| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé |
|
||||||
| Config direction | Config -> Transport uniquement | ownership tests | décidé |
|
| Config direction | Config -> Transport uniquement | ownership tests | décidé |
|
||||||
| heartbeat | Helius-only, actor commun | deterministic timers | décidé |
|
| heartbeat | Helius-only, actor commun | deterministic timers | décidé |
|
||||||
@@ -201,7 +202,7 @@ aucun payload brut dans logs/snapshots
|
|||||||
[x] SolanaStandard facade n'expose pas transactionSubscribe
|
[x] SolanaStandard facade n'expose pas transactionSubscribe
|
||||||
[x] Helius facade n'expose aucun escape hatch vers le handle générique
|
[x] Helius facade n'expose aucun escape hatch vers le handle générique
|
||||||
[x] protocol mismatch rejeté avant I/O — fixture opérateur verte
|
[x] protocol mismatch rejeté avant I/O — fixture opérateur verte
|
||||||
[ ] 6 familles standard Helius utilisent le wire standard exact — `pre.003`
|
[ ] 6 familles standard Helius utilisent le wire standard exact — implémenté en `pre.003`, fixture opérateur pending
|
||||||
[ ] transaction subscribe/ack exact
|
[ ] transaction subscribe/ack exact
|
||||||
[ ] transaction unsubscribe/result exact
|
[ ] transaction unsubscribe/result exact
|
||||||
[ ] transaction notification dispatch exact
|
[ ] transaction notification dispatch exact
|
||||||
@@ -254,46 +255,38 @@ Statut initial : **non exécuté**.
|
|||||||
|
|
||||||
Contrat cible : opt-in, Config résout l'api-key, Transport ne lit pas l'environnement. Aucun secret n'est versionné ou affiché. Un échec lié au plan/credential provider doit rester distinguable d'une panne du moteur.
|
Contrat cible : opt-in, Config résout l'api-key, Transport ne lit pas l'environnement. Aucun secret n'est versionné ou affiché. Un échec lié au plan/credential provider doit rester distinguable d'une panne du moteur.
|
||||||
|
|
||||||
## 10. Preuve `pre.002` et fix Clippy
|
## 10. Preuves `pre.002` / `fix.001` et préparation `pre.003`
|
||||||
|
|
||||||
Surface introduite :
|
Checkpoint `pre.002-fix.001` reçu :
|
||||||
|
|
||||||
```text
|
|
||||||
WsProtocolKind::HeliusLaserStream -> "helius_laserstream"
|
|
||||||
SolanaStandardWsSession
|
|
||||||
HeliusLaserStreamWsSession
|
|
||||||
WsSession::connect_for_protocol -> crate-internal
|
|
||||||
WsSession::connect_physical -> unique physical spawn path
|
|
||||||
```
|
|
||||||
|
|
||||||
Canaries ajoutées/prévues dans la livraison :
|
|
||||||
|
|
||||||
```text
|
|
||||||
[x] protocol descriptors distincts
|
|
||||||
[x] façade standard publique + 9 délégations vers les wrappers 0.2.7
|
|
||||||
[x] façade Helius publique + lifecycle partagé
|
|
||||||
[x] generic WsSession::connect rejette Helius avant I/O
|
|
||||||
[x] chaque façade rejette le mauvais protocol kind avant I/O
|
|
||||||
[x] les deux façades ouvrent/ferment une connexion contre un peer local via le même actor — test opérateur vert
|
|
||||||
[x] Debug Helius ne projette pas une query api-key canary — test opérateur vert
|
|
||||||
[x] source de façade sans second spawn/socket/command actor
|
|
||||||
[x] compile-fail Helius blockSubscribe — doctest opérateur vert
|
|
||||||
[x] compile-fail Helius into_inner — doctest opérateur vert
|
|
||||||
[ ] six wrappers standard Helius — `pre.003`
|
|
||||||
```
|
|
||||||
|
|
||||||
Validation opérateur reçue pour `pre.002` :
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
cargo fmt --all OK
|
cargo fmt --all OK
|
||||||
python3 scripts/audit_rust_workspace_rules.py clean
|
python3 scripts/audit_rust_workspace_rules.py clean
|
||||||
cargo check --workspace OK
|
cargo check --workspace OK
|
||||||
cargo clippy --workspace --all-targets FAIL : 5 `implicit_return` dans unit_tests/ws_protocol_session.rs
|
cargo clippy --workspace --all-targets OK
|
||||||
cargo test -p ksp-onchain-transport-lib OK
|
cargo test -p ksp-onchain-transport-lib OK
|
||||||
cargo test --workspace OK
|
cargo test --workspace OK
|
||||||
```
|
```
|
||||||
|
|
||||||
`pre.002-fix.001` ajoute les retours explicites exigés par la politique Clippy KSP et ne change aucun contrat runtime. Le fix doit être revalidé par le même checkpoint avant passage à `pre.003`.
|
Surface `pre.003` préparée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
[ ] Helius accountSubscribe/accountUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] Helius programSubscribe/programUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] Helius logsSubscribe/logsUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] Helius signatureSubscribe/signatureUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] Helius slotSubscribe/slotUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] Helius rootSubscribe/rootUnsubscribe — wrapper présent, fixture pending
|
||||||
|
[ ] compile-fail Helius blockSubscribe — doctest ajouté, exécution pending
|
||||||
|
[ ] compile-fail Helius slotsUpdatesSubscribe — doctest ajouté, exécution pending
|
||||||
|
[ ] compile-fail Helius voteSubscribe — doctest ajouté, exécution pending
|
||||||
|
[ ] public API canary des six wrappers — ajouté, exécution pending
|
||||||
|
[ ] release completeness canary — ajouté, exécution pending
|
||||||
|
```
|
||||||
|
|
||||||
|
La fixture Helius locale vérifie les noms de méthodes, paramètres, remote IDs et méthodes d'unsubscribe pour les six familles. Elle réutilise volontairement les DTOs Solana standard ; les tests historiques `ws_accounts`, `ws_transactions` et `ws_cluster` restent la preuve du décodage exact des notifications et de leurs variantes.
|
||||||
|
|
||||||
|
Aucun `transactionSubscribe`, changement Config, heartbeat ou nouvelle dépendance n'est introduit dans cette tranche.
|
||||||
|
|
||||||
## 11. Audit structurel des documents actifs
|
## 11. Audit structurel des documents actifs
|
||||||
|
|
||||||
@@ -320,3 +313,17 @@ Constats `pre.002-fix.001` :
|
|||||||
```
|
```
|
||||||
|
|
||||||
Aucun split en fichiers supplémentaires n'est retenu : les plans historiques `0.2.5`–`0.2.7` sont de taille comparable ou supérieure, et le contenu du plan `015` reste entièrement centré sur une seule release. Le problème identifié était **l'ordre interne et la duplication de responsabilités**, pas la nécessité d'un nouveau type de document.
|
Aucun split en fichiers supplémentaires n'est retenu : les plans historiques `0.2.5`–`0.2.7` sont de taille comparable ou supérieure, et le contenu du plan `015` reste entièrement centré sur une seule release. Le problème identifié était **l'ordre interne et la duplication de responsabilités**, pas la nécessité d'un nouveau type de document.
|
||||||
|
|
||||||
|
|
||||||
|
## 12. Gate opérateur `pre.003`
|
||||||
|
|
||||||
|
```text
|
||||||
|
[ ] cargo fmt --all
|
||||||
|
[ ] python3 scripts/audit_rust_workspace_rules.py = clean
|
||||||
|
[ ] cargo check --workspace
|
||||||
|
[ ] cargo clippy --workspace --all-targets
|
||||||
|
[ ] cargo test -p ksp-onchain-transport-lib
|
||||||
|
[ ] cargo test --workspace
|
||||||
|
```
|
||||||
|
|
||||||
|
Verdict courant : **`pre.003` préparé, non déclaré `DONE` avant ce checkpoint.**
|
||||||
|
|||||||
Reference in New Issue
Block a user