v0.2.5-pre.010.fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/client.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
/// Passive runtime availability reported for one logical HTTP endpoint or role.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -177,8 +177,9 @@ impl HttpEndpointClient {
|
||||
return Self::new_with_notify(settings, std::sync::Arc::new(tokio::sync::Notify::new()));
|
||||
}
|
||||
|
||||
/// Creates a new with notify value for `HttpEndpointClient`.
|
||||
pub(crate) fn new_with_notify(settings: crate::HttpEndpointSettings, notify: std::sync::Arc<tokio::sync::Notify>) -> ksp_core_lib::Result<Self> {
|
||||
let validation = crate::settings::validate_endpoint_settings(&settings);
|
||||
let validation = crate::validate_endpoint_settings(&settings);
|
||||
if let std::result::Result::Err(error) = validation {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
@@ -239,6 +240,7 @@ impl HttpEndpointClient {
|
||||
return self.inner.settings.request_timeout();
|
||||
}
|
||||
|
||||
/// Executes the crate-internal post json rpc operation for `HttpEndpointClient`.
|
||||
pub(crate) async fn post_json_rpc(&self, payload: &str, timeout: std::time::Duration) -> ksp_core_lib::Result<HttpEndpointHttpResponse> {
|
||||
if timeout.is_zero() {
|
||||
return std::result::Result::Err(
|
||||
@@ -301,6 +303,7 @@ impl HttpEndpointClient {
|
||||
};
|
||||
}
|
||||
|
||||
/// Executes the crate-internal matching role operation for `HttpEndpointClient`.
|
||||
pub(crate) fn matching_role<'a>(
|
||||
&'a self,
|
||||
role: &crate::HttpRoleName,
|
||||
@@ -322,6 +325,7 @@ impl HttpEndpointClient {
|
||||
return std::option::Option::None;
|
||||
}
|
||||
|
||||
/// Executes the crate-internal matching role runtime operation for `HttpEndpointClient`.
|
||||
pub(crate) fn matching_role_runtime(
|
||||
&self,
|
||||
role: &crate::HttpRoleName,
|
||||
@@ -352,6 +356,7 @@ impl HttpEndpointClient {
|
||||
return std::option::Option::None;
|
||||
}
|
||||
|
||||
/// Returns the current availability.
|
||||
pub(crate) fn availability(&self) -> crate::HttpEndpointAvailability {
|
||||
if !self.enabled() {
|
||||
return crate::HttpEndpointAvailability::Disabled;
|
||||
@@ -393,6 +398,7 @@ impl std::fmt::Debug for HttpEndpointClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// Crate-internal `HttpEndpointHttpResponse` state shared across the owning crate.
|
||||
pub(crate) struct HttpEndpointHttpResponse {
|
||||
status: u16,
|
||||
retry_after: std::option::Option<std::time::Duration>,
|
||||
@@ -400,14 +406,17 @@ pub(crate) struct HttpEndpointHttpResponse {
|
||||
}
|
||||
|
||||
impl HttpEndpointHttpResponse {
|
||||
/// Returns the current status.
|
||||
pub(crate) const fn status(&self) -> u16 {
|
||||
return self.status;
|
||||
}
|
||||
|
||||
/// Returns the current retry after.
|
||||
pub(crate) const fn retry_after(&self) -> std::option::Option<std::time::Duration> {
|
||||
return self.retry_after;
|
||||
}
|
||||
|
||||
/// Returns the current body.
|
||||
pub(crate) fn body(&self) -> &[u8] {
|
||||
return self.body.as_slice();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/executor.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
const HTTP_REQUEST_TIMEOUT: u16 = 408;
|
||||
const HTTP_TOO_MANY_REQUESTS: u16 = 429;
|
||||
const HTTP_INTERNAL_SERVER_ERROR: u16 = 500;
|
||||
const HTTP_BAD_GATEWAY: u16 = 502;
|
||||
const HTTP_SERVICE_UNAVAILABLE: u16 = 503;
|
||||
const HTTP_GATEWAY_TIMEOUT: u16 = 504;
|
||||
const HTTP_INTERNAL_SERVER_ERROR: u16 = 500;
|
||||
const HTTP_REQUEST_TIMEOUT: u16 = 408;
|
||||
const HTTP_SERVICE_UNAVAILABLE: u16 = 503;
|
||||
const HTTP_TOO_MANY_REQUESTS: u16 = 429;
|
||||
|
||||
impl crate::HttpTransportPool {
|
||||
/// Executes one audited standard Solana HTTP JSON-RPC method through KSP routing, admission and bounded retry policy.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/lib.rs
|
||||
// version: 20
|
||||
// version: 21
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -193,10 +193,6 @@ pub use self::rpc_common::SolanaContextConfig;
|
||||
pub use self::rpc_common::SolanaRpcContext;
|
||||
/// Generic contextual result returned by typed Solana HTTP RPC adapters.
|
||||
pub use self::rpc_common::SolanaRpcResponse;
|
||||
/// Decodes one private serde wire type into the shared Transport error domain for typed RPC adapters.
|
||||
pub(crate) use self::rpc_common::decode_wire_json;
|
||||
/// Parses a base58 public key without echoing its wire value into diagnostics for typed RPC adapters.
|
||||
pub(crate) use self::rpc_common::parse_wire_pubkey;
|
||||
/// Inflation-governor values returned by `getInflationGovernor`.
|
||||
pub use self::rpc_economics::SolanaInflationGovernor;
|
||||
/// Current inflation-rate values returned by `getInflationRate`.
|
||||
@@ -296,7 +292,17 @@ pub use self::settings::HttpRoleName;
|
||||
/// Complete runtime settings consumed by the Solana HTTP transport foundation.
|
||||
pub use self::settings::HttpTransportSettings;
|
||||
|
||||
/// Owning tracing target for events emitted by the on-chain transport crate.
|
||||
pub(crate) use self::constants::TRACING_TARGET;
|
||||
/// Crate-internal `HttpConcurrencyPermit` state shared across the owning crate.
|
||||
pub(crate) use self::resilience::HttpConcurrencyPermit;
|
||||
/// Crate-internal `HttpRoleRuntime` state shared across the owning crate.
|
||||
pub(crate) use self::resilience::HttpRoleRuntime;
|
||||
/// Crate-internal `RoleAdmissionAttempt` variants used by the owning crate.
|
||||
pub(crate) use self::resilience::RoleAdmissionAttempt;
|
||||
/// Decodes one private serde wire type into the shared Transport error domain for typed RPC adapters.
|
||||
pub(crate) use self::rpc_common::decode_wire_json;
|
||||
/// Parses a base58 public key without echoing its wire value into diagnostics for typed RPC adapters.
|
||||
pub(crate) use self::rpc_common::parse_wire_pubkey;
|
||||
/// Validates endpoint settings.
|
||||
pub(crate) use self::settings::validate_endpoint_settings;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/pool.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
/// Safe snapshot of the logical HTTP endpoint pool.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@@ -207,6 +207,7 @@ impl HttpTransportPool {
|
||||
return &self.inner.retry;
|
||||
}
|
||||
|
||||
/// Executes the crate-internal next request id operation for `HttpTransportPool`.
|
||||
pub(crate) fn next_request_id(&self) -> u64 {
|
||||
let id = self.inner.request_ids.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
if id == 0 {
|
||||
@@ -426,6 +427,7 @@ impl HttpTransportPool {
|
||||
return std::time::Instant::now() < deadline;
|
||||
}
|
||||
|
||||
/// Executes the crate-internal common request timeout operation for `HttpTransportPool`.
|
||||
pub(crate) fn common_request_timeout(
|
||||
&self,
|
||||
role: &crate::HttpRoleName,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/resilience.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
const DEFAULT_RATE_LIMIT_COOLDOWN: std::time::Duration = std::time::Duration::from_secs(1);
|
||||
const MAX_PROVIDER_RETRY_AFTER: std::time::Duration = std::time::Duration::from_secs(60);
|
||||
@@ -71,6 +71,7 @@ impl HttpRetryDecision {
|
||||
}
|
||||
}
|
||||
|
||||
/// Crate-internal `HttpRoleRuntime` state shared across the owning crate.
|
||||
pub(crate) struct HttpRoleRuntime {
|
||||
limits: crate::HttpRoleLimits,
|
||||
bucket: std::sync::Mutex<std::option::Option<HttpTokenBucketState>>,
|
||||
@@ -84,6 +85,7 @@ pub(crate) struct HttpRoleRuntime {
|
||||
}
|
||||
|
||||
impl HttpRoleRuntime {
|
||||
/// Creates a new `HttpRoleRuntime` value.
|
||||
pub(crate) fn new(settings: &crate::HttpEndpointRoleSettings, notify: std::sync::Arc<tokio::sync::Notify>) -> Self {
|
||||
let bucket = match settings.limits().requests_per_second() {
|
||||
std::option::Option::Some(requests_per_second) => {
|
||||
@@ -114,6 +116,7 @@ impl HttpRoleRuntime {
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the current availability.
|
||||
pub(crate) fn availability(&self, now: std::time::Instant) -> crate::HttpEndpointAvailability {
|
||||
if self.cooldown_remaining_at(now).is_some() {
|
||||
return crate::HttpEndpointAvailability::RateLimited;
|
||||
@@ -124,14 +127,17 @@ impl HttpRoleRuntime {
|
||||
return crate::HttpEndpointAvailability::Available;
|
||||
}
|
||||
|
||||
/// Returns the current cooldown remaining.
|
||||
pub(crate) fn cooldown_remaining(&self) -> std::option::Option<std::time::Duration> {
|
||||
return self.cooldown_remaining_at(std::time::Instant::now());
|
||||
}
|
||||
|
||||
/// Returns the current max concurrent requests.
|
||||
pub(crate) fn max_concurrent_requests(&self) -> std::option::Option<u32> {
|
||||
return self.limits.max_concurrent_requests().map(|value| return value.get());
|
||||
}
|
||||
|
||||
/// Returns the current in flight requests.
|
||||
pub(crate) fn in_flight_requests(&self) -> std::option::Option<u32> {
|
||||
let semaphore = match &self.semaphore {
|
||||
std::option::Option::Some(value) => value,
|
||||
@@ -149,18 +155,22 @@ impl HttpRoleRuntime {
|
||||
return std::option::Option::Some(maximum.saturating_sub(available_u32));
|
||||
}
|
||||
|
||||
/// Returns the current success count.
|
||||
pub(crate) fn success_count(&self) -> u64 {
|
||||
return self.success_count.load(std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Returns the current failure count.
|
||||
pub(crate) fn failure_count(&self) -> u64 {
|
||||
return self.failure_count.load(std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Returns the current rate limit count.
|
||||
pub(crate) fn rate_limit_count(&self) -> u64 {
|
||||
return self.rate_limit_count.load(std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Attempts to acquire.
|
||||
pub(crate) fn try_acquire(self: &std::sync::Arc<Self>, now: std::time::Instant) -> crate::RoleAdmissionAttempt {
|
||||
if let std::option::Option::Some(remaining) = self.cooldown_remaining_at(now) {
|
||||
let ready_at = match now.checked_add(remaining) {
|
||||
@@ -189,6 +199,7 @@ impl HttpRoleRuntime {
|
||||
return crate::RoleAdmissionAttempt::Ready(HttpConcurrencyPermit { semaphore_permit, notify: std::sync::Arc::clone(&self.notify) });
|
||||
}
|
||||
|
||||
/// Records success.
|
||||
pub(crate) fn record_success(&self) {
|
||||
self.success_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
self.degraded.store(false, std::sync::atomic::Ordering::Relaxed);
|
||||
@@ -196,6 +207,7 @@ impl HttpRoleRuntime {
|
||||
return;
|
||||
}
|
||||
|
||||
/// Records failure.
|
||||
pub(crate) fn record_failure(&self) {
|
||||
self.failure_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
self.degraded.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
@@ -203,6 +215,7 @@ impl HttpRoleRuntime {
|
||||
return;
|
||||
}
|
||||
|
||||
/// Records rate limited.
|
||||
pub(crate) fn record_rate_limited(&self, provider_retry_after: std::option::Option<std::time::Duration>) -> std::time::Duration {
|
||||
self.failure_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
self.rate_limit_count.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
@@ -269,6 +282,7 @@ impl HttpRoleRuntime {
|
||||
}
|
||||
}
|
||||
|
||||
/// Crate-internal `RoleAdmissionAttempt` variants used by the owning crate.
|
||||
pub(crate) enum RoleAdmissionAttempt {
|
||||
Ready(HttpConcurrencyPermit),
|
||||
BlockedUntil(std::time::Instant),
|
||||
@@ -276,6 +290,7 @@ pub(crate) enum RoleAdmissionAttempt {
|
||||
Unavailable,
|
||||
}
|
||||
|
||||
/// Crate-internal `HttpConcurrencyPermit` state shared across the owning crate.
|
||||
pub(crate) struct HttpConcurrencyPermit {
|
||||
semaphore_permit: std::option::Option<tokio::sync::OwnedSemaphorePermit>,
|
||||
notify: std::sync::Arc<tokio::sync::Notify>,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_accounts.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
const MAX_MEMCMP_BYTES: usize = 128;
|
||||
const MAX_MULTIPLE_ACCOUNTS: usize = 100;
|
||||
const MAX_PROGRAM_ACCOUNT_FILTERS: usize = 4;
|
||||
const MAX_MEMCMP_BYTES: usize = 128;
|
||||
|
||||
/// Account-data encoding accepted by Solana HTTP account methods.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -120,6 +120,7 @@ impl SolanaAccountInfoConfig {
|
||||
return self.context.min_context_slot();
|
||||
}
|
||||
|
||||
/// Returns whether empty.
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
return self.encoding.is_none() && self.data_slice.is_none() && self.commitment().is_none() && self.min_context_slot().is_none();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_cluster.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
const MAX_GET_SLOT_LEADERS: u64 = 5_000;
|
||||
|
||||
@@ -297,9 +297,11 @@ impl SolanaLeaderScheduleConfig {
|
||||
pub const fn commitment(&self) -> std::option::Option<crate::SolanaCommitment> {
|
||||
return self.commitment;
|
||||
}
|
||||
/// Returns whether empty.
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.identity.is_none() && self.commitment.is_none();
|
||||
}
|
||||
/// Executes the crate-internal to json value operation for `SolanaLeaderScheduleConfig`.
|
||||
pub(crate) fn to_json_value(&self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(identity) = self.identity.as_ref() {
|
||||
@@ -420,6 +422,7 @@ impl SolanaVoteAccountsConfig {
|
||||
pub const fn delinquent_slot_distance(&self) -> std::option::Option<u64> {
|
||||
return self.delinquent_slot_distance;
|
||||
}
|
||||
/// Returns whether empty.
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none() && self.vote_pubkey.is_none() && self.keep_unstaked_delinquents.is_none() && self.delinquent_slot_distance.is_none();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_method.rs
|
||||
// version: 3
|
||||
// version: 4
|
||||
|
||||
const CURRENT_HTTP_RPC_METHODS: [crate::HttpRpcMethodDescriptor; 52] = [
|
||||
crate::HttpRpcMethodDescriptor::new(
|
||||
@@ -1080,7 +1080,6 @@ impl HttpRpcMethodDescriptor {
|
||||
pub const fn current_http_rpc_methods() -> &'static [crate::HttpRpcMethodDescriptor] {
|
||||
return &CURRENT_HTTP_RPC_METHODS;
|
||||
}
|
||||
|
||||
/// Returns the 14 historically documented deprecated HTTP RPC descriptors retained for compliance history.
|
||||
#[must_use]
|
||||
pub const fn historical_http_rpc_methods() -> &'static [crate::HttpRpcMethodDescriptor] {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_transactions.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
const MAX_RECENT_PRIORITIZATION_FEE_ACCOUNTS: usize = 128;
|
||||
const MAX_SIGNATURES_FOR_ADDRESS_LIMIT: usize = 1_000;
|
||||
@@ -1389,7 +1389,6 @@ impl crate::HttpTransportPool {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut params = std::vec![serde_json::Value::String(transaction.to_owned())];
|
||||
if let std::option::Option::Some(config) = config
|
||||
&& !config.is_empty()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/settings.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
/// Runtime HTTP endpoint URL owned by Transport.
|
||||
///
|
||||
@@ -446,6 +446,7 @@ impl HttpTransportSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates endpoint settings.
|
||||
pub(crate) fn validate_endpoint_settings(endpoint: &crate::HttpEndpointSettings) -> ksp_core_lib::Result<()> {
|
||||
return validate_endpoint(endpoint, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user