|
|
@@ -1,4 +1,6 @@
|
|
|
+use core::array::ArrayTrait;
|
|
|
use core::fmt::{Debug, Formatter};
|
|
|
+use super::util::one_shift_left_bytes_u256;
|
|
|
|
|
|
/// A byte array with storage format similar to `core::ByteArray`, but
|
|
|
/// suitable for reading data from it.
|
|
|
@@ -35,8 +37,13 @@ pub impl ByteArrayImpl of ByteArrayTrait {
|
|
|
if data.len() == 0 {
|
|
|
assert!(num_last_bytes == 0);
|
|
|
} else {
|
|
|
+ assert!(num_last_bytes > 0);
|
|
|
assert!(num_last_bytes <= 31);
|
|
|
- // TODO: check that unused bytes are zeroed.
|
|
|
+ let last: u256 = (*data.at(data.len() - 1)).into();
|
|
|
+ assert!(
|
|
|
+ last / one_shift_left_bytes_u256(num_last_bytes) == 0,
|
|
|
+ "ByteArrayImpl::new: last value is too large"
|
|
|
+ );
|
|
|
}
|
|
|
ByteArray { num_last_bytes, data }
|
|
|
}
|
|
|
@@ -62,3 +69,100 @@ pub impl ByteArrayImpl of ByteArrayTrait {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#[cfg(test)]
|
|
|
+mod tests {
|
|
|
+ use super::{ByteArray, ByteArrayImpl};
|
|
|
+ use pyth::util::array_felt252_to_bytes31;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn empty_byte_array() {
|
|
|
+ let mut array = ByteArrayImpl::new(array![], 0);
|
|
|
+ assert!(array.len() == 0);
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn byte_array_3_zeros() {
|
|
|
+ let mut array = ByteArrayImpl::new(array_felt252_to_bytes31(array![0]), 3);
|
|
|
+ assert!(array.len() == 3);
|
|
|
+ assert!(array.pop_front() == Option::Some((0.try_into().unwrap(), 3)));
|
|
|
+ assert!(array.len() == 0);
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn byte_array_3_bytes() {
|
|
|
+ let mut array = ByteArrayImpl::new(array_felt252_to_bytes31(array![0x010203]), 3);
|
|
|
+ assert!(array.len() == 3);
|
|
|
+ assert!(array.pop_front() == Option::Some((0x010203.try_into().unwrap(), 3)));
|
|
|
+ assert!(array.len() == 0);
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn byte_array_single_full() {
|
|
|
+ let value_31_bytes = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
|
|
|
+ let mut array = ByteArrayImpl::new(array_felt252_to_bytes31(array![value_31_bytes]), 31);
|
|
|
+ assert!(array.len() == 31);
|
|
|
+ assert!(array.pop_front() == Option::Some((value_31_bytes.try_into().unwrap(), 31)));
|
|
|
+ assert!(array.len() == 0);
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn byte_array_two_full() {
|
|
|
+ let value_31_bytes = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
|
|
|
+ let value2_31_bytes = 0x2122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f;
|
|
|
+ let mut array = ByteArrayImpl::new(
|
|
|
+ array_felt252_to_bytes31(array![value_31_bytes, value2_31_bytes]), 31
|
|
|
+ );
|
|
|
+ assert!(array.len() == 62);
|
|
|
+ assert!(array.pop_front() == Option::Some((value_31_bytes.try_into().unwrap(), 31)));
|
|
|
+ assert!(array.len() == 31);
|
|
|
+ assert!(array.pop_front() == Option::Some((value2_31_bytes.try_into().unwrap(), 31)));
|
|
|
+ assert!(array.len() == 0);
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn byte_array_3_items() {
|
|
|
+ let value_31_bytes = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;
|
|
|
+ let value2_31_bytes = 0x2122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f;
|
|
|
+ let value3_5_bytes = 0x4142434445;
|
|
|
+ let mut array = ByteArrayImpl::new(
|
|
|
+ array_felt252_to_bytes31(array![value_31_bytes, value2_31_bytes, value3_5_bytes]), 5
|
|
|
+ );
|
|
|
+ assert!(array.len() == 67);
|
|
|
+ assert!(array.pop_front() == Option::Some((value_31_bytes.try_into().unwrap(), 31)));
|
|
|
+ assert!(array.len() == 36);
|
|
|
+ assert!(array.pop_front() == Option::Some((value2_31_bytes.try_into().unwrap(), 31)));
|
|
|
+ assert!(array.len() == 5);
|
|
|
+ assert!(array.pop_front() == Option::Some((value3_5_bytes.try_into().unwrap(), 5)));
|
|
|
+ assert!(array.pop_front() == Option::None);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[should_panic]
|
|
|
+ fn byte_array_empty_invalid() {
|
|
|
+ ByteArrayImpl::new(array![], 5);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[should_panic]
|
|
|
+ fn byte_array_last_too_large() {
|
|
|
+ ByteArrayImpl::new(array_felt252_to_bytes31(array![1, 2, 3]), 35);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[should_panic]
|
|
|
+ fn byte_array_last_zero_invalid() {
|
|
|
+ ByteArrayImpl::new(array_felt252_to_bytes31(array![1, 2, 0]), 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ #[should_panic]
|
|
|
+ fn byte_array_last_too_many_bytes() {
|
|
|
+ ByteArrayImpl::new(array_felt252_to_bytes31(array![1, 2, 0x010203]), 2);
|
|
|
+ }
|
|
|
+}
|