use vialabs_stellar_common::encoding::evm::{decode_abi_bridge_data, encode_abi_bridge_data};
use soroban_sdk::{xdr::ToXdr, Address, Bytes, Env};
#[cfg(test)]
mod test_encode_decode_success_cases {
use super::*;
const TEST_RECIPIENT: &[u8] =
b"a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef12345678";
const TEST_AMOUNT: u128 = 1000000000000000000000;
const TEST_TEXT: &[u8] = b"Cross-chain transfer";
#[test]
fn test_decode_chain_data() {
let env = Env::default();
let hex_string = "00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000033b2e3c9fd0803ce800000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002c0000001200000000000000001c58ff1b059c5d4b91f608aed35f6c62d327af2ad627d12beced04255954c84e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001443726f73732d636861696e207472616e73666572000000000000000000000000";
let encoded_bytes = hex::decode(hex_string).unwrap();
let encoded = Bytes::from_slice(&env, &encoded_bytes);
let (decoded_recipient, decoded_amount, decoded_text) = decode_abi_bridge_data(&env, &encoded);
let recipient_bytes = decoded_recipient.to_buffer::<1024>();
let recipient_hex = hex::encode(recipient_bytes.as_slice());
let recipient_actual_address = Address::from_str(
&env,
"GAOFR7Y3AWOF2S4R6YEK5U27NRRNGJ5PFLLCPUJL5TWQIJKZKTEE5YJT",
);
let address_bytes = recipient_actual_address.to_xdr(&env);
let address_bytes_buffer = address_bytes.to_buffer::<1024>();
let recipient = hex::encode(address_bytes_buffer.as_slice());
assert_eq!(recipient_hex, recipient);
let amount: u128 = TEST_AMOUNT;
assert_eq!(decoded_amount, amount);
let decoded_text_bytes = decoded_text.to_buffer::<1024>();
let decoded_text_bytes_slice = decoded_text_bytes.as_slice();
let decoded_text_string = String::from_utf8(decoded_text_bytes_slice.to_vec()).unwrap();
assert_eq!(decoded_text_string, "Cross-chain transfer");
}
#[test]
fn test_encode_and_decode_chain_data() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, TEST_RECIPIENT);
let amount: u128 = TEST_AMOUNT;
let text = Bytes::from_slice(&env, TEST_TEXT);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) = decode_abi_bridge_data(&env, &encoded);
let decoded_recipient_bytes = decoded_recipient.to_buffer::<1024>();
let decoded_recipient_slice = decoded_recipient_bytes.as_slice();
let decoded_recipient_hex = String::from_utf8(decoded_recipient_slice.to_vec()).unwrap();
let original_hex = String::from_utf8(TEST_RECIPIENT.to_vec()).unwrap();
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
assert_eq!(decoded_recipient_hex, original_hex);
}
#[test]
fn test_encode_and_decode_empty_data() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, &[]);
let amount: u128 = 0;
let text = Bytes::from_slice(&env, &[]);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) = decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
#[test]
fn test_encode_and_decode_large_data() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, &[42u8; 100]);
let amount: u128 = u128::MAX;
let text = Bytes::from_slice(&env, &[65u8; 200]);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) = decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
#[test]
fn test_encode_and_decode_roundtrip() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, &[10u8, 20u8, 30u8, 40u8, 50u8]);
let amount: u128 = 5000000000;
let text = Bytes::from_slice(&env, b"Roundtrip test message");
let mut current_encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
for _ in 0..5 {
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, ¤t_encoded);
current_encoded =
encode_abi_bridge_data(&env, &decoded_recipient, decoded_amount, &decoded_text);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
}
#[cfg(test)]
mod test_encode_decode_edge_cases {
use super::*;
const TEST_RECIPIENT: &[u8] =
b"f1e2d3c4b5a6789012345678901234567890fedcba1234567890fedcba12345678";
#[test]
fn test_encode_and_decode_different_amounts() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, TEST_RECIPIENT);
let test_amounts = vec![
0u128,
1u128,
1000u128,
1000000u128,
1000000000000000000u128,
u128::MAX / 2,
u128::MAX,
];
for amount in test_amounts {
let text = Bytes::from_slice(&env, &format!("amount test: {amount}").into_bytes());
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_and_decode_different_text_lengths() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, TEST_RECIPIENT);
let amount: u128 = 999999999999999999;
let large_text = vec![65u8; 500];
let test_texts: Vec<&[u8]> = vec![
&[],
&[65u8],
b"short",
b"medium length text message",
b"this is a much longer text message that tests the encoding and decoding with various text lengths to ensure proper handling",
&large_text,
];
for text_bytes in test_texts {
let text = Bytes::from_slice(&env, text_bytes);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_and_decode_different_recipient_lengths() {
let env = Env::default();
let amount: u128 = 123456789;
let text = Bytes::from_slice(&env, b"recipient length test");
let test_recipients = vec![
Bytes::from_slice(&env, &[]),
Bytes::from_slice(&env, &[1u8]),
Bytes::from_slice(&env, &[1u8, 2u8, 3u8, 4u8]),
Bytes::from_slice(&env, &[1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8]),
Bytes::from_slice(
&env,
&[
1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 16u8,
],
),
Bytes::from_slice(&env, &[42u8; 32]),
Bytes::from_slice(&env, &[99u8; 64]),
];
for recipient in test_recipients {
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_decode_boundary_amounts() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, b"boundary_test_recipient");
let text = Bytes::from_slice(&env, b"Boundary test");
let boundary_amounts = vec![
0u128,
1u128,
255u128,
256u128,
65535u128,
65536u128,
4294967295u128,
4294967296u128,
18446744073709551615u128,
18446744073709551616u128,
u128::MAX - 1,
u128::MAX,
];
for amount in boundary_amounts {
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_decode_boundary_text_lengths() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, b"boundary_test_recipient");
let amount: u128 = 12345;
let boundary_texts = vec![
vec![],
vec![65u8],
vec![65u8; 31],
vec![65u8; 32],
vec![65u8; 33],
vec![65u8; 63],
vec![65u8; 64],
vec![65u8; 65],
vec![65u8; 127],
vec![65u8; 128],
vec![65u8; 129],
];
for text_bytes in &boundary_texts {
let text = Bytes::from_slice(&env, text_bytes);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_decode_boundary_recipient_lengths() {
let env = Env::default();
let amount: u128 = 12345;
let text = Bytes::from_slice(&env, b"boundary recipient test");
let boundary_recipients = vec![
vec![],
vec![1u8],
vec![42u8; 31],
vec![42u8; 32],
vec![42u8; 33],
vec![42u8; 63],
vec![42u8; 64],
vec![42u8; 65],
vec![42u8; 127],
vec![42u8; 128],
vec![42u8; 129],
];
for recipient_bytes in &boundary_recipients {
let recipient = Bytes::from_slice(&env, recipient_bytes);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_decode_zero_padding_edge_cases() {
let env = Env::default();
let amount: u128 = 12345;
let text = Bytes::from_slice(&env, b"adding padding test");
let padding_test_recipients = vec![
vec![],
vec![1u8],
vec![1u8, 2u8],
vec![1u8, 2u8, 3u8],
vec![1u8, 2u8, 3u8, 4u8],
vec![1u8, 2u8, 3u8, 4u8, 5u8],
vec![1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8],
vec![
1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 16u8,
],
vec![
1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8, 13u8, 14u8, 15u8, 16u8,
17u8, 18u8, 19u8, 20u8, 21u8, 22u8, 23u8, 24u8, 25u8, 26u8, 27u8, 28u8, 29u8, 30u8, 31u8,
32u8,
],
];
for recipient_bytes in &padding_test_recipients {
let recipient = Bytes::from_slice(&env, recipient_bytes);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
}
#[test]
fn test_encode_decode_very_large_data() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, &[42u8; 500]);
let amount: u128 = u128::MAX;
let text = Bytes::from_slice(&env, &[65u8; 500]);
let encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
let (decoded_recipient, decoded_amount, decoded_text) = decode_abi_bridge_data(&env, &encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
}
#[test]
fn test_encode_decode_repeated_roundtrip_large_data() {
let env = Env::default();
let recipient = Bytes::from_slice(&env, &[99u8; 300]);
let amount: u128 = u128::MAX / 2;
let text = Bytes::from_slice(&env, &[88u8; 400]);
let mut current_encoded = encode_abi_bridge_data(&env, &recipient, amount, &text);
for i in 0..10 {
let (decoded_recipient, decoded_amount, decoded_text) =
decode_abi_bridge_data(&env, ¤t_encoded);
assert_eq!(decoded_recipient, recipient);
assert_eq!(decoded_amount, amount);
assert_eq!(decoded_text, text);
if i < 9 {
current_encoded =
encode_abi_bridge_data(&env, &decoded_recipient, decoded_amount, &decoded_text);
}
}
}
}
#[cfg(test)]
mod test_encode_decode_failure_cases {
use super::*;
#[test]
#[should_panic(expected = "range end index 64 out of range for slice of length 3")]
fn test_decode_malformed_data_too_short() {
let env = Env::default();
let malformed_data = Bytes::from_slice(&env, &[1u8, 2u8, 3u8]);
decode_abi_bridge_data(&env, &malformed_data);
}
#[test]
#[should_panic(expected = "range end index 64 out of range for slice of length 47")]
fn test_decode_malformed_data_missing_amount() {
let env = Env::default();
let malformed_data = Bytes::from_slice(&env, &[0u8; 47]);
decode_abi_bridge_data(&env, &malformed_data);
}
#[test]
#[should_panic(expected = "range end index 128 out of range for slice of length 95")]
fn test_decode_malformed_data_missing_recipient_length() {
let env = Env::default();
let malformed_data = Bytes::from_slice(&env, &[0u8; 95]);
decode_abi_bridge_data(&env, &malformed_data);
}
#[test]
#[should_panic(expected = "range end index 4294967423 out of range for slice of length 128")]
fn test_decode_malformed_data_invalid_recipient_length() {
let env = Env::default();
let mut malformed_data = Bytes::new(&env);
malformed_data.extend_from_slice(&[0u8; 96]);
malformed_data.extend_from_slice(&[0u8; 28]);
malformed_data.extend_from_slice(&[255u8, 255u8, 255u8, 255u8]);
decode_abi_bridge_data(&env, &malformed_data);
}
#[test]
#[should_panic(expected = "range end index 83886208 out of range for slice of length 164")]
fn test_decode_malformed_data_invalid_text_length() {
let env = Env::default();
let mut malformed_data = Bytes::new(&env);
malformed_data.extend_from_slice(&[0u8; 96]);
malformed_data.extend_from_slice(&[0u8; 28]);
malformed_data.extend_from_slice(&[5u8, 0u8, 0u8, 0u8]);
malformed_data.extend_from_slice(&[1u8, 2u8, 3u8, 4u8, 5u8]);
malformed_data.extend_from_slice(&[0u8; 27]);
malformed_data.extend_from_slice(&[255u8, 255u8, 255u8, 255u8]);
decode_abi_bridge_data(&env, &malformed_data);
}
}