242 lines
11 KiB
Rust
242 lines
11 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
|
|
// version: 2
|
|
|
|
fn network() -> std::option::Option<ksp_store_lib::RawNetworkId> {
|
|
return match ksp_store_lib::RawNetworkId::new("mainnet") {
|
|
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
|
std::result::Result::Err(_) => std::option::Option::None,
|
|
};
|
|
}
|
|
|
|
fn exact_scope(family: &'static str, fingerprint_byte: u8) -> crate::RawTransactionIngestCoverageScope {
|
|
return crate::RawTransactionIngestCoverageScope::exact_source_scope(family, [fingerprint_byte; 32]);
|
|
}
|
|
|
|
fn capability(
|
|
source_key_byte: u8,
|
|
commitment: ksp_onchain_transport_lib::SolanaCommitment,
|
|
scope: crate::RawTransactionIngestCoverageScope,
|
|
) -> std::option::Option<crate::RawTransactionIngestContinuityCapabilityDescriptor> {
|
|
let network = match network() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return std::option::Option::None,
|
|
};
|
|
return match crate::RawTransactionIngestContinuityCapabilityDescriptor::new(
|
|
[source_key_byte; 32],
|
|
network,
|
|
commitment,
|
|
scope,
|
|
true,
|
|
false,
|
|
false,
|
|
true,
|
|
false,
|
|
false,
|
|
) {
|
|
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
|
std::result::Result::Err(_) => std::option::Option::None,
|
|
};
|
|
}
|
|
|
|
fn gap(
|
|
gap_id: u64,
|
|
source_key_byte: u8,
|
|
start_slot: u64,
|
|
end_slot: u64,
|
|
state: super::RawTransactionIngestGapState,
|
|
) -> std::option::Option<super::RawTransactionIngestGap> {
|
|
let network = match network() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return std::option::Option::None,
|
|
};
|
|
let range = match super::RawTransactionIngestGapRange::new(start_slot, end_slot) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
return std::option::Option::Some(super::RawTransactionIngestGap {
|
|
commitment: ksp_onchain_transport_lib::SolanaCommitment::Confirmed,
|
|
coverage_requirement: exact_scope("standard_logs", 9),
|
|
gap_id: super::RawTransactionIngestGapId(gap_id),
|
|
network,
|
|
range,
|
|
reason: super::RawTransactionIngestGapReason::WebSocketReconnect,
|
|
source_key: [source_key_byte; 32],
|
|
state,
|
|
});
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_repair_bounds_are_exact_and_run_local() {
|
|
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS, 64);
|
|
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS, 1);
|
|
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT, 4);
|
|
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS, 512);
|
|
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS, 4_096);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_gap_range_is_inclusive_bounded_and_overflow_safe() {
|
|
assert!(super::RawTransactionIngestGapRange::new(10, 9).is_err());
|
|
assert!(super::RawTransactionIngestGapRange::new(10, 10 + super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS - 1).is_ok());
|
|
assert!(super::RawTransactionIngestGapRange::new(10, 10 + super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS).is_err());
|
|
assert!(super::RawTransactionIngestGapRange::new(u64::MAX, u64::MAX).is_ok());
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_gap_range_overlap_and_adjacency_are_explicit() {
|
|
let first = match super::RawTransactionIngestGapRange::new(100, 109) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("unexpected first range failure: {error}"),
|
|
};
|
|
let overlap = match super::RawTransactionIngestGapRange::new(105, 115) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("unexpected overlap range failure: {error}"),
|
|
};
|
|
let adjacent = match super::RawTransactionIngestGapRange::new(110, 120) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("unexpected adjacent range failure: {error}"),
|
|
};
|
|
let separate = match super::RawTransactionIngestGapRange::new(111, 120) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("unexpected separate range failure: {error}"),
|
|
};
|
|
assert!(first.overlaps_or_is_adjacent(overlap));
|
|
assert!(first.overlaps_or_is_adjacent(adjacent));
|
|
assert!(!first.overlaps_or_is_adjacent(separate));
|
|
let merged = first.try_merge(adjacent);
|
|
assert!(matches!(merged, std::result::Result::Ok(std::option::Option::Some(value)) if value.start_slot() == 100 && value.end_slot() == 120));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_target_coverage_deduplicates_exact_scopes_without_cross_commitment_broadening() {
|
|
let first = match capability(1, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("standard_logs", 7)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("first capability fixture unavailable"),
|
|
};
|
|
let second = match capability(2, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("standard_logs", 7)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("second capability fixture unavailable"),
|
|
};
|
|
let finalized_full =
|
|
match capability(3, ksp_onchain_transport_lib::SolanaCommitment::Finalized, crate::RawTransactionIngestCoverageScope::full_ledger_transactions()) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("full capability fixture unavailable"),
|
|
};
|
|
let contracts = match crate::RawTransactionIngestContinuityContracts::new(std::vec![first, second, finalized_full]) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("continuity contracts fixture failed: {error}"),
|
|
};
|
|
assert_eq!(contracts.capabilities.len(), 3);
|
|
assert_eq!(contracts.target_coverage.requirements.len(), 2);
|
|
assert!(contracts.target_coverage.requirements.iter().any(|requirement| {
|
|
return requirement.commitment == ksp_onchain_transport_lib::SolanaCommitment::Confirmed && requirement.scope == exact_scope("standard_logs", 7);
|
|
}));
|
|
assert!(contracts.target_coverage.requirements.iter().any(|requirement| {
|
|
return requirement.commitment == ksp_onchain_transport_lib::SolanaCommitment::Finalized
|
|
&& requirement.scope == crate::RawTransactionIngestCoverageScope::full_ledger_transactions();
|
|
}));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_full_ledger_scope_subsumes_only_same_commitment_targets() {
|
|
let exact = match capability(1, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("helius_transaction", 4)) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("exact capability fixture unavailable"),
|
|
};
|
|
let full = match capability(2, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, crate::RawTransactionIngestCoverageScope::full_ledger_transactions())
|
|
{
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("full capability fixture unavailable"),
|
|
};
|
|
let contracts = match crate::RawTransactionIngestContinuityContracts::new(std::vec![exact, full]) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(error) => panic!("continuity contracts fixture failed: {error}"),
|
|
};
|
|
assert_eq!(contracts.target_coverage.requirements.len(), 1);
|
|
assert_eq!(contracts.target_coverage.requirements[0].scope, crate::RawTransactionIngestCoverageScope::full_ledger_transactions());
|
|
assert_eq!(contracts.target_coverage.requirements[0].commitment, ksp_onchain_transport_lib::SolanaCommitment::Confirmed);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_known_references_can_never_be_configured_target_coverage() {
|
|
let network = match network() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("network fixture unavailable"),
|
|
};
|
|
let result = crate::RawTransactionIngestContinuityCapabilityDescriptor::new(
|
|
[1_u8; 32],
|
|
network,
|
|
ksp_onchain_transport_lib::SolanaCommitment::Confirmed,
|
|
crate::RawTransactionIngestCoverageScope::KnownReferences([2_u8; 32]),
|
|
true,
|
|
false,
|
|
false,
|
|
true,
|
|
false,
|
|
false,
|
|
);
|
|
assert!(result.is_err());
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_gap_ledger_rejects_coalescible_open_ranges_and_active_overflow() {
|
|
let network = match network() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("network fixture unavailable"),
|
|
};
|
|
let first = match gap(1, 1, 100, 109, super::RawTransactionIngestGapState::Pending) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("first gap fixture unavailable"),
|
|
};
|
|
let adjacent = match gap(2, 1, 110, 120, super::RawTransactionIngestGapState::Pending) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("adjacent gap fixture unavailable"),
|
|
};
|
|
let adjacent_ledger = super::RawTransactionIngestGapLedger { gaps: std::vec![first, adjacent], network: network.clone(), next_gap_id: 3 };
|
|
assert!(adjacent_ledger.validate_invariants().is_err());
|
|
let first_active = match gap(1, 1, 100, 109, super::RawTransactionIngestGapState::Repairing) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("first active gap fixture unavailable"),
|
|
};
|
|
let second_active = match gap(2, 2, 200, 209, super::RawTransactionIngestGapState::Repairing) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("second active gap fixture unavailable"),
|
|
};
|
|
let active_ledger = super::RawTransactionIngestGapLedger { gaps: std::vec![first_active, second_active], network, next_gap_id: 3 };
|
|
assert!(active_ledger.validate_invariants().is_err());
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_002_gap_ledger_enforces_open_gap_bound_and_next_id_monotonicity() {
|
|
let network = match network() {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("network fixture unavailable"),
|
|
};
|
|
let mut gaps = std::vec::Vec::new();
|
|
for index in 0..=super::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {
|
|
let gap_id = (index as u64) + 1;
|
|
let slot = (index as u64) * 2;
|
|
let gap = match gap(gap_id, 1, slot, slot, super::RawTransactionIngestGapState::Pending) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("gap fixture unavailable"),
|
|
};
|
|
gaps.push(gap);
|
|
}
|
|
let ledger = super::RawTransactionIngestGapLedger { gaps, network: network.clone(), next_gap_id: 66 };
|
|
assert!(ledger.validate_invariants().is_err());
|
|
let single = match gap(7, 1, 100, 100, super::RawTransactionIngestGapState::Unresolved) {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => panic!("single gap fixture unavailable"),
|
|
};
|
|
let stale_next = super::RawTransactionIngestGapLedger { gaps: std::vec![single], network, next_gap_id: 7 };
|
|
assert!(stale_next.validate_invariants().is_err());
|
|
return;
|
|
}
|