v0.2.9-pre.002
This commit is contained in:
99
crates/ksp-onchain-transport-lib/src/grpc_channel.rs
Normal file
99
crates/ksp-onchain-transport-lib/src/grpc_channel.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/grpc_channel.rs
|
||||
// version: 1
|
||||
|
||||
/// Prepared Yellowstone gRPC channel owned by KSP Transport.
|
||||
///
|
||||
/// `pre.002` intentionally prepares a lazy HTTP/2 channel without performing network I/O. TLS configuration, provider-neutral metadata injection and live
|
||||
/// connection/error semantics are added by `pre.003`. The underlying Tonic channel and upstream Yellowstone protobuf types are never exposed publicly.
|
||||
pub struct YellowstoneGrpcChannel {
|
||||
endpoint_name: std::string::String,
|
||||
provider: crate::YellowstoneGrpcProviderName,
|
||||
cluster: crate::YellowstoneGrpcClusterName,
|
||||
channel: tonic::transport::Channel,
|
||||
}
|
||||
|
||||
impl YellowstoneGrpcChannel {
|
||||
/// Prepares one lazy Yellowstone gRPC channel from validated Transport-owned endpoint settings.
|
||||
///
|
||||
/// This operation performs no network connection. HTTPS endpoints remain syntactically accepted here; TLS is deliberately completed in `pre.003`
|
||||
/// before any live call is allowed.
|
||||
pub fn prepare(endpoint: &crate::YellowstoneGrpcEndpointSettings) -> ksp_core_lib::Result<Self> {
|
||||
if let std::result::Result::Err(error) = endpoint.validate() {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if !endpoint.enabled() {
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_SETTINGS, "disabled Yellowstone gRPC endpoint cannot prepare a channel")
|
||||
.with_context("field", "grpc_endpoint.enabled")
|
||||
.with_context("endpoint_name", endpoint.name()),
|
||||
);
|
||||
}
|
||||
let tonic_endpoint = match tonic::transport::Endpoint::from_shared(endpoint.url().as_str().to_owned()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => {
|
||||
ksp_logging_lib::warn!(
|
||||
target: crate::TRACING_TARGET,
|
||||
endpoint_name = endpoint.name(),
|
||||
provider = endpoint.provider().as_str(),
|
||||
cluster = endpoint.cluster().as_str(),
|
||||
"failed to prepare Yellowstone gRPC channel URI"
|
||||
);
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(crate::ERROR_CODE_GRPC_CHANNEL_FAILED, "Yellowstone gRPC channel could not be prepared")
|
||||
.with_context("endpoint_name", endpoint.name()),
|
||||
);
|
||||
},
|
||||
};
|
||||
let tonic_endpoint = tonic_endpoint
|
||||
.connect_timeout(endpoint.session().connect_timeout())
|
||||
.timeout(endpoint.session().unary_timeout())
|
||||
.buffer_size(endpoint.session().request_channel_capacity());
|
||||
let channel = tonic_endpoint.connect_lazy();
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
endpoint_name = endpoint.name(),
|
||||
provider = endpoint.provider().as_str(),
|
||||
cluster = endpoint.cluster().as_str(),
|
||||
"prepared lazy Yellowstone gRPC channel"
|
||||
);
|
||||
return std::result::Result::Ok(Self {
|
||||
endpoint_name: endpoint.name().to_owned(),
|
||||
provider: endpoint.provider().clone(),
|
||||
cluster: endpoint.cluster().clone(),
|
||||
channel,
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns the safe logical endpoint name.
|
||||
#[must_use]
|
||||
pub fn endpoint_name(&self) -> &str {
|
||||
return self.endpoint_name.as_str();
|
||||
}
|
||||
|
||||
/// Returns the safe open provider descriptor.
|
||||
#[must_use]
|
||||
pub const fn provider(&self) -> &crate::YellowstoneGrpcProviderName {
|
||||
return &self.provider;
|
||||
}
|
||||
|
||||
/// Returns the safe open cluster descriptor.
|
||||
#[must_use]
|
||||
pub const fn cluster(&self) -> &crate::YellowstoneGrpcClusterName {
|
||||
return &self.cluster;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for YellowstoneGrpcChannel {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
return formatter
|
||||
.debug_struct("YellowstoneGrpcChannel")
|
||||
.field("endpoint_name", &self.endpoint_name)
|
||||
.field("provider", &self.provider)
|
||||
.field("cluster", &self.cluster)
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/grpc_channel.rs"]
|
||||
mod tests;
|
||||
Reference in New Issue
Block a user