253 lines
12 KiB
Rust
253 lines
12 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
|
// version: 1
|
|
|
|
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
|
let url = match ksp_onchain_transport_lib::YellowstoneGrpcEndpointUrl::parse("http://127.0.0.1:10000/GRPC-SECRET-CANARY") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
return std::option::Option::Some(ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings::new(
|
|
"yellowstone-fixture",
|
|
true,
|
|
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new("fixture-provider"),
|
|
ksp_onchain_transport_lib::YellowstoneGrpcClusterName::new(cluster),
|
|
url,
|
|
ksp_onchain_transport_lib::YellowstoneGrpcSessionSettings::default(),
|
|
));
|
|
}
|
|
|
|
fn http_pool(cluster: &str, role_name: &str, request_kind: &str) -> std::option::Option<ksp_onchain_transport_lib::HttpTransportPool> {
|
|
let url = match ksp_onchain_transport_lib::HttpEndpointUrl::parse("https://fixture.invalid/rpc?token=HTTP-SECRET-CANARY") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
let role = ksp_onchain_transport_lib::HttpEndpointRoleSettings::new(
|
|
ksp_onchain_transport_lib::HttpRoleName::new(role_name),
|
|
true,
|
|
std::vec![ksp_onchain_transport_lib::HttpRequestKind::new(request_kind)],
|
|
10,
|
|
ksp_onchain_transport_lib::HttpRoleLimits::new(
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
std::option::Option::None,
|
|
),
|
|
);
|
|
let endpoint = ksp_onchain_transport_lib::HttpEndpointSettings::new(
|
|
"http-fixture",
|
|
true,
|
|
ksp_onchain_transport_lib::HttpProviderName::new("fixture-provider"),
|
|
ksp_onchain_transport_lib::HttpClusterName::new(cluster),
|
|
url,
|
|
std::time::Duration::from_secs(1),
|
|
std::time::Duration::from_secs(2),
|
|
std::option::Option::Some(4),
|
|
std::vec![role],
|
|
);
|
|
let settings = ksp_onchain_transport_lib::HttpTransportSettings::new(
|
|
std::vec![endpoint],
|
|
ksp_onchain_transport_lib::HttpRetrySettings::new(1, std::time::Duration::from_millis(10), std::time::Duration::from_millis(20)),
|
|
);
|
|
return match ksp_onchain_transport_lib::HttpTransportPool::new(settings) {
|
|
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
|
std::result::Result::Err(_) => std::option::Option::None,
|
|
};
|
|
}
|
|
|
|
fn transaction_request(
|
|
commitment: std::option::Option<ksp_onchain_transport_lib::SolanaCommitment>,
|
|
) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneSubscribeRequest> {
|
|
let name = match ksp_onchain_transport_lib::YellowstoneSubscribeFilterName::new("tx-fixture") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
let mut request = ksp_onchain_transport_lib::YellowstoneSubscribeRequest::new();
|
|
if request.insert_transaction_filter(name, ksp_onchain_transport_lib::YellowstoneSubscribeTransactionFilter::new()).is_err() {
|
|
return std::option::Option::None;
|
|
}
|
|
request.set_commitment(commitment);
|
|
return std::option::Option::Some(request);
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_source_accepts_matching_confirmed_transaction_and_get_transaction_route_without_io() {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let request = match transaction_request(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration"));
|
|
assert!(source.is_ok());
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_source_rejects_processed_and_implicit_commitment() {
|
|
for commitment in [std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Processed), std::option::Option::None] {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let request = match transaction_request(commitment) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration"));
|
|
let error = match source {
|
|
std::result::Result::Ok(_) => return,
|
|
std::result::Result::Err(error) => error,
|
|
};
|
|
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID);
|
|
assert!(error.context().iter().any(|context| return context.value() == "runtime_resources.hydration_commitment_invalid"));
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_source_requires_ingestion_bearing_filter_family() {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let mut request = ksp_onchain_transport_lib::YellowstoneSubscribeRequest::new();
|
|
request.set_commitment(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Finalized));
|
|
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration"));
|
|
let error = match source {
|
|
std::result::Result::Ok(_) => return,
|
|
std::result::Result::Err(error) => error,
|
|
};
|
|
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID);
|
|
assert!(error.context().iter().any(|context| return context.value() == "runtime_resources.ingestion_filter_missing"));
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_source_rejects_missing_hydration_capability_and_cross_transport_network() {
|
|
for (http_cluster, request_kind, expected_condition) in [
|
|
("devnet", "get_balance", "runtime_resources.hydration_role_unsupported"),
|
|
("mainnet", "get_transaction", "runtime_resources.transport_network_mismatch"),
|
|
] {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let request = match transaction_request(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let pool = match http_pool(http_cluster, "hydration", request_kind) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration"));
|
|
let error = match source {
|
|
std::result::Result::Ok(_) => return,
|
|
std::result::Result::Err(error) => error,
|
|
};
|
|
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID);
|
|
assert!(error.context().iter().any(|context| return context.value() == expected_condition));
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_runtime_resource_debug_is_safe_and_exposes_no_client_inner() {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let request = match transaction_request(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = match crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration")) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let resources = crate::RawTransactionIngestRuntimeResources::new(source);
|
|
let debug = std::format!("{resources:?}");
|
|
assert!(debug.contains("RawTransactionIngestRuntimeResources"));
|
|
assert!(debug.contains("devnet"));
|
|
assert!(!debug.contains("GRPC-SECRET-CANARY"));
|
|
assert!(!debug.contains("HTTP-SECRET-CANARY"));
|
|
assert!(!debug.contains("127.0.0.1"));
|
|
assert!(!debug.contains("fixture.invalid"));
|
|
assert!(!debug.contains("tx-fixture"));
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_002_runtime_resources_reject_worker_network_mismatch_without_starting_source() {
|
|
let endpoint = match grpc_endpoint("devnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let request = match transaction_request(std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let source = match crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration")) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let resources = crate::RawTransactionIngestRuntimeResources::new(source);
|
|
let network = match ksp_store_lib::RawNetworkId::new("mainnet") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let error = match resources.validate_network(&network) {
|
|
std::result::Result::Ok(()) => return,
|
|
std::result::Result::Err(error) => error,
|
|
};
|
|
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID);
|
|
assert!(error.context().iter().any(|context| return context.value() == "runtime_resources.worker_network_mismatch"));
|
|
return;
|
|
}
|