-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Optimize encoding and decoding of Vec<T> when T is trivial
#7582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| [[package]] | ||
| name = "raw_ptr_ret" | ||
| source = "member" | ||
| dependencies = ["std"] | ||
| name = "std" | ||
| source = "path+from-root-2158C659FB34C0B1" | ||
|
|
||
| [[package]] | ||
| name = "std" | ||
| source = "path+from-root-51D3AF48CE04FAE0" | ||
| name = "vec_encoding_decoding" | ||
| source = "member" | ||
| dependencies = ["std"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cmds = ["forc test --path {root} --release --logs"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| script; | ||
|
|
||
| fn main(trivial: Vec<u64>, non_trivial: Vec<u32>) -> (Vec<u64>, Vec<u32>) { | ||
| assert_eq(trivial.len(), 3); | ||
| assert_eq(trivial.get(0).unwrap_or(0), 124); | ||
| assert_eq(trivial.get(1).unwrap_or(0), 124); | ||
| assert_eq(trivial.get(2).unwrap_or(0), 124); | ||
|
|
||
| let mut trivial = Vec::from(trivial.as_raw_slice()); | ||
| trivial.push(124); | ||
| trivial.push(124); | ||
| trivial.push(124); | ||
|
|
||
| assert_eq(non_trivial.len(), 3); | ||
| assert_eq(non_trivial.get(0).unwrap_or(0), 124); | ||
| assert_eq(non_trivial.get(1).unwrap_or(0), 124); | ||
| assert_eq(non_trivial.get(2).unwrap_or(0), 124); | ||
|
|
||
| let mut non_trivial = Vec::from(non_trivial.as_raw_slice()); | ||
| non_trivial.push(124); | ||
| non_trivial.push(124); | ||
| non_trivial.push(124); | ||
|
|
||
| (trivial, non_trivial) | ||
| } | ||
|
|
||
| #[test] | ||
| fn vec_trivial() { | ||
| let vec = create_vec_trivial(10); | ||
| let encoded_decoded: Vec<u64> = abi_decode(encode(vec)); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| let encoded_as_alias = encode_allow_alias(&encoded_decoded); | ||
| let encoded_decoded: Vec<u64> = abi_decode(encoded_as_alias); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| log(encoded_decoded); | ||
| } | ||
|
|
||
| #[test] | ||
| fn nested_vec_trivial() { | ||
| let vec = create_nested_vec_trivial(10); | ||
| let encoded_decoded: Vec<Vec<u64>> = abi_decode(encode(vec)); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| let encoded_as_alias = encode_allow_alias(&encoded_decoded); | ||
| let encoded_decoded: Vec<Vec<u64>> = abi_decode(encoded_as_alias); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| log(encoded_decoded); | ||
| } | ||
|
|
||
| #[test] | ||
| fn vec_non_trivial() { | ||
| let vec = create_vec_trivial(10); | ||
| let encoded_decoded: Vec<u64> = abi_decode(encode(vec)); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| let encoded_as_alias = encode_allow_alias(&encoded_decoded); | ||
| let encoded_decoded: Vec<u64> = abi_decode(encoded_as_alias); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| log(encoded_decoded); | ||
| } | ||
|
|
||
| #[test] | ||
| fn nested_vec_non_trivial() { | ||
| let vec = create_nested_vec_non_trivial(10); | ||
| let encoded_decoded: Vec<Vec<u32>> = abi_decode(encode(vec)); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| let encoded_as_alias = encode_allow_alias(&encoded_decoded); | ||
| let encoded_decoded: Vec<Vec<u32>> = abi_decode(encoded_as_alias); | ||
| assert_eq(encoded_decoded, vec); | ||
|
|
||
| log(encoded_decoded); | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| fn create_vec_trivial(n: u64) -> Vec<u64> { | ||
| let mut vec = Vec::<u64>::new(); | ||
| let mut i: u64 = 0; | ||
| while i < n { | ||
| vec.push(i); | ||
| i += 1; | ||
| } | ||
| vec | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| fn create_nested_vec_trivial(n: u64) -> Vec<Vec<u64>> { | ||
| let mut vec = Vec::<Vec<u64>>::new(); | ||
| let mut i: u64 = 0; | ||
| while i < n { | ||
| vec.push(create_vec_trivial(i)); | ||
| i += 1; | ||
| } | ||
| vec | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| fn create_vec_non_trivial(n: u32) -> Vec<u32> { | ||
| let mut vec = Vec::<u32>::new(); | ||
| let mut i: u32 = 0; | ||
| while i < n { | ||
| vec.push(i); | ||
| i += 1; | ||
| } | ||
| vec | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| fn create_nested_vec_non_trivial(n: u32) -> Vec<Vec<u32>> { | ||
| let mut vec = Vec::<Vec<u32>>::new(); | ||
| let mut i: u32 = 0; | ||
| while i < n { | ||
| vec.push(create_vec_non_trivial(i)); | ||
| i += 1; | ||
| } | ||
| vec | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| category = "run" | ||
|
|
||
| script_data_new_encoding = "0000000000000003000000000000007c000000000000007c000000000000007c 00000000000000030000007c0000007c0000007c" | ||
| expected_result_new_encoding = { action = "return_data", value = "0000000000000006000000000000007c000000000000007c000000000000007c000000000000007c000000000000007c000000000000007c 00000000000000060000007c0000007c0000007c0000007c0000007c0000007c" } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Script test data incompatible with new trivial encoding formatHigh Severity The |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| category = "unit_tests_pass" |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test
vec_non_trivialincorrectly tests trivial path insteadMedium Severity
The
vec_non_trivialtest callscreate_vec_trivial(10)and usesVec<u64>, making it an exact duplicate ofvec_trivial. It was clearly intended to callcreate_vec_non_trivial(10)and useVec<u32>(the non-trivial type, sinceu32hasis_encode_trivial() -> false). This means the non-trivial encoding/decoding path for flatVec<u32>has no unit test coverage. Compare withnested_vec_non_trivialwhich correctly usescreate_nested_vec_non_trivialandVec<Vec<u32>>.