vialabs-stellar-common 0.1.10

Common interfaces, types, and utilities for Stellar contracts in the VIA cross-chain messaging system
Documentation
use soroban_sdk::{bytes, testutils::EnvTestConfig, Address, Bytes, Env};
use vialabs_stellar_common::encoding::via::{encode_via_message, ViaMessage};
use vialabs_stellar_common::utils::address_to_raw_bytes;

fn setup_test_env() -> Env {
  let mut env = Env::default();

  env.set_config(EnvTestConfig {
    capture_snapshot_at_drop: false,
  });

  env
}

#[test]
fn test_encode_via_message_with_raw_bytes() {
  let env = setup_test_env();

  let tx_id: u128 = 1115511100000000000000000000011;
  let source_chain_id: u64 = 5555555555555555;
  let destination_chain_id: u64 = 11155111;
  let sender_bytes = bytes!(&env, 0x86e5fb5ffae1875f0cf590aa43205db08172857d);

  let recipient_address = Address::from_str(
    &env,
    "CCPDL7B56HBVSIOMS3HLYXFZRCTH2S3YIYBPF2EUOJP5AQWITNIZDQMP",
  );

  let on_chain_data_bytes = bytes!(
    &env,
    0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002c0000001200000000000000001c58ff1b059c5d4b91f608aed35f6c62d327af2ad627d12beced04255954c84e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001443726f73732d636861696e207472616e73666572000000000000000000000000
  );

  let off_chain_data_bytes = Bytes::from_slice(&env, &[]);

  let message_data = ViaMessage {
    tx_id,
    source_chain_id,
    destination_chain_id,
    sender: sender_bytes,
    recipient: recipient_address.clone(),
    on_chain_data: on_chain_data_bytes,
    off_chain_data: off_chain_data_bytes,
  };

  let encoded_data = encode_via_message(&env, message_data);

  let recipient_raw_bytes = address_to_raw_bytes(&env, recipient_address);
  let recipient_raw_bytes_buffer = recipient_raw_bytes.to_buffer::<1024>();
  let recipient_raw_bytes_slice = recipient_raw_bytes_buffer.as_slice();

  let encoded_data_buffer = encoded_data.to_buffer::<65536>();
  let encoded_data_slice = encoded_data_buffer.as_slice();

  assert!(encoded_data_slice.len() >= 32 + 8 + 8 + 20 + 32);

  let tx_id_from_encoded = &encoded_data_slice[0..32];
  let source_chain_id_from_encoded = &encoded_data_slice[32..40];
  let dest_chain_id_from_encoded = &encoded_data_slice[40..48];
  let sender_from_encoded = &encoded_data_slice[48..68];
  let recipient_from_encoded = &encoded_data_slice[68..100];

  let mut expected_tx_id_bytes = [0u8; 32];
  expected_tx_id_bytes[16..32].copy_from_slice(&tx_id.to_be_bytes());
  assert_eq!(tx_id_from_encoded, expected_tx_id_bytes.as_slice());
  assert_eq!(
    source_chain_id_from_encoded,
    source_chain_id.to_be_bytes().as_slice()
  );
  assert_eq!(
    dest_chain_id_from_encoded,
    destination_chain_id.to_be_bytes().as_slice()
  );

  let sender_bytes_copy = bytes!(&env, 0x86e5fb5ffae1875f0cf590aa43205db08172857d);
  assert_eq!(
    sender_from_encoded,
    sender_bytes_copy.to_buffer::<1024>().as_slice()
  );
  assert_eq!(recipient_from_encoded, recipient_raw_bytes_slice);
}

#[test]
fn test_encode_via_message_hash_matches_expected() {
  let env = setup_test_env();

  let tx_id: u128 = 1115511100000000000000000000011;
  let source_chain_id: u64 = 5555555555555555;
  let destination_chain_id: u64 = 11155111;
  let sender_bytes = bytes!(&env, 0x86e5fb5ffae1875f0cf590aa43205db08172857d);

  let recipient_address = Address::from_str(
    &env,
    "CCPDL7B56HBVSIOMS3HLYXFZRCTH2S3YIYBPF2EUOJP5AQWITNIZDQMP",
  );

  let on_chain_data_bytes = bytes!(
    &env,
    0x00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000002c0000001200000000000000001c58ff1b059c5d4b91f608aed35f6c62d327af2ad627d12beced04255954c84e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001443726f73732d636861696e207472616e73666572000000000000000000000000
  );

  let off_chain_data_bytes = Bytes::from_slice(&env, &[]);

  let message_data = ViaMessage {
    tx_id,
    source_chain_id,
    destination_chain_id,
    sender: sender_bytes,
    recipient: recipient_address,
    on_chain_data: on_chain_data_bytes,
    off_chain_data: off_chain_data_bytes,
  };

  let encoded_data = encode_via_message(&env, message_data);
  let encoded_hash = env.crypto().keccak256(&encoded_data);
  let encoded_hex = hex::encode(encoded_hash.to_array());

  assert_eq!(encoded_hex.len(), 64);
}

