// file: crates/ksp-job-backfill-lib/unit_tests/conversion.rs // version: 3 fn signature_text() -> std::option::Option { return match crate::BackfillSignature::new("1".repeat(64)) { std::result::Result::Ok(value) => std::option::Option::Some(value), std::result::Result::Err(_) => std::option::Option::None, }; } fn request(network: &str, signature: crate::BackfillSignature) -> std::option::Option { let network = match ksp_store_lib::RawNetworkId::new(network) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; let job_id = match ksp_job_api::JobId::new("backfill:pre006") { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; let scope = match crate::BackfillScope::explicit_signatures(std::vec![signature]) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; return match crate::BackfillRequest::new( job_id, network, ksp_onchain_transport_lib::HttpRoleName::new("history"), crate::BackfillCommitment::Finalized, scope, 100, 10, 100, 4, std::option::Option::None, ) { std::result::Result::Ok(value) => std::option::Option::Some(value), std::result::Result::Err(_) => std::option::Option::None, }; } fn candidate(network: &str, signature: crate::BackfillSignature) -> std::option::Option { let network = match ksp_store_lib::RawNetworkId::new(network) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; return std::option::Option::Some(crate::BackfillCandidate::new(crate::BackfillCandidateIdentity::new(network, signature), std::option::Option::Some(42))); } fn raw_reference(network: &str) -> std::option::Option { let network = match ksp_store_lib::RawNetworkId::new(network) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; return std::option::Option::Some(ksp_store_lib::RawTransactionReference::new(network, ksp_store_lib::RawTransactionSignature::new([0_u8; 64]))); } fn received_at() -> std::option::Option { return match ksp_store_lib::RawTimestamp::from_unix_millis(1_700_000_001_000) { std::result::Result::Ok(value) => std::option::Option::Some(value), std::result::Result::Err(_) => std::option::Option::None, }; } fn fields<'a>( transaction: &'a ksp_onchain_transport_lib::SolanaEncodedTransaction, meta: &'a ksp_onchain_transport_lib::SolanaWireField, version: &'a ksp_onchain_transport_lib::SolanaWireField, transaction_index: &'a ksp_onchain_transport_lib::SolanaWireField, block_time: std::option::Option, ) -> super::CanonicalTransactionFields<'a> { return super::CanonicalTransactionFields { slot: 123, block_time, transaction, meta, version, transaction_index }; } #[test] fn pre_006_signature_decoding_requires_exactly_sixty_four_bytes() { let signature = match signature_text() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let decoded = signature.to_raw_transaction_signature(); assert!(decoded.is_ok()); if let std::result::Result::Ok(decoded) = decoded { assert_eq!(decoded.as_bytes(), &[0_u8; 64]); } let too_many_zeroes = crate::BackfillSignature::new("1".repeat(65)); assert!(too_many_zeroes.is_ok()); if let std::result::Result::Ok(too_many_zeroes) = too_many_zeroes { assert!(too_many_zeroes.to_raw_transaction_signature().is_err()); } let overflow = crate::BackfillSignature::new("z".repeat(88)); assert!(overflow.is_ok()); if let std::result::Result::Ok(overflow) = overflow { assert!(overflow.to_raw_transaction_signature().is_err()); } return; } #[test] fn pre_006_canonical_payload_golden_bytes_hash_and_provenance_are_exact() { let signature = match signature_text() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let request = match request("devnet", signature.clone()) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let candidate = match candidate("devnet", signature) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let reference = match super::canonical_reference(&request, &candidate) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let transaction = ksp_onchain_transport_lib::SolanaEncodedTransaction::Binary { data: "AQID".to_owned(), encoding: ksp_onchain_transport_lib::SolanaTransactionBinaryEncoding::Base64, }; let meta = ksp_onchain_transport_lib::SolanaWireField::Value(serde_json::json!({"z": 1, "a": {"y": true, "x": null}})); let version = ksp_onchain_transport_lib::SolanaWireField::Value(ksp_onchain_transport_lib::SolanaTransactionVersion::Legacy); let transaction_index = ksp_onchain_transport_lib::SolanaWireField::Value(7_u32); let received_at = match received_at() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let acquisition = super::convert_available_fields( &request, reference, fields(&transaction, &meta, &version, &transaction_index, std::option::Option::Some(1_700_000_000)), "publicnode", "devnet-primary", received_at, ); assert!(acquisition.is_ok()); let acquisition = match acquisition { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let expected = b"{\"transaction\":[\"AQID\",\"base64\"],\"meta\":{\"a\":{\"x\":null,\"y\":true},\"z\":1},\"version\":\"legacy\",\"transactionIndex\":7}"; assert_eq!(acquisition.transaction().payload().bytes(), expected); assert_eq!(acquisition.transaction().payload().byte_len(), 112); assert_eq!(acquisition.transaction().payload().format_id().as_str(), crate::RAW_TRANSACTION_FORMAT_ID); assert_eq!(acquisition.transaction().payload().format_version(), crate::RAW_TRANSACTION_FORMAT_VERSION); assert_eq!( acquisition.transaction().payload().content_hash().as_bytes(), &[ 34, 7, 146, 210, 177, 93, 38, 47, 218, 36, 44, 178, 32, 119, 78, 233, 221, 239, 254, 191, 4, 220, 250, 218, 188, 248, 239, 118, 169, 177, 167, 195 ] ); assert_eq!(acquisition.transaction().slot(), 123); assert_eq!(acquisition.transaction().block_time().map(|value| return value.unix_millis()), std::option::Option::Some(1_700_000_000_000)); assert_eq!(acquisition.transaction().reference().network().as_str(), "devnet"); assert_eq!(acquisition.transaction().reference().signature().as_bytes(), &[0_u8; 64]); let provenance = acquisition.observation().provenance(); assert_eq!(provenance.provider().as_str(), "publicnode"); assert_eq!(provenance.protocol().as_str(), "solana.http.json_rpc"); assert_eq!(provenance.acquisition_method().as_str(), "getTransaction"); assert_eq!(provenance.endpoint_id().map(ksp_store_lib::RawProvenanceCode::as_str), std::option::Option::Some("devnet-primary")); assert_eq!(provenance.commitment().map(ksp_store_lib::RawProvenanceCode::as_str), std::option::Option::Some("finalized")); assert_eq!(provenance.capture_session_id().map(ksp_store_lib::RawProvenanceCode::as_str), std::option::Option::Some("backfill:pre006")); assert_eq!(provenance.received_at(), received_at); assert!(provenance.source_payload_hash().is_none()); assert!(provenance.source_payload_size_bytes().is_none()); return; } #[test] fn pre_006_wire_omission_and_null_produce_distinct_canonical_bytes() { let transaction = ksp_onchain_transport_lib::SolanaEncodedTransaction::Binary { data: "AQID".to_owned(), encoding: ksp_onchain_transport_lib::SolanaTransactionBinaryEncoding::Base64, }; let meta_omitted = ksp_onchain_transport_lib::SolanaWireField::Omitted; let meta_null = ksp_onchain_transport_lib::SolanaWireField::Null; let version_omitted = ksp_onchain_transport_lib::SolanaWireField::Omitted; let version_null = ksp_onchain_transport_lib::SolanaWireField::Null; let transaction_index_omitted = ksp_onchain_transport_lib::SolanaWireField::Omitted; let transaction_index_null = ksp_onchain_transport_lib::SolanaWireField::Null; let reference = match raw_reference("devnet") { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let omitted = super::canonical_transaction(&reference, fields(&transaction, &meta_omitted, &version_omitted, &transaction_index_omitted, std::option::Option::None)); assert!(omitted.is_ok()); let omitted = match omitted { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(omitted.payload().bytes(), b"{\"transaction\":[\"AQID\",\"base64\"]}"); let nulls = super::canonical_transaction(&reference, fields(&transaction, &meta_null, &version_null, &transaction_index_null, std::option::Option::None)); assert!(nulls.is_ok()); let nulls = match nulls { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert_eq!(nulls.payload().bytes(), b"{\"transaction\":[\"AQID\",\"base64\"],\"meta\":null,\"version\":null,\"transactionIndex\":null}"); assert_ne!(omitted.payload().bytes(), nulls.payload().bytes()); return; } #[test] fn pre_006_non_base64_transaction_shapes_are_rejected() { let base58 = ksp_onchain_transport_lib::SolanaEncodedTransaction::Binary { data: "1111".to_owned(), encoding: ksp_onchain_transport_lib::SolanaTransactionBinaryEncoding::Base58, }; let legacy = ksp_onchain_transport_lib::SolanaEncodedTransaction::LegacyBinary("1111".to_owned()); let json = ksp_onchain_transport_lib::SolanaEncodedTransaction::Json(serde_json::json!({"message": {}})); let meta = ksp_onchain_transport_lib::SolanaWireField::Omitted; let version = ksp_onchain_transport_lib::SolanaWireField::Omitted; let transaction_index = ksp_onchain_transport_lib::SolanaWireField::Omitted; let reference = match raw_reference("devnet") { std::option::Option::Some(value) => value, std::option::Option::None => return, }; for transaction in [&base58, &legacy, &json] { let result = super::canonical_transaction(&reference, fields(transaction, &meta, &version, &transaction_index, std::option::Option::None)); assert!(result.is_err()); if let std::result::Result::Err(error) = result { assert_eq!(error.code(), crate::ERROR_CODE_BACKFILL_RAW_CONVERSION_INVALID); } } return; } #[test] fn pre_006_negative_and_unrepresentable_block_times_are_terminal_conversion_errors() { let reference = match raw_reference("devnet") { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let transaction = ksp_onchain_transport_lib::SolanaEncodedTransaction::Binary { data: "AQID".to_owned(), encoding: ksp_onchain_transport_lib::SolanaTransactionBinaryEncoding::Base64, }; let meta = ksp_onchain_transport_lib::SolanaWireField::Omitted; let version = ksp_onchain_transport_lib::SolanaWireField::Omitted; let transaction_index = ksp_onchain_transport_lib::SolanaWireField::Omitted; let negative = super::canonical_transaction(&reference, fields(&transaction, &meta, &version, &transaction_index, std::option::Option::Some(-1))); assert!(negative.is_err()); let oversized = super::canonical_transaction(&reference, fields(&transaction, &meta, &version, &transaction_index, std::option::Option::Some(i64::MAX))); assert!(oversized.is_err()); let absent = super::canonical_transaction(&reference, fields(&transaction, &meta, &version, &transaction_index, std::option::Option::None)); assert!(absent.is_ok()); if let std::result::Result::Ok(absent) = absent { assert!(absent.block_time().is_none()); } return; } #[test] fn pre_006_observation_key_is_deterministic_and_endpoint_specific() { let signature = match signature_text() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let request = match request("devnet", signature.clone()) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let candidate = match candidate("devnet", signature) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let reference = match super::canonical_reference(&request, &candidate) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let first = super::observation_key(&request, &reference, "provider", "endpoint-a"); let same = super::observation_key(&request, &reference, "provider", "endpoint-a"); let other_endpoint = super::observation_key(&request, &reference, "provider", "endpoint-b"); let other_provider = super::observation_key(&request, &reference, "provider-2", "endpoint-a"); assert_eq!(first, same); assert_eq!( first.as_bytes(), &[ 184, 85, 15, 15, 33, 101, 243, 112, 222, 145, 139, 212, 251, 14, 199, 130, 57, 26, 253, 221, 184, 140, 87, 240, 16, 116, 62, 0, 11, 19, 103, 2 ] ); assert_ne!(first, other_endpoint); assert_ne!(first, other_provider); return; } #[test] fn pre_006_candidate_network_mismatch_is_rejected_before_transport() { let signature = match signature_text() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let request = match request("devnet", signature.clone()) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let candidate = match candidate("mainnet", signature) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let reference = super::canonical_reference(&request, &candidate); assert!(reference.is_err()); if let std::result::Result::Err(error) = reference { assert_eq!(error.code(), crate::ERROR_CODE_BACKFILL_RAW_CONVERSION_INVALID); } return; } #[test] fn pre_006_missing_outcome_contains_only_network_scoped_reference() { let signature = match signature_text() { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let request = match request("devnet", signature.clone()) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let candidate = match candidate("devnet", signature) { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let reference = match super::canonical_reference(&request, &candidate) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let outcome = crate::BackfillHydrationOutcome::Missing(reference); assert!(outcome.is_missing()); assert_eq!(outcome.reference().network().as_str(), "devnet"); assert_eq!(outcome.reference().signature().as_bytes(), &[0_u8; 64]); return; } #[test] fn pre_003_backfill_uses_common_raw_v1_contract_without_changing_frozen_identity() { assert_eq!(crate::RAW_TRANSACTION_FORMAT_ID, ksp_raw_transaction_lib::RAW_TRANSACTION_FORMAT_ID); assert_eq!(crate::RAW_TRANSACTION_FORMAT_VERSION, ksp_raw_transaction_lib::RAW_TRANSACTION_FORMAT_VERSION); assert_eq!(crate::MIN_BACKFILL_SIGNATURE_TEXT_BYTES, ksp_raw_transaction_lib::MIN_RAW_TRANSACTION_SIGNATURE_TEXT_BYTES); assert_eq!(crate::MAX_BACKFILL_SIGNATURE_TEXT_BYTES, ksp_raw_transaction_lib::MAX_RAW_TRANSACTION_SIGNATURE_TEXT_BYTES); return; } #[test] fn pre_006_fix_001_raw_acquisition_uses_one_private_indirection() { assert_eq!(std::mem::size_of::(), std::mem::size_of::(),); return; }