1452 lines
66 KiB
Rust
1452 lines
66 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
|
// version: 39
|
|
|
|
//! External public, security, redaction and release-boundary hardening canaries through `v0.3.15-pre.004`.
|
|
|
|
fn network(value: &'static str) -> std::option::Option<ksp_store_lib::RawNetworkId> {
|
|
let result = ksp_store_lib::RawNetworkId::new(value);
|
|
return match result {
|
|
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
|
std::result::Result::Err(error) => {
|
|
assert_eq!(error.code(), ksp_store_lib::ERROR_CODE_RAW_MODEL_INVALID);
|
|
std::option::Option::None
|
|
},
|
|
};
|
|
}
|
|
|
|
fn worker_id(value: &'static str) -> std::option::Option<ksp_worker_api::WorkerId> {
|
|
let result = ksp_worker_api::WorkerId::new(value);
|
|
return match result {
|
|
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
|
std::result::Result::Err(error) => {
|
|
assert_eq!(error.code(), ksp_worker_api::ERROR_CODE_WORKER_ID_INVALID);
|
|
std::option::Option::None
|
|
},
|
|
};
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_external_error_codes_are_stable_unique_and_domain_scoped() {
|
|
let codes = [
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_CONTENT_CONFLICT, "content_conflict"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_COUNTER_EXHAUSTED, "counter_exhausted"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT, "drain_timeout"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID, "runtime_invalid"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_SETTINGS_INVALID, "settings_invalid"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_SOURCE_FAILED, "source_failed"),
|
|
(ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_STORE_FAILED, "store_failed"),
|
|
];
|
|
for (index, (code, expected)) in codes.iter().enumerate() {
|
|
assert_eq!(code.domain(), "worker_raw_transaction_ingest");
|
|
assert_eq!(code.code(), *expected);
|
|
for (other_index, (other, _)) in codes.iter().enumerate() {
|
|
if index != other_index {
|
|
assert_ne!(code, other);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_debug_and_settings_errors_redact_worker_identity_and_invalid_values() {
|
|
let raw_worker_id = "raw-ingest-secret-marker-001";
|
|
let network = match network("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let parsed_worker_id = match worker_id(raw_worker_id) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
assert_eq!(std::format!("{parsed_worker_id:?}"), "WorkerId(..)");
|
|
let settings = match ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings::new(
|
|
network.clone(),
|
|
parsed_worker_id,
|
|
1,
|
|
1,
|
|
std::time::Duration::from_millis(100),
|
|
) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let settings_debug = std::format!("{settings:?}");
|
|
assert!(!settings_debug.contains(raw_worker_id));
|
|
assert!(settings_debug.contains("WorkerId(..)"));
|
|
let invalid_worker_id = match worker_id("raw-ingest-secret-marker-002") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let invalid =
|
|
ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings::new(network, invalid_worker_id, 65_537, 1, std::time::Duration::from_millis(100));
|
|
let error = match invalid {
|
|
std::result::Result::Ok(_) => return,
|
|
std::result::Result::Err(error) => error,
|
|
};
|
|
let error_debug = std::format!("{error:?}");
|
|
assert_eq!(error.code(), ksp_worker_raw_transaction_ingest_lib::ERROR_CODE_RAW_TRANSACTION_INGEST_SETTINGS_INVALID);
|
|
assert!(!error_debug.contains("raw-ingest-secret-marker-002"));
|
|
assert!(!error_debug.contains("65537"));
|
|
assert!(error.context().iter().any(|context| return context.key() == "field" && context.value() == "admission_queue_capacity"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_002_manifest_dependency_surface_opens_only_transport_and_remains_backend_neutral() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let mut section = "";
|
|
let mut normal = std::collections::BTreeSet::new();
|
|
let mut dev = std::collections::BTreeSet::new();
|
|
let mut build = std::collections::BTreeSet::new();
|
|
for line in manifest.lines() {
|
|
let trimmed = line.trim();
|
|
if trimmed.starts_with('[') && trimmed.ends_with(']') {
|
|
section = trimmed;
|
|
continue;
|
|
}
|
|
if trimmed.is_empty() || trimmed.starts_with('#') {
|
|
continue;
|
|
}
|
|
let name = match trimmed.split_once('=') {
|
|
std::option::Option::Some((name, _)) => name.trim(),
|
|
std::option::Option::None => continue,
|
|
};
|
|
if section == "[dependencies]" {
|
|
normal.insert(name);
|
|
} else if section == "[dev-dependencies]" {
|
|
dev.insert(name);
|
|
} else if section == "[build-dependencies]" {
|
|
build.insert(name);
|
|
}
|
|
}
|
|
assert_eq!(
|
|
normal,
|
|
std::collections::BTreeSet::from([
|
|
"ksp-core-lib",
|
|
"ksp-logging-lib",
|
|
"ksp-onchain-transport-lib",
|
|
"ksp-raw-transaction-lib",
|
|
"ksp-store-lib",
|
|
"ksp-worker-api",
|
|
"sha2",
|
|
"tokio",
|
|
])
|
|
);
|
|
assert!(dev.is_empty());
|
|
assert!(build.is_empty());
|
|
assert!(manifest.contains("ksp-store-lib = { path = \"../ksp-store-lib\", default-features = false }"));
|
|
assert!(manifest.contains("tokio = { workspace = true, features = [\"macros\", \"rt\", \"sync\", \"time\"] }"));
|
|
for forbidden in [
|
|
"ksp-config-lib",
|
|
"ksp-job-api",
|
|
"ksp-job-backfill-lib",
|
|
"ksp-store-api",
|
|
"ksp-store-postgres-lib",
|
|
"reqwest",
|
|
"tokio-tungstenite",
|
|
"tonic",
|
|
"yellowstone-grpc-proto",
|
|
] {
|
|
assert!(!manifest.contains(forbidden), "forbidden Worker manifest dependency present: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_source_visibility_contract_uses_crate_root_for_shared_items() {
|
|
let source_contracts: [(&str, &[&str]); 5] = [
|
|
(include_str!("../src/settings.rs"), &["RawTransactionIngestSettings"]),
|
|
(include_str!("../src/runtime.rs"), &["RawTransactionIngestHandle", "RawTransactionIngestWorker"]),
|
|
(include_str!("../src/snapshot.rs"), &["RawTransactionIngestSnapshot", "RawTransactionIngestSnapshotSource"]),
|
|
(include_str!("../src/persistence.rs"), &["RawTransactionIngestPersistenceOutcome", "RawTransactionIngestPersistencePort"]),
|
|
(
|
|
include_str!("../src/runtime_resources.rs"),
|
|
&[
|
|
"RawTransactionIngestStandardBlockSource",
|
|
"RawTransactionIngestStandardLogsSource",
|
|
"RawTransactionIngestYellowstoneSource",
|
|
"RawTransactionIngestRuntimeResources",
|
|
],
|
|
),
|
|
];
|
|
for (source, symbols) in source_contracts {
|
|
for symbol in symbols {
|
|
let required = std::format!("impl crate::{symbol}");
|
|
assert!(source.contains(required.as_str()), "shared item must use crate-root impl path: {symbol}");
|
|
let forbidden = std::format!("impl {symbol}");
|
|
assert!(!source.contains(forbidden.as_str()), "shared item must not use bare impl path: {symbol}");
|
|
}
|
|
}
|
|
for (module, source) in [
|
|
("admission", include_str!("../src/admission.rs")),
|
|
("error", include_str!("../src/error.rs")),
|
|
("identity", include_str!("../src/identity.rs")),
|
|
("persistence", include_str!("../src/persistence.rs")),
|
|
("runtime", include_str!("../src/runtime.rs")),
|
|
("runtime_resources", include_str!("../src/runtime_resources.rs")),
|
|
("settings", include_str!("../src/settings.rs")),
|
|
("snapshot", include_str!("../src/snapshot.rs")),
|
|
] {
|
|
let forbidden = std::format!("crate::{module}::");
|
|
assert!(!source.contains(forbidden.as_str()), "internal module path bypasses crate-root façade: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_production_surface_has_no_historical_backfill_or_retriever_contract() {
|
|
let sources = [
|
|
include_str!("../src/admission.rs"),
|
|
include_str!("../src/error.rs"),
|
|
include_str!("../src/identity.rs"),
|
|
include_str!("../src/lib.rs"),
|
|
include_str!("../src/persistence.rs"),
|
|
include_str!("../src/runtime.rs"),
|
|
include_str!("../src/runtime_resources.rs"),
|
|
include_str!("../src/settings.rs"),
|
|
include_str!("../src/snapshot.rs"),
|
|
];
|
|
for source in sources {
|
|
for forbidden in [
|
|
"ksp-worker-raw-retriever",
|
|
"raw_transaction_retriever",
|
|
"RawTransactionRetriever",
|
|
"Backfill",
|
|
"backfill",
|
|
"Checkpoint",
|
|
"checkpoint",
|
|
"historical",
|
|
] {
|
|
assert!(!source.contains(forbidden), "historical/retriever surface leaked into Worker production source: {forbidden}");
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_002_production_sources_keep_transport_confined_to_runtime_resources() {
|
|
for source in [
|
|
include_str!("../src/admission.rs"),
|
|
include_str!("../src/error.rs"),
|
|
include_str!("../src/identity.rs"),
|
|
include_str!("../src/lib.rs"),
|
|
include_str!("../src/persistence.rs"),
|
|
include_str!("../src/runtime.rs"),
|
|
include_str!("../src/runtime_resources.rs"),
|
|
include_str!("../src/settings.rs"),
|
|
include_str!("../src/snapshot.rs"),
|
|
] {
|
|
let lower = source.to_ascii_lowercase();
|
|
for forbidden in ["api_key", "api-key", "authorization", "bearer ", "password", "credential", "secret"] {
|
|
assert!(!lower.contains(forbidden), "secret-like material leaked into Worker production source: {forbidden}");
|
|
}
|
|
}
|
|
let transport_source = include_str!("../src/runtime_resources.rs");
|
|
assert!(transport_source.contains("ksp_onchain_transport_lib::"));
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"ksp_offchain_transport_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"postgresql://",
|
|
"postgres://",
|
|
] {
|
|
assert!(!transport_source.contains(forbidden), "forbidden implementation detail leaked into runtime resources: {forbidden}");
|
|
}
|
|
for source in [
|
|
include_str!("../src/admission.rs"),
|
|
include_str!("../src/error.rs"),
|
|
include_str!("../src/identity.rs"),
|
|
include_str!("../src/lib.rs"),
|
|
include_str!("../src/persistence.rs"),
|
|
include_str!("../src/runtime.rs"),
|
|
include_str!("../src/settings.rs"),
|
|
include_str!("../src/snapshot.rs"),
|
|
] {
|
|
assert!(!source.contains("ksp_onchain_transport_lib::"), "Transport dependency escaped runtime_resources.rs");
|
|
for forbidden in [
|
|
"ksp_config_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"ksp_offchain_transport_lib::",
|
|
"reqwest::",
|
|
"tokio_tungstenite::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
"postgresql://",
|
|
"postgres://",
|
|
] {
|
|
assert!(!source.contains(forbidden), "forbidden implementation detail leaked into Worker production source: {forbidden}");
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_003_private_signal_debug_and_shape_do_not_expose_signature_filters_or_payload() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
assert!(resources.contains("struct RawTransactionIngestSourceSignal"));
|
|
assert!(!root.contains("RawTransactionIngestSourceSignal"));
|
|
assert!(!resources.contains(".field(\"matched_filter_fingerprint\", &self.matched_filter_fingerprint)"));
|
|
assert!(!resources.contains(".field(\"signature\", &self.signature)"));
|
|
let signal_struct = match resources.split_once("struct RawTransactionIngestSourceSignal {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl std::fmt::Debug for RawTransactionIngestSourceSignal") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["transaction:", "meta:", "error:", "payload:", "body:", "is_vote:"] {
|
|
assert!(!signal_struct.contains(forbidden), "payload/provider-specific field leaked into private source signal: {forbidden}");
|
|
}
|
|
for required in [
|
|
"created_at:",
|
|
"family:",
|
|
"matched_filter_count:",
|
|
"matched_filter_fingerprint:",
|
|
"matched_filter_id:",
|
|
"network:",
|
|
"route:",
|
|
"signature:",
|
|
"slot:",
|
|
"transaction_index:",
|
|
] {
|
|
assert!(signal_struct.contains(required), "required private signal field missing: {required}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_004_hydration_provenance_and_remote_material_are_bounded_and_redacted() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"route_prefix",
|
|
"{}.{}:http.{}",
|
|
"composite_provider_unrepresentable",
|
|
"composite_endpoint_unrepresentable",
|
|
"RawAcquisitionOrigin::Live",
|
|
"with_capture_session_id",
|
|
"with_commitment",
|
|
"with_endpoint_id",
|
|
"with_filter_id",
|
|
"try_with_observed_at",
|
|
"hydration.signature_mismatch",
|
|
"hydration.slot_mismatch",
|
|
"hydration.transaction_index_mismatch",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.004 bounded provenance/mismatch guard missing: {required}");
|
|
}
|
|
for forbidden in ["source_payload_hash", "source_payload_size_bytes", "HTTP-SECRET-CANARY", "GRPC-SECRET-CANARY", "TransactionStatus.error", ".error()"] {
|
|
assert!(!resources.contains(forbidden), "pre.004 retained forbidden remote/source material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_005_block_and_continuity_shapes_are_bounded_redacted_and_raw_separated() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"impl RawTransactionIngestYellowstoneBlockView for ksp_onchain_transport_lib::YellowstoneBlockUpdate",
|
|
"impl RawTransactionIngestYellowstoneContinuityView for ksp_onchain_transport_lib::YellowstoneBlockMetaUpdate",
|
|
"impl RawTransactionIngestYellowstoneContinuityView for ksp_onchain_transport_lib::YellowstoneSlotUpdate",
|
|
"RawTransactionIngestSourceFamily::Block",
|
|
"project_yellowstone_block_signals",
|
|
"project_yellowstone_continuity_signal",
|
|
"RawTransactionIngestContinuityStatus::Dead",
|
|
"block_get_transaction",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.005 bounded adapter guard missing: {required}");
|
|
}
|
|
let continuity_struct = match resources.split_once("struct RawTransactionIngestContinuitySignal {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl std::fmt::Debug for RawTransactionIngestContinuitySignal") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for required in [
|
|
"created_at:",
|
|
"family:",
|
|
"matched_filter_count:",
|
|
"matched_filter_fingerprint:",
|
|
"matched_filter_id:",
|
|
"network:",
|
|
"parent_slot:",
|
|
"route:",
|
|
"slot:",
|
|
"status:",
|
|
] {
|
|
assert!(continuity_struct.contains(required), "required continuity-only field missing: {required}");
|
|
}
|
|
for forbidden in ["signature:", "transaction:", "meta:", "payload:", "body:", "error:", "dead_error:"] {
|
|
assert!(!continuity_struct.contains(forbidden), "RAW/remote material leaked into continuity-only signal: {forbidden}");
|
|
}
|
|
assert!(!resources.contains("YellowstoneSlotUpdate::dead_error"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_006_runtime_resource_contract_opens_one_supervised_transport_source() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for required in ["open_standard_subscribe", "next_update", "get_transaction_observed", "RawTransactionIngestHydrationCoordinator", "session.close().await"]
|
|
{
|
|
assert!(resources.contains(required), "productive runtime-resource source behavior missing: {required}");
|
|
}
|
|
assert!(runtime.contains("start_with_runtime_resources"));
|
|
assert!(runtime.contains("run_live_sources(source_settings, stop_receiver, admission_sender, processing_frontier_sender)"));
|
|
for forbidden in ["ksp_config_lib::", "ksp_store_postgres_lib::", "reqwest::", "tonic::", "yellowstone_grpc_proto::"] {
|
|
assert!(!resources.contains(forbidden) && !runtime.contains(forbidden), "pre.006 runtime source crossed a forbidden boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_006_source_coalescence_is_bounded_stop_preemptible_and_redacted() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"max_in_flight: usize",
|
|
"max_pending_signals: usize",
|
|
"RawTransactionIngestHydrationCoordinator::with_global_registry(",
|
|
"hydration_pending_limit,",
|
|
"hydration_in_flight_limit,",
|
|
"pending_signal_count",
|
|
"stop_receiver.changed()",
|
|
"tasks.abort_all()",
|
|
"source.hydration_pending_saturated",
|
|
"source.hydration_task_join_failed",
|
|
"hydration_transport_error(error.code())",
|
|
"source_transport_error(error.code())",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.006 bounded/stop-safe source guard missing: {required}");
|
|
}
|
|
for forbidden in ["remote_message", "response_body", "dead_error", "TransactionStatus.error", ".error()", "Authorization", "Bearer "] {
|
|
assert!(!resources.contains(forbidden), "remote/secret material leaked into productive source: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_010_lower_layers_have_no_dependency_return_to_concrete_worker() {
|
|
for manifest in [
|
|
include_str!("../../ksp-core-lib/Cargo.toml"),
|
|
include_str!("../../ksp-logging-lib/Cargo.toml"),
|
|
include_str!("../../ksp-raw-transaction-lib/Cargo.toml"),
|
|
include_str!("../../ksp-store-api/Cargo.toml"),
|
|
include_str!("../../ksp-store-lib/Cargo.toml"),
|
|
include_str!("../../ksp-store-postgres-lib/Cargo.toml"),
|
|
include_str!("../../ksp-worker-api/Cargo.toml"),
|
|
] {
|
|
assert!(!manifest.contains("ksp-worker-raw-transaction-ingest-lib"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_002_public_root_exposes_contract_types_without_transport_implementation_paths() {
|
|
let root = include_str!("../src/lib.rs");
|
|
for forbidden in [
|
|
"pub mod ",
|
|
"tokio::",
|
|
"JoinSet",
|
|
"watch::Receiver",
|
|
"watch::Sender",
|
|
"mpsc::Sender",
|
|
"ksp_store_postgres_lib::",
|
|
"ksp_onchain_transport_lib::",
|
|
"ksp_config_lib::",
|
|
"reqwest::",
|
|
"tonic::",
|
|
] {
|
|
assert!(!root.contains(forbidden), "implementation/backend/live-source detail leaked into public root: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_007_processing_frontier_is_bounded_processing_only_and_redacted() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
for required in [
|
|
"pending_total",
|
|
"std::collections::BTreeMap<u64, RawTransactionIngestProcessingSlotState>",
|
|
"settled_interval_highs",
|
|
"oldest_pending_slot",
|
|
"processing_frontier_slot",
|
|
"hydration_pending",
|
|
"processing_frontier.observe_pending",
|
|
"processing_frontier.settle_pending",
|
|
] {
|
|
assert!(resources.contains(required) || snapshot.contains(required), "required pre.007 bounded frontier guard 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 [
|
|
"signature: ksp_store_lib::RawTransactionSignature",
|
|
"filter_id",
|
|
"provider",
|
|
"endpoint_id",
|
|
"transaction:",
|
|
"meta:",
|
|
"ReplayInfo",
|
|
"from_slot",
|
|
"continuity_gap",
|
|
"repair",
|
|
] {
|
|
assert!(!frontier.contains(forbidden), "pre.007 frontier absorbed forbidden material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_008_reconnect_projection_is_source_neutral_bounded_and_contains_no_replay_material() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
for required in [
|
|
"RawTransactionIngestSourceState",
|
|
"source_reconnect_total",
|
|
"source_replay_attempt_total",
|
|
"source_continuity_gap_total",
|
|
"source.continuity_counter_regression",
|
|
"source.continuity_gap_proven",
|
|
] {
|
|
assert!(resources.contains(required) || snapshot.contains(required), "required pre.008 bounded continuity guard missing: {required}");
|
|
}
|
|
let projection = match snapshot.split_once("struct RawTransactionIngestProcessingFrontierProjection {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl crate::RawTransactionIngestProcessingFrontierProjection") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["signature", "provider", "endpoint", "filter", "transaction", "meta", "from_slot", "first_available", "ReplayInfo"] {
|
|
assert!(!projection.contains(forbidden), "pre.008 source projection leaked replay/provider/RAW material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_003_standard_logs_redaction_and_reference_only_contract_are_explicit() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestStandardLogsSource",
|
|
".field(\"filter_kind\"",
|
|
".field(\"filter_fingerprint_bytes\"",
|
|
".field(\"source_key_bytes\"",
|
|
"project_standard_logs_signal",
|
|
"matched_filter_count: 1",
|
|
"transaction_index: std::option::Option::None",
|
|
"created_at: std::option::Option::None",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.003 redaction/reference guard missing: {required}");
|
|
}
|
|
let source_struct = match resources.split_once("pub struct RawTransactionIngestStandardLogsSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl crate::RawTransactionIngestStandardLogsSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
assert!(source_struct.contains("filter: ksp_onchain_transport_lib::SolanaLogsSubscribeFilter"));
|
|
for forbidden in ["logs:", "err:", "payload:", "body:", "url:"] {
|
|
assert!(!source_struct.contains(forbidden), "remote/sensitive material stored in standard logs source: {forbidden}");
|
|
}
|
|
let projection = match resources.split_once("fn project_standard_logs_signal") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("fn route_yellowstone_update") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in [".logs()", ".err()"] {
|
|
assert!(!projection.contains(forbidden), "logs/error material copied into standard logs projection: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_004_standard_block_redaction_version_and_null_guards_are_explicit() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestStandardBlockSource",
|
|
".field(\"filter_kind\"",
|
|
".field(\"filter_fingerprint_bytes\"",
|
|
".field(\"source_key_bytes\"",
|
|
"source.standard_block_context_slot_mismatch",
|
|
"source.standard_block_remote_error",
|
|
"source.standard_block_missing",
|
|
"source.standard_block_transactions_missing",
|
|
"source.standard_block_transaction_version_unsupported",
|
|
"source.standard_block_transaction_version_unqualified",
|
|
"SolanaTransactionVersion::Number(0)",
|
|
"SolanaTransactionVersion::Number(1)",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.004 standard block hardening guard missing: {required}");
|
|
}
|
|
let source_struct = match resources.split_once("pub struct RawTransactionIngestStandardBlockSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl crate::RawTransactionIngestStandardBlockSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["err:", "block:", "transaction_data:", "url:"] {
|
|
assert!(!source_struct.contains(forbidden), "remote/raw material stored in standard block source: {forbidden}");
|
|
}
|
|
let source_impl = match resources.split_once("impl crate::RawTransactionIngestStandardBlockSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl std::fmt::Debug for crate::RawTransactionIngestStandardBlockSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
assert!(!source_impl.contains("observe_pending("), "direct Standard Block source must not inflate hydration_pending");
|
|
assert!(source_impl.contains("processing_frontier.observe_settled(slot)"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_005_helius_transaction_redaction_full_reference_and_tier_neutrality_are_explicit() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"RawTransactionIngestHeliusTransactionSource",
|
|
".field(\"filter\"",
|
|
".field(\"filter_fingerprint_bytes\"",
|
|
".field(\"source_key_bytes\"",
|
|
"HeliusTransactionNotification::Full(value)",
|
|
"source.helius_transaction_notification_unqualified",
|
|
"project_helius_transaction_signal",
|
|
"transaction_index: std::option::Option::Some(response.transaction_index())",
|
|
"RAW_TRANSACTION_INGEST_HELIUS_TRANSACTION_HTTP_PROTOCOL",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.005 Helius hardening guard missing: {required}");
|
|
}
|
|
let source_struct = match resources.split_once("pub struct RawTransactionIngestHeliusTransactionSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl crate::RawTransactionIngestHeliusTransactionSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["url:", "api_key", "credential", "transaction:", "payload:", "tier:"] {
|
|
assert!(!source_struct.contains(forbidden), "sensitive/provider material stored in Helius transaction source: {forbidden}");
|
|
}
|
|
let projection = match resources.split_once("fn project_helius_transaction_signal") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("trait RawTransactionIngestStandardLogsView") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
assert!(!projection.contains(".transaction()"), "Helius nested full payload must not enter Worker projection");
|
|
for forbidden in ["Developer", "Business", "Professional", "paid_tier", "provider_tier"] {
|
|
assert!(!resources.contains(forbidden), "provider tier must not be coded in Worker: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_006_http_block_polling_is_bounded_run_local_stop_preemptible_and_redacted() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"DEFAULT_RAW_TRANSACTION_INGEST_HTTP_POLL_INTERVAL",
|
|
"DEFAULT_RAW_TRANSACTION_INGEST_HTTP_POLL_MAX_BLOCKS_PER_CYCLE",
|
|
"MIN_RAW_TRANSACTION_INGEST_HTTP_POLL_INTERVAL",
|
|
"MAX_RAW_TRANSACTION_INGEST_HTTP_POLL_INTERVAL",
|
|
"MIN_RAW_TRANSACTION_INGEST_HTTP_POLL_MAX_BLOCKS_PER_CYCLE",
|
|
"MAX_RAW_TRANSACTION_INGEST_HTTP_POLL_MAX_BLOCKS_PER_CYCLE",
|
|
"let mut next_scan_slot = start_slot",
|
|
"next_scan_slot = slot",
|
|
"tokio::time::sleep(self.poll_interval)",
|
|
"processing_frontier.observe_settled(slot)",
|
|
"source.http_block_polling_transaction_version_unqualified",
|
|
"source.http_block_polling_transaction_version_unsupported",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.006 HTTP polling hardening guard 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);
|
|
assert!(!source_impl.contains("tokio::spawn"), "HTTP polling must not spawn one task per tick");
|
|
assert!(!source_impl.contains("observe_pending("), "HTTP block polling is direct RAW and must not inflate hydration_pending");
|
|
let source_struct = match resources.split_once("pub struct RawTransactionIngestHttpBlockPollingSource {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl crate::RawTransactionIngestHttpBlockPollingSource") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["url:", "api_key", "credential", "secret", "transaction:", "payload:", "tier:"] {
|
|
assert!(!source_struct.contains(forbidden), "sensitive/raw material stored in HTTP polling source: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_009_hydration_retry_ownership_and_no_orphan_cleanup_are_explicit() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
assert_eq!(resources.matches("get_transaction_observed(").count(), 1, "Worker must delegate one hydration attempt to Transport");
|
|
for required in [
|
|
"coordinator.abort_all(&mut processing_frontier).await",
|
|
"fn discard_all_pending(&mut self)",
|
|
"processing_frontier.discard_all_pending()",
|
|
"source.hydration_pending_saturated",
|
|
"tasks.abort_all()",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.009 no-orphan/backpressure guard missing: {required}");
|
|
}
|
|
let hydration = match resources.split_once("struct RawTransactionIngestHydrationCoordinator {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("fn hydration_method_code(") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for forbidden in ["tokio::time::sleep", "tokio::time::interval", "get_block_observed"] {
|
|
assert!(!hydration.contains(forbidden), "hydration coordinator introduced forbidden retry behavior: {forbidden}");
|
|
}
|
|
assert!(!resources.contains("unbounded_channel"), "Worker introduced an unbounded channel");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_007_multi_source_supervisor_is_fail_closed_joined_and_does_not_publish_source_identity() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"MAX_RAW_TRANSACTION_INGEST_LIVE_SOURCES",
|
|
"RawTransactionIngestSourceInventory",
|
|
"std::sync::Mutex",
|
|
"tokio::task::JoinSet",
|
|
"source.configured_source_closed",
|
|
"source.task_join_failed",
|
|
"source_stop_sender.send_replace(true)",
|
|
"drain_live_source_tasks",
|
|
"processing_frontier_slot = std::option::Option::None",
|
|
"saturating_add",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.007 supervisor hardening guard missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"pub struct RawTransactionIngestSourceInventory",
|
|
"pub struct RawTransactionIngestSourceInventoryPublisher",
|
|
"pub fn source_key(",
|
|
"source_keys:",
|
|
"unbounded_channel",
|
|
"primary_source",
|
|
"standby_source",
|
|
"first_provider_wins",
|
|
] {
|
|
assert!(!root.contains(forbidden), "private source identity/scheduling policy leaked into public root: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_008_cross_source_convergence_is_bounded_conflict_checked_and_private() {
|
|
let root = include_str!("../src/lib.rs");
|
|
let persistence = include_str!("../src/persistence.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"max_entries: usize",
|
|
"entries.len() >= self.max_entries",
|
|
"std::sync::Arc::strong_count(entry) == 1",
|
|
"known_state_value != &canonical_state",
|
|
"record_observation(observation)",
|
|
"persistence.additional_observation_not_recorded",
|
|
] {
|
|
assert!(persistence.contains(required), "required pre.008 persistence hardening guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"max_pending: usize",
|
|
"pending.len() >= self.max_pending",
|
|
"source.global_hydration_pending_saturated",
|
|
"tokio::sync::watch::channel",
|
|
"publish_and_remove",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.008 hydration hardening guard missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"pub struct RawTransactionIngestPersistenceConvergence",
|
|
"pub struct RawTransactionIngestGlobalHydrationRegistry",
|
|
"pub fn persist_raw_transaction_ingest_converged_acquisition",
|
|
] {
|
|
assert!(!root.contains(forbidden), "pre.008 private convergence implementation leaked publicly: {forbidden}");
|
|
}
|
|
assert!(!resources.contains("unbounded_channel"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_009_duplicate_storm_disagreement_and_starvation_guards_are_explicit() {
|
|
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 [
|
|
"runtime_resources.hydration_pending_capacity_insufficient",
|
|
"runtime_resources.hydration_concurrency_insufficient",
|
|
"base + usize::from(hydration_entry_index < remainder)",
|
|
"hydration_in_flight_limit",
|
|
"tokio::sync::Semaphore::new(max_in_flight)",
|
|
"RawTransactionIngestHydrationLeaderGuard",
|
|
"source.global_hydration_pending_saturated",
|
|
"block_time: transaction.block_time()",
|
|
"slot: transaction.slot()",
|
|
"content_hash: transaction.payload().content_hash()",
|
|
] {
|
|
assert!(
|
|
admission.contains(required) || persistence.contains(required) || resources.contains(required),
|
|
"required pre.009 adversarial guard missing: {required}"
|
|
);
|
|
}
|
|
for forbidden in [
|
|
"VecDeque::new()",
|
|
"unbounded_channel",
|
|
"first_provider_wins",
|
|
"provider_priority",
|
|
"majority_vote",
|
|
"preferred_provider",
|
|
"overwrite_conflict",
|
|
] {
|
|
assert!(
|
|
!admission.contains(forbidden) && !persistence.contains(forbidden) && !resources.contains(forbidden),
|
|
"pre.009 introduced forbidden unbounded/provider-preference behavior: {forbidden}"
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_010_multi_source_health_is_conservative_counted_and_redacted() {
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"source_total: usize",
|
|
"source_active: usize",
|
|
"source_reconnecting: usize",
|
|
"source_failed: usize",
|
|
"source_reconnecting > 0",
|
|
"source_failed > 0",
|
|
"source_active < source_total",
|
|
"WorkerHealth::Degraded",
|
|
"WorkerHealth::Unhealthy",
|
|
] {
|
|
assert!(snapshot.contains(required), "required pre.010 health guard missing: {required}");
|
|
}
|
|
for required in ["source_total = self.source_projections.len()", "with_source_counts(source_total, source_active, source_reconnecting, source_failed)"] {
|
|
assert!(resources.contains(required), "required pre.010 inventory count guard missing: {required}");
|
|
}
|
|
for forbidden in ["source_key: [u8; 32]", "provider_url", "endpoint_url", "filter_fingerprint", "credential", "api_key", "token_header"] {
|
|
assert!(!snapshot.contains(forbidden), "pre.010 snapshot leaks source/provider material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_011_shutdown_races_are_bounded_joined_atomic_and_counter_safe() {
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let supervisor = match runtime.split_once("async fn run_supervisor<Spawner>(") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("fn spawn_persistence(") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
let active_shutdown = match supervisor.split_once("let mut fault = supervise_until_stop(") {
|
|
std::option::Option::Some((_, value)) => value,
|
|
std::option::Option::None => "",
|
|
};
|
|
let stop_position = active_shutdown.find("source_stop_sender.send_replace(true);");
|
|
let stopping_position = active_shutdown.find("begin_stopping(");
|
|
let drain_position = active_shutdown.find("drain_owned_work(");
|
|
let terminal_position = active_shutdown.find("match fault {");
|
|
assert!(matches!((stop_position, stopping_position), (std::option::Option::Some(stop), std::option::Option::Some(stopping)) if stop < stopping));
|
|
assert!(matches!((stopping_position, drain_position), (std::option::Option::Some(stopping), std::option::Option::Some(drain)) if stopping < drain));
|
|
assert!(matches!((drain_position, terminal_position), (std::option::Option::Some(drain), std::option::Option::Some(terminal)) if drain < terminal));
|
|
for required in [
|
|
"tokio::time::timeout(settings.shutdown_drain_timeout(), drain).await",
|
|
"persistence.abort_all()",
|
|
"children.abort_all()",
|
|
"while persistence.join_next().await.is_some() {}",
|
|
"while children.join_next().await.is_some() {}",
|
|
] {
|
|
assert!(runtime.contains(required), "required pre.011 bounded-drain guard missing: {required}");
|
|
}
|
|
let registry_publish = match resources.split_once("fn publish_and_remove(&self, key: &RawTransactionIngestHydrationKey") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("type RawTransactionIngestHydrationTasks") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
let notify_position = registry_publish.find("sender.send_replace(std::option::Option::Some(result));");
|
|
let remove_position = registry_publish.find("pending.remove(key);");
|
|
assert!(matches!((notify_position, remove_position), (std::option::Option::Some(notify), std::option::Option::Some(remove)) if notify < remove));
|
|
let inventory = match resources.split_once("impl RawTransactionIngestSourceInventory {") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("impl RawTransactionIngestSourceInventoryPublisher") {
|
|
std::option::Option::Some((value, _)) => value,
|
|
std::option::Option::None => "",
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for required in [
|
|
"checked_add(projection.hydration_pending())",
|
|
"checked_add(projection.source_continuity_gap_total())",
|
|
"checked_add(projection.source_reconnect_total())",
|
|
"checked_add(projection.source_replay_attempt_total())",
|
|
"source.inventory_entry_missing",
|
|
"source.inventory_key_mismatch",
|
|
"source.inventory_projection_missing",
|
|
] {
|
|
assert!(inventory.contains(required), "required pre.011 inventory guard missing: {required}");
|
|
}
|
|
assert!(!inventory.contains("saturating_add"), "pre.011 source inventory must not silently saturate aggregate counters");
|
|
for source_marker in [
|
|
"impl crate::RawTransactionIngestYellowstoneSource",
|
|
"impl crate::RawTransactionIngestHeliusTransactionSource",
|
|
"impl crate::RawTransactionIngestHttpBlockPollingSource",
|
|
"impl crate::RawTransactionIngestStandardBlockSource",
|
|
"impl crate::RawTransactionIngestStandardLogsSource",
|
|
] {
|
|
let tail = match resources.split_once(source_marker) {
|
|
std::option::Option::Some((_, value)) => value,
|
|
std::option::Option::None => "",
|
|
};
|
|
assert!(tail.contains("stop_receiver.changed()"), "pre.011 source lacks stop-preemptible wait: {source_marker}");
|
|
}
|
|
assert!(!runtime.contains("unbounded_channel"));
|
|
assert!(!resources.contains("unbounded_channel"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_13_pre_012_cross_layer_security_closure_is_complete_and_source_neutral() {
|
|
let cross_layer = include_str!("cross_layer_completeness.rs");
|
|
for required in [
|
|
"v0_3_13_pre_012_legacy_v0_v1_is_proven_from_transport_through_worker_common_raw_to_store",
|
|
"v0_3_13_pre_012_yellowstone_non_regression_covers_identity_v1_reconnect_gap_and_worker_hydration",
|
|
"v0_3_13_pre_012_security_redaction_matrix_covers_all_live_sources_and_lower_layers",
|
|
] {
|
|
assert!(cross_layer.contains(required), "pre.012 security closure proof missing: {required}");
|
|
}
|
|
let root = include_str!("../src/lib.rs");
|
|
for forbidden in [
|
|
"SourceSnapshotByKey",
|
|
"SourceHealthByKey",
|
|
"provider_health",
|
|
"endpoint_health",
|
|
"RawTransactionIngestGlobalHydrationRegistry",
|
|
"RawTransactionIngestCanonicalState",
|
|
"source_key",
|
|
] {
|
|
assert!(!root.contains(forbidden), "pre.012 public root leaked private/source-specific material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_002_continuity_contracts_are_private_bounded_and_io_free() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS",
|
|
"MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS",
|
|
"MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT",
|
|
"MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS",
|
|
"MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS",
|
|
"FullLedgerTransactions",
|
|
"ExactSourceScope",
|
|
"KnownReferences",
|
|
"RawTransactionIngestGapLedger",
|
|
"RawTransactionIngestTargetCoverage",
|
|
"RawTransactionIngestContinuityCapabilityDescriptor",
|
|
"RawTransactionIngestContinuityContracts",
|
|
"continuity.known_references_not_target_scope",
|
|
"continuity.coalescible_gap_ranges",
|
|
] {
|
|
assert!(continuity.contains(required), "required pre.002 continuity contract missing: {required}");
|
|
}
|
|
for required in [
|
|
"repair_capability_descriptor",
|
|
"yellowstone_coverage_scope_fingerprint",
|
|
"http_role_supports_repair_scan",
|
|
"RawTransactionIngestContinuityContracts::new",
|
|
"validate_for_source_count",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.002 runtime-resource capability wiring missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"get_block_observed",
|
|
"get_transaction_observed",
|
|
"get_blocks_with_limit",
|
|
"get_blocks(",
|
|
"open_standard_subscribe",
|
|
"SolanaStandardWsSession::connect",
|
|
"HeliusLaserStreamWsSession::connect",
|
|
"ksp_config_lib::",
|
|
"ksp_job_backfill_lib::",
|
|
"ksp_store_postgres_lib::",
|
|
"reqwest::",
|
|
"tonic::",
|
|
"yellowstone_grpc_proto::",
|
|
] {
|
|
assert!(!continuity.contains(forbidden), "pre.002 continuity contract performed or imported forbidden I/O/boundary: {forbidden}");
|
|
}
|
|
assert!(!root.contains("pub use self::continuity::"));
|
|
assert!(!root.contains("repair"), "pre.002 private continuity wiring leaked repair responsibility through crate root");
|
|
assert!(root.contains("pub(crate) use self::continuity::RawTransactionIngestContinuityContracts;"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_003_websocket_continuity_observation_reuses_transport_snapshot_sources_only() {
|
|
let worker = include_str!("../src/runtime_resources.rs");
|
|
assert!(worker.matches("session.snapshot_source()").count() >= 3);
|
|
assert!(worker.contains("observe_websocket_session_snapshot"));
|
|
assert!(worker.contains("observe_websocket_post_incident_slot"));
|
|
assert!(!worker.contains("tokio_tungstenite::connect_async"));
|
|
assert!(!worker.contains("WebSocketStream<"));
|
|
assert!(!worker.contains("set_from_slot("));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_004_yellowstone_replay_evidence_is_transport_owned_and_fail_closed_without_coverage_proof() {
|
|
let worker = include_str!("../src/runtime_resources.rs");
|
|
let transport = include_str!("../../ksp-onchain-transport-lib/src/grpc_stream.rs");
|
|
for required in [
|
|
"snapshot.replay_delivery_count()",
|
|
"snapshot.replay_coverage_unproven_count()",
|
|
"source_replay_delivery_total",
|
|
"source_replay_coverage_unproven_total",
|
|
"source.replay_coverage_unproven",
|
|
] {
|
|
assert!(worker.contains(required), "required pre.004 Worker replay-evidence guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"replay_delivery_count",
|
|
"replay_coverage_unproven_count",
|
|
"pending_replay_from_slot",
|
|
"tracker.begin_replay(effective_from_slot)",
|
|
"first_available > requested",
|
|
] {
|
|
assert!(transport.contains(required), "required pre.004 Transport replay-evidence guard missing: {required}");
|
|
}
|
|
for forbidden in ["subscribe_replay_info(", "set_from_slot(", "YellowstoneReplayInfo", "last_requested_from_slot()"] {
|
|
assert!(!worker.contains(forbidden), "pre.004 Worker took replay ownership: {forbidden}");
|
|
}
|
|
assert!(!transport.contains("replay_covered_count"));
|
|
assert!(!transport.contains("replay_coverage_proven_count"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_005_redundant_coverage_requires_exact_or_superset_proof_over_full_range() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"RawTransactionIngestCoverageRelation",
|
|
"RawTransactionIngestCoverageEpoch",
|
|
"RawTransactionIngestCoverageEpochLedger",
|
|
"MAX_RAW_TRANSACTION_INGEST_COVERAGE_EPOCHS",
|
|
"self.source_key == target_source_key",
|
|
"self.commitment != requirement.commitment",
|
|
"!self.range.contains_gap(gap)",
|
|
"family_code == required_family_code && fingerprint == required_fingerprint",
|
|
"RawTransactionIngestCoverageRelation::Superset",
|
|
] {
|
|
assert!(continuity.contains(required), "required pre.005 conservative coverage guard missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"standard_logs\", \"helius_transaction",
|
|
"helius_transaction\", \"standard_logs",
|
|
"commitment >= requirement.commitment",
|
|
"commitment <= requirement.commitment",
|
|
"source_key == target_source_key &&",
|
|
] {
|
|
assert!(!continuity.contains(forbidden), "pre.005 introduced opportunistic coverage equivalence: {forbidden}");
|
|
}
|
|
for forbidden_public in [
|
|
"pub use self::continuity::RawTransactionIngestCoverageRelation",
|
|
"pub use self::continuity::RawTransactionIngestCoverageEpoch",
|
|
"pub use self::continuity::RawTransactionIngestTargetCoverage",
|
|
] {
|
|
assert!(!root.contains(forbidden_public), "pre.005 leaked private continuity proof type: {forbidden_public}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_006_http_discovery_is_bounded_prefers_closed_range_and_never_uses_tip_alone_as_coverage() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"RawTransactionIngestHttpDiscoveryStrategy",
|
|
"RawTransactionIngestHttpDiscoveryWindow",
|
|
"RawTransactionIngestHttpScanCapabilities",
|
|
"ClosedRange",
|
|
"WithLimitBoundary",
|
|
"MAX_RAW_TRANSACTION_INGEST_CONTINUITY_DISCOVERY_WINDOW_SLOTS",
|
|
"pool.get_blocks(role, start_slot, std::option::Option::Some(end_slot)",
|
|
"pool.get_blocks_with_limit(role, start_slot, slot_count",
|
|
"self.http_pool.get_block_observed",
|
|
"discovered.last().copied().map(|slot| return slot.min(end_slot))",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.006 bounded HTTP discovery guard missing: {required}");
|
|
}
|
|
assert!(resources.contains("http_role_scan_capabilities"));
|
|
assert!(resources.contains("http_role_supports_repair_scan"));
|
|
assert!(!resources.contains("ksp_job_backfill_lib::"));
|
|
assert!(!resources.contains("get_blocks_with_limit(role, start_slot, u64::MAX"));
|
|
assert!(!root.contains("repair"), "pre.006 leaked lower-case repair responsibility through crate root");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_007_known_reference_hydration_reuses_one_registry_and_preserves_missing_obligation() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"RawTransactionIngestKnownReferenceObligation",
|
|
"known_reference_processed_unsupported",
|
|
"RawTransactionIngestKnownReferenceHydrationResolution",
|
|
"RawTransactionIngestKnownReferenceMissingDisposition",
|
|
"fetch_hydration_shared",
|
|
"resolve_known_reference_hydration",
|
|
"PreferBlockSlot",
|
|
"AwaitCoverage",
|
|
"get_transaction_observed",
|
|
"http_role_supports_rpc_method",
|
|
] {
|
|
assert!(continuity.contains(required) || resources.contains(required), "required pre.007 known-reference guard missing: {required}");
|
|
}
|
|
assert_eq!(resources.matches("struct RawTransactionIngestGlobalHydrationRegistry").count(), 1);
|
|
assert!(!resources.contains("KnownReferenceHydrationRegistry"));
|
|
assert!(!resources.contains("known_reference_retry"));
|
|
assert!(!root.contains("pub use self::continuity::RawTransactionIngestKnownReferenceObligation"));
|
|
assert!(!root.contains("repair"), "pre.007 leaked lower-case repair responsibility through crate root");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_008_reconciliation_and_source_loss_are_target_coverage_gated_without_respawn() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"RawTransactionIngestSourceLossDecision",
|
|
"source_loss_decision",
|
|
"is_covered_by_active_sources",
|
|
"reconcile_with_coverage_epochs",
|
|
"record_coverage_epoch",
|
|
"record_known_reference_gap",
|
|
"record_source_loss_gap",
|
|
"continuity_frontier",
|
|
"has_open_gaps",
|
|
"continuity.source_loss_active_set_invalid",
|
|
"RawTransactionIngestSourceLossDecision::Fault",
|
|
"RawTransactionIngestSourceLossDecision::Continue",
|
|
] {
|
|
assert!(continuity.contains(required), "required pre.008 reconciliation guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"source_loss_is_reconcilable",
|
|
"inventory.supervisor_state()",
|
|
"source_loss_continuity_range",
|
|
"contracts.record_known_reference_gap",
|
|
"contracts.record_source_loss_gap",
|
|
"contracts.source_loss_decision",
|
|
"RawTransactionIngestSourceLossDecision::Continue",
|
|
"RawTransactionIngestSourceLossDecision::Fault",
|
|
"source.websocket_incident_unbounded",
|
|
"source.replay_coverage_unproven",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.008 supervisor gate missing: {required}");
|
|
}
|
|
assert!(!resources.contains("respawn_source"));
|
|
assert!(!resources.contains("restart_source"));
|
|
assert!(!root.contains("pub use self::continuity::RawTransactionIngestSourceLossDecision"));
|
|
assert!(!root.contains("repair"), "pre.008 leaked lower-case repair responsibility through crate root");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_009_health_policy_is_present_future_coverage_gated_and_source_neutral() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"health_projection",
|
|
"future_target_coverage",
|
|
"continuity_frontier",
|
|
"has_open_gaps",
|
|
"is_covered_by_active_sources",
|
|
"source_failures_reconciled",
|
|
"failed_source_losses_reconciled",
|
|
] {
|
|
assert!(continuity.contains(required) || snapshot.contains(required), "required pre.009 coverage-health guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"continuity_policy_observed",
|
|
"continuity_has_open_gaps",
|
|
"snapshot.continuity_frontier_slot != snapshot.processing_frontier_slot",
|
|
"!snapshot.future_target_coverage",
|
|
"snapshot.source_reconnecting > 0",
|
|
"snapshot.source_active == snapshot.source_total",
|
|
"ksp_worker_api::WorkerHealth::Healthy",
|
|
"ksp_worker_api::WorkerHealth::Degraded",
|
|
"ksp_worker_api::WorkerHealth::Unhealthy",
|
|
"ksp_worker_api::WorkerState::Faulted",
|
|
] {
|
|
assert!(snapshot.contains(required), "required pre.009 health projection guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"continuity_contracts",
|
|
"contracts.health_projection",
|
|
"inventory.active_source_keys()",
|
|
"inventory.failed_source_keys()",
|
|
"aggregate.with_continuity_health",
|
|
"with_failed_source_losses_reconciled",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.009 inventory-health bridge missing: {required}");
|
|
}
|
|
assert!(!root.contains("SourceHealthByKey"));
|
|
assert!(!root.contains("provider_health"));
|
|
assert!(!root.contains("endpoint_health"));
|
|
assert!(!root.contains("pub use self::continuity::RawTransactionIngestTargetCoverage"));
|
|
assert!(!snapshot.contains("WorkerHealth::Faulted"), "Faulted must remain a Worker lifecycle state rather than a new health enum variant");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_010_repair_fairness_shares_existing_bounds_without_second_pipeline() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let admission = include_str!("../src/admission.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"MAX_RAW_TRANSACTION_INGEST_REPAIR_BURST: usize = 1",
|
|
"RawTransactionIngestTrafficClass",
|
|
"RawTransactionIngestFairTurnGate",
|
|
"RawTransactionIngestTrafficClass::Nominal",
|
|
"RawTransactionIngestTrafficClass::Repair",
|
|
"acquire_hydration_permit",
|
|
"validate_repair_fairness_contract",
|
|
"repair_block_fetch_limit",
|
|
] {
|
|
assert!(resources.contains(required) || continuity.contains(required), "required pre.010 fairness guard missing: {required}");
|
|
}
|
|
assert!(continuity.contains("MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT: usize = 4"));
|
|
assert!(continuity.contains("MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS: u64 = 512"));
|
|
assert!(admission.contains("tokio::sync::mpsc::channel(capacity)"));
|
|
assert!(!resources.contains("tokio::sync::mpsc::channel("), "pre.010 created a second admission pipeline");
|
|
assert_eq!(resources.matches("struct RawTransactionIngestGlobalHydrationRegistry").count(), 1);
|
|
assert!(!resources.contains("RepairHydrationRegistry"));
|
|
assert!(!root.contains("RawTransactionIngestTrafficClass"));
|
|
assert!(!root.contains("RawTransactionIngestFairTurnGate"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_011_gap_observability_is_bounded_checked_and_redacted() {
|
|
let continuity = include_str!("../src/continuity.rs");
|
|
let snapshot = include_str!("../src/snapshot.rs");
|
|
let root = include_str!("../src/lib.rs");
|
|
for required in [
|
|
"pub struct RawTransactionIngestGapId",
|
|
"pub enum RawTransactionIngestGapState",
|
|
"pub enum RawTransactionIngestGapReason",
|
|
"pub enum RawTransactionIngestRepairMethod",
|
|
"pub struct RawTransactionIngestGapSnapshot",
|
|
"open_gap_count",
|
|
"repairing_gap_count",
|
|
"repaired_gap_total",
|
|
"unresolved_gap_total",
|
|
"replay_repair_total",
|
|
"redundant_coverage_repair_total",
|
|
"http_scan_repair_total",
|
|
"repair_block_fetch_total",
|
|
"repair_transaction_hydration_total",
|
|
"oldest_open_gap_start_slot",
|
|
] {
|
|
assert!(snapshot.contains(required), "required pre.011 snapshot observability guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS: usize = 64",
|
|
"std::vec::Vec::with_capacity(MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS)",
|
|
"gaps.len() == MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS",
|
|
"counter_exhausted_error(\"continuity.repaired_gap_total\")",
|
|
"counter_exhausted_error(\"continuity.unresolved_gap_total\")",
|
|
"gap.last_method = std::option::Option::Some(crate::RawTransactionIngestRepairMethod::RedundantCoverage)",
|
|
] {
|
|
assert!(continuity.contains(required), "required pre.011 bounded/checked continuity guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"RawTransactionIngestGapId",
|
|
"RawTransactionIngestGapReason",
|
|
"RawTransactionIngestGapSnapshot",
|
|
"RawTransactionIngestGapState",
|
|
"RawTransactionIngestRepairMethod",
|
|
] {
|
|
assert!(root.contains(required), "required pre.011 public source-neutral type missing: {required}");
|
|
}
|
|
for forbidden in ["source_key:", "endpoint_url:", "signature:", "payload:", "provider_error:"] {
|
|
assert!(!snapshot.contains(forbidden), "pre.011 snapshot leaked sensitive/source-specific field: {forbidden}");
|
|
}
|
|
assert!(!root.contains("source_key"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_012_shutdown_races_are_bounded_across_source_and_worker_drains() {
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"tokio::time::timeout(settings.shutdown_drain_timeout(), drain).await",
|
|
"persistence.abort_all()",
|
|
"while persistence.join_next().await.is_some() {}",
|
|
"while children.join_next().await.is_some() {}",
|
|
] {
|
|
assert!(runtime.contains(required), "required pre.012 outer shutdown guard missing: {required}");
|
|
}
|
|
for required in [
|
|
"shutdown_drain_timeout: std::time::Duration",
|
|
"tokio::time::timeout(shutdown_drain_timeout, drain).await",
|
|
"children.abort_all()",
|
|
"ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT",
|
|
"coordinator.abort_all(&mut processing_frontier).await",
|
|
"discover_http_block_window(",
|
|
"admission_sender.send(ingress)",
|
|
"if *stop_receiver.borrow()",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.012 source shutdown guard 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!(!runtime.contains(forbidden) && !resources.contains(forbidden), "pre.012 crossed a Worker/facade boundary: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_14_pre_013_cross_layer_completeness_security_closure_is_exact_and_redacted() {
|
|
let cross_layer = include_str!("cross_layer_completeness.rs");
|
|
let dependency_boundary = include_str!("dependency_boundary.rs");
|
|
let public_api = include_str!("public_api.rs");
|
|
for required in [
|
|
"v0_3_14_pre_013_gap_repair_closure_keeps_one_transport_worker_common_raw_store_pipeline",
|
|
"v0_3_14_pre_013_security_redaction_covers_gap_repair_and_terminal_paths",
|
|
"v0_3_14_pre_013_legacy_v0_v1_remains_proven_after_gap_repair_hardening",
|
|
"v0_3_14_pre_013_worker_and_backfill_remain_independent_producers",
|
|
] {
|
|
assert!(cross_layer.contains(required), "pre.013 cross-layer hardening proof missing: {required}");
|
|
}
|
|
assert!(dependency_boundary.contains("v0_3_14_pre_013_cross_layer_closure_keeps_dependency_and_producer_boundaries_exact"));
|
|
assert!(public_api.contains("v0_3_14_pre_013_completeness_closure_adds_no_public_surface"));
|
|
let root = include_str!("../src/lib.rs");
|
|
for forbidden in ["source_key", "provider_gap", "endpoint_gap", "signature_gap", "payload_gap", "pub mod "] {
|
|
assert!(!root.contains(forbidden), "pre.013 public Worker root leaked forbidden material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_004_websocket_source_constructors_enforce_transport_capabilities_before_io() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
for required in [
|
|
"supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs)",
|
|
"runtime_resources.standard_logs_capability_missing",
|
|
"supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block)",
|
|
"runtime_resources.standard_block_capability_missing",
|
|
"supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::HeliusTransaction)",
|
|
"runtime_resources.helius_transaction_capability_missing",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.004 WebSocket capability enforcement missing: {required}");
|
|
}
|
|
let logs_impl = match resources.split_once("impl crate::RawTransactionIngestStandardLogsSource {") {
|
|
std::option::Option::Some((_, tail)) => tail,
|
|
std::option::Option::None => "",
|
|
};
|
|
let block_impl = match resources.split_once("impl crate::RawTransactionIngestStandardBlockSource {") {
|
|
std::option::Option::Some((_, tail)) => tail,
|
|
std::option::Option::None => "",
|
|
};
|
|
let helius_impl = match resources.split_once("impl crate::RawTransactionIngestHeliusTransactionSource {") {
|
|
std::option::Option::Some((_, tail)) => tail,
|
|
std::option::Option::None => "",
|
|
};
|
|
let logs_capability = logs_impl.find("supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Logs)");
|
|
let logs_connect = logs_impl.find("SolanaStandardWsSession::connect");
|
|
let block_capability = block_impl.find("supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::Block)");
|
|
let block_connect = block_impl.find("SolanaStandardWsSession::connect");
|
|
let helius_capability = helius_impl.find("supports_subscription(ksp_onchain_transport_lib::WsSubscriptionKind::HeliusTransaction)");
|
|
let helius_connect = helius_impl.find("HeliusLaserStreamWsSession::connect");
|
|
assert!(matches!((logs_capability, logs_connect), (std::option::Option::Some(capability), std::option::Option::Some(connect)) if capability < connect));
|
|
assert!(matches!((block_capability, block_connect), (std::option::Option::Some(capability), std::option::Option::Some(connect)) if capability < connect));
|
|
assert!(matches!((helius_capability, helius_connect), (std::option::Option::Some(capability), std::option::Option::Some(connect)) if capability < connect));
|
|
assert!(!resources.contains("provider_supports_subscription"));
|
|
assert!(!resources.contains("match ws_endpoint.provider()"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_15_pre_013_yellowstone_block_hydration_is_bounded_concurrent_and_stop_preemptible() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let block_run = match resources.split_once("async fn run_block_hydration(") {
|
|
std::option::Option::Some((_, tail)) => match tail.split_once("/// Validated Helius") {
|
|
std::option::Option::Some((body, _)) => body,
|
|
std::option::Option::None => tail,
|
|
},
|
|
std::option::Option::None => "",
|
|
};
|
|
for required in [
|
|
"RawTransactionIngestYellowstoneBlockHydrationCoordinator::new",
|
|
"coordinator.start_hydrations",
|
|
"joined = coordinator.tasks.join_next()",
|
|
"update = session.next_update(), if can_receive",
|
|
"coordinator.queue_slot(value.slot()",
|
|
"coordinator.abort_all(&mut processing_frontier).await",
|
|
] {
|
|
assert!(block_run.contains(required), "required pre.013 bounded Yellowstone block hydration guard missing: {required}");
|
|
}
|
|
assert!(!block_run.contains("fetch_yellowstone_block_ingresses(&self"));
|
|
assert!(!block_run.contains("admission_sender.send(ingress)"));
|
|
for required in [
|
|
"hydrate_yellowstone_block",
|
|
"result = admission_sender.send(ingress)",
|
|
"source.yellowstone_block_hydration_pending_saturated",
|
|
"source.yellowstone_block_hydration_concurrency_missing",
|
|
] {
|
|
assert!(resources.contains(required), "required pre.013 Yellowstone block hydration bound missing: {required}");
|
|
}
|
|
for forbidden in ["unbounded_channel", "tokio::spawn(", "std::thread::spawn("] {
|
|
assert!(!block_run.contains(forbidden), "pre.013 introduced forbidden unbounded/detached execution: {forbidden}");
|
|
}
|
|
return;
|
|
}
|