365 lines
15 KiB
Rust
365 lines
15 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
|
// version: 4
|
|
|
|
//! External public, security, redaction and release-boundary hardening canaries for `pre.010`.
|
|
|
|
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"), &["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",
|
|
"Discovery",
|
|
"discovery",
|
|
"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("}\n\nimpl 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:",
|
|
"network:",
|
|
"route:",
|
|
"signature:",
|
|
"slot:",
|
|
"transaction_index:",
|
|
] {
|
|
assert!(signal_struct.contains(required), "required private signal field missing: {required}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_12_pre_002_runtime_resource_contract_performs_no_live_io_or_source_spawn() {
|
|
let resources = include_str!("../src/runtime_resources.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for forbidden in ["open_standard_subscribe", "next_update", "get_transaction_observed", "get_block_observed", "tokio::spawn", "JoinSet"] {
|
|
assert!(!resources.contains(forbidden), "pre.002 runtime-resource contract opened premature live behavior: {forbidden}");
|
|
}
|
|
assert!(runtime.contains("start_with_runtime_resources"));
|
|
for forbidden in ["open_standard_subscribe", "next_update", "get_transaction_observed", "get_block_observed"] {
|
|
assert!(!runtime.contains(forbidden), "pre.002 runtime start opened premature live behavior: {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;
|
|
}
|