Skip to content
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

[framework] Adds bcs::peel_enum_tag #20984

Merged
merged 2 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions crates/sui-framework/docs/sui/bcs.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ let leftovers = prepared.into_remainder_bytes();
- [Function `peel_vec_u64`](#sui_bcs_peel_vec_u64)
- [Function `peel_vec_u128`](#sui_bcs_peel_vec_u128)
- [Function `peel_vec_u256`](#sui_bcs_peel_vec_u256)
- [Function `peel_enum_tag`](#sui_bcs_peel_enum_tag)
- [Macro function `peel_option`](#sui_bcs_peel_option)
- [Function `peel_option_address`](#sui_bcs_peel_option_address)
- [Function `peel_option_bool`](#sui_bcs_peel_option_bool)
Expand Down Expand Up @@ -766,6 +767,46 @@ Peel a vector of <code>u256</code> from serialized bytes.



</details>

<a name="sui_bcs_peel_enum_tag"></a>

## Function `peel_enum_tag`

Peel enum from serialized bytes, where <code>$f</code> takes a <code>tag</code> value and returns
the corresponding enum variant. Move enums are limited to 127 variants,
however the tag can be any <code>u32</code> value.

Example:
```rust
let my_enum = match (bcs.peel_enum_tag()) {
0 => Enum::Empty,
1 => Enum::U8(bcs.peel_u8()),
2 => Enum::U16(bcs.peel_u16()),
3 => Enum::Struct { a: bcs.peel_address(), b: bcs.peel_u8() },
_ => abort,
};
```


<pre><code><b>public</b> <b>fun</b> <a href="../sui/bcs.md#sui_bcs_peel_enum_tag">peel_enum_tag</a>(<a href="../sui/bcs.md#sui_bcs">bcs</a>: &<b>mut</b> <a href="../sui/bcs.md#sui_bcs_BCS">sui::bcs::BCS</a>): u32
</code></pre>



<details>
<summary>Implementation</summary>


<pre><code><b>public</b> <b>fun</b> <a href="../sui/bcs.md#sui_bcs_peel_enum_tag">peel_enum_tag</a>(<a href="../sui/bcs.md#sui_bcs">bcs</a>: &<b>mut</b> <a href="../sui/bcs.md#sui_bcs_BCS">BCS</a>): u32 {
<b>let</b> tag = <a href="../sui/bcs.md#sui_bcs">bcs</a>.<a href="../sui/bcs.md#sui_bcs_peel_vec_length">peel_vec_length</a>();
<b>assert</b>!(tag &lt;= <a href="../std/u32.md#std_u32_max_value">std::u32::max_value</a>!() <b>as</b> u64, <a href="../sui/bcs.md#sui_bcs_EOutOfRange">EOutOfRange</a>);
tag <b>as</b> u32
}
</code></pre>



</details>

<a name="sui_bcs_peel_option"></a>
Expand Down
22 changes: 22 additions & 0 deletions crates/sui-framework/packages/sui-framework/sources/bcs.move
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,28 @@ public fun peel_vec_u256(bcs: &mut BCS): vector<u256> {
bcs.peel_vec!(|bcs| bcs.peel_u256())
}

// === Enum ===

/// Peel enum from serialized bytes, where `$f` takes a `tag` value and returns
/// the corresponding enum variant. Move enums are limited to 127 variants,
/// however the tag can be any `u32` value.
///
/// Example:
/// ```rust
/// let my_enum = match (bcs.peel_enum_tag()) {
/// 0 => Enum::Empty,
/// 1 => Enum::U8(bcs.peel_u8()),
/// 2 => Enum::U16(bcs.peel_u16()),
/// 3 => Enum::Struct { a: bcs.peel_address(), b: bcs.peel_u8() },
/// _ => abort,
/// };
/// ```
public fun peel_enum_tag(bcs: &mut BCS): u32 {
let tag = bcs.peel_vec_length();
assert!(tag <= std::u32::max_value!() as u64, EOutOfRange);
tag as u32
}

// === Option<T> ===

/// Peel `Option<$T>` from serialized bytes, where `$peel: |&mut BCS| -> $T` gives the
Expand Down
22 changes: 22 additions & 0 deletions crates/sui-framework/packages/sui-framework/tests/bcs_tests.move
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ module sui::bcs_tests {
const U256_MAX: u256 =
0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF;

public enum Enum has copy, drop {
Empty,
U8(u8),
U16(u16),
}

public struct Info has copy, drop {
a: bool,
b: u8,
Expand Down Expand Up @@ -182,6 +188,22 @@ module sui::bcs_tests {
);
}

#[test]
fun test_enum() {
let enum_cases = vector[Enum::Empty, Enum::U8(1), Enum::U16(2)];
cases!(enum_cases, |bytes| bytes.peel_test_enum());
}

use fun peel_test_enum as BCS.peel_test_enum;
fun peel_test_enum(bytes: &mut BCS): Enum {
match (bytes.peel_enum_tag()) {
0 => Enum::Empty,
1 => Enum::U8(bytes.peel_u8()),
2 => Enum::U16(bytes.peel_u16()),
_ => abort,
}
}

#[test]
fun test_complex() {
let vec_vec_u8_cases = vector[vector[], vector[b"hello world"], vector[b"hello", b"world"]];
Expand Down
Binary file modified crates/sui-framework/packages_compiled/sui-framework
Binary file not shown.
3 changes: 3 additions & 0 deletions crates/sui-framework/published_api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,9 @@ peel_vec_u128
peel_vec_u256
public fun
0x2::bcs
peel_enum_tag
public fun
0x2::bcs
peel_option_address
public fun
0x2::bcs
Expand Down
2 changes: 1 addition & 1 deletion crates/sui-open-rpc/spec/openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@
"name": "Result",
"value": {
"minSupportedProtocolVersion": "1",
"maxSupportedProtocolVersion": "73",
"maxSupportedProtocolVersion": "74",
"protocolVersion": "6",
"featureFlags": {
"accept_zklogin_in_multisig": false,
Expand Down
5 changes: 4 additions & 1 deletion crates/sui-protocol-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use tracing::{info, warn};

/// The minimum and maximum protocol versions supported by this build.
const MIN_PROTOCOL_VERSION: u64 = 1;
const MAX_PROTOCOL_VERSION: u64 = 73;
const MAX_PROTOCOL_VERSION: u64 = 74;

// Record history of protocol version allocations here:
//
Expand Down Expand Up @@ -213,6 +213,8 @@ const MAX_PROTOCOL_VERSION: u64 = 73;
// Enable zstd compression for consensus tonic network in testnet.
// Enable smart ancestor selection in mainnet.
// Enable probing for accepted rounds in round prober in mainnet
// Version 74:
//

#[derive(Copy, Clone, Debug, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtocolVersion(u64);
Expand Down Expand Up @@ -3195,6 +3197,7 @@ impl ProtocolConfig {
cfg.feature_flags
.consensus_round_prober_probe_accepted_rounds = true;
}
74 => {}
// Use this template when making changes:
//
// // modify an existing constant.
Expand Down
Loading
Loading