v0.3.12-pre.003
This commit is contained in:
@@ -1,15 +1,23 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
||||
return grpc_endpoint_with_identity(cluster, "yellowstone-fixture", "fixture-provider");
|
||||
}
|
||||
|
||||
fn grpc_endpoint_with_identity(
|
||||
cluster: &str,
|
||||
endpoint_name: &str,
|
||||
provider: &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",
|
||||
endpoint_name,
|
||||
true,
|
||||
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new("fixture-provider"),
|
||||
ksp_onchain_transport_lib::YellowstoneGrpcProviderName::new(provider),
|
||||
ksp_onchain_transport_lib::YellowstoneGrpcClusterName::new(cluster),
|
||||
url,
|
||||
ksp_onchain_transport_lib::YellowstoneGrpcSessionSettings::default(),
|
||||
@@ -69,6 +77,76 @@ fn transaction_request(
|
||||
return std::option::Option::Some(request);
|
||||
}
|
||||
|
||||
struct SignalViewFixture {
|
||||
created_at: std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp>,
|
||||
family: super::RawTransactionIngestSourceFamily,
|
||||
filters: std::vec::Vec<ksp_onchain_transport_lib::YellowstoneSubscribeFilterName>,
|
||||
index: u64,
|
||||
signature: ksp_onchain_transport_lib::YellowstoneTransactionSignature,
|
||||
slot: u64,
|
||||
}
|
||||
|
||||
impl super::RawTransactionIngestYellowstoneSignalView for SignalViewFixture {
|
||||
fn created_at(&self) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneUpdateTimestamp> {
|
||||
return self.created_at;
|
||||
}
|
||||
|
||||
fn family(&self) -> super::RawTransactionIngestSourceFamily {
|
||||
return self.family;
|
||||
}
|
||||
|
||||
fn filters(&self) -> &[ksp_onchain_transport_lib::YellowstoneSubscribeFilterName] {
|
||||
return self.filters.as_slice();
|
||||
}
|
||||
|
||||
fn index(&self) -> u64 {
|
||||
return self.index;
|
||||
}
|
||||
|
||||
fn signature(&self) -> ksp_onchain_transport_lib::YellowstoneTransactionSignature {
|
||||
return self.signature;
|
||||
}
|
||||
|
||||
fn slot(&self) -> u64 {
|
||||
return self.slot;
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_names(values: &[&str]) -> std::option::Option<std::vec::Vec<ksp_onchain_transport_lib::YellowstoneSubscribeFilterName>> {
|
||||
let mut filters = std::vec::Vec::with_capacity(values.len());
|
||||
for value in values {
|
||||
let filter = match ksp_onchain_transport_lib::YellowstoneSubscribeFilterName::new(*value) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return std::option::Option::None,
|
||||
};
|
||||
filters.push(filter);
|
||||
}
|
||||
return std::option::Option::Some(filters);
|
||||
}
|
||||
|
||||
fn signal_source() -> std::option::Option<crate::RawTransactionIngestYellowstoneSource> {
|
||||
let endpoint = match grpc_endpoint("devnet") {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let channel = match ksp_onchain_transport_lib::YellowstoneGrpcChannel::prepare(&endpoint) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return std::option::Option::None,
|
||||
};
|
||||
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 std::option::Option::None,
|
||||
};
|
||||
let pool = match http_pool("devnet", "hydration", "get_transaction") {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
return match crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration")) {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(_) => std::option::Option::None,
|
||||
};
|
||||
}
|
||||
|
||||
#[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") {
|
||||
@@ -250,3 +328,149 @@ async fn pre_002_runtime_resources_reject_worker_network_mismatch_without_starti
|
||||
assert!(error.context().iter().any(|context| return context.value() == "runtime_resources.worker_network_mismatch"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn pre_003_transaction_signal_fixture_preserves_exact_source_neutral_identity() {
|
||||
let source = match signal_source() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let filters = match filter_names(&["filter-b", "filter-a", "filter-a"]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let created_at = match ksp_onchain_transport_lib::YellowstoneUpdateTimestamp::new(1_760_000_123, 456_000_000) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let fixture = SignalViewFixture {
|
||||
created_at: std::option::Option::Some(created_at),
|
||||
family: super::RawTransactionIngestSourceFamily::Transaction,
|
||||
filters,
|
||||
index: 7,
|
||||
signature: ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([0xAB; 64]),
|
||||
slot: 42,
|
||||
};
|
||||
let signal = super::project_yellowstone_signal(&source, &fixture);
|
||||
assert_eq!(signal.family, super::RawTransactionIngestSourceFamily::Transaction);
|
||||
assert_eq!(signal.network.as_str(), "devnet");
|
||||
assert_eq!(signal.signature.as_bytes(), &[0xAB; 64]);
|
||||
assert_eq!(signal.slot, 42);
|
||||
assert_eq!(signal.transaction_index, std::option::Option::Some(7));
|
||||
assert_eq!(signal.route.provider.as_str(), "fixture-provider");
|
||||
assert_eq!(signal.route.endpoint_id.as_str(), "yellowstone-fixture");
|
||||
assert_eq!(signal.matched_filter_count, 3);
|
||||
assert_eq!(
|
||||
signal.matched_filter_fingerprint,
|
||||
[
|
||||
0x20, 0x83, 0x1d, 0xc8, 0x37, 0x8b, 0x60, 0x70, 0xf9, 0x1d, 0x9d, 0xe6, 0xd3, 0xa1, 0xd2, 0xb3, 0xd7, 0x72, 0x98, 0xe3, 0xad, 0xa7, 0x6c, 0x01,
|
||||
0xfa, 0xa3, 0x08, 0x26, 0xff, 0xab, 0xcd, 0x84,
|
||||
]
|
||||
);
|
||||
assert_eq!(signal.created_at, std::option::Option::Some(super::RawTransactionIngestSourceTimestamp { nanos: 456_000_000, seconds: 1_760_000_123 }));
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn pre_003_transaction_status_signal_has_no_payload_or_remote_error_material() {
|
||||
let source = match signal_source() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let filters = match filter_names(&["status-secret-canary"]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let fixture = SignalViewFixture {
|
||||
created_at: std::option::Option::None,
|
||||
family: super::RawTransactionIngestSourceFamily::TransactionStatus,
|
||||
filters,
|
||||
index: 9,
|
||||
signature: ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([0xCD; 64]),
|
||||
slot: 84,
|
||||
};
|
||||
let signal = super::project_yellowstone_signal(&source, &fixture);
|
||||
assert_eq!(signal.family, super::RawTransactionIngestSourceFamily::TransactionStatus);
|
||||
assert_eq!(signal.signature.as_bytes(), &[0xCD; 64]);
|
||||
assert_eq!(signal.slot, 84);
|
||||
assert_eq!(signal.transaction_index, std::option::Option::Some(9));
|
||||
assert_eq!(signal.created_at, std::option::Option::None);
|
||||
let debug = std::format!("{signal:?}");
|
||||
assert!(!debug.contains("status-secret-canary"));
|
||||
assert!(debug.contains("signature_bytes"));
|
||||
assert!(!debug.contains("YellowstoneTransactionError"));
|
||||
assert!(!debug.contains("transaction_body"));
|
||||
assert!(!debug.contains("transaction_meta"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn pre_003_filter_fingerprint_is_order_and_duplicate_insensitive() {
|
||||
let source = match signal_source() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let first_filters = match filter_names(&["filter-b", "filter-a", "filter-a"]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let second_filters = match filter_names(&["filter-a", "filter-b"]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let first = SignalViewFixture {
|
||||
created_at: std::option::Option::None,
|
||||
family: super::RawTransactionIngestSourceFamily::Transaction,
|
||||
filters: first_filters,
|
||||
index: 1,
|
||||
signature: ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([1; 64]),
|
||||
slot: 1,
|
||||
};
|
||||
let second = SignalViewFixture {
|
||||
created_at: std::option::Option::None,
|
||||
family: super::RawTransactionIngestSourceFamily::Transaction,
|
||||
filters: second_filters,
|
||||
index: 1,
|
||||
signature: ksp_onchain_transport_lib::YellowstoneTransactionSignature::new([1; 64]),
|
||||
slot: 1,
|
||||
};
|
||||
let first_signal = super::project_yellowstone_signal(&source, &first);
|
||||
let second_signal = super::project_yellowstone_signal(&source, &second);
|
||||
assert_eq!(first_signal.matched_filter_fingerprint, second_signal.matched_filter_fingerprint);
|
||||
assert_eq!(first_signal.matched_filter_count, 3);
|
||||
assert_eq!(second_signal.matched_filter_count, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn pre_003_source_rejects_route_identity_that_cannot_become_safe_provenance() {
|
||||
for (endpoint_name, provider, expected_condition) in [
|
||||
("yellowstone-fixture", "fixture/provider", "runtime_resources.yellowstone_provider_unrepresentable"),
|
||||
("yellowstone/fixture", "fixture-provider", "runtime_resources.yellowstone_endpoint_unrepresentable"),
|
||||
] {
|
||||
let endpoint = match grpc_endpoint_with_identity("devnet", endpoint_name, provider) {
|
||||
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 result = crate::RawTransactionIngestYellowstoneSource::new(channel, request, pool, ksp_onchain_transport_lib::HttpRoleName::new("hydration"));
|
||||
let error = match result {
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user