v0.3.10-pre.004

This commit is contained in:
2026-09-06 17:15:51 +02:00
parent 8309d829cc
commit e19a202565
20 changed files with 949 additions and 56 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
// version: 7
// version: 8
const MAX_GET_BLOCKS_RANGE: u64 = 500_000;
const MAX_GET_RECENT_PERFORMANCE_SAMPLES: u64 = 720;
@@ -591,25 +591,42 @@ impl crate::HttpTransportPool {
slot: u64,
config: std::option::Option<&crate::SolanaGetBlockConfig>,
) -> ksp_core_lib::Result<std::option::Option<crate::SolanaConfirmedBlock>> {
if let std::option::Option::Some(config) = config
&& config.commitment() == std::option::Option::Some(crate::SolanaCommitment::Processed)
{
return std::result::Result::Err(
ksp_core_lib::Error::new(
crate::ERROR_CODE_INVALID_RPC_PARAMETERS,
"getBlock commitment must be confirmed or finalized when explicitly provided",
)
.with_context("rpc_method", "getBlock")
.with_context("commitment", "processed"),
);
}
let mut params = std::vec![serde_json::json!(slot)];
if let std::option::Option::Some(config) = config {
params.push((*config).to_json_value());
}
let params = get_block_params(slot, config);
let params = match params {
std::result::Result::Ok(params) => params,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return self.execute_get_block(role, params).await;
}
/// Executes the current object-form `getBlock` request and reports the safe identity of the endpoint that produced the successful response.
///
/// Routing, admission, timeout and retry behavior are identical to [`Self::get_block`]. The returned observation never contains an endpoint URL,
/// HTTP headers or a raw HTTP body.
pub async fn get_block_observed(
&self,
role: &crate::HttpRoleName,
slot: u64,
config: std::option::Option<&crate::SolanaGetBlockConfig>,
) -> ksp_core_lib::Result<crate::HttpObservedValue<std::option::Option<crate::SolanaConfirmedBlock>>> {
let params = get_block_params(slot, config);
let params = match params {
std::result::Result::Ok(params) => params,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let observed = self.execute_blocks_rpc_observed("getBlock", role, params).await;
let observed = match observed {
std::result::Result::Ok(observed) => observed,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let (value, endpoint_name, provider) = observed.into_parts();
let block = decode_get_block(value);
return match block {
std::result::Result::Ok(block) => std::result::Result::Ok(crate::HttpObservedValue::new(block, endpoint_name, provider)),
std::result::Result::Err(error) => std::result::Result::Err(error),
};
}
/// Executes the deprecated bare-encoding `getBlock` request form retained by Solana RPC for backwards compatibility.
#[deprecated(note = "use HttpTransportPool::get_block with SolanaGetBlockConfig; the bare encoding request form is deprecated")]
pub async fn get_block_legacy(
@@ -635,16 +652,8 @@ impl crate::HttpTransportPool {
params: std::vec::Vec<serde_json::Value>,
) -> ksp_core_lib::Result<std::option::Option<crate::SolanaConfirmedBlock>> {
let value = self.execute_blocks_rpc("getBlock", role, params).await;
let value = match value {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
if value.is_null() {
return std::result::Result::Ok(std::option::Option::None);
}
let block = crate::SolanaConfirmedBlock::decode_wire("getBlock", value);
return match block {
std::result::Result::Ok(block) => std::result::Result::Ok(std::option::Option::Some(block)),
return match value {
std::result::Result::Ok(value) => decode_get_block(value),
std::result::Result::Err(error) => std::result::Result::Err(error),
};
}
@@ -829,6 +838,48 @@ impl crate::HttpTransportPool {
};
return self.execute_standard_rpc(role, method, params).await;
}
async fn execute_blocks_rpc_observed(
&self,
method_name: &'static str,
role: &crate::HttpRoleName,
params: std::vec::Vec<serde_json::Value>,
) -> ksp_core_lib::Result<crate::HttpObservedValue<serde_json::Value>> {
let method = blocks_descriptor(method_name);
let method = match method {
std::result::Result::Ok(method) => method,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return self.execute_standard_rpc_observed(role, method, params).await;
}
}
fn decode_get_block(value: serde_json::Value) -> ksp_core_lib::Result<std::option::Option<crate::SolanaConfirmedBlock>> {
if value.is_null() {
return std::result::Result::Ok(std::option::Option::None);
}
let block = crate::SolanaConfirmedBlock::decode_wire("getBlock", value);
return match block {
std::result::Result::Ok(block) => std::result::Result::Ok(std::option::Option::Some(block)),
std::result::Result::Err(error) => std::result::Result::Err(error),
};
}
fn get_block_params(slot: u64, config: std::option::Option<&crate::SolanaGetBlockConfig>) -> ksp_core_lib::Result<std::vec::Vec<serde_json::Value>> {
if let std::option::Option::Some(config) = config
&& config.commitment() == std::option::Option::Some(crate::SolanaCommitment::Processed)
{
return std::result::Result::Err(
ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_RPC_PARAMETERS, "getBlock commitment must be confirmed or finalized when explicitly provided")
.with_context("rpc_method", "getBlock")
.with_context("commitment", "processed"),
);
}
let mut params = std::vec![serde_json::json!(slot)];
if let std::option::Option::Some(config) = config {
params.push((*config).to_json_value());
}
return std::result::Result::Ok(params);
}
#[derive(serde::Deserialize)]