0.3.16-pre.007

This commit is contained in:
2026-09-22 06:22:40 +02:00
parent a97837b832
commit d768737629
22 changed files with 842 additions and 276 deletions

View File

@@ -1,9 +1,10 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/persistence.rs
// version: 3
// version: 4
#[derive(Clone, Copy)]
enum PortResponse {
Outcome(ksp_store_lib::RawEntityWriteOutcome, ksp_store_lib::RawObservationWriteOutcome),
VariantOutcome(ksp_store_lib::RawEntityWriteOutcome, ksp_store_lib::RawObservationWriteOutcome, ksp_store_lib::RawTransactionVariantWriteOutcome),
Conflict,
StoreFailure,
}
@@ -12,8 +13,6 @@ struct FakePersistencePort {
calls: std::sync::atomic::AtomicUsize,
network: ksp_store_lib::RawNetworkId,
normal_mode_seen: std::sync::atomic::AtomicBool,
observation_calls: std::sync::atomic::AtomicUsize,
observation_response: std::option::Option<ksp_store_lib::RawObservationWriteOutcome>,
response: PortResponse,
}
@@ -23,16 +22,9 @@ impl FakePersistencePort {
calls: std::sync::atomic::AtomicUsize::new(0),
network,
normal_mode_seen: std::sync::atomic::AtomicBool::new(false),
observation_calls: std::sync::atomic::AtomicUsize::new(0),
observation_response: std::option::Option::None,
response,
};
}
fn with_observation_response(mut self, observation_response: ksp_store_lib::RawObservationWriteOutcome) -> Self {
self.observation_response = std::option::Option::Some(observation_response);
return self;
}
}
impl crate::RawTransactionIngestPersistencePort for FakePersistencePort {
@@ -52,28 +44,9 @@ impl crate::RawTransactionIngestPersistencePort for FakePersistencePort {
return std::boxed::Box::pin(async move {
return match response {
PortResponse::Outcome(entity, observation) => std::result::Result::Ok(ksp_store_lib::RawAcquisitionWriteOutcome::new(entity, observation)),
PortResponse::Conflict => std::result::Result::Err(ksp_core_lib::Error::new(ksp_store_lib::ERROR_CODE_RAW_CONFLICT, "synthetic conflict")),
PortResponse::StoreFailure => std::result::Result::Err(ksp_core_lib::Error::new(
ksp_core_lib::ErrorCode::new("synthetic_store", "write_failed"),
"synthetic remote failure text that must not escape",
)),
};
});
}
fn record_observation<'a>(
&'a self,
_observation: ksp_store_lib::RawTransactionObservation,
) -> ksp_store_lib::StoreApiFuture<'a, ksp_store_lib::Result<ksp_store_lib::RawObservationWriteOutcome>> {
self.observation_calls.fetch_add(1, std::sync::atomic::Ordering::AcqRel);
let observation_response = self.observation_response;
let response = self.response;
return std::boxed::Box::pin(async move {
if let std::option::Option::Some(outcome) = observation_response {
return std::result::Result::Ok(outcome);
}
return match response {
PortResponse::Outcome(_, observation) => std::result::Result::Ok(observation),
PortResponse::VariantOutcome(entity, observation, transaction_variant) => {
std::result::Result::Ok(ksp_store_lib::RawAcquisitionWriteOutcome::with_transaction_variant(entity, observation, transaction_variant))
},
PortResponse::Conflict => std::result::Result::Err(ksp_core_lib::Error::new(ksp_store_lib::ERROR_CODE_RAW_CONFLICT, "synthetic conflict")),
PortResponse::StoreFailure => std::result::Result::Err(ksp_core_lib::Error::new(
ksp_core_lib::ErrorCode::new("synthetic_store", "write_failed"),
@@ -203,7 +176,36 @@ async fn pre_007_normal_mode_classifies_new_idempotent_and_purged_outcomes() {
}
#[tokio::test(flavor = "current_thread")]
async fn pre_007_content_conflict_maps_to_terminal_worker_code_without_remote_text() {
async fn v0_3_16_pre_007_quarantined_conflict_is_successful_and_explicit() {
let network = match network("mainnet") {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let port = FakePersistencePort::new(
network,
PortResponse::VariantOutcome(
ksp_store_lib::RawEntityWriteOutcome::AlreadyPresent,
ksp_store_lib::RawObservationWriteOutcome::Inserted,
ksp_store_lib::RawTransactionVariantWriteOutcome::QuarantinedConflict,
),
);
let acquisition = match acquisition("mainnet", 8) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let result = crate::persist_raw_transaction_ingest_acquisition(&port, acquisition).await;
let outcome = match result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(outcome.entity(), crate::RawTransactionIngestEntityPersistence::AlreadyPresent);
assert_eq!(outcome.observation(), crate::RawTransactionIngestObservationPersistence::Inserted);
assert!(outcome.quarantined_conflict());
return;
}
#[tokio::test(flavor = "current_thread")]
async fn pre_007_legacy_store_conflict_error_maps_to_terminal_worker_code_without_remote_text() {
let network = match network("mainnet") {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
@@ -303,14 +305,14 @@ async fn pre_007_store_network_mismatch_is_rejected_before_write() {
}
#[tokio::test(flavor = "current_thread")]
async fn v0_3_13_pre_008_same_canonical_identity_uses_atomic_entity_once_then_additional_observation() {
async fn v0_3_16_pre_007_same_identity_is_serialized_but_every_acquisition_reaches_store() {
let network = match network("mainnet") {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let port = FakePersistencePort::new(
network,
PortResponse::Outcome(ksp_store_lib::RawEntityWriteOutcome::Inserted, ksp_store_lib::RawObservationWriteOutcome::Inserted),
PortResponse::Outcome(ksp_store_lib::RawEntityWriteOutcome::AlreadyPresent, ksp_store_lib::RawObservationWriteOutcome::Inserted),
);
let convergence = crate::RawTransactionIngestPersistenceConvergence::new(8);
let first = match acquisition_with_observation_key("mainnet", 41, 1) {
@@ -321,56 +323,14 @@ async fn v0_3_13_pre_008_same_canonical_identity_uses_atomic_entity_once_then_ad
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let first_outcome = crate::persist_raw_transaction_ingest_converged_acquisition(&port, first, &convergence).await;
let second_outcome = crate::persist_raw_transaction_ingest_converged_acquisition(&port, second, &convergence).await;
assert!(first_outcome.is_ok());
assert!(second_outcome.is_ok());
assert_eq!(port.calls.load(std::sync::atomic::Ordering::Acquire), 1);
assert_eq!(port.observation_calls.load(std::sync::atomic::Ordering::Acquire), 1);
let second_outcome = match second_outcome {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(second_outcome.entity(), crate::RawTransactionIngestEntityPersistence::AlreadyPresent);
assert_eq!(second_outcome.observation(), crate::RawTransactionIngestObservationPersistence::Inserted);
assert!(crate::persist_raw_transaction_ingest_converged_acquisition(&port, first, &convergence).await.is_ok());
assert!(crate::persist_raw_transaction_ingest_converged_acquisition(&port, second, &convergence).await.is_ok());
assert_eq!(port.calls.load(std::sync::atomic::Ordering::Acquire), 2);
return;
}
#[tokio::test(flavor = "current_thread")]
async fn v0_3_13_pre_008_replayed_same_observation_is_idempotent_without_raw_resubmission() {
let network = match network("mainnet") {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let port = FakePersistencePort::new(
network,
PortResponse::Outcome(ksp_store_lib::RawEntityWriteOutcome::Inserted, ksp_store_lib::RawObservationWriteOutcome::Inserted),
)
.with_observation_response(ksp_store_lib::RawObservationWriteOutcome::AlreadyPresent);
let convergence = crate::RawTransactionIngestPersistenceConvergence::new(8);
let first = match acquisition_with_observation_key("mainnet", 42, 3) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let second = match acquisition_with_observation_key("mainnet", 42, 3) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
let first_result = crate::persist_raw_transaction_ingest_converged_acquisition(&port, first, &convergence).await;
assert!(first_result.is_ok());
let second_result = crate::persist_raw_transaction_ingest_converged_acquisition(&port, second, &convergence).await;
let second_outcome = match second_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(port.calls.load(std::sync::atomic::Ordering::Acquire), 1);
assert_eq!(port.observation_calls.load(std::sync::atomic::Ordering::Acquire), 1);
assert_eq!(second_outcome.observation(), crate::RawTransactionIngestObservationPersistence::AlreadyPresent);
return;
}
#[tokio::test(flavor = "current_thread")]
async fn v0_3_13_pre_009_source_skew_and_provider_disagreement_fail_before_additional_observation() {
async fn v0_3_16_pre_007_run_local_cache_never_rejects_divergent_shapes_before_store() {
let cases = [
(43_u64, std::option::Option::Some(1_700_000_000_i64), "AQID"),
(42_u64, std::option::Option::Some(1_700_000_001_i64), "AQID"),
@@ -383,7 +343,11 @@ async fn v0_3_13_pre_009_source_skew_and_provider_disagreement_fail_before_addit
};
let port = FakePersistencePort::new(
network,
PortResponse::Outcome(ksp_store_lib::RawEntityWriteOutcome::Inserted, ksp_store_lib::RawObservationWriteOutcome::Inserted),
PortResponse::VariantOutcome(
ksp_store_lib::RawEntityWriteOutcome::AlreadyPresent,
ksp_store_lib::RawObservationWriteOutcome::Inserted,
ksp_store_lib::RawTransactionVariantWriteOutcome::QuarantinedConflict,
),
);
let convergence = crate::RawTransactionIngestPersistenceConvergence::new(8);
let first = match acquisition_with_shape("mainnet", 51, 10, 42, std::option::Option::Some(1_700_000_000), "AQID") {
@@ -394,15 +358,11 @@ async fn v0_3_13_pre_009_source_skew_and_provider_disagreement_fail_before_addit
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert!(crate::persist_raw_transaction_ingest_converged_acquisition(&port, first, &convergence).await.is_ok());
let conflict = crate::persist_raw_transaction_ingest_converged_acquisition(&port, divergent, &convergence).await;
let error = match conflict {
std::result::Result::Ok(_) => return,
std::result::Result::Err(value) => value,
};
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_CONTENT_CONFLICT);
assert_eq!(port.calls.load(std::sync::atomic::Ordering::Acquire), 1);
assert_eq!(port.observation_calls.load(std::sync::atomic::Ordering::Acquire), 0);
let first_outcome = crate::persist_raw_transaction_ingest_converged_acquisition(&port, first, &convergence).await;
let second_outcome = crate::persist_raw_transaction_ingest_converged_acquisition(&port, divergent, &convergence).await;
assert!(matches!(first_outcome, std::result::Result::Ok(value) if value.quarantined_conflict()));
assert!(matches!(second_outcome, std::result::Result::Ok(value) if value.quarantined_conflict()));
assert_eq!(port.calls.load(std::sync::atomic::Ordering::Acquire), 2);
}
return;
}