-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[move-stdlib] Implement bcs::constant_serialized_size<T>(): Option<u64> #14984
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,8 @@ | |
/// published on-chain. See https://github.com/aptos-labs/bcs#binary-canonical-serialization-bcs for more | ||
/// details on BCS. | ||
module std::bcs { | ||
use std::option::Option; | ||
|
||
/// Returns the binary representation of `v` in BCS (Binary Canonical Serialization) format. | ||
/// Aborts with `0x1c5` error code if serialization fails. | ||
native public fun to_bytes<MoveValue>(v: &MoveValue): vector<u8>; | ||
|
@@ -11,6 +13,23 @@ module std::bcs { | |
/// Aborts with `0x1c5` error code if there is a failure when calculating serialized size. | ||
native public fun serialized_size<MoveValue>(v: &MoveValue): u64; | ||
|
||
// TODO - function `constant_serialized_size1 is `public(friend)` here for one release, | ||
// and to be changed to `public` one release later. | ||
#[test_only] | ||
friend std::bcs_tests; | ||
|
||
/// If the type has known constant (always the same, independent of instance) serialized size | ||
/// in BCS (Binary Canonical Serialization) format, returns it, otherwise returns None. | ||
/// Aborts with `0x1c5` error code if there is a failure when calculating serialized size. | ||
/// | ||
/// Note: | ||
/// For some types it might not be known they have constant size, and function might return None. | ||
/// For example, signer appears to have constant size, but it's size might change. | ||
/// If this function returned Some() for some type before - it is guaranteed to continue returning Some(). | ||
/// On the other hand, if function has returned None for some type, | ||
/// it might change in the future to return Some() instead, if size becomes "known". | ||
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. How can this happen - for a size of a type to become known in the future? 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. what I meant here was with a future release, size goes from None to Some. for example if we start supporting bcs serialization and size for delayed fields. 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. KK, that makes sense. |
||
native public(friend) fun constant_serialized_size<MoveValue>(): Option<u64>; | ||
|
||
// ============================== | ||
// Module Specification | ||
spec module {} // switch to module documentation context | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ | |
module std::bcs_tests { | ||
use std::bcs; | ||
use std::vector; | ||
use std::option; | ||
use std::signer; | ||
|
||
struct Box<T> has copy, drop, store { x: T } | ||
struct Box3<T> has copy, drop, store { x: Box<Box<T>> } | ||
|
@@ -20,6 +22,8 @@ module std::bcs_tests { | |
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&true); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<bool>(), 2); | ||
} | ||
|
||
#[test] | ||
|
@@ -31,6 +35,8 @@ module std::bcs_tests { | |
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&1u8); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<u8>(), 2); | ||
} | ||
|
||
#[test] | ||
|
@@ -42,6 +48,8 @@ module std::bcs_tests { | |
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&1); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<u64>(), 2); | ||
} | ||
|
||
#[test] | ||
|
@@ -53,6 +61,8 @@ module std::bcs_tests { | |
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&1u128); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<u128>(), 2); | ||
} | ||
|
||
#[test] | ||
|
@@ -66,6 +76,23 @@ module std::bcs_tests { | |
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&v); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::none() == bcs::constant_serialized_size<vector<u8>>(), 2); | ||
} | ||
|
||
#[test(creator = @0xcafe)] | ||
fun bcs_address(creator: &signer) { | ||
let v = signer::address_of(creator); | ||
|
||
let expected_bytes = x"000000000000000000000000000000000000000000000000000000000000CAFE"; | ||
let actual_bytes = bcs::to_bytes(&v); | ||
assert!(actual_bytes == expected_bytes, 0); | ||
|
||
let expected_size = vector::length(&actual_bytes); | ||
let actual_size = bcs::serialized_size(&v); | ||
assert!(actual_size == expected_size, 1); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<address>(), 2); | ||
} | ||
|
||
fun box3<T>(x: T): Box3<T> { | ||
|
@@ -101,5 +128,18 @@ module std::bcs_tests { | |
|
||
let actual_size = bcs::serialized_size(&box); | ||
assert!(actual_size == expected_size, 0); | ||
|
||
assert!(option::some(actual_size) == bcs::constant_serialized_size<Box127<bool>>(), 1); | ||
assert!(option::none() == bcs::constant_serialized_size<Box63<vector<bool>>>(), 2); | ||
assert!(option::none() == bcs::constant_serialized_size<Box63<option::Option<bool>>>(), 3); | ||
} | ||
|
||
// enum Singleton { | ||
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. This for Move 2 tests only? You have tested it locally? Or will enable later? 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. will enable this once framework is compiled with move 2 |
||
// V1(u64), | ||
// } | ||
|
||
// fun encode_enum() { | ||
// assert!(option::none() == bcs::constant_serialized_size<Singleton>()); | ||
// assert!(option::none() == bcs::constant_serialized_size<Box3<Singleton>>()); | ||
// } | ||
} |
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.
Why this change?
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.
unrelated, but done while working on this PR - added a test that move correctly returns Option from natives, which this PR also does