From eef16b3591a9ef9056a5979950aa9d4c68425995 Mon Sep 17 00:00:00 2001 From: WGB5445 <919603023@qq.com> Date: Mon, 4 Jul 2022 16:47:28 +0800 Subject: [PATCH] Add multiple types of bcs skip and test (#52) * Add multiple types of bcs skip and test * Optimized location and add unit test --- build/StarcoinFramework/BuildInfo.yaml | 2 +- .../StarcoinFramework/bytecode_modules/BCS.mv | Bin 2344 -> 3212 bytes build/StarcoinFramework/docs/BCS.md | 662 ++++++++++++++++-- build/StarcoinFramework/source_maps/BCS.mvsm | Bin 25877 -> 36252 bytes sources/BCS.move | 318 ++++++++- 5 files changed, 915 insertions(+), 67 deletions(-) diff --git a/build/StarcoinFramework/BuildInfo.yaml b/build/StarcoinFramework/BuildInfo.yaml index 013c40fd..ae8f3019 100644 --- a/build/StarcoinFramework/BuildInfo.yaml +++ b/build/StarcoinFramework/BuildInfo.yaml @@ -261,7 +261,7 @@ compiled_package_info: ? address: "0x00000000000000000000000000000001" name: YieldFarmingV2 : StarcoinFramework - source_digest: F39F5364AE53D568F6DE697F20438F49769B5D07FDB6D7231ED2F8262053CE66 + source_digest: 3DB38FA53B8165D50EFE27CA96B9F5C6B7B338D7519835094216173A9B06D40B build_flags: dev_mode: false test_mode: false diff --git a/build/StarcoinFramework/bytecode_modules/BCS.mv b/build/StarcoinFramework/bytecode_modules/BCS.mv index ee2fa3e92f1bcf33b50a8ff120bb66f63786f889..cdebc88d58c69ead28d3749ecf3d4bfc5ce15c31 100644 GIT binary patch literal 3212 zcma)8OK%%D5FV0C?k=^Kw6?sKZTTrb^JpT+5!6F2X^Wyjfubndt6;}MV#KiwOHPqq z(%;Z~5B&lC6TRio_R@Q=1$ytX={MY6?J9|b63~b<{5bQG91i!V*54J6h(bYu42-J& zCA@z`OaCB$5&j?Ql@5Lk>*nY1Ao?@>w+f&jNlHpzpzlE=EftZGaNi+6peZRgJ@5i^Qd)57_GFB=@lK&+Cw2}fn?ka_a z3OA7bdl=y#Mx+uFW5N?kXkkJULKqv80$v$~X4#8?N%{~Wc|0NnTmc-C!#KazNglA$ zSv~8ye`S>~1T&E!2;ZJyjv6KpzFZUP;YVMYPcAQqmm~AV#rSl1ZoU~j8V@gnM@Q%V z(bLn5#>rqbxI8^NJN<6Z?{xdeFUEt>T-kVZa&kEsjp}9F@o;z+PZ@Yx^DRsNxr29^ghN69e=9!10Id~a2PxujNQ^I+&Ry-x72qy;G4xMV4Ab0jv_v#es&0-p_et-!N$=N5@Ad1~FEfQ23l`TXsZfu$RiJCoSZ_y4$6=%@N+mwU zySoylf@-*WRv1($*W$TIR%FSLNC}h*85N62@o>ClaUo%@E;;jTgge<08!FV*0CO?o zTEb@9P;j9M1EPFMP2UcV~tFrLuB~k;iuvs8bkJA>(o``(Z7S&c&y#j<6 zdy$UJj9)Q5X?27;Q;>+H276KQt>>)5bEHwY5nyS-1;DmM+Uj*)0kA!k9TYzB@xTo$ z?x7yZ0Qi+_2usI_Zo_;1p%DGh6S!TV@L z9J#{#Vq~_|*HdI%C4i!OYOFhsJt%pm2%lL7689&vZ z`C=E&wFJaZBBM<@8_zs7R?17TJzg}@ap8wj`c;D3iZaM@83ktrD9 zMyAm}bkTJh-RgUtpoudu*1K>0JJ_)4<8oB2k@Ij{Yhe|_QpdkL@weUpb6SjdLq{fpOYfQ zK653J>jh%Hyy3Z$$c+M#*CTf%xsu4u0+E*@hsc#gwt;vD^Bj;fpXiC)5|Xy@qyGT? C>}{O@ delta 1125 zcmZ{j&ui2`6vyA2nM{(&N z$przqAT-{{4DqfR6G9;+6k2B4CLS_B0Lc9iponPJ31Wb55}@F{G(+HJo>C?Kv_s>d zOCw)cj1X`bMZgzF2|^weK_}=2d0CWsScG|0L_OWtxh^!5ig89?eGf0B+^je%h5|WS zC|#&O;iFYVl*$EyUEl%@Zz1D?@oU!~$Q$GF_IO9$eLdOO-jWa3pG~&MKbF}()_bB= ze-piQbA9W@Y7 zxZ}2>#*?hOjU3l+txJzN39V2W&eB42atXzc0@5sFf{6BLM$oBDO|uHLt(f9VJh1vi zh?r|jOW*cnh4sEHcP;uk6-~Z~Nm>+n6Um{PEM*P3YXu%)ML`%*oB{|_Y{ivmE=li< z%wj&XJjqOPwNOpA`amYHoLLQw(M5%Du6wDbv-z)kim3h>ndN+DcbZwr%5L`TnG~Mc zv!tutSlpzzd`iifo?+$%8Jl6pO2+&dMh~E|8Fs8>EFf&qRJ<}h$kWH<%$Mw+l=R-zM35I>z%L$^OQuSZwT&Fy5wq1EGmJqZ= o8&)i9yesYi%leLcHB8B~d}ZGA%Y9 + + + +## Function `get_byte` + + + +
fun get_byte(input: &vector<u8>, offset: u64): u8
+
+ + + +
+Implementation + + +
fun get_byte(input: &vector<u8>, offset: u64): u8 {
+    assert!(((offset + 1) <= Vector::length(input)) && (offset < offset + 1), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
+    *Vector::borrow(input, offset)
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `get_n_bytes` + + + +
fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8>
+
+ + + +
+Implementation + + +
fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8> {
+    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
+    let i = 0;
+    let content = Vector::empty<u8>();
+    while (i < n) {
+        let b = *Vector::borrow(input, offset + i);
+        Vector::push_back(&mut content, b);
+        i = i + 1;
+    };
+    content
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `get_n_bytes_as_u128` + + + +
fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128
+
+ + + +
+Implementation + + +
fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128 {
+    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
+    let number: u128 = 0;
+    let i = 0;
+    while (i < n) {
+        let byte = *Vector::borrow(input, offset + i);
+        let s = (i as u8) * 8;
+        number = number + ((byte as u128) << s);
+        i = i + 1;
+    };
+    number
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + +
@@ -827,13 +968,13 @@ Return the address of key bytes - + -## Function `get_byte` +## Function `serialize_u32_as_uleb128` -
fun get_byte(input: &vector<u8>, offset: u64): u8
+
fun serialize_u32_as_uleb128(value: u64): vector<u8>
 
@@ -842,9 +983,14 @@ Return the address of key bytes Implementation -
fun get_byte(input: &vector<u8>, offset: u64): u8 {
-    assert!(((offset + 1) <= Vector::length(input)) && (offset < offset + 1), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
-    *Vector::borrow(input, offset)
+
fun serialize_u32_as_uleb128(value: u64): vector<u8> {
+    let output = Vector::empty<u8>();
+    while ((value >> 7) != 0) {
+        Vector::push_back(&mut output, (((value & 0x7f) | 0x80) as u8));
+        value = value >> 7;
+    };
+    Vector::push_back(&mut output, (value as u8));
+    output
 }
 
@@ -864,13 +1010,13 @@ Return the address of key bytes - + -## Function `get_n_bytes` +## Function `skip_option_bytes_vector` -
fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8>
+
public fun skip_option_bytes_vector(input: &vector<u8>, offset: u64): u64
 
@@ -879,16 +1025,14 @@ Return the address of key bytes Implementation -
fun get_n_bytes(input: &vector<u8>, offset: u64, n: u64): vector<u8> {
-    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
+
public fun skip_option_bytes_vector(input: &vector<u8>, offset: u64): u64 {
+    let (len, new_offset) = deserialize_len(input, offset);
     let i = 0;
-    let content = Vector::empty<u8>();
-    while (i < n) {
-        let b = *Vector::borrow(input, offset + i);
-        Vector::push_back(&mut content, b);
+    while (i < len) {
+        new_offset = skip_option_bytes(input, new_offset);
         i = i + 1;
     };
-    content
+    new_offset
 }
 
@@ -908,13 +1052,13 @@ Return the address of key bytes - + -## Function `get_n_bytes_as_u128` +## Function `skip_option_bytes` -
fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128
+
public fun skip_option_bytes(input: &vector<u8>, offset: u64): u64
 
@@ -923,17 +1067,55 @@ Return the address of key bytes Implementation -
fun get_n_bytes_as_u128(input: &vector<u8>, offset: u64, n: u64): u128 {
-    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
-    let number: u128 = 0;
+
public fun skip_option_bytes(input: &vector<u8>, offset: u64):  u64 {
+    let (tag, new_offset) = deserialize_option_tag(input, offset);
+    if (!tag) {
+        new_offset
+    } else {
+        skip_bytes(input, new_offset)
+    }
+}
+
+ + + + + +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_bytes_vector` + + + +
public fun skip_bytes_vector(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_bytes_vector(input: &vector<u8>, offset: u64): u64 {
+    let (len, new_offset) = deserialize_len(input, offset);
     let i = 0;
-    while (i < n) {
-        let byte = *Vector::borrow(input, offset + i);
-        let s = (i as u8) * 8;
-        number = number + ((byte as u128) << s);
+    while (i < len) {
+        new_offset = skip_bytes(input, new_offset);
         i = i + 1;
     };
-    number
+    new_offset
 }
 
@@ -953,13 +1135,13 @@ Return the address of key bytes
- + -## Function `serialize_u32_as_uleb128` +## Function `skip_bytes` -
fun serialize_u32_as_uleb128(value: u64): vector<u8>
+
public fun skip_bytes(input: &vector<u8>, offset: u64): u64
 
@@ -968,14 +1150,416 @@ Return the address of key bytes Implementation -
fun serialize_u32_as_uleb128(value: u64): vector<u8> {
-    let output = Vector::empty<u8>();
-    while ((value >> 7) != 0) {
-        Vector::push_back(&mut output, (((value & 0x7f) | 0x80) as u8));
-        value = value >> 7;
-    };
-    Vector::push_back(&mut output, (value as u8));
-    output
+
public fun skip_bytes(input: &vector<u8>, offset: u64): u64 {
+    let (len, new_offset) = deserialize_len(input, offset);
+    new_offset + len
+}
+
+ + + + + +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_n_bytes` + + + +
public fun skip_n_bytes(input: &vector<u8>, offset: u64, n: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_n_bytes(input: &vector<u8>, offset: u64, n:u64): u64 {
+    can_skip(input, offset, n );
+    offset + n
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u64_vector` + + + +
public fun skip_u64_vector(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u64_vector(input: &vector<u8>, offset: u64): u64 {
+    let (len, new_offset) = deserialize_len(input, offset);
+    can_skip(input, new_offset, len * 8);
+    new_offset + len * 8
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u128_vector` + + + +
public fun skip_u128_vector(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u128_vector(input: &vector<u8>, offset: u64): u64 {
+    let (len, new_offset) = deserialize_len(input, offset);
+    can_skip(input, new_offset, len * 16);
+    new_offset + len * 16
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u256` + + + +
public fun skip_u256(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u256(input: &vector<u8>, offset: u64): u64 {
+    can_skip(input, offset, 32 );
+    offset + 32
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u128` + + + +
public fun skip_u128(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u128(input: &vector<u8>, offset: u64): u64 {
+    can_skip(input, offset, 16 );
+    offset + 16
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u64` + + + +
public fun skip_u64(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u64(input: &vector<u8>, offset: u64): u64 {
+    can_skip(input, offset, 8 );
+    offset + 8
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u32` + + + +
public fun skip_u32(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u32(input: &vector<u8>, offset: u64): u64 {
+    can_skip(input, offset, 4 );
+    offset + 4
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_u16` + + + +
public fun skip_u16(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_u16(input: &vector<u8>, offset: u64): u64 {
+    can_skip(input, offset, 2 );
+    offset + 2
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_address` + + + +
public fun skip_address(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_address(input: &vector<u8>, offset: u64): u64 {
+    skip_n_bytes(input, offset, 16)
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `skip_bool` + + + +
public fun skip_bool(input: &vector<u8>, offset: u64): u64
+
+ + + +
+Implementation + + +
public fun skip_bool(input: &vector<u8>, offset: u64):  u64{
+    can_skip(input, offset, 1);
+    offset + 1
+}
+
+ + + +
+ +
+Specification + + + +
pragma verify = false;
+
+ + + +
+ + + +## Function `can_skip` + + + +
fun can_skip(input: &vector<u8>, offset: u64, n: u64)
+
+ + + +
+Implementation + + +
fun can_skip(input: &vector<u8>, offset: u64, n: u64){
+    assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH));
 }
 
diff --git a/build/StarcoinFramework/source_maps/BCS.mvsm b/build/StarcoinFramework/source_maps/BCS.mvsm index d0a81bc0ba5d8a06810dd862782a763096eb65d4..08a694ec40f08cff7fe8a59944d313163148753e 100644 GIT binary patch literal 36252 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 Jis|X|{smlC+o=Em literal 25877 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 Xdxv@dZ}b7)=ty6;UOjrnc%1(LLxqv< diff --git a/sources/BCS.move b/sources/BCS.move index 3b44a3d6..139117d7 100644 --- a/sources/BCS.move +++ b/sources/BCS.move @@ -310,33 +310,6 @@ module BCS { assert!(!d, 1015); } - public fun deserialize_uleb128_as_u32(input: &vector, offset: u64): (u64, u64) { - let value: u64 = 0; - let shift = 0; - let new_offset = offset; - while (shift < 32) { - let x = get_byte(input, new_offset); - new_offset = new_offset + 1; - let digit: u8 = x & 0x7F; - value = value | (digit as u64) << shift; - if ((value < 0) || (value > INTEGER32_MAX_VALUE)) { - abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32 - }; - if (digit == x) { - if (shift > 0 && digit == 0) { - abort ERR_INVALID_ULEB128_NUMBER_UNEXPECTED_ZERO_DIGIT - }; - return (value, new_offset) - }; - shift = shift + 7 - }; - abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32 - } - - spec deserialize_uleb128_as_u32 { - pragma verify = false; - } - fun get_byte(input: &vector, offset: u64): u8 { assert!(((offset + 1) <= Vector::length(input)) && (offset < offset + 1), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH)); *Vector::borrow(input, offset) @@ -379,6 +352,33 @@ module BCS { pragma verify = false; } + public fun deserialize_uleb128_as_u32(input: &vector, offset: u64): (u64, u64) { + let value: u64 = 0; + let shift = 0; + let new_offset = offset; + while (shift < 32) { + let x = get_byte(input, new_offset); + new_offset = new_offset + 1; + let digit: u8 = x & 0x7F; + value = value | (digit as u64) << shift; + if ((value < 0) || (value > INTEGER32_MAX_VALUE)) { + abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32 + }; + if (digit == x) { + if (shift > 0 && digit == 0) { + abort ERR_INVALID_ULEB128_NUMBER_UNEXPECTED_ZERO_DIGIT + }; + return (value, new_offset) + }; + shift = shift + 7 + }; + abort ERR_OVERFLOW_PARSING_ULEB128_ENCODED_UINT32 + } + + spec deserialize_uleb128_as_u32 { + pragma verify = false; + } + #[test] public fun test_deserialize_uleb128_as_u32() { let i: u64 = 0x7F; @@ -427,5 +427,269 @@ module BCS { pragma verify = false; } + // skip Vector>> + public fun skip_option_bytes_vector(input: &vector, offset: u64): u64 { + let (len, new_offset) = deserialize_len(input, offset); + let i = 0; + while (i < len) { + new_offset = skip_option_bytes(input, new_offset); + i = i + 1; + }; + new_offset + } + + spec skip_option_bytes_vector { + pragma verify = false; + } + + #[test] + fun test_skip_option_bytes_vector(){ + let vec = Vector::empty>>(); + Vector::push_back(&mut vec, Option::some(x"01020304")); + Vector::push_back(&mut vec, Option::some(x"04030201")); + let vec = to_bytes(&vec); + //vec : [2, 1, 4, 1, 2, 3, 4, 1, 4, 4, 3, 2, 1] + assert!(skip_option_bytes_vector(&vec, 0) == 13,2000); + } + + // skip Option::Option> + public fun skip_option_bytes(input: &vector, offset: u64): u64 { + let (tag, new_offset) = deserialize_option_tag(input, offset); + if (!tag) { + new_offset + } else { + skip_bytes(input, new_offset) + } + } + + spec skip_option_bytes { + pragma verify = false; + } + + #[test] + fun test_skip_none_option_bytes(){ + let op = Option::none>(); + let op = to_bytes(&op); + let vec = to_bytes(&x"01020304"); + Vector::append(&mut op, vec); + // op : [0, 4, 1, 2, 3, 4] + assert!(skip_option_bytes(&op, 0) == 1,2007); + } + + #[test] + fun test_skip_some_option_bytes(){ + let op = Option::some(x"01020304"); + let op = to_bytes(&op); + let vec = to_bytes(&x"01020304"); + Vector::append(&mut op, vec); + // op : [1, 4, 1, 2, 3, 4, 4, 1, 2, 3, 4] + assert!(skip_option_bytes(&op, 0) == 6,2008); + } + + // skip vector> + public fun skip_bytes_vector(input: &vector, offset: u64): u64 { + let (len, new_offset) = deserialize_len(input, offset); + let i = 0; + while (i < len) { + new_offset = skip_bytes(input, new_offset); + i = i + 1; + }; + new_offset + } + + spec skip_bytes_vector { + pragma verify = false; + } + + // skip vector + public fun skip_bytes(input: &vector, offset: u64): u64 { + let (len, new_offset) = deserialize_len(input, offset); + new_offset + len + } + + spec skip_bytes { + pragma verify = false; + } + + #[test] + fun test_skip_bytes(){ + let vec = to_bytes(&x"01020304"); + let u_64 = to_bytes(&10); + Vector::append(&mut vec, u_64); + // vec : [4, 1, 2, 3, 4, 10, 0, 0, 0, 0, 0, 0, 0] + assert!(skip_bytes(&vec, 0) == 5,2001); + } + + // skip some bytes + public fun skip_n_bytes(input: &vector, offset: u64, n:u64): u64 { + can_skip(input, offset, n ); + offset + n + } + + spec skip_n_bytes { + pragma verify = false; + } + + #[test] + fun test_skip_n_bytes(){ + let vec = to_bytes(&x"01020304"); + let u_64 = to_bytes(&10); + Vector::append(&mut vec, u_64); + // vec : [4, 1, 2, 3, 4, 10, 0, 0, 0, 0, 0, 0, 0] + assert!(skip_n_bytes(&vec, 0, 1) == 1,2002); + } + + // skip vector + public fun skip_u64_vector(input: &vector, offset: u64): u64 { + let (len, new_offset) = deserialize_len(input, offset); + can_skip(input, new_offset, len * 8); + new_offset + len * 8 + } + + spec skip_u64_vector { + pragma verify = false; + } + + #[test] + fun test_skip_u64_vector(){ + let vec = Vector::empty(); + Vector::push_back(&mut vec, 11111); + Vector::push_back(&mut vec, 22222); + let u_64 = to_bytes(&10); + let vec = to_bytes(&vec); + Vector::append(&mut vec, u_64); + // vec : [2, 103, 43, 0, 0, 0, 0, 0, 0, 206, 86, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0] + assert!(skip_u64_vector(&vec, 0) == 17,2004); + } + + // skip vector + public fun skip_u128_vector(input: &vector, offset: u64): u64 { + let (len, new_offset) = deserialize_len(input, offset); + can_skip(input, new_offset, len * 16); + new_offset + len * 16 + } + + spec skip_u128_vector { + pragma verify = false; + } + + #[test] + fun test_skip_u128_vector(){ + let vec = Vector::empty(); + Vector::push_back(&mut vec, 11111); + Vector::push_back(&mut vec, 22222); + let u_64 = to_bytes(&10); + let vec = to_bytes(&vec); + Vector::append(&mut vec, u_64); + // vec : [2, 103, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0] + assert!(skip_u128_vector(&vec, 0) == 33,2003); + } + + // skip u256 + public fun skip_u256(input: &vector, offset: u64): u64 { + can_skip(input, offset, 32 ); + offset + 32 + } + + spec skip_u256 { + pragma verify = false; + } + + // skip u128 + public fun skip_u128(input: &vector, offset: u64): u64 { + can_skip(input, offset, 16 ); + offset + 16 + } + + spec skip_u128 { + pragma verify = false; + } + + #[test] + fun test_skip_u128(){ + let u_128:u128 = 100; + let u_128 = to_bytes(&u_128); + let vec = to_bytes(&x"01020304"); + Vector::append(&mut u_128, vec); + // u_128 : [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 2, 3, 4] + assert!(skip_u128(&u_128, 0) == 16,2005); + } + + // skip u64 + public fun skip_u64(input: &vector, offset: u64): u64 { + can_skip(input, offset, 8 ); + offset + 8 + } + + spec skip_u64 { + pragma verify = false; + } + + #[test] + fun test_skip_u64(){ + let u_64:u64 = 100; + let u_64 = to_bytes(&u_64); + let vec = to_bytes(&x"01020304"); + Vector::append(&mut u_64, vec); + // u_64 : [100, 0, 0, 0, 0, 0, 0, 0, 4, 1, 2, 3, 4] + assert!(skip_u64(&u_64, 0) == 8,2006); + } + + // skip u32 + public fun skip_u32(input: &vector, offset: u64): u64 { + can_skip(input, offset, 4 ); + offset + 4 + } + + spec skip_u32 { + pragma verify = false; + } + + // skip u16 + public fun skip_u16(input: &vector, offset: u64): u64 { + can_skip(input, offset, 2 ); + offset + 2 + } + + spec skip_u16 { + pragma verify = false; + } + + // skip address + public fun skip_address(input: &vector, offset: u64): u64 { + skip_n_bytes(input, offset, 16) + } + + spec skip_address { + pragma verify = false; + } + + #[test] + fun test_address(){ + let addr:address = @0x1; + let addr = to_bytes(&addr); + let vec = to_bytes(&x"01020304"); + Vector::append(&mut addr, vec); + // addr : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 1, 2, 3, 4] + assert!(skip_address(&addr, 0) == 16,2006); + } + + // skip bool + public fun skip_bool(input: &vector, offset: u64): u64{ + can_skip(input, offset, 1); + offset + 1 + } + + spec skip_bool { + pragma verify = false; + } + + fun can_skip(input: &vector, offset: u64, n: u64){ + assert!(((offset + n) <= Vector::length(input)) && (offset < offset + n), Errors::invalid_state(ERR_INPUT_NOT_LARGE_ENOUGH)); + } + + spec can_skip { + pragma verify = false; + } } }