653 lines
26 KiB
Rust
653 lines
26 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/dependency_boundary.rs
|
|
// version: 26
|
|
|
|
//! Dependency firewall canaries for the RAW transaction ingest Worker foundation.
|
|
|
|
#[test]
|
|
fn pre_002_manifest_dependency_surface_is_exact() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let dependencies = dependency_section(manifest);
|
|
let names = manifest_dependency_names(dependencies);
|
|
assert_eq!(
|
|
names,
|
|
vec![
|
|
"ksp-core-lib",
|
|
"ksp-logging-lib",
|
|
"ksp-onchain-transport-lib",
|
|
"ksp-raw-transaction-lib",
|
|
"ksp-store-lib",
|
|
"ksp-worker-api",
|
|
"sha2",
|
|
"tokio",
|
|
],
|
|
);
|
|
for required in [
|
|
"ksp-core-lib = { path = \"../ksp-core-lib\" }",
|
|
"ksp-logging-lib = { path = \"../ksp-logging-lib\" }",
|
|
"ksp-onchain-transport-lib = { path = \"../ksp-onchain-transport-lib\" }",
|
|
"ksp-raw-transaction-lib = { path = \"../ksp-raw-transaction-lib\" }",
|
|
"ksp-store-lib = { path = \"../ksp-store-lib\", default-features = false }",
|
|
"ksp-worker-api = { path = \"../ksp-worker-api\" }",
|
|
"sha2 = { workspace = true }",
|
|
"tokio = { workspace = true, features = [\"macros\", \"rt\", \"sync\", \"time\"] }",
|
|
] {
|
|
assert!(dependencies.contains(required), "required Worker dependency missing: {required}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_002_manifest_opens_only_the_onchain_transport_live_source_edge() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let dependencies = dependency_section(manifest);
|
|
for forbidden in [
|
|
"futures-util",
|
|
"ksp-config-lib",
|
|
"ksp-interface-lib",
|
|
"ksp-job-api",
|
|
"ksp-job-backfill-lib",
|
|
"ksp-program-api",
|
|
"ksp-store-api",
|
|
"ksp-store-postgres-lib",
|
|
"ksp-wallet-lib",
|
|
"reqwest",
|
|
"solana-",
|
|
"tokio-tungstenite",
|
|
"tonic",
|
|
"yellowstone-grpc-proto",
|
|
] {
|
|
assert!(!dependencies.contains(forbidden), "forbidden Worker dependency present: {forbidden}");
|
|
}
|
|
assert!(!manifest.contains("[dev-dependencies]"), "foundation requires no test-only dependency");
|
|
assert!(!manifest.contains("[build-dependencies]"), "foundation requires no build dependency");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_003_transaction_and_status_adapters_are_private_and_transport_facade_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestYellowstoneSignalView for ksp_onchain_transport_lib::YellowstoneTransactionUpdate",
|
|
"RawTransactionIngestYellowstoneSignalView for ksp_onchain_transport_lib::YellowstoneTransactionStatusUpdate",
|
|
"YellowstoneTransactionUpdate::transaction(self).signature()",
|
|
"YellowstoneTransactionUpdate::transaction(self).index()",
|
|
"YellowstoneTransactionStatusUpdate::signature(self)",
|
|
"YellowstoneTransactionStatusUpdate::index(self)",
|
|
"RawTransactionSignature::new",
|
|
"matched_filter_fingerprint",
|
|
"yellowstone_provider_unrepresentable",
|
|
"yellowstone_endpoint_unrepresentable",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.003 signal-adapter contract missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"pub struct RawTransactionIngestSourceSignal",
|
|
"pub(crate) struct RawTransactionIngestSourceSignal",
|
|
"pub use self::runtime_resources::RawTransactionIngestSourceSignal",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
] {
|
|
assert!(!resources.contains(forbidden) && !root.contains(forbidden), "pre.003 crossed a private/offline boundary: {forbidden}");
|
|
}
|
|
let status_impl =
|
|
match resources.split_once("impl RawTransactionIngestYellowstoneSignalView for ksp_onchain_transport_lib::YellowstoneTransactionStatusUpdate") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl std::convert::From<") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => tail,
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
assert!(!status_impl.contains("::error(self)"), "TransactionStatus remote error material must not enter the private signal");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_004_hydration_contract_uses_only_transport_facade_common_raw_and_existing_ingress() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"get_transaction_observed",
|
|
"SolanaGetTransactionConfig::new",
|
|
"SolanaTransactionEncoding::Base64",
|
|
"format_raw_transaction_signature",
|
|
"extract_raw_transaction_signature_from_binary_base64",
|
|
"RawTransactionMaterial::binary_base64",
|
|
"RawTransactionIngress",
|
|
"yellowstone_http",
|
|
"transaction_get_transaction",
|
|
"status_get_transaction",
|
|
"RawAcquisitionOrigin::Live",
|
|
"composite_provenance_codes",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.004 hydration contract missing: {required}");
|
|
}
|
|
assert!(resources.contains("fn finalize_hydration"));
|
|
assert!(resources.contains("fn fetch_hydration"));
|
|
for forbidden in ["ksp_config_lib::", "ksp_job_backfill_lib::", "ksp_store_postgres_lib::", "reqwest::", "tonic::", "yellowstone_grpc_proto::"] {
|
|
assert!(!resources.contains(forbidden) && !root.contains(forbidden), "pre.004 crossed a forbidden boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_005_block_and_continuity_adapters_remain_private_and_transport_facade_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestYellowstoneBlockView",
|
|
"YellowstoneBlockUpdate",
|
|
"project_yellowstone_block_signals",
|
|
"RawTransactionIngestYellowstoneContinuityView",
|
|
"YellowstoneBlockMetaUpdate",
|
|
"YellowstoneSlotUpdate",
|
|
"RawTransactionIngestContinuitySignal",
|
|
"block_get_transaction",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.005 private adapter contract missing: {required}");
|
|
}
|
|
for forbidden in ["ksp_config_lib::", "ksp_job_backfill_lib::", "ksp_store_postgres_lib::", "reqwest::", "tonic::", "yellowstone_grpc_proto::"] {
|
|
assert!(!resources.contains(forbidden) && !root.contains(forbidden), "pre.005 crossed a forbidden boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_006_productive_source_uses_transport_session_bounded_coalescence_and_existing_admission() {
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in ["children.spawn", ".run_live_sources(source_settings, stop_receiver, admission_sender, processing_frontier_sender)"] {
|
|
assert!(runtime.contains(required), "required pre.006 supervisor wiring missing: {required}");
|
|
}
|
|
for required in [
|
|
"open_standard_subscribe",
|
|
"next_update",
|
|
"RawTransactionIngestHydrationCoordinator",
|
|
"std::collections::BTreeMap",
|
|
"tokio::task::JoinSet",
|
|
"RawTransactionIngestHydrationCoordinator::with_global_registry(",
|
|
"hydration_pending_limit,",
|
|
"hydration_in_flight_limit,",
|
|
"get_transaction_observed",
|
|
"admission_sender.send(ingress)",
|
|
"tasks.abort_all()",
|
|
"session.close().await",
|
|
"commitment: hydration.commitment.as_str()",
|
|
"network: signal.network.clone()",
|
|
"signature: signal.signature",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.006 productive-source contract missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"unbounded_channel",
|
|
] {
|
|
assert!(!runtime.contains(forbidden) && !resources.contains(forbidden), "pre.006 crossed a forbidden productive-source boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_006_http_block_polling_reuses_transport_facades_without_becoming_backfill() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestHttpBlockPollingSource",
|
|
"get_slot(&self.polling_role",
|
|
"get_blocks_with_limit(",
|
|
"get_block_observed(&self.polling_role",
|
|
"let mut next_scan_slot = start_slot",
|
|
"next_scan_slot = slot",
|
|
"tokio::time::sleep(self.poll_interval)",
|
|
"RawAcquisitionOrigin::Live",
|
|
"block_polling_get_block",
|
|
"SolanaTransactionEncoding::Base64",
|
|
"SolanaTransactionDetails::Full",
|
|
"std::option::Option::Some(1)",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.006 HTTP polling contract missing: {required}");
|
|
}
|
|
let source_impl = match resources.split_once("impl crate::RawTransactionIngestHttpBlockPollingSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl std::fmt::Debug for crate::RawTransactionIngestHttpBlockPollingSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
assert_eq!(source_impl.matches("get_block_observed(").count(), 1);
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"unbounded_channel",
|
|
] {
|
|
assert!(!source_impl.contains(forbidden) && !root.contains(forbidden), "pre.006 HTTP polling crossed a forbidden boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_003_standard_logs_source_reuses_transport_facades_and_common_hydration_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestStandardLogsSource",
|
|
"SolanaStandardWsSession::connect",
|
|
".logs_subscribe(",
|
|
"SolanaLogsSubscribeFilter",
|
|
"SolanaCommitmentConfig::new",
|
|
"project_standard_logs_signal",
|
|
"RawTransactionIngestSourceFamily::Logs",
|
|
"logs_get_transaction",
|
|
"solana_ws_http",
|
|
"get_transaction_observed",
|
|
"RawTransactionIngestHydrationCoordinator::with_global_registry(",
|
|
"hydration_pending_limit,",
|
|
"hydration_in_flight_limit,",
|
|
"std::option::Option::Some(1)",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.003 standard logs contract missing: {required}");
|
|
}
|
|
assert!(runtime.contains("run_live_sources"));
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"unbounded_channel",
|
|
] {
|
|
assert!(
|
|
!runtime.contains(forbidden) && !resources.contains(forbidden) && !root.contains(forbidden),
|
|
"pre.003 crossed a forbidden boundary: {forbidden}",
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_004_standard_block_source_is_direct_raw_and_transport_facade_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestStandardBlockSource",
|
|
"SolanaStandardWsSession::connect",
|
|
".block_subscribe(",
|
|
"SolanaBlockSubscribeConfig::new",
|
|
"SolanaTransactionEncoding::Base64",
|
|
"SolanaTransactionDetails::Full",
|
|
"std::option::Option::Some(1)",
|
|
"std::option::Option::Some(false)",
|
|
"build_standard_block_material",
|
|
"RawTransactionMaterial::binary_base64_with_embedded_signature",
|
|
"RawTransactionVersion::Number(1)",
|
|
"block_subscribe",
|
|
"source.standard_block_missing",
|
|
"source.standard_block_remote_error",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.004 standard block contract missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"unbounded_channel",
|
|
] {
|
|
assert!(
|
|
!runtime_contains(forbidden) && !resources.contains(forbidden) && !root.contains(forbidden),
|
|
"pre.004 crossed a forbidden standard-block boundary: {forbidden}",
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_005_helius_transaction_source_reuses_transport_facade_and_common_hydration_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestHeliusTransactionSource",
|
|
"HeliusLaserStreamWsSession::connect",
|
|
".transaction_subscribe(",
|
|
"HeliusTransactionSubscribeOptions::new",
|
|
"HeliusTransactionSubscribeEncoding::Base64",
|
|
"SolanaTransactionDetails::Full",
|
|
"std::option::Option::Some(1)",
|
|
"project_helius_transaction_signal",
|
|
"helius_ws_http",
|
|
"get_transaction_observed",
|
|
"RawTransactionIngestHydrationCoordinator::with_global_registry(",
|
|
"hydration_pending_limit,",
|
|
"hydration_in_flight_limit,",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.005 Helius transaction contract missing: {required}");
|
|
}
|
|
assert_eq!(resources.matches("get_transaction_observed(").count(), 1);
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"helius_sdk",
|
|
"unbounded_channel",
|
|
] {
|
|
assert!(
|
|
!runtime.contains(forbidden) && !resources.contains(forbidden) && !root.contains(forbidden),
|
|
"pre.005 crossed a forbidden Helius transaction boundary: {forbidden}",
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
fn runtime_contains(value: &str) -> bool {
|
|
return include_str!("../src/runtime.rs").contains(value);
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_006_source_surface_hardens_shutdown_and_faults_without_backend_edges() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let admission = include_str!("../src/admission.rs");
|
|
let persistence = include_str!("../src/persistence.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
let runtime_resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"tokio::sync::mpsc::channel",
|
|
"canonicalize_raw_transaction",
|
|
"assemble_raw_transaction_acquisition",
|
|
"RawTransactionIngestPersistencePort",
|
|
"RawTransactionAcquisitionMode::Normal",
|
|
"RawTransactionIngestSnapshot",
|
|
"RawTransactionIngestSnapshotSource",
|
|
"WorkerSnapshotSource",
|
|
"tokio::sync::watch::channel",
|
|
"ERROR_CODE_RAW_TRANSACTION_INGEST_COUNTER_EXHAUSTED",
|
|
"ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT",
|
|
"ERROR_CODE_RAW_TRANSACTION_INGEST_SOURCE_FAILED",
|
|
"record_source_failure",
|
|
"tokio::time::timeout",
|
|
"abort_all",
|
|
"backpressure_wait_total",
|
|
] {
|
|
assert!(
|
|
root.contains(required)
|
|
|| runtime.contains(required)
|
|
|| admission.contains(required)
|
|
|| persistence.contains(required)
|
|
|| snapshot.contains(required)
|
|
|| runtime_resources.contains(required),
|
|
"required pre.009 hardening contract missing: {required}"
|
|
);
|
|
}
|
|
for forbidden in [
|
|
"pub use self::admission::RawTransactionAdmission",
|
|
"pub use self::admission::RawTransactionIngress",
|
|
"pub use self::persistence::RawTransactionIngestPersistencePort",
|
|
"unbounded_channel",
|
|
"ksp_store_postgres_lib::",
|
|
"ForceRehydrate",
|
|
"ksp_config_lib::",
|
|
"reqwest::",
|
|
] {
|
|
assert!(
|
|
!root.contains(forbidden)
|
|
&& !runtime.contains(forbidden)
|
|
&& !admission.contains(forbidden)
|
|
&& !persistence.contains(forbidden)
|
|
&& !snapshot.contains(forbidden)
|
|
&& !runtime_resources.contains(forbidden),
|
|
"pre.009 crossed a forbidden runtime boundary: {forbidden}"
|
|
);
|
|
}
|
|
assert_eq!(
|
|
runtime.matches("tokio::sync::watch::channel(false)").count(),
|
|
2,
|
|
"runtime retains exactly the external-control and private-source stop watches"
|
|
);
|
|
assert_eq!(
|
|
runtime.matches("tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty())").count(),
|
|
1,
|
|
"runtime retains exactly one run-local processing-frontier latest-value watch",
|
|
);
|
|
assert_eq!(runtime.matches("tokio::sync::watch::channel").count(), 3, "runtime watch inventory is two stop watches plus one processing-frontier watch");
|
|
assert_eq!(snapshot.matches("tokio::sync::watch::channel").count(), 1, "exactly one shared concrete snapshot watch is allowed");
|
|
return;
|
|
}
|
|
|
|
fn dependency_section(manifest: &str) -> &str {
|
|
let after_header = match manifest.split_once("[dependencies]") {
|
|
std::option::Option::Some((_, section)) => section,
|
|
std::option::Option::None => {
|
|
return "";
|
|
},
|
|
};
|
|
let end = match after_header.find("\n[") {
|
|
std::option::Option::Some(index) => index,
|
|
std::option::Option::None => after_header.len(),
|
|
};
|
|
return &after_header[..end];
|
|
}
|
|
|
|
fn manifest_dependency_names(section: &str) -> std::vec::Vec<&str> {
|
|
let mut names = std::vec::Vec::new();
|
|
for line in section.lines() {
|
|
let content = match line.split('#').next() {
|
|
std::option::Option::Some(value) => value.trim(),
|
|
std::option::Option::None => continue,
|
|
};
|
|
if content.is_empty() {
|
|
continue;
|
|
}
|
|
let name = match content.split('=').next() {
|
|
std::option::Option::Some(value) => value.trim().trim_end_matches(".workspace"),
|
|
std::option::Option::None => continue,
|
|
};
|
|
if !name.is_empty() {
|
|
names.push(name);
|
|
}
|
|
}
|
|
names.sort_unstable();
|
|
return names;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_007_multi_source_supervisor_and_inventory_remain_private_bounded_and_source_neutral() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestSourceInventory",
|
|
"RawTransactionIngestSourceInventoryPublisher",
|
|
"for (entry_index, source) in self.sources.into_iter().enumerate()",
|
|
"tokio::task::JoinSet::new()",
|
|
"supervise_live_source_tasks",
|
|
"drain_live_source_tasks",
|
|
"source_stop_sender.send_replace(true)",
|
|
"processing_frontier_sender.clone()",
|
|
"source.configured_source_closed",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.007 multi-source supervisor contract missing: {required}");
|
|
}
|
|
assert!(runtime.contains("run_live_sources"));
|
|
assert!(!runtime.contains("validate_single_source_activation"));
|
|
assert!(!resources.contains("multi_source_activation_pending"));
|
|
for forbidden in [
|
|
"pub struct RawTransactionIngestSourceInventory",
|
|
"pub struct RawTransactionIngestSourceInventoryPublisher",
|
|
"unbounded_channel",
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
] {
|
|
assert!(
|
|
!root.contains(forbidden) && !runtime.contains(forbidden) && !resources.contains(forbidden),
|
|
"pre.007 crossed a private/bounded boundary: {forbidden}"
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_007_processing_frontier_remains_run_local_and_backend_neutral_after_continuity_extension() {
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
for required in [
|
|
"RawTransactionIngestProcessingFrontierProjection",
|
|
"processing_frontier_sender",
|
|
"wait_processing_frontier",
|
|
"record_processing_frontier",
|
|
"hydration_pending",
|
|
"processing_frontier_slot",
|
|
"oldest_pending_slot",
|
|
"RawTransactionIngestProcessingFrontier",
|
|
"settle_pending",
|
|
"observe_settled",
|
|
] {
|
|
assert!(
|
|
runtime.contains(required) || resources.contains(required) || snapshot.contains(required),
|
|
"required pre.007 frontier contract missing: {required}"
|
|
);
|
|
}
|
|
let frontier = match resources.split_once("struct RawTransactionIngestProcessingFrontier {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("struct RawTransactionIngestProcessingFrontierReporter") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["SubscribeReplayInfo", "from_slot", "repair", "ksp_job_backfill_lib::", "ksp_store_postgres_lib::"] {
|
|
assert!(!frontier.contains(forbidden), "pre.007 processing frontier absorbed replay/backend responsibility: {forbidden}");
|
|
}
|
|
for forbidden in ["ksp_job_backfill_lib::", "ksp_store_postgres_lib::", "reqwest::", "tonic::", "yellowstone_grpc_proto::"] {
|
|
assert!(
|
|
!runtime.contains(forbidden) && !resources.contains(forbidden) && !snapshot.contains(forbidden),
|
|
"Worker crossed backend boundary: {forbidden}"
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_008_worker_observes_transport_reconnect_replay_and_faults_only_on_proven_retention_gap() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let transport = include_str!("../../ksp-onchain-transport-lib/src/grpc_stream.rs");
|
|
for required in [
|
|
"snapshot_source()",
|
|
"wait_yellowstone_session_snapshot",
|
|
"source_reconnect_total",
|
|
"source_replay_attempt_total",
|
|
"source_continuity_gap_total",
|
|
"source.continuity_gap_proven",
|
|
"RawTransactionIngestSourceState::Reconnecting",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.008 Worker continuity token missing: {required}");
|
|
}
|
|
for forbidden in ["subscribe_replay_info(", "set_from_slot(", "YellowstoneReplayInfo", "last_requested_from_slot()", "ksp_job_backfill_lib::"] {
|
|
assert!(!resources.contains(forbidden), "Worker took ownership of replay/repair responsibility: {forbidden}");
|
|
}
|
|
for required in ["SubscribeReplayInfo", "set_from_slot(effective_from_slot)", "first_available > requested", "replay_attempt_count"] {
|
|
assert!(transport.contains(required), "Transport replay ownership token missing: {required}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_008_cross_source_convergence_reuses_store_and_transport_facades_only() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let persistence = include_str!("../src/persistence.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestPersistenceConvergence",
|
|
"persist_raw_transaction_ingest_converged_acquisition",
|
|
"RawTransactionIngestPersistencePort",
|
|
"record_raw_transaction_observation",
|
|
"RawTransactionObservationWrite",
|
|
"payload().content_hash()",
|
|
"content_conflict_error()",
|
|
] {
|
|
assert!(persistence.contains(required) || root.contains(required), "required pre.008 persistence convergence contract missing: {required}");
|
|
}
|
|
for required in [
|
|
"RawTransactionIngestGlobalHydrationRegistry",
|
|
"fetch_hydration_shared",
|
|
"subscribe_or_lead",
|
|
"get_transaction_observed",
|
|
"settings.admission_queue_capacity()",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.008 hydration convergence contract missing: {required}");
|
|
}
|
|
assert!(runtime.contains("settings.admission_queue_capacity().max(settings.persistence_concurrency())"));
|
|
for forbidden in ["ksp_store_postgres_lib::", "reqwest::", "tonic::", "yellowstone_grpc_proto::", "ksp_job_backfill_lib::", "unbounded_channel"] {
|
|
assert!(
|
|
!persistence.contains(forbidden) && !runtime.contains(forbidden) && !resources.contains(forbidden),
|
|
"pre.008 convergence crossed a dependency/boundedness boundary: {forbidden}"
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_009_global_bounds_and_fairness_stay_inside_worker_facades() {
|
|
let admission = include_str!("../src/admission.rs");
|
|
let persistence = include_str!("../src/persistence.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"validate_hydration_fairness_capacity",
|
|
"let hydration_pending_budget = settings.admission_queue_capacity();",
|
|
"let hydration_in_flight_budget = settings.persistence_concurrency();",
|
|
"hydration_pending_limit",
|
|
"hydration_in_flight_limit",
|
|
"tokio::sync::Semaphore",
|
|
"acquire_owned",
|
|
"RawTransactionIngestHydrationLeaderGuard",
|
|
"RawTransactionIngestCanonicalState",
|
|
"content_conflict_error()",
|
|
] {
|
|
assert!(
|
|
admission.contains(required) || persistence.contains(required) || resources.contains(required),
|
|
"required pre.009 global-bound contract missing: {required}"
|
|
);
|
|
}
|
|
for forbidden in [
|
|
"unbounded_channel",
|
|
"ksp_store_postgres_lib::",
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
] {
|
|
assert!(
|
|
!admission.contains(forbidden) && !persistence.contains(forbidden) && !resources.contains(forbidden),
|
|
"pre.009 crossed a Worker facade boundary: {forbidden}"
|
|
);
|
|
}
|
|
return;
|
|
}
|