Files
khadhroony-solana-project/crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
2026-09-03 13:09:25 +02:00

615 lines
32 KiB
Rust

// file: crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
// version: 6
fn network() -> ksp_store_api::RawNetworkId {
return match ksp_store_api::RawNetworkId::new("devnet") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid test network rejected: {error:?}"),
};
}
fn page_query(
network_name: &str,
pubkey: std::option::Option<ksp_store_api::Pubkey>,
start: std::option::Option<u64>,
end: std::option::Option<u64>,
direction: ksp_store_api::RawSortDirection,
) -> ksp_store_api::RawAccountStateQuery {
let network = match ksp_store_api::RawNetworkId::new(network_name) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid test network rejected: {error:?}"),
};
let slots = match ksp_store_api::RawSlotRange::new(start, end) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid slot range rejected: {error:?}"),
};
let limit = match ksp_store_api::RawPageLimit::new(2) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid page limit rejected: {error:?}"),
};
return ksp_store_api::RawAccountStateQuery::new(network, pubkey, slots, direction, ksp_store_api::RawPageRequest::first(limit));
}
fn state_row() -> super::RawAccountStateDbRow {
return super::RawAccountStateDbRow {
data: vec![1, 2, 3, 4],
executable: true,
lamports_text: u64::MAX.to_string(),
owner: vec![2; 32],
pubkey: vec![1; 32],
rent_epoch_text: u64::MAX.to_string(),
slot_text: u64::MAX.to_string(),
state_hash: vec![3; 32],
};
}
fn observation_row() -> super::RawAccountObservationDbRow {
return super::RawAccountObservationDbRow {
account_pubkey: vec![1; 32],
account_slot_text: u64::MAX.to_string(),
account_state_hash: vec![3; 32],
acquisition_method: "account_subscribe".to_owned(),
capture_session_id: std::option::Option::Some("session_1".to_owned()),
commitment: std::option::Option::Some("confirmed".to_owned()),
endpoint_id: std::option::Option::Some("endpoint_1".to_owned()),
filter_id: std::option::Option::Some("filter_1".to_owned()),
is_startup: std::option::Option::Some(true),
observation_key: vec![4; 32],
observed_at_unix_millis: std::option::Option::Some(1_700_000_000_000),
origin: "live".to_owned(),
protocol: "yellowstone_grpc".to_owned(),
provider: "publicnode".to_owned(),
received_at_unix_millis: 1_700_000_000_001,
source_payload_hash: std::option::Option::Some(vec![5; 32]),
source_payload_size_bytes: std::option::Option::Some(67_108_864),
transaction_signature: std::option::Option::Some(vec![6; 64]),
write_version_text: std::option::Option::Some(u64::MAX.to_string()),
};
}
return super::RawAccountInspectionDbRow {
data_length_bytes: std::option::Option::Some(data_length_bytes),
executable: std::option::Option::Some(true),
filtered_count_text: "3".to_owned(),
lamports_text: std::option::Option::Some(u64::MAX.to_string()),
owner: std::option::Option::Some(vec![2; 32]),
page_present: true,
pubkey: std::option::Option::Some(vec![1; 32]),
rent_epoch_text: std::option::Option::Some(u64::MAX.to_string()),
slot_text: std::option::Option::Some(u64::MAX.to_string()),
state_hash: std::option::Option::Some(vec![3; 32]),
total_count_text: "4".to_owned(),
};
}
#[test]
fn v0_3_8_pre_005_inspection_window_rejects_unrepresentable_limit_and_offset_before_io() {
let normal_limit = match ksp_store_api::RawPageLimit::new(100) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account inspection page limit rejected: {error:?}"),
};
let normal = super::raw_account_inspection_sql_window(ksp_store_api::RawInspectionPageRequest::new(25, normal_limit));
assert_eq!(normal, std::result::Result::Ok((100, 25)));
let huge_limit = match ksp_store_api::RawPageLimit::new(u64::MAX) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("API unexpectedly rejected backend-physical account limit fixture: {error:?}"),
};
let limit_error = super::raw_account_inspection_sql_window(ksp_store_api::RawInspectionPageRequest::new(0, huge_limit));
assert_eq!(
limit_error.err().map(|value| return (value.kind(), value.phase())),
std::option::Option::Some((crate::PostgresBackendErrorKind::PageLimitUnsupported, "raw_account_inspection_limit")),
);
let offset_error = super::raw_account_inspection_sql_window(ksp_store_api::RawInspectionPageRequest::new(u64::MAX, normal_limit));
assert_eq!(
offset_error.err().map(|value| return (value.kind(), value.phase())),
std::option::Option::Some((crate::PostgresBackendErrorKind::QueryInvalid, "raw_account_inspection_offset")),
);
return;
}
#[test]
fn v0_3_8_pre_005_inspection_summary_is_data_free_and_preserves_complete_u64_domain() {
let network = network();
let decoded = super::decode_raw_account_inspection_summary(&network, inspection_row(4));
let summary = match decoded {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account inspection summary rejected: {error:?}"),
};
assert_eq!(summary.reference().network().as_str(), "devnet");
assert_eq!(summary.reference().pubkey(), &ksp_store_api::Pubkey::new_from_array([1; 32]));
assert_eq!(summary.reference().slot(), u64::MAX);
assert_eq!(summary.reference().state_hash(), ksp_store_api::RawContentHash::new([3; 32]));
assert_eq!(summary.lamports(), u64::MAX);
assert_eq!(summary.owner(), &ksp_store_api::Pubkey::new_from_array([2; 32]));
assert!(summary.executable());
assert_eq!(summary.rent_epoch(), u64::MAX);
assert_eq!(summary.data_length_bytes(), 4);
return;
}
#[test]
fn v0_3_8_pre_005_inspection_summary_rejects_hostile_width_decimal_and_data_length() {
let network = network();
let mut bad_owner = inspection_row(4);
bad_owner.owner = std::option::Option::Some(vec![2; 31]);
assert_eq!(
super::decode_raw_account_inspection_summary(&network, bad_owner).err().map(|value| return value.kind()),
std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid)
);
let mut bad_slot = inspection_row(4);
bad_slot.slot_text = std::option::Option::Some("18446744073709551616-HOSTILE".to_owned());
let error = match super::decode_raw_account_inspection_summary(&network, bad_slot) {
std::result::Result::Err(value) => value,
std::result::Result::Ok(_) => panic!("hostile account inspection slot unexpectedly decoded"),
};
assert_eq!(error.kind(), crate::PostgresBackendErrorKind::DataInvalid);
assert!(!std::format!("{error:?}").contains("HOSTILE"));
let maximum = match i64::try_from(ksp_store_api::MAX_RAW_ACCOUNT_DATA_BYTES) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => panic!("account data bound must fit PostgreSQL BIGINT in test fixture"),
};
for length in [-1_i64, maximum.saturating_add(1)] {
let result = super::decode_raw_account_inspection_summary(&network, inspection_row(length));
assert_eq!(result.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid));
}
return;
}
#[test]
fn pre_004_account_state_row_round_trips_complete_u64_domain_and_bytes() {
let network = network();
let decoded = super::decode_raw_account_state_row(&network, state_row());
let state = match decoded {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account state row rejected: {error:?}"),
};
assert_eq!(state.reference().network().as_str(), "devnet");
assert_eq!(state.reference().pubkey(), &ksp_store_api::Pubkey::new_from_array([1_u8; 32]));
assert_eq!(state.reference().slot(), u64::MAX);
assert_eq!(state.reference().state_hash(), ksp_store_api::RawContentHash::new([3_u8; 32]));
assert_eq!(state.lamports(), u64::MAX);
assert_eq!(state.owner(), &ksp_store_api::Pubkey::new_from_array([2_u8; 32]));
assert!(state.executable());
assert_eq!(state.rent_epoch(), u64::MAX);
assert_eq!(state.data(), &[1, 2, 3, 4]);
return;
}
#[test]
fn pre_004_account_state_accepts_empty_data_and_rejects_oversized_data() {
let network = network();
let mut empty = state_row();
empty.data = std::vec::Vec::new();
let empty = super::decode_raw_account_state_row(&network, empty);
assert!(matches!(empty, std::result::Result::Ok(_)));
let mut oversized = state_row();
oversized.data = vec![0_u8; ksp_store_api::MAX_RAW_ACCOUNT_DATA_BYTES + 1];
let oversized = super::decode_raw_account_state_row(&network, oversized);
assert_eq!(oversized.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid));
return;
}
#[test]
fn pre_004_account_state_rejects_hostile_width_and_decimal_rows_without_echo() {
let network = network();
let mut bad_pubkey = state_row();
bad_pubkey.pubkey = vec![0xA5; 31];
let error = super::decode_raw_account_state_row(&network, bad_pubkey).err();
assert_eq!(error.map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid));
let mut bad_slot = state_row();
bad_slot.slot_text = "18446744073709551616-HOSTILE".to_owned();
let error = match super::decode_raw_account_state_row(&network, bad_slot) {
std::result::Result::Err(value) => value,
std::result::Result::Ok(_) => panic!("hostile slot unexpectedly decoded"),
};
assert_eq!(error.kind(), crate::PostgresBackendErrorKind::DataInvalid);
assert!(!std::format!("{error:?}").contains("HOSTILE"));
let mut bad_lamports = state_row();
bad_lamports.lamports_text = "-1".to_owned();
assert_eq!(
super::decode_raw_account_state_row(&network, bad_lamports).err().map(|value| return value.kind()),
std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid)
);
return;
}
#[test]
fn pre_004_account_observation_round_trips_complete_provenance_and_yellowstone_metadata() {
let network = network();
let decoded = super::decode_raw_account_observation_row(&network, observation_row());
let observation = match decoded {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account observation row rejected: {error:?}"),
};
assert_eq!(observation.observation_key(), ksp_store_api::RawObservationKey::new([4_u8; 32]));
assert_eq!(observation.account().network().as_str(), "devnet");
assert_eq!(observation.account().pubkey(), &ksp_store_api::Pubkey::new_from_array([1_u8; 32]));
assert_eq!(observation.account().slot(), u64::MAX);
assert_eq!(observation.account().state_hash(), ksp_store_api::RawContentHash::new([3_u8; 32]));
assert_eq!(observation.provenance().provider().as_str(), "publicnode");
assert_eq!(observation.provenance().protocol().as_str(), "yellowstone_grpc");
assert_eq!(observation.provenance().acquisition_method().as_str(), "account_subscribe");
assert_eq!(observation.provenance().capture_session_id().map(|value| return value.as_str()), std::option::Option::Some("session_1"));
assert_eq!(observation.provenance().commitment().map(|value| return value.as_str()), std::option::Option::Some("confirmed"));
assert_eq!(observation.provenance().endpoint_id().map(|value| return value.as_str()), std::option::Option::Some("endpoint_1"));
assert_eq!(observation.provenance().filter_id().map(|value| return value.as_str()), std::option::Option::Some("filter_1"));
assert_eq!(observation.provenance().received_at().unix_millis(), 1_700_000_000_001);
assert_eq!(observation.provenance().observed_at().map(|value| return value.unix_millis()), std::option::Option::Some(1_700_000_000_000));
assert_eq!(observation.provenance().source_payload_hash(), std::option::Option::Some(ksp_store_api::RawContentHash::new([5_u8; 32])));
assert_eq!(observation.provenance().source_payload_size_bytes(), std::option::Option::Some(ksp_store_api::MAX_RAW_SOURCE_PAYLOAD_BYTES));
assert_eq!(observation.is_startup(), std::option::Option::Some(true));
assert_eq!(observation.transaction_signature(), std::option::Option::Some(ksp_store_api::RawTransactionSignature::new([6_u8; 64])));
assert_eq!(observation.write_version(), std::option::Option::Some(u64::MAX));
return;
}
#[test]
fn pre_004_account_observation_keeps_optional_metadata_absent() {
let network = network();
let mut row = observation_row();
row.capture_session_id = std::option::Option::None;
row.commitment = std::option::Option::None;
row.endpoint_id = std::option::Option::None;
row.filter_id = std::option::Option::None;
row.observed_at_unix_millis = std::option::Option::None;
row.source_payload_hash = std::option::Option::None;
row.source_payload_size_bytes = std::option::Option::None;
row.is_startup = std::option::Option::None;
row.transaction_signature = std::option::Option::None;
row.write_version_text = std::option::Option::None;
let decoded = super::decode_raw_account_observation_row(&network, row);
let observation = match decoded {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid sparse account observation rejected: {error:?}"),
};
assert!(observation.provenance().capture_session_id().is_none());
assert!(observation.provenance().commitment().is_none());
assert!(observation.provenance().endpoint_id().is_none());
assert!(observation.provenance().filter_id().is_none());
assert!(observation.provenance().observed_at().is_none());
assert!(observation.provenance().source_payload_hash().is_none());
assert!(observation.provenance().source_payload_size_bytes().is_none());
assert!(observation.is_startup().is_none());
assert!(observation.transaction_signature().is_none());
assert!(observation.write_version().is_none());
return;
}
#[test]
fn pre_004_account_observation_rejects_hostile_rows_without_echoing_values() {
let network = network();
let mut bad_signature = observation_row();
bad_signature.transaction_signature = std::option::Option::Some(vec![8; 63]);
assert_eq!(
super::decode_raw_account_observation_row(&network, bad_signature).err().map(|value| return value.kind()),
std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid)
);
let mut bad_write_version = observation_row();
bad_write_version.write_version_text = std::option::Option::Some("18446744073709551616-HOSTILE".to_owned());
let error = match super::decode_raw_account_observation_row(&network, bad_write_version) {
std::result::Result::Err(value) => value,
std::result::Result::Ok(_) => panic!("hostile write version unexpectedly decoded"),
};
assert_eq!(error.kind(), crate::PostgresBackendErrorKind::DataInvalid);
assert!(!std::format!("{error:?}").contains("HOSTILE"));
let mut bad_origin = observation_row();
bad_origin.origin = "hostile-origin".to_owned();
assert_eq!(
super::decode_raw_account_observation_row(&network, bad_origin).err().map(|value| return value.kind()),
std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid)
);
let mut bad_time = observation_row();
bad_time.observed_at_unix_millis = std::option::Option::Some(bad_time.received_at_unix_millis + 1);
assert_eq!(
super::decode_raw_account_observation_row(&network, bad_time).err().map(|value| return value.kind()),
std::option::Option::Some(crate::PostgresBackendErrorKind::DataInvalid)
);
return;
}
#[test]
fn pre_004_account_wrong_network_guard_is_pre_io_and_static() {
let backend = network();
let foreign = match ksp_store_api::RawNetworkId::new("mainnet-beta") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign network rejected: {error:?}"),
};
let reference = ksp_store_api::RawAccountStateReference::new(
foreign,
ksp_store_api::Pubkey::new_from_array([1_u8; 32]),
1,
ksp_store_api::RawContentHash::new([2_u8; 32]),
);
let error = super::ensure_network(&backend, &reference, "raw_account_state_network").err();
let error = match error {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("wrong-network account reference unexpectedly accepted"),
};
assert_eq!(error.kind(), crate::PostgresBackendErrorKind::WrongNetwork);
assert_eq!(error.phase(), "raw_account_state_network");
return;
}
#[test]
fn pre_005_account_acquisition_input_guard_requires_network_and_exact_reference() {
let backend = network();
let valid_state = match super::decode_raw_account_state_row(&backend, state_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account state rejected: {error:?}"),
};
let valid_observation = match super::decode_raw_account_observation_row(&backend, observation_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account observation rejected: {error:?}"),
};
assert!(super::ensure_acquisition_inputs(&backend, &valid_state, &valid_observation).is_ok());
let foreign = match ksp_store_api::RawNetworkId::new("mainnet-beta") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign network rejected: {error:?}"),
};
let foreign_state = match super::decode_raw_account_state_row(&foreign, state_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign account state rejected: {error:?}"),
};
let foreign_observation = match super::decode_raw_account_observation_row(&foreign, observation_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign account observation rejected: {error:?}"),
};
let error = super::ensure_acquisition_inputs(&backend, &foreign_state, &foreign_observation).err();
assert_eq!(error.map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::WrongNetwork));
let mut mismatched_row = observation_row();
mismatched_row.account_state_hash = vec![9; 32];
let mismatched_observation = match super::decode_raw_account_observation_row(&backend, mismatched_row) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid mismatched observation model rejected: {error:?}"),
};
let error = super::ensure_acquisition_inputs(&backend, &valid_state, &mismatched_observation).err();
assert_eq!(error.map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::Conflict));
return;
}
#[test]
fn pre_005_account_state_idempotence_compares_complete_content_not_state_hash_only() {
let backend = network();
let first = match super::decode_raw_account_state_row(&backend, state_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account state rejected: {error:?}"),
};
let identical = match super::decode_raw_account_state_row(&backend, state_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid identical account state rejected: {error:?}"),
};
assert!(super::raw_account_states_equal(&first, &identical));
let mut divergent_row = state_row();
divergent_row.lamports_text = (u64::MAX - 1).to_string();
let divergent = match super::decode_raw_account_state_row(&backend, divergent_row) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid divergent account state rejected: {error:?}"),
};
assert_eq!(first.reference(), divergent.reference());
assert!(!super::raw_account_states_equal(&first, &divergent));
return;
}
#[test]
fn pre_005_account_observation_idempotence_compares_optional_metadata_exactly() {
let backend = network();
let first = match super::decode_raw_account_observation_row(&backend, observation_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account observation rejected: {error:?}"),
};
let identical = match super::decode_raw_account_observation_row(&backend, observation_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid identical account observation rejected: {error:?}"),
};
assert_eq!(first, identical);
let mut divergent_row = observation_row();
divergent_row.write_version_text = std::option::Option::Some((u64::MAX - 1).to_string());
let divergent = match super::decode_raw_account_observation_row(&backend, divergent_row) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid divergent account observation rejected: {error:?}"),
};
assert_eq!(first.observation_key(), divergent.observation_key());
assert_eq!(first.account(), divergent.account());
assert_ne!(first, divergent);
return;
}
#[test]
fn pre_005_account_origin_encoding_is_exact_and_static() {
let cases = [
(ksp_store_api::RawAcquisitionOrigin::Backfill, "backfill"),
(ksp_store_api::RawAcquisitionOrigin::Import, "import"),
(ksp_store_api::RawAcquisitionOrigin::Live, "live"),
(ksp_store_api::RawAcquisitionOrigin::Repair, "repair"),
(ksp_store_api::RawAcquisitionOrigin::Replay, "replay"),
];
for (origin, expected) in cases {
let encoded = match super::encode_origin(origin) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account origin rejected: {error:?}"),
};
assert_eq!(encoded, expected);
}
return;
}
#[test]
fn pre_006_additional_observation_input_guard_rejects_wrong_network_before_io() {
let backend = network();
let foreign = match ksp_store_api::RawNetworkId::new("mainnet-beta") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign network rejected: {error:?}"),
};
let observation = match super::decode_raw_account_observation_row(&foreign, observation_row()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid foreign account observation rejected: {error:?}"),
};
let error = super::ensure_observation_write_input(&backend, &observation).err();
assert_eq!(error.map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::WrongNetwork));
return;
}
#[test]
fn pre_006_additional_observation_race_and_cancellation_contract_is_transaction_bounded() {
let source = include_str!("../src/raw_account.rs");
let start = match source.find("pub(crate) async fn record_raw_account_observation") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("record_raw_account_observation function missing"),
};
let tail = &source[start..];
let end = match tail.find("fn raw_account_observation_db_row") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("record_raw_account_observation boundary missing"),
};
let function = &tail[..end];
let begin = match function.find("client.transaction().await") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("additional observation transaction begin missing"),
};
let key_share = match function.find("LOCK_ACCOUNT_REFERENCE_SQL") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("additional observation reference lock missing"),
};
let persist = match function.find("persist_account_observation_row") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("additional observation insert/compare missing"),
};
let commit = match function.find("sql_transaction.commit().await") {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("additional observation commit missing"),
};
assert!(begin < key_share);
assert!(key_share < persist);
assert!(persist < commit);
assert!(!function.contains("tokio::spawn"));
assert!(!function.contains("std::mem::forget"));
assert!(!function.contains("ON CONFLICT DO UPDATE"));
return;
}
#[test]
fn pre_007_account_cursor_v1_round_trip_is_fixed_109_bytes_and_exact() {
let pubkey = ksp_store_api::Pubkey::new_from_array([7_u8; 32]);
let query = page_query(
"devnet",
std::option::Option::Some(pubkey),
std::option::Option::Some(10),
std::option::Option::Some(20),
ksp_store_api::RawSortDirection::Ascending,
);
let state_hash = ksp_store_api::RawContentHash::new([9_u8; 32]);
let cursor = match crate::encode_raw_account_cursor(&query, 15, &pubkey, &state_hash) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account cursor encoding rejected: {error:?}"),
};
assert_eq!(cursor.as_bytes().len(), 109);
assert_eq!(cursor.as_bytes().get(0..4), std::option::Option::Some(b"KSPA".as_ref()));
assert_eq!(cursor.as_bytes().get(4).copied(), std::option::Option::Some(1));
let decoded = match crate::decode_raw_account_cursor(&query, &cursor) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account cursor decoding rejected: {error:?}"),
};
assert_eq!(decoded.last_slot, 15);
assert_eq!(decoded.last_pubkey, [7_u8; 32]);
assert_eq!(decoded.last_state_hash, [9_u8; 32]);
assert_eq!(std::format!("{cursor:?}"), "RawPageCursor { len: 109 }");
return;
}
#[test]
fn pre_007_account_cursor_rejects_replay_across_query_context_and_transaction_family() {
let pubkey = ksp_store_api::Pubkey::new_from_array([4_u8; 32]);
let query = page_query(
"devnet",
std::option::Option::Some(pubkey),
std::option::Option::Some(10),
std::option::Option::Some(20),
ksp_store_api::RawSortDirection::Ascending,
);
let state_hash = ksp_store_api::RawContentHash::new([5_u8; 32]);
let cursor = match crate::encode_raw_account_cursor(&query, 15, &pubkey, &state_hash) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account cursor encoding rejected: {error:?}"),
};
let other_network = page_query("mainnet-beta", Some(pubkey), Some(10), Some(20), ksp_store_api::RawSortDirection::Ascending);
let other_pubkey =
page_query("devnet", Some(ksp_store_api::Pubkey::new_from_array([6_u8; 32])), Some(10), Some(20), ksp_store_api::RawSortDirection::Ascending);
let other_direction = page_query("devnet", Some(pubkey), Some(10), Some(20), ksp_store_api::RawSortDirection::Descending);
let other_range = page_query("devnet", Some(pubkey), Some(11), Some(20), ksp_store_api::RawSortDirection::Ascending);
for candidate in [&other_network, &other_pubkey, &other_direction, &other_range] {
let error = crate::decode_raw_account_cursor(candidate, &cursor).err();
assert_eq!(error.map(|value| return value.kind()), Some(crate::PostgresBackendErrorKind::QueryInvalid));
}
let transaction_query = match ksp_store_api::RawSlotRange::new(Some(10), Some(20)) {
std::result::Result::Ok(slots) => {
let limit = match ksp_store_api::RawPageLimit::new(2) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid transaction page limit rejected: {error:?}"),
};
ksp_store_api::RawTransactionQuery::new(network(), slots, ksp_store_api::RawSortDirection::Ascending, ksp_store_api::RawPageRequest::first(limit))
},
std::result::Result::Err(error) => panic!("valid transaction slot range rejected: {error:?}"),
};
let signature = ksp_store_api::RawTransactionSignature::new([8_u8; 64]);
let transaction_cursor = match crate::encode_raw_transaction_cursor(&transaction_query, 15, &signature) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid transaction cursor encoding rejected: {error:?}"),
};
let error = crate::decode_raw_account_cursor(&query, &transaction_cursor).err();
assert_eq!(error.map(|value| return value.phase()), Some("raw_account_cursor_magic"));
return;
}
#[test]
fn pre_007_account_cursor_hostile_size_magic_version_and_digest_are_rejected() {
let query = page_query("devnet", None, None, None, ksp_store_api::RawSortDirection::Ascending);
for size in [1_usize, 108, 109, 110, 4_096] {
let raw = match ksp_store_api::RawPageCursor::try_new(vec![0_u8; size].into_boxed_slice()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("bounded hostile cursor rejected by API before backend test: {error:?}"),
};
assert!(crate::decode_raw_account_cursor(&query, &raw).is_err());
}
let pubkey = ksp_store_api::Pubkey::new_from_array([3_u8; 32]);
let state_hash = ksp_store_api::RawContentHash::new([2_u8; 32]);
let valid = match crate::encode_raw_account_cursor(&query, 42, &pubkey, &state_hash) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account cursor encoding rejected: {error:?}"),
};
for index in [0_usize, 4, 108] {
let mut bytes = valid.as_bytes().to_vec();
bytes[index] ^= 0xff;
let hostile = match ksp_store_api::RawPageCursor::try_new(bytes.into_boxed_slice()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("fixed-size hostile cursor rejected by API before backend test: {error:?}"),
};
let error = crate::decode_raw_account_cursor(&query, &hostile).err();
assert_eq!(error.map(|value| return value.kind()), Some(crate::PostgresBackendErrorKind::QueryInvalid));
}
return;
}
#[test]
fn pre_007_account_page_limit_exposes_only_the_real_postgres_limit_plus_one_boundary() {
let maximum = crate::raw_account_physical_page_limit(9_223_372_036_854_775_806);
assert_eq!(maximum, Ok((9_223_372_036_854_775_806_usize, i64::MAX)));
let rejected = crate::raw_account_physical_page_limit(9_223_372_036_854_775_807).err();
assert_eq!(rejected.map(|value| return value.kind()), Some(crate::PostgresBackendErrorKind::PageLimitUnsupported));
return;
}
#[test]
fn pre_007_account_list_row_decodes_full_reference_without_integer_narrowing() {
let row = super::RawAccountListDbRow { pubkey: vec![1_u8; 32], slot_text: u64::MAX.to_string(), state_hash: vec![2_u8; 32] };
let decoded = match super::decode_raw_account_list_row(&network(), row) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("valid account list row rejected: {error:?}"),
};
assert_eq!(decoded.0, u64::MAX);
assert_eq!(decoded.1.pubkey(), &ksp_store_api::Pubkey::new_from_array([1_u8; 32]));
assert_eq!(decoded.1.slot(), u64::MAX);
assert_eq!(decoded.1.state_hash(), ksp_store_api::RawContentHash::new([2_u8; 32]));
return;
}