v0.3.14-pre.007
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
||||
// version: 26
|
||||
// version: 27
|
||||
|
||||
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
||||
return grpc_endpoint_with_identity(cluster, "yellowstone-fixture", "fixture-provider");
|
||||
@@ -450,6 +450,16 @@ const PRE_004_ZERO_SIGNATURE_TEXT: &str = "1111111111111111111111111111111111111
|
||||
const PRE_004_ZERO_TRANSACTION_BASE64: &str = "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
|
||||
fn http_pool_for_url(url: &str, cluster: &str, endpoint_name: &str, provider: &str) -> std::option::Option<ksp_onchain_transport_lib::HttpTransportPool> {
|
||||
return http_pool_for_url_with_request_kinds(url, cluster, endpoint_name, provider, &["get_transaction"]);
|
||||
}
|
||||
|
||||
fn http_pool_for_url_with_request_kinds(
|
||||
url: &str,
|
||||
cluster: &str,
|
||||
endpoint_name: &str,
|
||||
provider: &str,
|
||||
request_kinds: &[&str],
|
||||
) -> std::option::Option<ksp_onchain_transport_lib::HttpTransportPool> {
|
||||
let url = match ksp_onchain_transport_lib::HttpEndpointUrl::parse(url) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return std::option::Option::None,
|
||||
@@ -457,7 +467,7 @@ fn http_pool_for_url(url: &str, cluster: &str, endpoint_name: &str, provider: &s
|
||||
let role = ksp_onchain_transport_lib::HttpEndpointRoleSettings::new(
|
||||
ksp_onchain_transport_lib::HttpRoleName::new("hydration"),
|
||||
true,
|
||||
std::vec![ksp_onchain_transport_lib::HttpRequestKind::new("get_transaction")],
|
||||
request_kinds.iter().map(|value| return ksp_onchain_transport_lib::HttpRequestKind::new(*value)).collect(),
|
||||
10,
|
||||
ksp_onchain_transport_lib::HttpRoleLimits::new(
|
||||
std::option::Option::None,
|
||||
@@ -517,6 +527,29 @@ fn signal_source_for_http_url_with_commitment(
|
||||
};
|
||||
}
|
||||
|
||||
fn signal_source_for_http_url_with_request_kinds(url: &str, request_kinds: &[&str]) -> 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_for_url_with_request_kinds(url, "devnet", "http-hydration-fixture", "fixture-http-provider", request_kinds) {
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
fn standard_logs_source_for_http_url(
|
||||
url: &str,
|
||||
filter: ksp_onchain_transport_lib::SolanaLogsSubscribeFilter,
|
||||
@@ -3140,6 +3173,196 @@ fn v0_3_14_pre_006_with_limit_discovery_never_uses_tip_alone_as_tail_coverage_pr
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_007_known_reference_hydration_reuses_global_registry_and_available_material() {
|
||||
let body = std::format!(
|
||||
"{{\"jsonrpc\":\"2.0\",\"result\":{{\"slot\":42,\"blockTime\":1760000120,\"transaction\":[\"{}\",\"base64\"],\"meta\":null,\"version\":0,\"transactionIndex\":7}},\"id\":1}}",
|
||||
PRE_004_ZERO_TRANSACTION_BASE64,
|
||||
);
|
||||
let (url, server) = match serve_http_once(body) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let source = match signal_source_for_http_url(url.as_str()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let settings = match pre_004_settings() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let signal = match pre_004_signal(&source, super::RawTransactionIngestSourceFamily::Transaction, 42, 7, &["tx-fixture"], 0) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let hydration = source.hydration_context();
|
||||
let key = match super::hydration_key(&hydration, &signal) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let registry = std::sync::Arc::new(super::RawTransactionIngestGlobalHydrationRegistry::new(4, 1));
|
||||
let first = super::fetch_hydration_shared(
|
||||
std::sync::Arc::clone(®istry),
|
||||
hydration.http_pool.clone(),
|
||||
hydration.hydration_role.clone(),
|
||||
hydration.network.clone(),
|
||||
key.clone(),
|
||||
hydration.commitment,
|
||||
);
|
||||
let second = super::fetch_hydration_shared(
|
||||
std::sync::Arc::clone(®istry),
|
||||
hydration.http_pool.clone(),
|
||||
hydration.hydration_role.clone(),
|
||||
hydration.network.clone(),
|
||||
key,
|
||||
hydration.commitment,
|
||||
);
|
||||
let (first, second) = tokio::join!(first, second);
|
||||
let first = match first {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
assert!(second.is_ok());
|
||||
let request = match server.join() {
|
||||
std::result::Result::Ok(std::result::Result::Ok(value)) => value,
|
||||
_ => return,
|
||||
};
|
||||
assert!(request.contains("\"method\":\"getTransaction\""));
|
||||
let received_at = match ksp_store_lib::RawTimestamp::from_unix_millis(1_760_000_200_000) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let resolved = super::resolve_known_reference_hydration(&hydration, &settings, signal, received_at, &first.observed);
|
||||
let ingress = match resolved {
|
||||
std::result::Result::Ok(super::RawTransactionIngestKnownReferenceHydrationResolution::Available(value)) => value,
|
||||
_ => return,
|
||||
};
|
||||
let (mut admission, sender) = crate::RawTransactionAdmission::new(1);
|
||||
if sender.send(ingress).await.is_err() {
|
||||
return;
|
||||
}
|
||||
std::mem::drop(sender);
|
||||
let acquisition = match admission.receive(settings.network()).await {
|
||||
std::result::Result::Ok(std::option::Option::Some(value)) => value,
|
||||
_ => return,
|
||||
};
|
||||
assert_eq!(acquisition.transaction().slot(), 42);
|
||||
assert_eq!(acquisition.transaction().reference().signature().as_bytes(), &[0_u8; 64]);
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_007_missing_known_reference_remains_open_without_block_capability() {
|
||||
let (url, server) = match serve_http_once("{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":1}".to_owned()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let source = match signal_source_for_http_url(url.as_str()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let settings = match pre_004_settings() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let signal = match pre_004_signal(&source, super::RawTransactionIngestSourceFamily::TransactionStatus, 77, 0, &["status-fixture"], 0) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let hydration = source.hydration_context();
|
||||
let key = match super::hydration_key(&hydration, &signal) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let registry = std::sync::Arc::new(super::RawTransactionIngestGlobalHydrationRegistry::new(2, 1));
|
||||
let fetched = super::fetch_hydration_shared(
|
||||
registry,
|
||||
hydration.http_pool.clone(),
|
||||
hydration.hydration_role.clone(),
|
||||
hydration.network.clone(),
|
||||
key,
|
||||
hydration.commitment,
|
||||
)
|
||||
.await;
|
||||
let fetched = match fetched {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let _request = match server.join() {
|
||||
std::result::Result::Ok(std::result::Result::Ok(value)) => value,
|
||||
_ => return,
|
||||
};
|
||||
let received_at = match ksp_store_lib::RawTimestamp::from_unix_millis(1_760_000_200_000) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let resolved = super::resolve_known_reference_hydration(&hydration, &settings, signal, received_at, &fetched.observed);
|
||||
let (disposition, obligation) = match resolved {
|
||||
std::result::Result::Ok(super::RawTransactionIngestKnownReferenceHydrationResolution::Missing { disposition, obligation }) => (disposition, obligation),
|
||||
_ => return,
|
||||
};
|
||||
assert_eq!(disposition, super::RawTransactionIngestKnownReferenceMissingDisposition::AwaitCoverage);
|
||||
assert_eq!(obligation.slot(), 77);
|
||||
assert_eq!(obligation.commitment(), ksp_onchain_transport_lib::SolanaCommitment::Confirmed);
|
||||
assert_eq!(obligation.reference().signature().as_bytes(), &[0_u8; 64]);
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_007_missing_known_reference_prefers_same_role_block_slot_when_supported() {
|
||||
let (url, server) = match serve_http_once("{\"jsonrpc\":\"2.0\",\"result\":null,\"id\":1}".to_owned()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let source = match signal_source_for_http_url_with_request_kinds(url.as_str(), &["get_transaction", "get_block"]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let settings = match pre_004_settings() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let signal = match pre_004_signal(&source, super::RawTransactionIngestSourceFamily::Transaction, 88, 0, &["tx-fixture"], 0) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let hydration = source.hydration_context();
|
||||
let key = match super::hydration_key(&hydration, &signal) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let registry = std::sync::Arc::new(super::RawTransactionIngestGlobalHydrationRegistry::new(2, 1));
|
||||
let fetched = super::fetch_hydration_shared(
|
||||
registry,
|
||||
hydration.http_pool.clone(),
|
||||
hydration.hydration_role.clone(),
|
||||
hydration.network.clone(),
|
||||
key,
|
||||
hydration.commitment,
|
||||
)
|
||||
.await;
|
||||
let fetched = match fetched {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let _request = match server.join() {
|
||||
std::result::Result::Ok(std::result::Result::Ok(value)) => value,
|
||||
_ => return,
|
||||
};
|
||||
let received_at = match ksp_store_lib::RawTimestamp::from_unix_millis(1_760_000_200_000) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let resolved = super::resolve_known_reference_hydration(&hydration, &settings, signal, received_at, &fetched.observed);
|
||||
let (disposition, obligation) = match resolved {
|
||||
std::result::Result::Ok(super::RawTransactionIngestKnownReferenceHydrationResolution::Missing { disposition, obligation }) => (disposition, obligation),
|
||||
_ => return,
|
||||
};
|
||||
assert_eq!(disposition, super::RawTransactionIngestKnownReferenceMissingDisposition::PreferBlockSlot);
|
||||
assert_eq!(obligation.slot(), 88);
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v0_3_13_pre_006_http_block_polling_qualifies_legacy_v0_v1_and_rejects_ambiguous_or_future_versions() {
|
||||
let cases = [
|
||||
|
||||
Reference in New Issue
Block a user