v0.2.3-pre.002-fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/rpc_transactions.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Binary encoding accepted for serialized transaction input payloads.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
@@ -20,6 +20,7 @@ impl SolanaTransactionBinaryEncoding {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn from_wire(value: &str) -> std::option::Option<Self> {
|
||||
return match value {
|
||||
"base58" => std::option::Option::Some(Self::Base58),
|
||||
@@ -159,12 +160,14 @@ impl SolanaGetTransactionConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the modern config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.commitment.is_none() && self.encoding.is_none() && self.max_supported_transaction_version.is_none();
|
||||
}
|
||||
|
||||
/// Serializes the modern config to its 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 {
|
||||
@@ -233,12 +236,14 @@ impl SolanaSignaturesForAddressConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the pagination config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
return self.before.is_none() && self.until.is_none() && self.limit.is_none() && self.commitment().is_none() && self.min_context_slot().is_none();
|
||||
}
|
||||
|
||||
/// Serializes this pagination config to the Solana JSON-RPC wire object.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_json_value(&self) -> serde_json::Value {
|
||||
let context = self.context.to_json_value();
|
||||
let mut object = match context {
|
||||
@@ -278,12 +283,14 @@ impl SolanaSignatureStatusesConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the status config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.search_transaction_history.is_none();
|
||||
}
|
||||
|
||||
/// 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(value) = self.search_transaction_history {
|
||||
@@ -320,12 +327,14 @@ impl SolanaRequestAirdropConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the airdrop config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
return self.recent_blockhash.is_none() && self.commitment.is_none();
|
||||
}
|
||||
|
||||
/// 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(blockhash) = self.recent_blockhash.as_ref() {
|
||||
@@ -392,6 +401,7 @@ impl SolanaSendTransactionConfig {
|
||||
}
|
||||
|
||||
/// Returns whether the send config would serialize to an empty object.
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn is_empty(&self) -> bool {
|
||||
return self.skip_preflight.is_none()
|
||||
&& self.preflight_commitment.is_none()
|
||||
@@ -402,6 +412,7 @@ impl SolanaSendTransactionConfig {
|
||||
|
||||
/// 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(value) = self.skip_preflight {
|
||||
@@ -451,12 +462,16 @@ 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 {
|
||||
object.insert("encoding".to_owned(), serde_json::Value::String(encoding.as_str().to_owned()));
|
||||
}
|
||||
let addresses = self.addresses.iter().map(|address| address.to_string()).map(serde_json::Value::String).collect::<std::vec::Vec<_>>();
|
||||
let mut addresses = std::vec::Vec::with_capacity(self.addresses.len());
|
||||
for address in &self.addresses {
|
||||
addresses.push(serde_json::Value::String(address.to_string()));
|
||||
}
|
||||
object.insert("addresses".to_owned(), serde_json::Value::Array(addresses));
|
||||
return serde_json::Value::Object(object);
|
||||
}
|
||||
@@ -540,6 +555,7 @@ 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()
|
||||
@@ -552,6 +568,7 @@ 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 {
|
||||
@@ -600,6 +617,7 @@ impl SolanaLatestBlockhash {
|
||||
}
|
||||
|
||||
/// Decodes a latest-blockhash object from the Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireLatestBlockhash>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -634,6 +652,7 @@ impl SolanaPrioritizationFee {
|
||||
}
|
||||
|
||||
/// Decodes one prioritization-fee sample from the Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WirePrioritizationFee>(method, value);
|
||||
return match decoded {
|
||||
@@ -710,6 +729,7 @@ impl SolanaSignatureInfo {
|
||||
}
|
||||
|
||||
/// Decodes one signature record from the Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireSignatureInfo>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -775,6 +795,7 @@ impl SolanaSignatureStatus {
|
||||
}
|
||||
|
||||
/// Decodes one present signature status from the Solana JSON wire shape.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireSignatureStatus>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -814,6 +835,7 @@ pub enum SolanaEncodedTransaction {
|
||||
|
||||
impl SolanaEncodedTransaction {
|
||||
/// Decodes the untagged transaction wire union without decoding transaction bytes.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
return match value {
|
||||
serde_json::Value::String(data) => std::result::Result::Ok(Self::LegacyBinary(data)),
|
||||
@@ -834,6 +856,7 @@ pub enum SolanaTransactionVersion {
|
||||
}
|
||||
|
||||
impl SolanaTransactionVersion {
|
||||
#[cfg(test)]
|
||||
fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
return match value {
|
||||
serde_json::Value::String(value) if value == "legacy" => std::result::Result::Ok(Self::Legacy),
|
||||
@@ -911,6 +934,7 @@ impl SolanaConfirmedTransaction {
|
||||
}
|
||||
|
||||
/// Decodes one non-null confirmed transaction without decoding Program-specific transaction internals.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn decode_wire(method: &str, value: serde_json::Value) -> ksp_core_lib::Result<Self> {
|
||||
let decoded = crate::decode_wire_json::<WireConfirmedTransaction>(method, value);
|
||||
let wire = match decoded {
|
||||
@@ -1043,6 +1067,7 @@ 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 {
|
||||
@@ -1078,10 +1103,12 @@ impl SolanaSimulateTransactionResult {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn invalid_transaction_wire(method: &str, field: &str, message: &'static str) -> ksp_core_lib::Error {
|
||||
return ksp_core_lib::Error::new(crate::ERROR_CODE_INVALID_RESPONSE, message).with_context("rpc_method", method).with_context("field", field);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_confirmation_status(
|
||||
method: &str,
|
||||
field: &str,
|
||||
@@ -1100,6 +1127,7 @@ fn decode_confirmation_status(
|
||||
return std::result::Result::Ok(std::option::Option::Some(status));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_binary_transaction_tuple(method: &str, values: std::vec::Vec<serde_json::Value>) -> ksp_core_lib::Result<crate::SolanaEncodedTransaction> {
|
||||
if values.len() != 2 {
|
||||
return std::result::Result::Err(invalid_transaction_wire(method, "transaction", "encoded transaction tuple must contain data and encoding"));
|
||||
@@ -1139,6 +1167,7 @@ fn decode_binary_transaction_tuple(method: &str, values: std::vec::Vec<serde_jso
|
||||
return std::result::Result::Ok(crate::SolanaEncodedTransaction::Binary { data, encoding });
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn decode_transaction_version_field(
|
||||
method: &str,
|
||||
field: crate::SolanaWireField<serde_json::Value>,
|
||||
@@ -1156,6 +1185,7 @@ 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>>>,
|
||||
@@ -1183,6 +1213,7 @@ 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>,
|
||||
@@ -1199,6 +1230,7 @@ fn decode_replacement_blockhash_field(
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireLatestBlockhash {
|
||||
@@ -1206,6 +1238,7 @@ struct WireLatestBlockhash {
|
||||
last_valid_block_height: u64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WirePrioritizationFee {
|
||||
@@ -1213,6 +1246,7 @@ struct WirePrioritizationFee {
|
||||
prioritization_fee: u64,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireSignatureInfo {
|
||||
@@ -1230,6 +1264,7 @@ struct WireSignatureInfo {
|
||||
transaction_index: std::option::Option<u32>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireSignatureStatus {
|
||||
@@ -1243,6 +1278,7 @@ struct WireSignatureStatus {
|
||||
confirmation_status: std::option::Option<std::string::String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireConfirmedTransaction {
|
||||
@@ -1258,6 +1294,7 @@ struct WireConfirmedTransaction {
|
||||
transaction_index: crate::SolanaWireField<u32>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct WireSimulateTransactionResult {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_transactions.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
#[test]
|
||||
fn transaction_encoding_strings_match_current_and_legacy_wire_labels() {
|
||||
@@ -75,15 +75,19 @@ fn signatures_for_address_config_preserves_pagination_and_context_order_independ
|
||||
#[test]
|
||||
fn signature_status_and_airdrop_configs_preserve_explicit_options() {
|
||||
let status = crate::SolanaSignatureStatusesConfig::new(std::option::Option::Some(false));
|
||||
assert!(!status.is_empty());
|
||||
assert_eq!(status.search_transaction_history(), std::option::Option::Some(false));
|
||||
assert_eq!(status.to_json_value(), serde_json::json!({"searchTransactionHistory":false}));
|
||||
assert!(crate::SolanaSignatureStatusesConfig::default().is_empty());
|
||||
let airdrop = crate::SolanaRequestAirdropConfig::new(
|
||||
std::option::Option::Some("recent-blockhash".to_owned()),
|
||||
std::option::Option::Some(crate::SolanaCommitment::Confirmed),
|
||||
);
|
||||
assert!(!airdrop.is_empty());
|
||||
assert_eq!(airdrop.recent_blockhash(), std::option::Option::Some("recent-blockhash"));
|
||||
assert_eq!(airdrop.commitment(), std::option::Option::Some(crate::SolanaCommitment::Confirmed));
|
||||
assert_eq!(airdrop.to_json_value(), serde_json::json!({"recentBlockhash":"recent-blockhash","commitment":"confirmed"}));
|
||||
assert!(crate::SolanaRequestAirdropConfig::default().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user