浏览代码

feat(target_chains/starknet): add utils for decoding signed integers, move array_felt252_to_bytes31 to utils

Pavel Strakhov 1 年之前
父节点
当前提交
a1e4fc0924
共有 2 个文件被更改,包括 66 次插入13 次删除
  1. 64 0
      target_chains/starknet/contracts/src/util.cairo
  2. 2 13
      target_chains/starknet/contracts/tests/wormhole.cairo

+ 64 - 0
target_chains/starknet/contracts/src/util.cairo

@@ -62,3 +62,67 @@ pub fn u64_byte_reverse(value: u64) -> u64 {
 pub trait UnwrapWithFelt252<T, E> {
     fn unwrap_with_felt252(self: Result<T, E>) -> T;
 }
+
+/// Reinterpret `u64` as `i64` as if it was a two's complement binary representation.
+pub fn u64_as_i64(value: u64) -> i64 {
+    if value < 0x8000000000000000 {
+        value.try_into().unwrap()
+    } else {
+        let value: i128 = value.into();
+        (value - 0x10000000000000000).try_into().unwrap()
+    }
+}
+
+/// Reinterpret `u32` as `i32` as if it was a two's complement binary representation.
+pub fn u32_as_i32(value: u32) -> i32 {
+    if value < 0x80000000 {
+        value.try_into().unwrap()
+    } else {
+        let value: i64 = value.into();
+        (value - 0x100000000).try_into().unwrap()
+    }
+}
+
+pub fn array_felt252_to_bytes31(mut input: Array<felt252>) -> Array<bytes31> {
+    let mut output = array![];
+    loop {
+        match input.pop_front() {
+            Option::Some(v) => { output.append(v.try_into().unwrap()); },
+            Option::None => { break; },
+        }
+    };
+    output
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{u64_as_i64, u32_as_i32};
+
+    #[test]
+    fn test_u64_as_i64() {
+        assert!(u64_as_i64(0) == 0);
+        assert!(u64_as_i64(1) == 1);
+        assert!(u64_as_i64(2) == 2);
+        assert!(u64_as_i64(3) == 3);
+        assert!(u64_as_i64(9223372036854775806) == 9223372036854775806);
+        assert!(u64_as_i64(9223372036854775807) == 9223372036854775807);
+        assert!(u64_as_i64(9223372036854775808) == -9223372036854775808);
+        assert!(u64_as_i64(9223372036854775809) == -9223372036854775807);
+        assert!(u64_as_i64(18446744073709551614) == -2);
+        assert!(u64_as_i64(18446744073709551615) == -1);
+    }
+
+    #[test]
+    fn test_u32_as_i32() {
+        assert!(u32_as_i32(0) == 0);
+        assert!(u32_as_i32(1) == 1);
+        assert!(u32_as_i32(2) == 2);
+        assert!(u32_as_i32(3) == 3);
+        assert!(u32_as_i32(2147483646) == 2147483646);
+        assert!(u32_as_i32(2147483647) == 2147483647);
+        assert!(u32_as_i32(2147483648) == -2147483648);
+        assert!(u32_as_i32(2147483649) == -2147483647);
+        assert!(u32_as_i32(4294967294) == -2);
+        assert!(u32_as_i32(4294967295) == -1);
+    }
+}

+ 2 - 13
target_chains/starknet/contracts/tests/wormhole.cairo

@@ -1,7 +1,7 @@
 use snforge_std::{declare, ContractClassTrait, start_prank, stop_prank, CheatTarget};
 use pyth::wormhole::{IWormholeDispatcher, IWormholeDispatcherTrait, ParseAndVerifyVmError};
 use pyth::reader::{ByteArray, ByteArrayImpl, ReaderImpl};
-use pyth::util::UnwrapWithFelt252;
+use pyth::util::{UnwrapWithFelt252, array_felt252_to_bytes31};
 use core::starknet::ContractAddress;
 use core::panic_with_felt252;
 
@@ -94,17 +94,6 @@ fn test_submit_guardian_set_rejects_empty() {
     dispatcher.submit_new_guardian_set(1, array![]).unwrap_with_felt252();
 }
 
-fn array_left252_to_bytes31(mut input: Array<felt252>) -> Array<bytes31> {
-    let mut output = array![];
-    loop {
-        match input.pop_front() {
-            Option::Some(v) => { output.append(v.try_into().unwrap()); },
-            Option::None => { break; },
-        }
-    };
-    output
-}
-
 fn deploy(owner: ContractAddress, guardians: Array<felt252>) -> IWormholeDispatcher {
     let mut args = array![];
     (owner, guardians).serialize(ref args);
@@ -300,5 +289,5 @@ fn good_vm1() -> ByteArray {
         52685537088250779930155363779405986390839624071318818148325576008719597568,
         14615204155786886573933667335033405822686404253588533,
     ];
-    ByteArrayImpl::new(array_left252_to_bytes31(bytes), 22)
+    ByteArrayImpl::new(array_felt252_to_bytes31(bytes), 22)
 }