#[test]
fn test_encode_via_message_different_recipient() {
  let env = setup_test_env();

  let tx_id: u128 = 1234567890123456789;
  let source_chain_id: u64 = 1;
  let destination_chain_id: u64 = 10001;
  let sender_bytes = bytes!(&env, 0x742d35cc6634c0532925a3b844bc9e7595f0beb);

  let recipient_address_1 = Address::from_str(
    &env,
    "GB55RC2UCALEHMW6WBOPOB6VATIAJE6WJHSTAYAFN6VWMF2RJV6UC2P2",
  );

  let recipient_address_2 = Address::from_str(
    &env,
    "CCPDL7B56HBVSIOMS3HLYXFZRCTH2S3YIYBPF2EUOJP5AQWITNIZDQMP",
  );

  let on_chain_data_bytes = Bytes::from_slice(&env, &[]);
  let off_chain_data_bytes = Bytes::from_slice(&env, &[]);

  let message_data_1 = ViaMessage {
    tx_id,
    source_chain_id,
    destination_chain_id,
    sender: sender_bytes.clone(),
    recipient: recipient_address_1,
    on_chain_data: on_chain_data_bytes.clone(),
    off_chain_data: off_chain_data_bytes.clone(),
  };

  let message_data_2 = ViaMessage {
    tx_id,
    source_chain_id,
    destination_chain_id,
    sender: sender_bytes,
    recipient: recipient_address_2,
    on_chain_data: on_chain_data_bytes,
    off_chain_data: off_chain_data_bytes,
  };

  let encoded_data_1 = encode_via_message(&env, message_data_1);
  let encoded_data_2 = encode_via_message(&env, message_data_2);

  assert_ne!(encoded_data_1, encoded_data_2);

  let hash_1 = env.crypto().keccak256(&encoded_data_1);
  let hash_2 = env.crypto().keccak256(&encoded_data_2);

  assert_ne!(hash_1.to_array(), hash_2.to_array());
}

#[test]
fn test_encode_via_message_tx_id_encoding() {
  let env = setup_test_env();

  let tx_id: u128 = 1234567890123456789;
  let source_chain_id: u64 = 1;
  let destination_chain_id: u64 = 10001;
  let sender_bytes = bytes!(&env, 0x742d35cc6634c0532925a3b844bc9e7595f0beb);

  let recipient_address = Address::from_str(
    &env,
    "GB55RC2UCALEHMW6WBOPOB6VATIAJE6WJHSTAYAFN6VWMF2RJV6UC2P2",
  );

  let on_chain_data_bytes = Bytes::from_slice(&env, &[]);
  let off_chain_data_bytes = Bytes::from_slice(&env, &[]);

  let message_data = ViaMessage {
    tx_id,
    source_chain_id,
    destination_chain_id,
    sender: sender_bytes,
    recipient: recipient_address,
    on_chain_data: on_chain_data_bytes,
    off_chain_data: off_chain_data_bytes,
  };

  let encoded_data = encode_via_message(&env, message_data);
  let encoded_data_buffer = encoded_data.to_buffer::<65536>();
  let encoded_data_slice = encoded_data_buffer.as_slice();

  let tx_id_from_encoded = &encoded_data_slice[0..32];
  let source_chain_id_from_encoded = &encoded_data_slice[32..40];
  let dest_chain_id_from_encoded = &encoded_data_slice[40..48];

  let mut expected_tx_id_bytes = [0u8; 32];
  expected_tx_id_bytes[16..32].copy_from_slice(&tx_id.to_be_bytes());
  assert_eq!(tx_id_from_encoded, expected_tx_id_bytes.as_slice());
  assert_eq!(
    source_chain_id_from_encoded,
    source_chain_id.to_be_bytes().as_slice()
  );
  assert_eq!(
    dest_chain_id_from_encoded,
    destination_chain_id.to_be_bytes().as_slice()
  );
}