v0.2.2-pre.002

This commit is contained in:
2026-08-18 07:15:59 +02:00
parent bffb4f9a31
commit e68f073505
18 changed files with 2049 additions and 78 deletions

View File

@@ -0,0 +1,53 @@
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_accounts.rs
// version: 1
#[test]
fn account_config_serializes_all_common_fields() {
let config = crate::SolanaAccountInfoConfig::new(
std::option::Option::Some(crate::SolanaAccountEncoding::Base64),
std::option::Option::Some(crate::SolanaDataSliceConfig::new(8, 32)),
std::option::Option::Some(crate::SolanaCommitment::Finalized),
std::option::Option::Some(99),
);
assert_eq!(
config.to_json_value(),
serde_json::json!({"encoding":"base64","dataSlice":{"offset":8,"length":32},"commitment":"finalized","minContextSlot":99})
);
}
#[test]
fn program_accounts_config_preserves_filter_variants_and_flags() {
let filters = std::vec![
crate::SolanaProgramAccountFilter::DataSize(165),
crate::SolanaProgramAccountFilter::Memcmp(crate::SolanaMemcmpFilter::new(4, crate::SolanaMemcmpBytes::Base64("AQID".to_owned()))),
crate::SolanaProgramAccountFilter::TokenAccountState,
];
let config = crate::SolanaProgramAccountsConfig::new(crate::SolanaAccountInfoConfig::default(), filters, std::option::Option::Some(true), std::option::Option::Some(true));
assert_eq!(
config.to_json_value(),
serde_json::json!({
"filters":[{"dataSize":165},{"memcmp":{"offset":4,"bytes":"AQID","encoding":"base64"}},"tokenAccountState"],
"withContext":true,
"sortResults":true
})
);
}
#[test]
fn account_wire_fixture_preserves_legacy_encoded_and_json_parsed_data() {
let values: std::vec::Vec<serde_json::Value> = serde_json::from_str(include_str!("../fixtures/http/account_data.variants.json")).expect("fixture must decode");
let legacy = crate::SolanaAccount::decode_wire("fixture", values[0].clone()).expect("legacy account must decode");
assert!(matches!(legacy.data(), crate::SolanaAccountData::LegacyBinary(_)));
assert_eq!(legacy.space(), std::option::Option::None);
let encoded = crate::SolanaAccount::decode_wire("fixture", values[1].clone()).expect("encoded account must decode");
assert!(matches!(encoded.data(), crate::SolanaAccountData::Encoded { encoding: crate::SolanaAccountEncoding::Base64Zstd, .. }));
let parsed = crate::SolanaAccount::decode_wire("fixture", values[2].clone()).expect("parsed account must decode");
match parsed.data() {
crate::SolanaAccountData::JsonParsed(value) => {
assert_eq!(value.program(), "spl-token");
assert_eq!(value.space(), 165);
assert_eq!(value.parsed()["type"], serde_json::json!("account"));
}
_ => assert!(false, "jsonParsed fixture must retain parsed data"),
}
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_canary.rs
// version: 1
// version: 2
fn pool_for_url(url: &str) -> crate::HttpTransportPool {
let role = crate::HttpEndpointRoleSettings::new(

View File

@@ -0,0 +1,52 @@
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_cluster.rs
// version: 1
#[test]
fn cluster_node_fixture_preserves_v4_client_id_and_optional_fields() {
let value: serde_json::Value = serde_json::from_str(include_str!("../fixtures/http/cluster_node.v4_2_1.json")).expect("fixture must decode");
let node = crate::SolanaClusterNode::decode_wire("getClusterNodes", value).expect("cluster node must decode");
assert_eq!(node.client_id(), std::option::Option::Some("Agave"));
assert_eq!(node.rpc(), std::option::Option::Some("127.0.0.1:8899"));
assert_eq!(node.pubsub(), std::option::Option::None);
}
#[test]
fn vote_account_fixture_preserves_optional_basis_point_commission_and_epoch_credit_triples() {
let value: serde_json::Value = serde_json::from_str(include_str!("../fixtures/http/vote_account.v4_2_1.json")).expect("fixture must decode");
let info = crate::SolanaVoteAccountInfo::decode_wire("getVoteAccounts", value).expect("vote account must decode");
assert_eq!(info.commission(), 8);
assert_eq!(info.inflation_rewards_commission_bps(), std::option::Option::Some(750));
assert_eq!(info.epoch_credits().len(), 2);
assert_eq!(info.epoch_credits()[0].epoch(), 700);
assert_eq!(info.epoch_credits()[0].previous_credits(), 90);
}
#[test]
fn vote_account_wire_accepts_nodes_predating_basis_point_commission_field() {
let value = serde_json::json!({
"votePubkey":"11111111111111111111111111111111",
"nodePubkey":"11111111111111111111111111111111",
"activatedStake":1,
"commission":5,
"epochVoteAccount":true,
"epochCredits":[],
"lastVote":2,
"rootSlot":1
});
let info = crate::SolanaVoteAccountInfo::decode_wire("getVoteAccounts", value).expect("legacy node shape must decode");
assert_eq!(info.inflation_rewards_commission_bps(), std::option::Option::None);
}
#[test]
fn leader_schedule_request_encodes_current_epoch_and_slot_overloads_without_ambiguous_arrays() {
let identity = "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>().expect("fixture pubkey must parse");
let config = crate::SolanaLeaderScheduleConfig::new(std::option::Option::Some(identity), std::option::Option::Some(crate::SolanaCommitment::Finalized));
assert_eq!(
crate::SolanaLeaderScheduleRequest::CurrentEpoch(std::option::Option::Some(config.clone())).to_json_params(),
std::vec![serde_json::json!({"identity":"11111111111111111111111111111111","commitment":"finalized"})]
);
assert_eq!(
crate::SolanaLeaderScheduleRequest::Slot { slot: 123, config: std::option::Option::Some(config) }.to_json_params(),
std::vec![serde_json::json!(123), serde_json::json!({"identity":"11111111111111111111111111111111","commitment":"finalized"})]
);
}

View File

@@ -0,0 +1,19 @@
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_common.rs
// version: 1
#[test]
fn shared_context_configs_preserve_commitment_and_min_context_slot() {
let commitment = crate::SolanaCommitmentConfig::new(std::option::Option::Some(crate::SolanaCommitment::Finalized));
assert_eq!(commitment.to_json_value(), serde_json::json!({"commitment":"finalized"}));
let context = crate::SolanaContextConfig::new(std::option::Option::Some(crate::SolanaCommitment::Confirmed), std::option::Option::Some(42));
assert_eq!(context.to_json_value(), serde_json::json!({"commitment":"confirmed","minContextSlot":42}));
}
#[test]
fn rpc_context_preserves_nullable_api_version() {
let with_version = crate::SolanaRpcContext::decode_wire("fixture", serde_json::json!({"slot":10,"apiVersion":"4.2.1"})).expect("context must decode");
assert_eq!(with_version.slot(), 10);
assert_eq!(with_version.api_version(), std::option::Option::Some("4.2.1"));
let without_version = crate::SolanaRpcContext::decode_wire("fixture", serde_json::json!({"slot":11})).expect("context must decode");
assert_eq!(without_version.api_version(), std::option::Option::None);
}

View File

@@ -0,0 +1,19 @@
// file: crates/ksp-onchain-transport-lib/unit_tests/rpc_tokens.rs
// version: 1
#[test]
fn token_selector_is_exclusive_by_construction() {
let mint = "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>().expect("fixture pubkey must parse");
assert_eq!(crate::SolanaTokenAccountSelector::Mint(mint).to_json_value(), serde_json::json!({"mint":"11111111111111111111111111111111"}));
assert_eq!(crate::SolanaTokenAccountSelector::ProgramId(mint).to_json_value(), serde_json::json!({"programId":"11111111111111111111111111111111"}));
}
#[test]
fn token_amount_fixture_preserves_nullable_ui_amount() {
let value: serde_json::Value = serde_json::from_str(include_str!("../fixtures/http/token_amount.null_ui.json")).expect("fixture must decode");
let amount = crate::SolanaTokenAmount::decode_wire("fixture", value).expect("token amount must decode");
assert_eq!(amount.amount(), "18446744073709551615");
assert_eq!(amount.decimals(), 9);
assert_eq!(amount.ui_amount(), std::option::Option::None);
assert_eq!(amount.ui_amount_string(), "18446744073.709551615");
}