v0.3.12-pre.005

This commit is contained in:
2026-09-09 12:45:29 +02:00
parent df1dbbb8fb
commit 3a8fa87acb
9 changed files with 846 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
// version: 4
// version: 5
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
return grpc_endpoint_with_identity(cluster, "yellowstone-fixture", "fixture-provider");
@@ -112,6 +112,73 @@ impl super::RawTransactionIngestYellowstoneSignalView for SignalViewFixture {
}
}
struct BlockViewFixture {
created_at: std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp>,
filters: std::vec::Vec<ksp_onchain_transport_lib::YellowstoneSubscribeFilterName>,
slot: u64,
transactions: std::vec::Vec<(ksp_onchain_transport_lib::YellowstoneTransactionSignature, u64)>,
}
impl super::RawTransactionIngestYellowstoneBlockView for BlockViewFixture {
fn created_at(&self) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp> {
return self.created_at;
}
fn filters(&self) -> &[ksp_onchain_transport_lib::YellowstoneSubscribeFilterName] {
return self.filters.as_slice();
}
fn slot(&self) -> u64 {
return self.slot;
}
fn transaction_count(&self) -> usize {
return self.transactions.len();
}
fn transaction_identity(&self, position: usize) -> ksp_core_lib::Result<(ksp_onchain_transport_lib::YellowstoneTransactionSignature, u64)> {
return match self.transactions.get(position) {
std::option::Option::Some(value) => std::result::Result::Ok(*value),
std::option::Option::None => std::result::Result::Err(crate::runtime_error("fixture.block_transaction_missing")),
};
}
}
struct ContinuityViewFixture {
created_at: std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp>,
family: super::RawTransactionIngestContinuityFamily,
filters: std::vec::Vec<ksp_onchain_transport_lib::YellowstoneSubscribeFilterName>,
parent_slot: std::option::Option<u64>,
slot: u64,
status: std::option::Option<super::RawTransactionIngestContinuityStatus>,
}
impl super::RawTransactionIngestYellowstoneContinuityView for ContinuityViewFixture {
fn created_at(&self) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp> {
return self.created_at;
}
fn family(&self) -> super::RawTransactionIngestContinuityFamily {
return self.family;
}
fn filters(&self) -> &[ksp_onchain_transport_lib::YellowstoneSubscribeFilterName] {
return self.filters.as_slice();
}
fn parent_slot(&self) -> std::option::Option<u64> {
return self.parent_slot;
}
fn slot(&self) -> u64 {
return self.slot;
}
fn status(&self) -> std::option::Option<super::RawTransactionIngestContinuityStatus> {
return self.status;
}
}
fn filter_names(values: &[&str]) -> std::option::Option<std::vec::Vec<ksp_onchain_transport_lib::YellowstoneSubscribeFilterName>> {
let mut filters = std::vec::Vec::with_capacity(values.len());
for value in values {
@@ -478,6 +545,8 @@ async fn pre_002_runtime_resource_debug_is_safe_and_exposes_no_client_inner() {
let debug = std::format!("{resources:?}");
assert!(debug.contains("RawTransactionIngestRuntimeResources"));
assert!(debug.contains("devnet"));
assert!(debug.contains("blocks_meta_filter_count"));
assert!(debug.contains("slot_filter_count"));
assert!(!debug.contains("GRPC-SECRET-CANARY"));
assert!(!debug.contains("HTTP-SECRET-CANARY"));
assert!(!debug.contains("127.0.0.1"));
@@ -668,6 +737,150 @@ async fn pre_003_source_rejects_route_identity_that_cannot_become_safe_provenanc
return;
}
#[tokio::test(flavor = "current_thread")]
async fn pre_005_block_projects_transaction_signals_in_exact_source_order() {
let source = match signal_source() {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let filters = match filter_names(&["block-filter-b", "block-filter-a"]) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let created_at = match ksp_onchain_transport_lib::YellowstoneUpdateTimestamp::new(1_760_000_321, 123_000_000) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let fixture = BlockViewFixture {
created_at: std::option::Option::Some(created_at),
filters,
slot: 777,
transactions: std::vec![
(ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([0x11; 64]), 9),
(ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([0x22; 64]), 3),
(ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([0x33; 64]), 17),
],
};
let signals = match super::project_yellowstone_block_signals(&source, &fixture) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(signals.len(), 3);
assert_eq!(signals[0].signature.as_bytes(), &[0x11; 64]);
assert_eq!(signals[1].signature.as_bytes(), &[0x22; 64]);
assert_eq!(signals[2].signature.as_bytes(), &[0x33; 64]);
assert_eq!(signals[0].transaction_index, std::option::Option::Some(9));
assert_eq!(signals[1].transaction_index, std::option::Option::Some(3));
assert_eq!(signals[2].transaction_index, std::option::Option::Some(17));
for signal in &signals {
assert_eq!(signal.family, super::RawTransactionIngestSourceFamily::Block);
assert_eq!(signal.slot, 777);
assert_eq!(signal.network.as_str(), "devnet");
assert_eq!(signal.matched_filter_count, 2);
assert_eq!(signal.created_at, std::option::Option::Some(super::RawTransactionIngestSourceTimestamp { nanos: 123_000_000, seconds: 1_760_000_321 }));
}
return;
}
#[tokio::test(flavor = "current_thread")]
async fn pre_005_block_hydration_uses_distinct_composite_method() {
let source = match signal_source() {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let settings = match pre_004_settings() {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let signal = match pre_004_signal(&source, super::RawTransactionIngestSourceFamily::Block, 42, 7, &["block-filter"], 0) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let received_at = match ksp_store_lib::RawTimestamp::from_unix_millis(1_760_000_124_000) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let provenance = match super::build_hydration_provenance(
&settings,
&signal,
"fixture-http-provider",
"http-hydration-fixture",
ksp_onchain_transport_lib::SolanaCommitment::Confirmed,
received_at,
) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(provenance.acquisition_method().as_str(), "block_get_transaction");
return;
}
#[tokio::test(flavor = "current_thread")]
async fn pre_005_block_meta_and_slot_project_continuity_only_without_remote_dead_error() {
let source = match signal_source() {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let block_filters = match filter_names(&["block-meta-filter"]) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let slot_filters = match filter_names(&["slot-filter-secret", "slot-filter-secret"]) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let block_meta = ContinuityViewFixture {
created_at: std::option::Option::None,
family: super::RawTransactionIngestContinuityFamily::BlockMeta,
filters: block_filters,
parent_slot: std::option::Option::Some(899),
slot: 900,
status: std::option::Option::None,
};
let slot = ContinuityViewFixture {
created_at: std::option::Option::None,
family: super::RawTransactionIngestContinuityFamily::Slot,
filters: slot_filters,
parent_slot: std::option::Option::Some(900),
slot: 901,
status: std::option::Option::Some(super::RawTransactionIngestContinuityStatus::Dead),
};
let block_meta_signal = super::project_yellowstone_continuity_signal(&source, &block_meta);
let slot_signal = super::project_yellowstone_continuity_signal(&source, &slot);
assert_eq!(block_meta_signal.family, super::RawTransactionIngestContinuityFamily::BlockMeta);
assert_eq!(block_meta_signal.slot, 900);
assert_eq!(block_meta_signal.parent_slot, std::option::Option::Some(899));
assert_eq!(block_meta_signal.status, std::option::Option::None);
assert_eq!(slot_signal.family, super::RawTransactionIngestContinuityFamily::Slot);
assert_eq!(slot_signal.slot, 901);
assert_eq!(slot_signal.parent_slot, std::option::Option::Some(900));
assert_eq!(slot_signal.status, std::option::Option::Some(super::RawTransactionIngestContinuityStatus::Dead));
assert_eq!(slot_signal.matched_filter_count, 2);
let debug = std::format!("{slot_signal:?}");
assert!(!debug.contains("slot-filter-secret"));
assert!(!debug.contains("dead_error"));
assert!(!debug.contains("transaction"));
assert!(!debug.contains("meta"));
assert!(!debug.contains("payload"));
return;
}
#[test]
fn pre_005_slot_status_projection_is_exact_and_source_neutral() {
for (source, expected) in [
(ksp_onchain_transport_lib::YellowstoneSlotStatus::Processed, super::RawTransactionIngestContinuityStatus::Processed),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::Confirmed, super::RawTransactionIngestContinuityStatus::Confirmed),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::Finalized, super::RawTransactionIngestContinuityStatus::Finalized),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::FirstShredReceived, super::RawTransactionIngestContinuityStatus::FirstShredReceived),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::Completed, super::RawTransactionIngestContinuityStatus::Completed),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::CreatedBank, super::RawTransactionIngestContinuityStatus::CreatedBank),
(ksp_onchain_transport_lib::YellowstoneSlotStatus::Dead, super::RawTransactionIngestContinuityStatus::Dead),
] {
assert_eq!(super::map_yellowstone_slot_status(source), expected);
}
return;
}
#[test]
fn pre_004_composite_provenance_rejects_overflow_without_truncation() {
let provider = match ksp_store_lib::RawProvenanceCode::new("yellowstone-provider") {