0.3.16-pre.004

This commit is contained in:
2026-09-21 17:53:13 +02:00
parent ec053c98ab
commit 19712aa7a6
9 changed files with 622 additions and 43 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs
// version: 7
// version: 9
#![warn(missing_docs)]
#![deny(unreachable_pub)]
@@ -18,7 +18,11 @@ const LIVE_INDEX_EXISTS_SQL: &str = r#"SELECT EXISTS (
AND indexname = 'ix_ksp_raw_transactions_slot_signature'
)"#;
const LIVE_LOCK_OBSERVATION_SQL: &str = "SELECT observation_key FROM ksp_raw_transaction_observations WHERE observation_key = $1 FOR UPDATE";
const LIVE_MANAGED_SCHEMA_DROP_SQL: &str = r#"DROP TABLE IF EXISTS ksp_raw_account_observations;
const LIVE_MANAGED_SCHEMA_DROP_SQL: &str = r#"DROP TABLE IF EXISTS ksp_raw_transaction_conflicts;
DROP TABLE IF EXISTS ksp_raw_transaction_observation_variants;
DROP TABLE IF EXISTS ksp_raw_transaction_canonical_selectors;
DROP TABLE IF EXISTS ksp_raw_transaction_variants;
DROP TABLE IF EXISTS ksp_raw_account_observations;
DROP TABLE IF EXISTS ksp_raw_account_states;
DROP TABLE IF EXISTS ksp_raw_transaction_observations;
DROP TABLE IF EXISTS ksp_raw_transaction_archive_payloads;
@@ -34,6 +38,10 @@ const LIVE_MANAGED_SCHEMA_EXISTS_SQL: &str = r#"SELECT EXISTS (
'ksp_raw_transactions',
'ksp_raw_transaction_observations',
'ksp_raw_transaction_archive_payloads',
'ksp_raw_transaction_variants',
'ksp_raw_transaction_canonical_selectors',
'ksp_raw_transaction_observation_variants',
'ksp_raw_transaction_conflicts',
'ksp_raw_account_states',
'ksp_raw_account_observations'
)
@@ -42,6 +50,7 @@ const LIVE_MANAGED_SCHEMA_EXISTS_SQL: &str = r#"SELECT EXISTS (
const LIVE_MAX_URI_BYTES: usize = 4_096;
const LIVE_OBSERVATION_EXISTS_SQL: &str = "SELECT EXISTS (SELECT 1 FROM ksp_raw_transaction_observations WHERE observation_key = $1)";
const LIVE_TRANSACTION_EXISTS_SQL: &str = "SELECT EXISTS (SELECT 1 FROM ksp_raw_transactions WHERE signature = $1)";
const LIVE_VARIANT_IDEMPOTENCE_SQL: &str = "SELECT (SELECT COUNT(*) = 1 FROM ksp_raw_transaction_variants WHERE transaction_signature = $1) AND (SELECT COUNT(*) = 1 FROM ksp_raw_transaction_canonical_selectors WHERE transaction_signature = $1) AND (SELECT COUNT(*) = 1 FROM ksp_raw_transaction_observation_variants WHERE transaction_signature = $1) AND EXISTS (SELECT 1 FROM ksp_raw_transaction_observation_variants AS mapping INNER JOIN ksp_raw_transaction_canonical_selectors AS selector ON selector.transaction_signature = mapping.transaction_signature AND selector.canonical_variant_id = mapping.variant_id WHERE mapping.observation_key = $2 AND mapping.transaction_signature = $1)";
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct LiveFailure {
@@ -157,7 +166,7 @@ async fn run_raw_transaction_scenario(admin: &mut tokio_postgres::Client, uri: &
};
*owns_schema = true;
let initial_health = initial.health().await;
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(2) || initial_health.pending_migration_count() != 0 {
if !initial_health.is_ready() || initial_health.migration_version() != std::option::Option::Some(3) || initial_health.pending_migration_count() != 0 {
return std::result::Result::Err(LiveFailure::new("initial_health"));
}
let wrong_network_result = open_backend_result(uri, "testnet", true, true).await;
@@ -197,7 +206,7 @@ async fn run_raw_transaction_scenario(admin: &mut tokio_postgres::Client, uri: &
if let std::result::Result::Err(error) = backend_close {
return std::result::Result::Err(error);
}
let identical_result = prove_concurrent_identical_insert(uri).await;
let identical_result = prove_concurrent_identical_insert(admin, uri).await;
if let std::result::Result::Err(error) = identical_result {
return std::result::Result::Err(error);
}
@@ -219,7 +228,7 @@ async fn run_raw_transaction_scenario(admin: &mut tokio_postgres::Client, uri: &
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let reopened_health = reopened.health().await;
if !reopened_health.is_ready() || reopened_health.migration_version() != std::option::Option::Some(2) {
if !reopened_health.is_ready() || reopened_health.migration_version() != std::option::Option::Some(3) {
return std::result::Result::Err(LiveFailure::new("reopen_health"));
}
let reference_result = raw_reference(10);
@@ -361,7 +370,7 @@ async fn prove_additional_observation_and_atomic_rollback(backend: &ksp_store_po
return std::result::Result::Ok(());
}
async fn prove_concurrent_identical_insert(uri: &str) -> std::result::Result<(), LiveFailure> {
async fn prove_concurrent_identical_insert(admin: &tokio_postgres::Client, uri: &str) -> std::result::Result<(), LiveFailure> {
let first = tokio::spawn(persist_once(uri.to_owned(), 20, 2_000, 20, 20));
let second = tokio::spawn(persist_once(uri.to_owned(), 20, 2_000, 20, 20));
let first_result = match joined_persist(first.await, "concurrent_identical_first") {
@@ -378,6 +387,17 @@ async fn prove_concurrent_identical_insert(uri: &str) -> std::result::Result<(),
if inserted != 1 || already != 1 {
return std::result::Result::Err(LiveFailure::new("concurrent_identical_outcome"));
}
let reference = match raw_reference(20) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let key = ksp_store_api::RawObservationKey::new([20; 32]);
let projection_result = variant_projection_is_exact(admin, &reference, &key).await;
match projection_result {
std::result::Result::Ok(true) => {},
std::result::Result::Ok(false) => return std::result::Result::Err(LiveFailure::new("concurrent_identical_variant_projection")),
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
return std::result::Result::Ok(());
}
@@ -1256,3 +1276,21 @@ async fn observation_exists(client: &tokio_postgres::Client, key: &ksp_store_api
std::result::Result::Err(_) => std::result::Result::Err(LiveFailure::new("observation_exists_decode")),
};
}
async fn variant_projection_is_exact(
client: &tokio_postgres::Client,
reference: &ksp_store_api::RawTransactionReference,
key: &ksp_store_api::RawObservationKey,
) -> std::result::Result<bool, LiveFailure> {
let signature = reference.signature();
let signature_bytes: &[u8] = signature.as_bytes();
let key_bytes: &[u8] = key.as_bytes();
let row = match client.query_one(LIVE_VARIANT_IDEMPOTENCE_SQL, &[&signature_bytes, &key_bytes]).await {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return std::result::Result::Err(LiveFailure::new("variant_projection_probe")),
};
return match row.try_get::<usize, bool>(0) {
std::result::Result::Ok(value) => std::result::Result::Ok(value),
std::result::Result::Err(_) => std::result::Result::Err(LiveFailure::new("variant_projection_decode")),
};
}