v0.3.4-pre.004
This commit is contained in:
221
crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
Normal file
221
crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
Normal file
@@ -0,0 +1,221 @@
|
||||
// file: crates/ksp-store-postgres-lib/unit_tests/raw_account.rs
|
||||
// version: 1
|
||||
|
||||
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 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()),
|
||||
};
|
||||
}
|
||||
|
||||
#[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;
|
||||
}
|
||||
Reference in New Issue
Block a user