0.3.16-pre.005

This commit is contained in:
2026-09-21 19:31:35 +02:00
parent 19712aa7a6
commit 8b0fbf831e
14 changed files with 895 additions and 132 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-store-api/unit_tests/model/raw_transaction.rs
// version: 3
// version: 5
fn network() -> std::option::Option<crate::RawNetworkId> {
return match crate::RawNetworkId::new("mainnet".to_owned()) {
@@ -140,3 +140,121 @@ fn transaction_variant_codes_and_outcomes_are_stable_backend_neutral_contracts()
assert_ne!(crate::RawTransactionVariantWriteOutcome::QuarantinedConflict, crate::RawTransactionVariantWriteOutcome::PromotedCompatibleMoreComplete);
return;
}
fn comparison_transaction(payload_bytes: &[u8], hash_byte: u8) -> std::option::Option<crate::RawTransaction> {
let network = match network() {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::option::Option::None,
};
let format = match crate::RawFormatId::new("ksp.solana.raw_transaction".to_owned()) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return std::option::Option::None,
};
let payload = match crate::RawPayload::try_new(format, 1, payload_bytes.to_vec().into_boxed_slice(), crate::RawContentHash::new([hash_byte; 32])) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return std::option::Option::None,
};
let reference = crate::RawTransactionReference::new(network, crate::RawTransactionSignature::new([21_u8; 64]));
return std::option::Option::Some(crate::RawTransaction::new(reference, 88, std::option::Option::None, payload));
}
fn comparison_relation(
canonical_payload: &[u8],
canonical_hash: u8,
incoming_payload: &[u8],
incoming_hash: u8,
) -> std::option::Option<crate::RawTransactionVariantComparison> {
let canonical = match comparison_transaction(canonical_payload, canonical_hash) {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::option::Option::None,
};
let incoming = match comparison_transaction(incoming_payload, incoming_hash) {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::option::Option::None,
};
return crate::compare_raw_transaction_variants(&canonical, &incoming).ok();
}
#[test]
fn v0_3_16_pre_005_comparator_proves_bidirectional_log_messages_truncation_only() {
let full = br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["Program Vote111 invoke [1]","Program log: stable","Program Vote111 success"],"rewards":[]},"version":0,"transactionIndex":7}"#;
let truncated = br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["Program Vote111 invoke [1]","Program log: stable","Log truncated"],"rewards":[]},"version":0,"transactionIndex":7}"#;
let less = match comparison_relation(full, 31, truncated, 32) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(less.relation(), crate::RawTransactionVariantRelation::CompatibleLessComplete);
assert_eq!(less.reason(), crate::RawTransactionVariantRelationReason::IncomingLogMessagesTruncated);
let more = match comparison_relation(truncated, 32, full, 31) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(more.relation(), crate::RawTransactionVariantRelation::CompatibleMoreComplete);
assert_eq!(more.reason(), crate::RawTransactionVariantRelationReason::CanonicalLogMessagesTruncated);
return;
}
#[test]
fn v0_3_16_pre_005_comparator_rejects_unproved_log_shortening_and_marker_shapes() {
let full = br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["a","b","c"],"rewards":[]},"version":0}"#;
let shorter = br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["a","b"],"rewards":[]},"version":0}"#;
let marker_not_last =
br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["a","Log truncated","c"],"rewards":[]},"version":0}"#;
let marker_not_exact =
br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["a","b","Log truncated by provider"],"rewards":[]},"version":0}"#;
let bad_prefix =
br#"{"transaction":["AQID","base64"],"meta":{"err":null,"fee":5000,"logMessages":["a","changed","Log truncated"],"rewards":[]},"version":0}"#;
let candidates: [&[u8]; 4] = [shorter, marker_not_last, marker_not_exact, bad_prefix];
for (index, candidate) in candidates.iter().enumerate() {
let hash_offset = match u8::try_from(index) {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let comparison = match comparison_relation(full, 40, candidate, 41 + hash_offset) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(comparison.relation(), crate::RawTransactionVariantRelation::Conflict);
assert_eq!(comparison.reason(), crate::RawTransactionVariantRelationReason::CanonicalPayloadConflict);
}
return;
}
#[test]
fn v0_3_16_pre_005_comparator_is_fail_closed_for_optional_and_other_payload_differences() {
let canonical = br#"{"transaction":["AQID","base64"],"meta":{"fee":5000,"logMessages":["a"],"returnData":null},"version":0}"#;
let optional_value =
br#"{"transaction":["AQID","base64"],"meta":{"fee":5000,"logMessages":["a"],"returnData":{"data":["","base64"],"programId":"Vote111"}},"version":0}"#;
let concrete_conflict = br#"{"transaction":["AQID","base64"],"meta":{"fee":5001,"logMessages":["a"],"returnData":null},"version":0}"#;
let optional = match comparison_relation(canonical, 50, optional_value, 51) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(optional.relation(), crate::RawTransactionVariantRelation::Incomparable);
assert_eq!(optional.reason(), crate::RawTransactionVariantRelationReason::UnsupportedCanonicalDifference);
let conflict = match comparison_relation(canonical, 50, concrete_conflict, 52) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(conflict.relation(), crate::RawTransactionVariantRelation::Conflict);
assert_eq!(conflict.reason(), crate::RawTransactionVariantRelationReason::CanonicalPayloadConflict);
return;
}
#[test]
fn v0_3_16_pre_005_comparator_uses_exact_bytes_and_detects_hash_collision_without_hash_equality_shortcut() {
let canonical = br#"{"transaction":["AQID","base64"],"meta":{"logMessages":["a"]}}"#;
let same_bytes = match comparison_relation(canonical, 60, canonical, 61) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(same_bytes.relation(), crate::RawTransactionVariantRelation::Exact);
let different = br#"{"transaction":["AQID","base64"],"meta":{"logMessages":["b"]}}"#;
let collision = match comparison_relation(canonical, 62, different, 62) {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
};
assert_eq!(collision.relation(), crate::RawTransactionVariantRelation::Conflict);
assert_eq!(collision.reason(), crate::RawTransactionVariantRelationReason::ContentHashCollision);
return;
}