v0.2.3-pre.007
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/lib.rs
|
||||
// version: 15
|
||||
// version: 16
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![forbid(unsafe_code)]
|
||||
@@ -10,9 +10,9 @@
|
||||
//! independent from `ksp-config-lib`, Store and Program layers. `ksp-config-lib` now constructs these public settings through its one-way Config ->
|
||||
//! Transport adapter without creating a reverse dependency. Logical endpoint clients, priority-aware pools, bounded admission limits and retry/no-resend policy
|
||||
//! are available. The four typed Solana HTTP foundation canaries plus all 22 typed `0.2.2` Accounts, Tokens and Cluster wrappers execute real JSON-RPC
|
||||
//! requests through the shared transport path. `0.2.3` exposes its shared Transaction wire/config primitives, all eight read wrappers and both write
|
||||
//! submissions through `pre.006`, including complete modern/legacy `getTransaction` coverage and centralized no-resend protection for writes.
|
||||
//! `simulateTransaction` and the `0.2.4` family remain staged.
|
||||
//! requests through the shared transport path. `0.2.3` exposes its shared Transaction wire/config primitives and all eleven Transaction wrappers through
|
||||
//! `pre.007`: eight reads, two write submissions with centralized no-resend protection, and retry-safe `simulateTransaction`, including complete
|
||||
//! modern/legacy `getTransaction` coverage. The `0.2.4` family remains staged.
|
||||
|
||||
mod client;
|
||||
mod constants;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_transactions.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
/// Binary encoding accepted for serialized transaction input payloads.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -452,7 +452,6 @@ impl SolanaSimulationAccountsConfig {
|
||||
|
||||
/// Serializes the nested account config to the Solana JSON-RPC wire object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(&self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(encoding) = self.encoding {
|
||||
@@ -545,7 +544,6 @@ impl SolanaSimulateTransactionConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the simulation config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none()
|
||||
&& self.encoding.is_none()
|
||||
@@ -558,7 +556,6 @@ impl SolanaSimulateTransactionConfig {
|
||||
|
||||
/// Serializes this config to the Solana JSON-RPC wire object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(&self) -> serde_json::Value {
|
||||
let mut object = serde_json::Map::new();
|
||||
if let std::option::Option::Some(commitment) = self.commitment {
|
||||
@@ -1050,7 +1047,6 @@ impl SolanaSimulateTransactionResult {
|
||||
}
|
||||
|
||||
/// Decodes a simulation result while preserving optional/nullable current Agave fields.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireSimulateTransactionResult>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -1357,6 +1353,65 @@ impl crate::HttpTransportPool {
|
||||
};
|
||||
}
|
||||
|
||||
/// Executes typed `simulateTransaction` through the common KSP HTTP transport path.
|
||||
///
|
||||
/// Transport forwards the already encoded transaction as opaque text. The wrapper enforces only deterministic RPC invariants that do not require
|
||||
/// decoding transaction bytes: `sigVerify` cannot be combined with `replaceRecentBlockhash`, and simulation account-return encoding cannot use the
|
||||
/// legacy `binary` / `base58` account encodings rejected by the targeted Agave runtime.
|
||||
pub async fn simulate_transaction(
|
||||
&self,
|
||||
role: &crate::HttpRoleName,
|
||||
transaction: &str,
|
||||
config: std::option::Option<&crate::SolanaSimulateTransactionConfig>,
|
||||
) -> ksp_core_lib::Result<crate::SolanaRpcResponse<crate::SolanaSimulateTransactionResult>> {
|
||||
if let std::option::Option::Some(config) = config {
|
||||
if config.sig_verify() == std::option::Option::Some(true) && config.replace_recent_blockhash() == std::option::Option::Some(true) {
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_INVALID_RPC_PARAMETERS,
|
||||
"simulateTransaction sigVerify may not be used with replaceRecentBlockhash",
|
||||
)
|
||||
.with_context("rpc_method", "simulateTransaction"),
|
||||
);
|
||||
}
|
||||
if let std::option::Option::Some(accounts) = config.accounts()
|
||||
&& let std::option::Option::Some(encoding) = accounts.encoding()
|
||||
&& (encoding == crate::SolanaAccountEncoding::Binary || encoding == crate::SolanaAccountEncoding::Base58)
|
||||
{
|
||||
return std::result::Result::Err(
|
||||
ksp_core_lib::Error::new(
|
||||
crate::ERROR_CODE_INVALID_RPC_PARAMETERS,
|
||||
"simulateTransaction account-return encoding must be base64, base64+zstd, or jsonParsed",
|
||||
)
|
||||
.with_context("rpc_method", "simulateTransaction")
|
||||
.with_context("accounts_encoding", encoding.as_str()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut params = std::vec![serde_json::Value::String(transaction.to_owned())];
|
||||
if let std::option::Option::Some(config) = config
|
||||
&& !config.is_empty()
|
||||
{
|
||||
params.push(config.to_json_value());
|
||||
}
|
||||
let value = self.execute_transaction_rpc("simulateTransaction", role, params).await;
|
||||
let value = match value {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let contextual = decode_transaction_contextual_wire("simulateTransaction", value);
|
||||
let (context, value) = match contextual {
|
||||
std::result::Result::Ok(contextual) => contextual,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let result = crate::SolanaSimulateTransactionResult::decode_wire("simulateTransaction", value);
|
||||
return match result {
|
||||
std::result::Result::Ok(result) => std::result::Result::Ok(crate::SolanaRpcResponse::new(context, result)),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error),
|
||||
};
|
||||
}
|
||||
|
||||
/// Executes typed `getTransactionCount` through the common KSP HTTP transport path.
|
||||
pub async fn get_transaction_count(
|
||||
&self,
|
||||
@@ -1612,7 +1667,6 @@ fn decode_transaction_version_field(
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_simulation_accounts_field(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<std::vec::Vec<std::option::Option<serde_json::Value>>>,
|
||||
@@ -1640,7 +1694,6 @@ fn decode_simulation_accounts_field(
|
||||
return std::result::Result::Ok(crate::SolanaWireField::Value(accounts));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_replacement_blockhash_field(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<serde_json::Value>,
|
||||
@@ -1716,7 +1769,6 @@ struct WireConfirmedTransaction {
|
||||
transaction_index: crate::SolanaWireField<u32>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireSimulateTransactionResult {
|
||||
|
||||
Reference in New Issue
Block a user