diff --git a/crates/sui-framework/docs/sui-framework/authenticator_state.md b/crates/sui-framework/docs/sui-framework/authenticator_state.md index 93d44e078b5d6..fe4f48e3a07de 100644 --- a/crates/sui-framework/docs/sui-framework/authenticator_state.md +++ b/crates/sui-framework/docs/sui-framework/authenticator_state.md @@ -308,9 +308,9 @@ Sender is not @0x0 the system address.
fun jwk_equal(a: &JWK, b: &JWK): bool {
(&a.kty == &b.kty) &&
- (&a.e == &b.e) &&
- (&a.n == &b.n) &&
- (&a.alg == &b.alg)
+ (&a.e == &b.e) &&
+ (&a.n == &b.n) &&
+ (&a.alg == &b.alg)
}
@@ -484,9 +484,7 @@ Can only be called by genesis or change_epoch transactions.
fun load_inner_mut(
- self: &mut AuthenticatorState,
-): &mut AuthenticatorStateInner {
+fun load_inner_mut(self: &mut AuthenticatorState): &mut AuthenticatorStateInner {
let version = self.version;
// replace this with a lazy update function when we add a new version of the inner object.
@@ -518,9 +516,7 @@ Can only be called by genesis or change_epoch transactions.
Implementation
-fun load_inner(
- self: &AuthenticatorState,
-): &AuthenticatorStateInner {
+fun load_inner(self: &AuthenticatorState): &AuthenticatorStateInner {
let version = self.version;
// replace this with a lazy update function when we add a new version of the inner object.
@@ -709,7 +705,8 @@ indicate that the JWK has been validated in the current epoch and should not be
self: &mut AuthenticatorState,
// any jwk below this epoch is not retained
min_epoch: u64,
- ctx: &TxContext) {
+ ctx: &TxContext,
+) {
// This will only be called by sui_system::advance_epoch
assert!(ctx.sender() == @0x0, ENotSystemAddress);
@@ -793,10 +790,7 @@ JWK state from the chain.
Implementation
-fun get_active_jwks(
- self: &AuthenticatorState,
- ctx: &TxContext,
-): vector<ActiveJwk> {
+fun get_active_jwks(self: &AuthenticatorState, ctx: &TxContext): vector<ActiveJwk> {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
self.load_inner().active_jwks
}
diff --git a/crates/sui-framework/docs/sui-framework/borrow.md b/crates/sui-framework/docs/sui-framework/borrow.md
index 0fe949d035fb0..c9af348f4c10c 100644
--- a/crates/sui-framework/docs/sui-framework/borrow.md
+++ b/crates/sui-framework/docs/sui-framework/borrow.md
@@ -137,7 +137,7 @@ Create a new Referent
s
public fun new<T: key + store>(value: T, ctx: &mut TxContext): Referent<T> {
Referent {
id: tx_context::fresh_object_address(ctx),
- value: option::some(value)
+ value: option::some(value),
}
}
@@ -167,10 +167,13 @@ hot potato.
let value = self.value.extract();
let id = object::id(&value);
- (value, Borrow {
- ref: self.id,
- obj: id
- })
+ (
+ value,
+ Borrow {
+ ref: self.id,
+ obj: id,
+ },
+ )
}
diff --git a/crates/sui-framework/docs/sui-framework/clock.md b/crates/sui-framework/docs/sui-framework/clock.md
index 4093c882c71ad..3919d8837f026 100644
--- a/crates/sui-framework/docs/sui-framework/clock.md
+++ b/crates/sui-framework/docs/sui-framework/clock.md
@@ -154,11 +154,7 @@ called exactly once, during genesis.
Implementation
-fun consensus_commit_prologue(
- clock: &mut Clock,
- timestamp_ms: u64,
- ctx: &TxContext,
-) {
+fun consensus_commit_prologue(clock: &mut Clock, timestamp_ms: u64, ctx: &TxContext) {
// Validator will make a special system call with sender set as 0x0.
assert!(ctx.sender() == @0x0, ENotSystemAddress);
diff --git a/crates/sui-framework/docs/sui-framework/display.md b/crates/sui-framework/docs/sui-framework/display.md
index 3d085df973e54..e56a69e0d080f 100644
--- a/crates/sui-framework/docs/sui-framework/display.md
+++ b/crates/sui-framework/docs/sui-framework/display.md
@@ -247,7 +247,10 @@ Create a new Display object with a set of fields.
public fun new_with_fields<T: key>(
- pub: &Publisher, fields: vector<String>, values: vector<String>, ctx: &mut TxContext
+ pub: &Publisher,
+ fields: vector<String>,
+ values: vector<String>,
+ ctx: &mut TxContext,
): Display<T> {
let len = fields.length();
assert!(len == values.length(), EVecLengthMismatch);
@@ -283,7 +286,7 @@ Create a new empty Display object and keep it.
Implementation
-entry public fun create_and_keep<T: key>(pub: &Publisher, ctx: &mut TxContext) {
+public entry fun create_and_keep<T: key>(pub: &Publisher, ctx: &mut TxContext) {
transfer::public_transfer(new<T>(pub, ctx), ctx.sender())
}
@@ -308,9 +311,7 @@ Manually bump the version and emit an event with the updated version's contents.
Implementation
-entry public fun update_version<T: key>(
- display: &mut Display<T>
-) {
+public entry fun update_version<T: key>(display: &mut Display<T>) {
display.version = display.version + 1;
event::emit(VersionUpdated<T> {
version: display.version,
@@ -340,7 +341,7 @@ Sets a custom name
field with the value
.
Implementation
-entry public fun add<T: key>(self: &mut Display<T>, name: String, value: String) {
+public entry fun add<T: key>(self: &mut Display<T>, name: String, value: String) {
self.add_internal(name, value)
}
@@ -365,8 +366,10 @@ Sets multiple fields
with values
.
Implementation
-entry public fun add_multiple<T: key>(
- self: &mut Display<T>, fields: vector<String>, values: vector<String>
+public entry fun add_multiple<T: key>(
+ self: &mut Display<T>,
+ fields: vector<String>,
+ values: vector<String>,
) {
let len = fields.length();
assert!(len == values.length(), EVecLengthMismatch);
@@ -400,7 +403,7 @@ TODO (long run): version changes;
Implementation
-entry public fun edit<T: key>(self: &mut Display<T>, name: String, value: String) {
+public entry fun edit<T: key>(self: &mut Display<T>, name: String, value: String) {
let (_, _) = self.fields.remove(&name);
self.add_internal(name, value)
}
@@ -426,7 +429,7 @@ Remove the key from the Display.
Implementation
-entry public fun remove<T: key>(self: &mut Display<T>, name: String) {
+public entry fun remove<T: key>(self: &mut Display<T>, name: String) {
self.fields.remove(&name);
}
@@ -530,7 +533,7 @@ Internal function to create a new let uid = object::new(ctx);
event::emit(DisplayCreated<T> {
- id: uid.to_inner()
+ id: uid.to_inner(),
});
Display {
diff --git a/crates/sui-framework/docs/sui-framework/hex.md b/crates/sui-framework/docs/sui-framework/hex.md
index 5a835de9a6314..c7844eb46f877 100644
--- a/crates/sui-framework/docs/sui-framework/hex.md
+++ b/crates/sui-framework/docs/sui-framework/hex.md
@@ -133,11 +133,11 @@ Aborts if the hex string contains non-valid hex characters (valid characters are
fun decode_byte(hex: u8): u8 {
- if (/* 0 .. 9 */ 48 <= hex && hex < 58) {
+ if (48 <= hex && hex < 58) {
hex - 48
- } else if (/* A .. F */ 65 <= hex && hex < 71) {
+ } else if (65 <= hex && hex < 71) {
10 + hex - 65
- } else if (/* a .. f */ 97 <= hex && hex < 103) {
+ } else if (97 <= hex && hex < 103) {
10 + hex - 97
} else {
abort ENotValidHexCharacter
diff --git a/crates/sui-framework/docs/sui-framework/math.md b/crates/sui-framework/docs/sui-framework/math.md
index d138083a64689..be044025e9ba1 100644
--- a/crates/sui-framework/docs/sui-framework/math.md
+++ b/crates/sui-framework/docs/sui-framework/math.md
@@ -162,7 +162,7 @@ DEPRECATED, use std::u128::sqrt
instead
public fun sqrt_u128(x: u128): u128 {
- x.sqrt()
+ x.sqrt()
}
diff --git a/crates/sui-framework/docs/sui-framework/object.md b/crates/sui-framework/docs/sui-framework/object.md
index 8e7a390ad700e..020d715c11e82 100644
--- a/crates/sui-framework/docs/sui-framework/object.md
+++ b/crates/sui-framework/docs/sui-framework/object.md
@@ -330,7 +330,7 @@ This should only be called once from clock(): UID {
UID {
- id: ID { bytes: SUI_CLOCK_OBJECT_ID }
+ id: ID { bytes: SUI_CLOCK_OBJECT_ID },
}
}
@@ -358,7 +358,7 @@ This should only be called once from authenticator_state(): UID {
UID {
- id: ID { bytes: SUI_AUTHENTICATOR_STATE_ID }
+ id: ID { bytes: SUI_AUTHENTICATOR_STATE_ID },
}
}
@@ -386,7 +386,7 @@ This should only be called once from randomness_state(): UID {
UID {
- id: ID { bytes: SUI_RANDOM_ID }
+ id: ID { bytes: SUI_RANDOM_ID },
}
}
@@ -414,7 +414,7 @@ This should only be called once from sui_deny_list_object_id(): UID {
UID {
- id: ID { bytes: SUI_DENY_LIST_OBJECT_ID }
+ id: ID { bytes: SUI_DENY_LIST_OBJECT_ID },
}
}
@@ -442,7 +442,7 @@ This should only be called once from bridge
.
fun bridge(): UID {
UID {
- id: ID { bytes: SUI_BRIDGE_ID }
+ id: ID { bytes: SUI_BRIDGE_ID },
}
}
diff --git a/crates/sui-framework/docs/sui-framework/package.md b/crates/sui-framework/docs/sui-framework/package.md
index a2c043014e433..b718af007cc98 100644
--- a/crates/sui-framework/docs/sui-framework/package.md
+++ b/crates/sui-framework/docs/sui-framework/package.md
@@ -899,11 +899,7 @@ for the upgrade to succeed.
Implementation
-public fun authorize_upgrade(
- cap: &mut UpgradeCap,
- policy: u8,
- digest: vector<u8>
-): UpgradeTicket {
+public fun authorize_upgrade(cap: &mut UpgradeCap, policy: u8, digest: vector<u8>): UpgradeTicket {
let id_zero = @0x0.to_id();
assert!(cap.package != id_zero, EAlreadyAuthorized);
assert!(policy >= cap.policy, ETooPermissive);
@@ -941,10 +937,7 @@ the upgrade.
Implementation
-public fun commit_upgrade(
- cap: &mut UpgradeCap,
- receipt: UpgradeReceipt,
-) {
+public fun commit_upgrade(cap: &mut UpgradeCap, receipt: UpgradeReceipt) {
let UpgradeReceipt { cap: cap_id, package } = receipt;
assert!(object::id(cap) == cap_id, EWrongUpgradeCap);
diff --git a/crates/sui-framework/docs/sui-framework/pay.md b/crates/sui-framework/docs/sui-framework/pay.md
index 7abd57b9fe2ed..84b2a29a92726 100644
--- a/crates/sui-framework/docs/sui-framework/pay.md
+++ b/crates/sui-framework/docs/sui-framework/pay.md
@@ -80,9 +80,7 @@ and the remaining balance is left is self
.
Implementation
-public entry fun split<T>(
- coin: &mut Coin<T>, split_amount: u64, ctx: &mut TxContext
-) {
+public entry fun split<T>(coin: &mut Coin<T>, split_amount: u64, ctx: &mut TxContext) {
keep(coin.split(split_amount, ctx), ctx)
}
@@ -108,9 +106,7 @@ in split_amounts
. Remaining balance is left in self
.
Implementation
-public entry fun split_vec<T>(
- self: &mut Coin<T>, split_amounts: vector<u64>, ctx: &mut TxContext
-) {
+public entry fun split_vec<T>(self: &mut Coin<T>, split_amounts: vector<u64>, ctx: &mut TxContext) {
let (mut i, len) = (0, split_amounts.length());
while (i < len) {
split(self, split_amounts[i], ctx);
@@ -141,7 +137,10 @@ Aborts with EVALUE
if amount
is greater than or equal
public entry fun split_and_transfer<T>(
- c: &mut Coin<T>, amount: u64, recipient: address, ctx: &mut TxContext
+ c: &mut Coin<T>,
+ amount: u64,
+ recipient: address,
+ ctx: &mut TxContext,
) {
transfer::public_transfer(c.split(amount, ctx), recipient)
}
@@ -168,9 +167,7 @@ not evenly divisible by n
, the remainder is left in selfImplementation
-public entry fun divide_and_keep<T>(
- self: &mut Coin<T>, n: u64, ctx: &mut TxContext
-) {
+public entry fun divide_and_keep<T>(self: &mut Coin<T>, n: u64, ctx: &mut TxContext) {
let mut vec: vector<Coin<T>> = self.divide_into_n(n, ctx);
let (mut i, len) = (0, vec.length());
while (i < len) {
diff --git a/crates/sui-framework/docs/sui-framework/random.md b/crates/sui-framework/docs/sui-framework/random.md
index 27837f0a1cf5c..a685e78d198b9 100644
--- a/crates/sui-framework/docs/sui-framework/random.md
+++ b/crates/sui-framework/docs/sui-framework/random.md
@@ -300,9 +300,7 @@ Can only be called by genesis or change_epoch transactions.
Implementation
-fun load_inner_mut(
- self: &mut Random,
-): &mut RandomInner {
+fun load_inner_mut(self: &mut Random): &mut RandomInner {
let version = versioned::version(&self.inner);
// Replace this with a lazy update function when we add a new version of the inner object.
@@ -332,9 +330,7 @@ Can only be called by genesis or change_epoch transactions.
Implementation
-fun load_inner(
- self: &Random,
-): &RandomInner {
+fun load_inner(self: &Random): &RandomInner {
let version = versioned::version(&self.inner);
// Replace this with a lazy update function when we add a new version of the inner object.
@@ -387,8 +383,8 @@ transaction.
// randomness ever being generated in that epoch.
assert!(
(epoch > inner.epoch && new_round == 0) ||
- (new_round == inner.randomness_round + 1),
- EInvalidRandomnessUpdate
+ (new_round == inner.randomness_round + 1),
+ EInvalidRandomnessUpdate,
);
};
@@ -422,7 +418,7 @@ Create a generator. Can be used to derive up to MAX_U16 * 32 random bytes.
let inner = load_inner(r);
let seed = hmac_sha3_256(
&inner.random_bytes,
- &ctx.fresh_object_address().to_bytes()
+ &ctx.fresh_object_address().to_bytes(),
);
RandomGenerator { seed, counter: 0, buffer: vector[] }
}
diff --git a/crates/sui-framework/docs/sui-framework/tx_context.md b/crates/sui-framework/docs/sui-framework/tx_context.md
index 97e1840b5aed6..380f047c58eeb 100644
--- a/crates/sui-framework/docs/sui-framework/tx_context.md
+++ b/crates/sui-framework/docs/sui-framework/tx_context.md
@@ -167,7 +167,7 @@ Return the epoch start time as a unix timestamp in milliseconds.
public fun epoch_timestamp_ms(self: &TxContext): u64 {
- self.epoch_timestamp_ms
+ self.epoch_timestamp_ms
}
diff --git a/crates/sui-framework/docs/sui-framework/url.md b/crates/sui-framework/docs/sui-framework/url.md
index e0e2204219292..6129f0f7d229c 100644
--- a/crates/sui-framework/docs/sui-framework/url.md
+++ b/crates/sui-framework/docs/sui-framework/url.md
@@ -113,7 +113,7 @@ Get inner URL
Implementation
-public fun inner_url(self: &Url): String{
+public fun inner_url(self: &Url): String {
self.url
}
diff --git a/crates/sui-framework/docs/sui-framework/versioned.md b/crates/sui-framework/docs/sui-framework/versioned.md
index afc62e3e59a44..6a67a4a33f744 100644
--- a/crates/sui-framework/docs/sui-framework/versioned.md
+++ b/crates/sui-framework/docs/sui-framework/versioned.md
@@ -241,7 +241,7 @@ and must be used when we upgrade.
VersionChangeCap {
versioned_id: object::id(self),
old_version: self.version,
- }
+ },
)
}
@@ -267,7 +267,12 @@ by calling remove_value_for_upgrade.
Implementation
-public fun upgrade<T: store>(self: &mut Versioned, new_version: u64, new_value: T, cap: VersionChangeCap) {
+public fun upgrade<T: store>(
+ self: &mut Versioned,
+ new_version: u64,
+ new_value: T,
+ cap: VersionChangeCap,
+) {
let VersionChangeCap { versioned_id, old_version } = cap;
assert!(versioned_id == object::id(self), EInvalidUpgrade);
assert!(old_version < new_version, EInvalidUpgrade);
diff --git a/crates/sui-framework/packages/sui-framework/sources/address.move b/crates/sui-framework/packages/sui-framework/sources/address.move
index 129908910df05..51d65d7b98b5a 100644
--- a/crates/sui-framework/packages/sui-framework/sources/address.move
+++ b/crates/sui-framework/packages/sui-framework/sources/address.move
@@ -2,85 +2,85 @@
// SPDX-License-Identifier: Apache-2.0
#[defines_primitive(address)]
-module sui::address {
- use sui::hex;
- use std::ascii;
- use std::bcs;
- use std::string;
-
- /// Allows calling `.to_id()` on an address to get its `ID`.
- public use fun sui::object::id_from_address as address.to_id;
-
- /// The length of an address, in bytes
- const LENGTH: u64 = 32;
-
- // The largest integer that can be represented with 32 bytes: 2^(8*32) - 1
- const MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
-
- #[allow(unused_const)]
- /// Error from `from_bytes` when it is supplied too many or too few bytes.
- const EAddressParseError: u64 = 0;
-
- /// Convert `a` into a u256 by interpreting `a` as the bytes of a big-endian integer
- /// (e.g., `to_u256(0x1) == 1`)
- public native fun to_u256(a: address): u256;
-
- /// Convert `n` into an address by encoding it as a big-endian integer (e.g., `from_u256(1) = @0x1`)
- /// Aborts if `n` > `MAX_ADDRESS`
- public native fun from_u256(n: u256): address;
-
- /// Convert `bytes` into an address.
- /// Aborts with `EAddressParseError` if the length of `bytes` is not 32
- public native fun from_bytes(bytes: vector): address;
-
- /// Convert `a` into BCS-encoded bytes.
- public fun to_bytes(a: address): vector {
- bcs::to_bytes(&a)
- }
-
- /// Convert `a` to a hex-encoded ASCII string
- public fun to_ascii_string(a: address): ascii::String {
- hex::encode(to_bytes(a)).to_ascii_string()
- }
-
- /// Convert `a` to a hex-encoded string
- public fun to_string(a: address): string::String {
- to_ascii_string(a).to_string()
- }
-
- /// Converts an ASCII string to an address, taking the numerical value for each character. The
- /// string must be Base16 encoded, and thus exactly 64 characters long.
- /// For example, the string "00000000000000000000000000000000000000000000000000000000DEADB33F"
- /// will be converted to the address @0xDEADB33F.
- /// Aborts with `EAddressParseError` if the length of `s` is not 64,
- /// or if an invalid character is encountered.
- public fun from_ascii_bytes(bytes: &vector): address {
- assert!(bytes.length() == 64, EAddressParseError);
- let mut hex_bytes = vector[];
- let mut i = 0;
- while (i < 64) {
- let hi = hex_char_value(bytes[i]);
- let lo = hex_char_value(bytes[i+1]);
- hex_bytes.push_back((hi << 4) | lo);
- i = i + 2;
- };
- from_bytes(hex_bytes)
- }
-
- fun hex_char_value(c: u8): u8 {
- if (c >= 48 && c <= 57) c - 48 // 0-9
- else if (c >= 65 && c <= 70) c - 55 // A-F
- else if (c >= 97 && c <= 102) c - 87 // a-f
- else abort EAddressParseError
- }
-
- /// Length of a Sui address in bytes
- public fun length(): u64 {
- LENGTH
- }
-
- /// Largest possible address
- public fun max(): u256 {
- MAX
- }
+module sui::address;
+
+use std::ascii;
+use std::bcs;
+use std::string;
+use sui::hex;
+
+/// Allows calling `.to_id()` on an address to get its `ID`.
+public use fun sui::object::id_from_address as address.to_id;
+
+/// The length of an address, in bytes
+const LENGTH: u64 = 32;
+
+// The largest integer that can be represented with 32 bytes: 2^(8*32) - 1
+const MAX: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
+
+#[allow(unused_const)]
+/// Error from `from_bytes` when it is supplied too many or too few bytes.
+const EAddressParseError: u64 = 0;
+
+/// Convert `a` into a u256 by interpreting `a` as the bytes of a big-endian integer
+/// (e.g., `to_u256(0x1) == 1`)
+public native fun to_u256(a: address): u256;
+
+/// Convert `n` into an address by encoding it as a big-endian integer (e.g., `from_u256(1) = @0x1`)
+/// Aborts if `n` > `MAX_ADDRESS`
+public native fun from_u256(n: u256): address;
+
+/// Convert `bytes` into an address.
+/// Aborts with `EAddressParseError` if the length of `bytes` is not 32
+public native fun from_bytes(bytes: vector): address;
+
+/// Convert `a` into BCS-encoded bytes.
+public fun to_bytes(a: address): vector {
+ bcs::to_bytes(&a)
+}
+
+/// Convert `a` to a hex-encoded ASCII string
+public fun to_ascii_string(a: address): ascii::String {
+ hex::encode(to_bytes(a)).to_ascii_string()
+}
+
+/// Convert `a` to a hex-encoded string
+public fun to_string(a: address): string::String {
+ to_ascii_string(a).to_string()
+}
+
+/// Converts an ASCII string to an address, taking the numerical value for each character. The
+/// string must be Base16 encoded, and thus exactly 64 characters long.
+/// For example, the string "00000000000000000000000000000000000000000000000000000000DEADB33F"
+/// will be converted to the address @0xDEADB33F.
+/// Aborts with `EAddressParseError` if the length of `s` is not 64,
+/// or if an invalid character is encountered.
+public fun from_ascii_bytes(bytes: &vector): address {
+ assert!(bytes.length() == 64, EAddressParseError);
+ let mut hex_bytes = vector[];
+ let mut i = 0;
+ while (i < 64) {
+ let hi = hex_char_value(bytes[i]);
+ let lo = hex_char_value(bytes[i+1]);
+ hex_bytes.push_back((hi << 4) | lo);
+ i = i + 2;
+ };
+ from_bytes(hex_bytes)
+}
+
+fun hex_char_value(c: u8): u8 {
+ if (c >= 48 && c <= 57) c - 48 // 0-9
+ else if (c >= 65 && c <= 70) c - 55 // A-F
+ else if (c >= 97 && c <= 102) c - 87 // a-f
+ else abort EAddressParseError
+}
+
+/// Length of a Sui address in bytes
+public fun length(): u64 {
+ LENGTH
+}
+
+/// Largest possible address
+public fun max(): u256 {
+ MAX
}
diff --git a/crates/sui-framework/packages/sui-framework/sources/authenticator_state.move b/crates/sui-framework/packages/sui-framework/sources/authenticator_state.move
index beca79feea46c..fb39f865ac071 100644
--- a/crates/sui-framework/packages/sui-framework/sources/authenticator_state.move
+++ b/crates/sui-framework/packages/sui-framework/sources/authenticator_state.move
@@ -7,389 +7,377 @@
//
// This module is not currently accessible from user contracts, and is used only to record the JWK
// state to the chain for auditability + restore from snapshot purposes.
-module sui::authenticator_state {
- use std::string;
- use sui::dynamic_field;
- use std::string::{String, utf8};
-
- /// Sender is not @0x0 the system address.
- const ENotSystemAddress: u64 = 0;
- const EWrongInnerVersion: u64 = 1;
- const EJwksNotSorted: u64 = 2;
-
- const CurrentVersion: u64 = 1;
-
- /// Singleton shared object which stores the global authenticator state.
- /// The actual state is stored in a dynamic field of type AuthenticatorStateInner to support
- /// future versions of the authenticator state.
- public struct AuthenticatorState has key {
- id: UID,
- version: u64,
- }
+module sui::authenticator_state;
- public struct AuthenticatorStateInner has store {
- version: u64,
+use std::string::{Self, String, utf8};
+use sui::dynamic_field;
- /// List of currently active JWKs.
- active_jwks: vector,
- }
+/// Sender is not @0x0 the system address.
+const ENotSystemAddress: u64 = 0;
+const EWrongInnerVersion: u64 = 1;
+const EJwksNotSorted: u64 = 2;
- #[allow(unused_field)]
- /// Must match the JWK struct in fastcrypto-zkp
- public struct JWK has store, drop, copy {
- kty: String,
- e: String,
- n: String,
- alg: String,
- }
+const CurrentVersion: u64 = 1;
- #[allow(unused_field)]
- /// Must match the JwkId struct in fastcrypto-zkp
- public struct JwkId has store, drop, copy {
- iss: String,
- kid: String,
- }
+/// Singleton shared object which stores the global authenticator state.
+/// The actual state is stored in a dynamic field of type AuthenticatorStateInner to support
+/// future versions of the authenticator state.
+public struct AuthenticatorState has key {
+ id: UID,
+ version: u64,
+}
- #[allow(unused_field)]
- public struct ActiveJwk has store, drop, copy {
- jwk_id: JwkId,
- jwk: JWK,
- epoch: u64,
- }
+public struct AuthenticatorStateInner has store {
+ version: u64,
+ /// List of currently active JWKs.
+ active_jwks: vector,
+}
- #[test_only]
- public fun create_active_jwk(iss: String, kid: String, kty: String, epoch: u64): ActiveJwk {
- ActiveJwk {
- jwk_id: JwkId {
- iss: iss,
- kid: kid,
- },
- jwk: JWK {
- kty: kty,
- e: utf8(b"AQAB"),
- n: utf8(b"test"),
- alg: utf8(b"RS256"),
- },
- epoch,
- }
- }
+#[allow(unused_field)]
+/// Must match the JWK struct in fastcrypto-zkp
+public struct JWK has store, drop, copy {
+ kty: String,
+ e: String,
+ n: String,
+ alg: String,
+}
- fun active_jwk_equal(a: &ActiveJwk, b: &ActiveJwk): bool {
- // note: epoch is ignored
- jwk_equal(&a.jwk, &b.jwk) && jwk_id_equal(&a.jwk_id, &b.jwk_id)
+#[allow(unused_field)]
+/// Must match the JwkId struct in fastcrypto-zkp
+public struct JwkId has store, drop, copy {
+ iss: String,
+ kid: String,
+}
+
+#[allow(unused_field)]
+public struct ActiveJwk has store, drop, copy {
+ jwk_id: JwkId,
+ jwk: JWK,
+ epoch: u64,
+}
+
+#[test_only]
+public fun create_active_jwk(iss: String, kid: String, kty: String, epoch: u64): ActiveJwk {
+ ActiveJwk {
+ jwk_id: JwkId {
+ iss: iss,
+ kid: kid,
+ },
+ jwk: JWK {
+ kty: kty,
+ e: utf8(b"AQAB"),
+ n: utf8(b"test"),
+ alg: utf8(b"RS256"),
+ },
+ epoch,
}
+}
+
+fun active_jwk_equal(a: &ActiveJwk, b: &ActiveJwk): bool {
+ // note: epoch is ignored
+ jwk_equal(&a.jwk, &b.jwk) && jwk_id_equal(&a.jwk_id, &b.jwk_id)
+}
- fun jwk_equal(a: &JWK, b: &JWK): bool {
- (&a.kty == &b.kty) &&
+fun jwk_equal(a: &JWK, b: &JWK): bool {
+ (&a.kty == &b.kty) &&
(&a.e == &b.e) &&
(&a.n == &b.n) &&
(&a.alg == &b.alg)
- }
+}
- fun jwk_id_equal(a: &JwkId, b: &JwkId): bool {
- (&a.iss == &b.iss) && (&a.kid == &b.kid)
- }
+fun jwk_id_equal(a: &JwkId, b: &JwkId): bool {
+ (&a.iss == &b.iss) && (&a.kid == &b.kid)
+}
- // Compare the underlying byte arrays lexicographically. Since the strings may be utf8 this
- // ordering is not necessarily the same as the string ordering, but we just need some
- // canonical that is cheap to compute.
- fun string_bytes_lt(a: &String, b: &String): bool {
- let a_bytes = a.as_bytes();
- let b_bytes = b.as_bytes();
-
- if (a_bytes.length() < b_bytes.length()) {
- true
- } else if (a_bytes.length() > b_bytes.length()) {
- false
- } else {
- let mut i = 0;
- while (i < a_bytes.length()) {
- let a_byte = a_bytes[i];
- let b_byte = b_bytes[i];
- if (a_byte < b_byte) {
- return true
- } else if (a_byte > b_byte) {
- return false
- };
- i = i + 1;
+// Compare the underlying byte arrays lexicographically. Since the strings may be utf8 this
+// ordering is not necessarily the same as the string ordering, but we just need some
+// canonical that is cheap to compute.
+fun string_bytes_lt(a: &String, b: &String): bool {
+ let a_bytes = a.as_bytes();
+ let b_bytes = b.as_bytes();
+
+ if (a_bytes.length() < b_bytes.length()) {
+ true
+ } else if (a_bytes.length() > b_bytes.length()) {
+ false
+ } else {
+ let mut i = 0;
+ while (i < a_bytes.length()) {
+ let a_byte = a_bytes[i];
+ let b_byte = b_bytes[i];
+ if (a_byte < b_byte) {
+ return true
+ } else if (a_byte > b_byte) {
+ return false
};
- // all bytes are equal
- false
- }
- }
-
- fun jwk_lt(a: &ActiveJwk, b: &ActiveJwk): bool {
- // note: epoch is ignored
- if (&a.jwk_id.iss != &b.jwk_id.iss) {
- return string_bytes_lt(&a.jwk_id.iss, &b.jwk_id.iss)
- };
- if (&a.jwk_id.kid != &b.jwk_id.kid) {
- return string_bytes_lt(&a.jwk_id.kid, &b.jwk_id.kid)
- };
- if (&a.jwk.kty != &b.jwk.kty) {
- return string_bytes_lt(&a.jwk.kty, &b.jwk.kty)
- };
- if (&a.jwk.e != &b.jwk.e) {
- return string_bytes_lt(&a.jwk.e, &b.jwk.e)
- };
- if (&a.jwk.n != &b.jwk.n) {
- return string_bytes_lt(&a.jwk.n, &b.jwk.n)
+ i = i + 1;
};
- string_bytes_lt(&a.jwk.alg, &b.jwk.alg)
+ // all bytes are equal
+ false
}
+}
- #[allow(unused_function)]
- /// Create and share the AuthenticatorState object. This function is call exactly once, when
- /// the authenticator state object is first created.
- /// Can only be called by genesis or change_epoch transactions.
- fun create(ctx: &TxContext) {
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
+fun jwk_lt(a: &ActiveJwk, b: &ActiveJwk): bool {
+ // note: epoch is ignored
+ if (&a.jwk_id.iss != &b.jwk_id.iss) {
+ return string_bytes_lt(&a.jwk_id.iss, &b.jwk_id.iss)
+ };
+ if (&a.jwk_id.kid != &b.jwk_id.kid) {
+ return string_bytes_lt(&a.jwk_id.kid, &b.jwk_id.kid)
+ };
+ if (&a.jwk.kty != &b.jwk.kty) {
+ return string_bytes_lt(&a.jwk.kty, &b.jwk.kty)
+ };
+ if (&a.jwk.e != &b.jwk.e) {
+ return string_bytes_lt(&a.jwk.e, &b.jwk.e)
+ };
+ if (&a.jwk.n != &b.jwk.n) {
+ return string_bytes_lt(&a.jwk.n, &b.jwk.n)
+ };
+ string_bytes_lt(&a.jwk.alg, &b.jwk.alg)
+}
- let version = CurrentVersion;
+#[allow(unused_function)]
+/// Create and share the AuthenticatorState object. This function is call exactly once, when
+/// the authenticator state object is first created.
+/// Can only be called by genesis or change_epoch transactions.
+fun create(ctx: &TxContext) {
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
- let inner = AuthenticatorStateInner {
- version,
- active_jwks: vector[],
- };
+ let version = CurrentVersion;
- let mut self = AuthenticatorState {
- id: object::authenticator_state(),
- version,
- };
+ let inner = AuthenticatorStateInner {
+ version,
+ active_jwks: vector[],
+ };
- dynamic_field::add(&mut self.id, version, inner);
- transfer::share_object(self);
- }
+ let mut self = AuthenticatorState {
+ id: object::authenticator_state(),
+ version,
+ };
- fun load_inner_mut(
- self: &mut AuthenticatorState,
- ): &mut AuthenticatorStateInner {
- let version = self.version;
+ dynamic_field::add(&mut self.id, version, inner);
+ transfer::share_object(self);
+}
- // replace this with a lazy update function when we add a new version of the inner object.
- assert!(version == CurrentVersion, EWrongInnerVersion);
+fun load_inner_mut(self: &mut AuthenticatorState): &mut AuthenticatorStateInner {
+ let version = self.version;
- let inner: &mut AuthenticatorStateInner = dynamic_field::borrow_mut(&mut self.id, self.version);
+ // replace this with a lazy update function when we add a new version of the inner object.
+ assert!(version == CurrentVersion, EWrongInnerVersion);
- assert!(inner.version == version, EWrongInnerVersion);
- inner
- }
+ let inner: &mut AuthenticatorStateInner = dynamic_field::borrow_mut(&mut self.id, self.version);
- fun load_inner(
- self: &AuthenticatorState,
- ): &AuthenticatorStateInner {
- let version = self.version;
+ assert!(inner.version == version, EWrongInnerVersion);
+ inner
+}
- // replace this with a lazy update function when we add a new version of the inner object.
- assert!(version == CurrentVersion, EWrongInnerVersion);
+fun load_inner(self: &AuthenticatorState): &AuthenticatorStateInner {
+ let version = self.version;
- let inner: &AuthenticatorStateInner = dynamic_field::borrow(&self.id, self.version);
+ // replace this with a lazy update function when we add a new version of the inner object.
+ assert!(version == CurrentVersion, EWrongInnerVersion);
- assert!(inner.version == version, EWrongInnerVersion);
- inner
- }
+ let inner: &AuthenticatorStateInner = dynamic_field::borrow(&self.id, self.version);
- fun check_sorted(new_active_jwks: &vector) {
- let mut i = 0;
- while (i < new_active_jwks.length() - 1) {
- let a = &new_active_jwks[i];
- let b = &new_active_jwks[i + 1];
- assert!(jwk_lt(a, b), EJwksNotSorted);
- i = i + 1;
- };
- }
+ assert!(inner.version == version, EWrongInnerVersion);
+ inner
+}
- #[allow(unused_function)]
- /// Record a new set of active_jwks. Called when executing the AuthenticatorStateUpdate system
- /// transaction. The new input vector must be sorted and must not contain duplicates.
- /// If a new JWK is already present, but with a previous epoch, then the epoch is updated to
- /// indicate that the JWK has been validated in the current epoch and should not be expired.
- fun update_authenticator_state(
- self: &mut AuthenticatorState,
- new_active_jwks: vector,
- ctx: &TxContext,
- ) {
- // Validator will make a special system call with sender set as 0x0.
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
-
- check_sorted(&new_active_jwks);
- let new_active_jwks = deduplicate(new_active_jwks);
-
- let inner = self.load_inner_mut();
-
- let mut res = vector[];
- let mut i = 0;
- let mut j = 0;
- let active_jwks_len = inner.active_jwks.length();
- let new_active_jwks_len = new_active_jwks.length();
-
- while (i < active_jwks_len && j < new_active_jwks_len) {
- let old_jwk = &inner.active_jwks[i];
- let new_jwk = &new_active_jwks[j];
-
- // when they are equal, push only one, but use the max epoch of the two
- if (active_jwk_equal(old_jwk, new_jwk)) {
- let mut jwk = *old_jwk;
- jwk.epoch = old_jwk.epoch.max(new_jwk.epoch);
- res.push_back(jwk);
- i = i + 1;
- j = j + 1;
- } else if (jwk_id_equal(&old_jwk.jwk_id, &new_jwk.jwk_id)) {
- // if only jwk_id is equal, then the key has changed. Providers should not send
- // JWKs like this, but if they do, we must ignore the new JWK to avoid having a
- // liveness / forking issues
- res.push_back(*old_jwk);
- i = i + 1;
- j = j + 1;
- } else if (jwk_lt(old_jwk, new_jwk)) {
- res.push_back(*old_jwk);
- i = i + 1;
- } else {
- res.push_back(*new_jwk);
- j = j + 1;
- }
- };
+fun check_sorted(new_active_jwks: &vector) {
+ let mut i = 0;
+ while (i < new_active_jwks.length() - 1) {
+ let a = &new_active_jwks[i];
+ let b = &new_active_jwks[i + 1];
+ assert!(jwk_lt(a, b), EJwksNotSorted);
+ i = i + 1;
+ };
+}
- while (i < active_jwks_len) {
- res.push_back(inner.active_jwks[i]);
+#[allow(unused_function)]
+/// Record a new set of active_jwks. Called when executing the AuthenticatorStateUpdate system
+/// transaction. The new input vector must be sorted and must not contain duplicates.
+/// If a new JWK is already present, but with a previous epoch, then the epoch is updated to
+/// indicate that the JWK has been validated in the current epoch and should not be expired.
+fun update_authenticator_state(
+ self: &mut AuthenticatorState,
+ new_active_jwks: vector,
+ ctx: &TxContext,
+) {
+ // Validator will make a special system call with sender set as 0x0.
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
+
+ check_sorted(&new_active_jwks);
+ let new_active_jwks = deduplicate(new_active_jwks);
+
+ let inner = self.load_inner_mut();
+
+ let mut res = vector[];
+ let mut i = 0;
+ let mut j = 0;
+ let active_jwks_len = inner.active_jwks.length();
+ let new_active_jwks_len = new_active_jwks.length();
+
+ while (i < active_jwks_len && j < new_active_jwks_len) {
+ let old_jwk = &inner.active_jwks[i];
+ let new_jwk = &new_active_jwks[j];
+
+ // when they are equal, push only one, but use the max epoch of the two
+ if (active_jwk_equal(old_jwk, new_jwk)) {
+ let mut jwk = *old_jwk;
+ jwk.epoch = old_jwk.epoch.max(new_jwk.epoch);
+ res.push_back(jwk);
i = i + 1;
- };
- while (j < new_active_jwks_len) {
- res.push_back(new_active_jwks[j]);
j = j + 1;
- };
-
- inner.active_jwks = res;
- }
-
- fun deduplicate(jwks: vector): vector {
- let mut res = vector[];
- let mut i = 0;
- let mut prev: Option = option::none();
- while (i < jwks.length()) {
- let jwk = &jwks[i];
- if (prev.is_none()) {
- prev.fill(jwk.jwk_id);
- } else if (jwk_id_equal(prev.borrow(), &jwk.jwk_id)) {
- // skip duplicate jwks in input
- i = i + 1;
- continue
- } else {
- *prev.borrow_mut() = jwk.jwk_id;
- };
- res.push_back(*jwk);
+ } else if (jwk_id_equal(&old_jwk.jwk_id, &new_jwk.jwk_id)) {
+ // if only jwk_id is equal, then the key has changed. Providers should not send
+ // JWKs like this, but if they do, we must ignore the new JWK to avoid having a
+ // liveness / forking issues
+ res.push_back(*old_jwk);
i = i + 1;
- };
- res
- }
-
- #[allow(unused_function)]
- // Called directly by rust when constructing the ChangeEpoch transaction.
- fun expire_jwks(
- self: &mut AuthenticatorState,
- // any jwk below this epoch is not retained
- min_epoch: u64,
- ctx: &TxContext) {
- // This will only be called by sui_system::advance_epoch
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
-
- let inner = load_inner_mut(self);
-
- let len = inner.active_jwks.length();
-
- // first we count how many jwks from each issuer are above the min_epoch
- // and store the counts in a vector that parallels the (sorted) active_jwks vector
- let mut issuer_max_epochs = vector[];
- let mut i = 0;
- let mut prev_issuer: Option = option::none();
+ j = j + 1;
+ } else if (jwk_lt(old_jwk, new_jwk)) {
+ res.push_back(*old_jwk);
+ i = i + 1;
+ } else {
+ res.push_back(*new_jwk);
+ j = j + 1;
+ }
+ };
+
+ while (i < active_jwks_len) {
+ res.push_back(inner.active_jwks[i]);
+ i = i + 1;
+ };
+ while (j < new_active_jwks_len) {
+ res.push_back(new_active_jwks[j]);
+ j = j + 1;
+ };
+
+ inner.active_jwks = res;
+}
- while (i < len) {
- let cur = &inner.active_jwks[i];
- let cur_iss = &cur.jwk_id.iss;
- if (prev_issuer.is_none()) {
- prev_issuer.fill(*cur_iss);
- issuer_max_epochs.push_back(cur.epoch);
- } else {
- if (cur_iss == prev_issuer.borrow()) {
- let back = issuer_max_epochs.length() - 1;
- let prev_max_epoch = &mut issuer_max_epochs[back];
- *prev_max_epoch = (*prev_max_epoch).max(cur.epoch);
- } else {
- *prev_issuer.borrow_mut() = *cur_iss;
- issuer_max_epochs.push_back(cur.epoch);
- }
- };
+fun deduplicate(jwks: vector): vector {
+ let mut res = vector[];
+ let mut i = 0;
+ let mut prev: Option = option::none();
+ while (i < jwks.length()) {
+ let jwk = &jwks[i];
+ if (prev.is_none()) {
+ prev.fill(jwk.jwk_id);
+ } else if (jwk_id_equal(prev.borrow(), &jwk.jwk_id)) {
+ // skip duplicate jwks in input
i = i + 1;
+ continue
+ } else {
+ *prev.borrow_mut() = jwk.jwk_id;
};
+ res.push_back(*jwk);
+ i = i + 1;
+ };
+ res
+}
- // Now, filter out any JWKs that are below the min_epoch, unless that issuer has no
- // JWKs >= the min_epoch, in which case we keep all of them.
- let mut new_active_jwks: vector = vector[];
- let mut prev_issuer: Option = option::none();
- let mut i = 0;
- let mut j = 0;
- while (i < len) {
- let jwk = &inner.active_jwks[i];
- let cur_iss = &jwk.jwk_id.iss;
-
- if (prev_issuer.is_none()) {
- prev_issuer.fill(*cur_iss);
- } else if (cur_iss != prev_issuer.borrow()) {
+#[allow(unused_function)]
+// Called directly by rust when constructing the ChangeEpoch transaction.
+fun expire_jwks(
+ self: &mut AuthenticatorState,
+ // any jwk below this epoch is not retained
+ min_epoch: u64,
+ ctx: &TxContext,
+) {
+ // This will only be called by sui_system::advance_epoch
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
+
+ let inner = load_inner_mut(self);
+
+ let len = inner.active_jwks.length();
+
+ // first we count how many jwks from each issuer are above the min_epoch
+ // and store the counts in a vector that parallels the (sorted) active_jwks vector
+ let mut issuer_max_epochs = vector[];
+ let mut i = 0;
+ let mut prev_issuer: Option = option::none();
+
+ while (i < len) {
+ let cur = &inner.active_jwks[i];
+ let cur_iss = &cur.jwk_id.iss;
+ if (prev_issuer.is_none()) {
+ prev_issuer.fill(*cur_iss);
+ issuer_max_epochs.push_back(cur.epoch);
+ } else {
+ if (cur_iss == prev_issuer.borrow()) {
+ let back = issuer_max_epochs.length() - 1;
+ let prev_max_epoch = &mut issuer_max_epochs[back];
+ *prev_max_epoch = (*prev_max_epoch).max(cur.epoch);
+ } else {
*prev_issuer.borrow_mut() = *cur_iss;
- j = j + 1;
- };
+ issuer_max_epochs.push_back(cur.epoch);
+ }
+ };
+ i = i + 1;
+ };
+
+ // Now, filter out any JWKs that are below the min_epoch, unless that issuer has no
+ // JWKs >= the min_epoch, in which case we keep all of them.
+ let mut new_active_jwks: vector = vector[];
+ let mut prev_issuer: Option = option::none();
+ let mut i = 0;
+ let mut j = 0;
+ while (i < len) {
+ let jwk = &inner.active_jwks[i];
+ let cur_iss = &jwk.jwk_id.iss;
+
+ if (prev_issuer.is_none()) {
+ prev_issuer.fill(*cur_iss);
+ } else if (cur_iss != prev_issuer.borrow()) {
+ *prev_issuer.borrow_mut() = *cur_iss;
+ j = j + 1;
+ };
- let max_epoch_for_iss = &issuer_max_epochs[j];
+ let max_epoch_for_iss = &issuer_max_epochs[j];
- // TODO: if the iss for this jwk has *no* jwks that meet the minimum epoch,
- // then expire nothing.
- if (*max_epoch_for_iss < min_epoch || jwk.epoch >= min_epoch) {
- new_active_jwks.push_back(*jwk);
- };
- i = i + 1;
+ // TODO: if the iss for this jwk has *no* jwks that meet the minimum epoch,
+ // then expire nothing.
+ if (*max_epoch_for_iss < min_epoch || jwk.epoch >= min_epoch) {
+ new_active_jwks.push_back(*jwk);
};
- inner.active_jwks = new_active_jwks;
- }
+ i = i + 1;
+ };
+ inner.active_jwks = new_active_jwks;
+}
- #[allow(unused_function)]
- /// Get the current active_jwks. Called when the node starts up in order to load the current
- /// JWK state from the chain.
- fun get_active_jwks(
- self: &AuthenticatorState,
- ctx: &TxContext,
- ): vector {
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
- self.load_inner().active_jwks
- }
+#[allow(unused_function)]
+/// Get the current active_jwks. Called when the node starts up in order to load the current
+/// JWK state from the chain.
+fun get_active_jwks(self: &AuthenticatorState, ctx: &TxContext): vector {
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
+ self.load_inner().active_jwks
+}
- #[test_only]
- public fun create_for_testing(ctx: &TxContext) {
- create(ctx);
- }
+#[test_only]
+public fun create_for_testing(ctx: &TxContext) {
+ create(ctx);
+}
- #[test_only]
- public fun update_authenticator_state_for_testing(
- self: &mut AuthenticatorState,
- new_active_jwks: vector,
- ctx: &TxContext,
- ) {
- self.update_authenticator_state(new_active_jwks, ctx);
- }
+#[test_only]
+public fun update_authenticator_state_for_testing(
+ self: &mut AuthenticatorState,
+ new_active_jwks: vector,
+ ctx: &TxContext,
+) {
+ self.update_authenticator_state(new_active_jwks, ctx);
+}
- #[test_only]
- public fun expire_jwks_for_testing(
- self: &mut AuthenticatorState,
- min_epoch: u64,
- ctx: &TxContext,
- ) {
- self.expire_jwks(min_epoch, ctx);
- }
+#[test_only]
+public fun expire_jwks_for_testing(self: &mut AuthenticatorState, min_epoch: u64, ctx: &TxContext) {
+ self.expire_jwks(min_epoch, ctx);
+}
- #[test_only]
- public fun get_active_jwks_for_testing(
- self: &AuthenticatorState,
- ctx: &TxContext,
- ): vector {
- self.get_active_jwks(ctx)
- }
+#[test_only]
+public fun get_active_jwks_for_testing(
+ self: &AuthenticatorState,
+ ctx: &TxContext,
+): vector {
+ self.get_active_jwks(ctx)
}
diff --git a/crates/sui-framework/packages/sui-framework/sources/bcs.move b/crates/sui-framework/packages/sui-framework/sources/bcs.move
index 66ecb2b2e6b40..83f69cdc0c554 100644
--- a/crates/sui-framework/packages/sui-framework/sources/bcs.move
+++ b/crates/sui-framework/packages/sui-framework/sources/bcs.move
@@ -32,237 +32,237 @@
/// (u8_value, u64_value, leftovers)
/// }
/// ```
-module sui::bcs {
- use sui::address;
- use std::bcs;
-
- /// For when bytes length is less than required for deserialization.
- const EOutOfRange: u64 = 0;
- /// For when the boolean value different than `0` or `1`.
- const ENotBool: u64 = 1;
- /// For when ULEB byte is out of range (or not found).
- const ELenOutOfRange: u64 = 2;
-
- /// A helper struct that saves resources on operations. For better
- /// vector performance, it stores reversed bytes of the BCS and
- /// enables use of `vector::pop_back`.
- public struct BCS has store, copy, drop {
- bytes: vector
- }
-
- /// Get BCS serialized bytes for any value.
- /// Re-exports stdlib `bcs::to_bytes`.
- public fun to_bytes(value: &T): vector {
- bcs::to_bytes(value)
- }
-
- /// Creates a new instance of BCS wrapper that holds inversed
- /// bytes for better performance.
- public fun new(mut bytes: vector): BCS {
- bytes.reverse();
- BCS { bytes }
- }
-
- /// Unpack the `BCS` struct returning the leftover bytes.
- /// Useful for passing the data further after partial deserialization.
- public fun into_remainder_bytes(bcs: BCS): vector {
- let BCS { mut bytes } = bcs;
- bytes.reverse();
- bytes
- }
-
- /// Read address from the bcs-serialized bytes.
- public fun peel_address(bcs: &mut BCS): address {
- assert!(bcs.bytes.length() >= address::length(), EOutOfRange);
- let (mut addr_bytes, mut i) = (vector[], 0);
- while (i < address::length()) {
- addr_bytes.push_back(bcs.bytes.pop_back());
- i = i + 1;
- };
- address::from_bytes(addr_bytes)
- }
-
- /// Read a `bool` value from bcs-serialized bytes.
- public fun peel_bool(bcs: &mut BCS): bool {
- let value = bcs.peel_u8();
- if (value == 0) false
- else if (value == 1) true
- else abort ENotBool
- }
-
- /// Read `u8` value from bcs-serialized bytes.
- public fun peel_u8(bcs: &mut BCS): u8 {
- assert!(bcs.bytes.length() >= 1, EOutOfRange);
- bcs.bytes.pop_back()
- }
-
- macro fun peel_num<$I, $T>($bcs: &mut BCS, $len: u64, $bits: $I): $T {
- let bcs = $bcs;
- assert!(bcs.bytes.length() >= $len, EOutOfRange);
-
- let mut value: $T = 0;
- let mut i: $I = 0;
- let bits = $bits;
- while (i < bits) {
- let byte = bcs.bytes.pop_back() as $T;
- value = value + (byte << (i as u8));
- i = i + 8;
- };
-
- value
- }
-
- /// Read `u16` value from bcs-serialized bytes.
- public fun peel_u16(bcs: &mut BCS): u16 {
- bcs.peel_num!(2, 16u8)
- }
-
- /// Read `u32` value from bcs-serialized bytes.
- public fun peel_u32(bcs: &mut BCS): u32 {
- bcs.peel_num!(4, 32u8)
- }
-
- /// Read `u64` value from bcs-serialized bytes.
- public fun peel_u64(bcs: &mut BCS): u64 {
- bcs.peel_num!(8, 64u8)
- }
-
- /// Read `u128` value from bcs-serialized bytes.
- public fun peel_u128(bcs: &mut BCS): u128 {
- bcs.peel_num!(16, 128u8)
- }
-
- /// Read `u256` value from bcs-serialized bytes.
- public fun peel_u256(bcs: &mut BCS): u256 {
- bcs.peel_num!(32, 256u16)
- }
-
- // === Vector ===
-
- /// Read ULEB bytes expecting a vector length. Result should
- /// then be used to perform `peel_*` operation LEN times.
- ///
- /// In BCS `vector` length is implemented with ULEB128;
- /// See more here: https://en.wikipedia.org/wiki/LEB128
- public fun peel_vec_length(bcs: &mut BCS): u64 {
- let (mut total, mut shift, mut len) = (0u64, 0, 0);
- loop {
- assert!(len <= 4, ELenOutOfRange);
- let byte = bcs.bytes.pop_back() as u64;
- len = len + 1;
- total = total | ((byte & 0x7f) << shift);
- if ((byte & 0x80) == 0) break;
- shift = shift + 7;
- };
- total
- }
-
- /// Peel `vector<$T>` from serialized bytes, where `$peel: |&mut BCS| -> $T` gives the
- /// functionality of peeling each value.
- public macro fun peel_vec<$T>($bcs: &mut BCS, $peel: |&mut BCS| -> $T): vector<$T> {
- let bcs = $bcs;
- let len = bcs.peel_vec_length();
- let mut i = 0;
- let mut res = vector[];
- while (i < len) {
- res.push_back($peel(bcs));
- i = i + 1;
- };
- res
- }
-
- /// Peel a vector of `address` from serialized bytes.
- public fun peel_vec_address(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_address())
- }
-
- /// Peel a vector of `address` from serialized bytes.
- public fun peel_vec_bool(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_bool())
- }
-
- /// Peel a vector of `u8` (eg string) from serialized bytes.
- public fun peel_vec_u8(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u8())
- }
-
- /// Peel a `vector>` (eg vec of string) from serialized bytes.
- public fun peel_vec_vec_u8(bcs: &mut BCS): vector> {
- bcs.peel_vec!(|bcs| bcs.peel_vec_u8())
- }
-
- /// Peel a vector of `u16` from serialized bytes.
- public fun peel_vec_u16(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u16())
- }
-
- /// Peel a vector of `u32` from serialized bytes.
- public fun peel_vec_u32(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u32())
- }
-
- /// Peel a vector of `u64` from serialized bytes.
- public fun peel_vec_u64(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u64())
- }
-
- /// Peel a vector of `u128` from serialized bytes.
- public fun peel_vec_u128(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u128())
- }
-
- /// Peel a vector of `u256` from serialized bytes.
- public fun peel_vec_u256(bcs: &mut BCS): vector {
- bcs.peel_vec!(|bcs| bcs.peel_u256())
- }
-
- // === Option ===
-
- /// Peel `Option<$T>` from serialized bytes, where `$peel: |&mut BCS| -> $T` gives the
- /// functionality of peeling the inner value.
- public macro fun peel_option<$T>($bcs: &mut BCS, $peel: |&mut BCS| -> $T): Option<$T> {
- let bcs = $bcs;
- if (bcs.peel_bool())option::some($peel(bcs))
- else option::none()
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_address(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_address())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_bool(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_bool())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u8(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u8())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u16(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u16())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u32(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u32())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u64(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u64())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u128(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u128())
- }
-
- /// Peel `Option` from serialized bytes.
- public fun peel_option_u256(bcs: &mut BCS): Option {
- bcs.peel_option!(|bcs| bcs.peel_u256())
- }
+module sui::bcs;
+
+use std::bcs;
+use sui::address;
+
+/// For when bytes length is less than required for deserialization.
+const EOutOfRange: u64 = 0;
+/// For when the boolean value different than `0` or `1`.
+const ENotBool: u64 = 1;
+/// For when ULEB byte is out of range (or not found).
+const ELenOutOfRange: u64 = 2;
+
+/// A helper struct that saves resources on operations. For better
+/// vector performance, it stores reversed bytes of the BCS and
+/// enables use of `vector::pop_back`.
+public struct BCS has store, copy, drop {
+ bytes: vector,
+}
+
+/// Get BCS serialized bytes for any value.
+/// Re-exports stdlib `bcs::to_bytes`.
+public fun to_bytes(value: &T): vector {
+ bcs::to_bytes(value)
+}
+
+/// Creates a new instance of BCS wrapper that holds inversed
+/// bytes for better performance.
+public fun new(mut bytes: vector): BCS {
+ bytes.reverse();
+ BCS { bytes }
+}
+
+/// Unpack the `BCS` struct returning the leftover bytes.
+/// Useful for passing the data further after partial deserialization.
+public fun into_remainder_bytes(bcs: BCS): vector {
+ let BCS { mut bytes } = bcs;
+ bytes.reverse();
+ bytes
+}
+
+/// Read address from the bcs-serialized bytes.
+public fun peel_address(bcs: &mut BCS): address {
+ assert!(bcs.bytes.length() >= address::length(), EOutOfRange);
+ let (mut addr_bytes, mut i) = (vector[], 0);
+ while (i < address::length()) {
+ addr_bytes.push_back(bcs.bytes.pop_back());
+ i = i + 1;
+ };
+ address::from_bytes(addr_bytes)
+}
+
+/// Read a `bool` value from bcs-serialized bytes.
+public fun peel_bool(bcs: &mut BCS): bool {
+ let value = bcs.peel_u8();
+ if (value == 0) false
+ else if (value == 1) true
+ else abort ENotBool
+}
+
+/// Read `u8` value from bcs-serialized bytes.
+public fun peel_u8(bcs: &mut BCS): u8 {
+ assert!(bcs.bytes.length() >= 1, EOutOfRange);
+ bcs.bytes.pop_back()
+}
+
+macro fun peel_num<$I, $T>($bcs: &mut BCS, $len: u64, $bits: $I): $T {
+ let bcs = $bcs;
+ assert!(bcs.bytes.length() >= $len, EOutOfRange);
+
+ let mut value: $T = 0;
+ let mut i: $I = 0;
+ let bits = $bits;
+ while (i < bits) {
+ let byte = bcs.bytes.pop_back() as $T;
+ value = value + (byte << (i as u8));
+ i = i + 8;
+ };
+
+ value
+}
+
+/// Read `u16` value from bcs-serialized bytes.
+public fun peel_u16(bcs: &mut BCS): u16 {
+ bcs.peel_num!(2, 16u8)
+}
+
+/// Read `u32` value from bcs-serialized bytes.
+public fun peel_u32(bcs: &mut BCS): u32 {
+ bcs.peel_num!(4, 32u8)
+}
+
+/// Read `u64` value from bcs-serialized bytes.
+public fun peel_u64(bcs: &mut BCS): u64 {
+ bcs.peel_num!(8, 64u8)
+}
+
+/// Read `u128` value from bcs-serialized bytes.
+public fun peel_u128(bcs: &mut BCS): u128 {
+ bcs.peel_num!(16, 128u8)
+}
+
+/// Read `u256` value from bcs-serialized bytes.
+public fun peel_u256(bcs: &mut BCS): u256 {
+ bcs.peel_num!(32, 256u16)
+}
+
+// === Vector ===
+
+/// Read ULEB bytes expecting a vector length. Result should
+/// then be used to perform `peel_*` operation LEN times.
+///
+/// In BCS `vector` length is implemented with ULEB128;
+/// See more here: https://en.wikipedia.org/wiki/LEB128
+public fun peel_vec_length(bcs: &mut BCS): u64 {
+ let (mut total, mut shift, mut len) = (0u64, 0, 0);
+ loop {
+ assert!(len <= 4, ELenOutOfRange);
+ let byte = bcs.bytes.pop_back() as u64;
+ len = len + 1;
+ total = total | ((byte & 0x7f) << shift);
+ if ((byte & 0x80) == 0) break;
+ shift = shift + 7;
+ };
+ total
+}
+
+/// Peel `vector<$T>` from serialized bytes, where `$peel: |&mut BCS| -> $T` gives the
+/// functionality of peeling each value.
+public macro fun peel_vec<$T>($bcs: &mut BCS, $peel: |&mut BCS| -> $T): vector<$T> {
+ let bcs = $bcs;
+ let len = bcs.peel_vec_length();
+ let mut i = 0;
+ let mut res = vector[];
+ while (i < len) {
+ res.push_back($peel(bcs));
+ i = i + 1;
+ };
+ res
+}
+
+/// Peel a vector of `address` from serialized bytes.
+public fun peel_vec_address(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_address())
+}
+
+/// Peel a vector of `address` from serialized bytes.
+public fun peel_vec_bool(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_bool())
+}
+
+/// Peel a vector of `u8` (eg string) from serialized bytes.
+public fun peel_vec_u8(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u8())
+}
+
+/// Peel a `vector>` (eg vec of string) from serialized bytes.
+public fun peel_vec_vec_u8(bcs: &mut BCS): vector> {
+ bcs.peel_vec!(|bcs| bcs.peel_vec_u8())
+}
+
+/// Peel a vector of `u16` from serialized bytes.
+public fun peel_vec_u16(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u16())
+}
+
+/// Peel a vector of `u32` from serialized bytes.
+public fun peel_vec_u32(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u32())
+}
+
+/// Peel a vector of `u64` from serialized bytes.
+public fun peel_vec_u64(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u64())
+}
+
+/// Peel a vector of `u128` from serialized bytes.
+public fun peel_vec_u128(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u128())
+}
+
+/// Peel a vector of `u256` from serialized bytes.
+public fun peel_vec_u256(bcs: &mut BCS): vector {
+ bcs.peel_vec!(|bcs| bcs.peel_u256())
+}
+
+// === Option ===
+
+/// Peel `Option<$T>` from serialized bytes, where `$peel: |&mut BCS| -> $T` gives the
+/// functionality of peeling the inner value.
+public macro fun peel_option<$T>($bcs: &mut BCS, $peel: |&mut BCS| -> $T): Option<$T> {
+ let bcs = $bcs;
+ if (bcs.peel_bool()) option::some($peel(bcs))
+ else option::none()
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_address(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_address())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_bool(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_bool())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u8(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u8())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u16(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u16())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u32(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u32())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u64(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u64())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u128(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u128())
+}
+
+/// Peel `Option` from serialized bytes.
+public fun peel_option_u256(bcs: &mut BCS): Option {
+ bcs.peel_option!(|bcs| bcs.peel_u256())
}
diff --git a/crates/sui-framework/packages/sui-framework/sources/borrow.move b/crates/sui-framework/packages/sui-framework/sources/borrow.move
index 55eb1e1ae5bd3..483a6aab4912a 100644
--- a/crates/sui-framework/packages/sui-framework/sources/borrow.move
+++ b/crates/sui-framework/packages/sui-framework/sources/borrow.move
@@ -6,113 +6,115 @@
/// With Programmable transactions, it is possible to borrow a value within
/// a transaction, use it and put back in the end. Hot-potato `Borrow` makes
/// sure the object is returned and was not swapped for another one.
-module sui::borrow {
+module sui::borrow;
- /// The `Borrow` does not match the `Referent`.
- const EWrongBorrow: u64 = 0;
- /// An attempt to swap the `Referent.value` with another object of the same type.
- const EWrongValue: u64 = 1;
+/// The `Borrow` does not match the `Referent`.
+const EWrongBorrow: u64 = 0;
+/// An attempt to swap the `Referent.value` with another object of the same type.
+const EWrongValue: u64 = 1;
- /// An object wrapping a `T` and providing the borrow API.
- public struct Referent has store {
- id: address,
- value: Option
- }
+/// An object wrapping a `T` and providing the borrow API.
+public struct Referent has store {
+ id: address,
+ value: Option,
+}
- /// A hot potato making sure the object is put back once borrowed.
- public struct Borrow { ref: address, obj: ID }
+/// A hot potato making sure the object is put back once borrowed.
+public struct Borrow { ref: address, obj: ID }
- /// Create a new `Referent` struct
- public fun new(value: T, ctx: &mut TxContext): Referent {
- Referent {
- id: tx_context::fresh_object_address(ctx),
- value: option::some(value)
- }
+/// Create a new `Referent` struct
+public fun new(value: T, ctx: &mut TxContext): Referent {
+ Referent {
+ id: tx_context::fresh_object_address(ctx),
+ value: option::some(value),
}
+}
- /// Borrow the `T` from the `Referent` receiving the `T` and a `Borrow`
- /// hot potato.
- public fun borrow(self: &mut Referent): (T, Borrow) {
- let value = self.value.extract();
- let id = object::id(&value);
+/// Borrow the `T` from the `Referent` receiving the `T` and a `Borrow`
+/// hot potato.
+public fun borrow(self: &mut Referent): (T, Borrow) {
+ let value = self.value.extract();
+ let id = object::id(&value);
- (value, Borrow {
+ (
+ value,
+ Borrow {
ref: self.id,
- obj: id
- })
- }
+ obj: id,
+ },
+ )
+}
- /// Put an object and the `Borrow` hot potato back.
- public fun put_back(self: &mut Referent, value: T, borrow: Borrow) {
- let Borrow { ref, obj } = borrow;
+/// Put an object and the `Borrow` hot potato back.
+public fun put_back(self: &mut Referent, value: T, borrow: Borrow) {
+ let Borrow { ref, obj } = borrow;
- assert!(object::id(&value) == obj, EWrongValue);
- assert!(self.id == ref, EWrongBorrow);
- self.value.fill(value);
- }
+ assert!(object::id(&value) == obj, EWrongValue);
+ assert!(self.id == ref, EWrongBorrow);
+ self.value.fill(value);
+}
- /// Unpack the `Referent` struct and return the value.
- public fun destroy(self: Referent): T {
- let Referent { id: _, value } = self;
- value.destroy_some()
- }
+/// Unpack the `Referent` struct and return the value.
+public fun destroy(self: Referent): T {
+ let Referent { id: _, value } = self;
+ value.destroy_some()
+}
- #[test_only]
- public struct Test has key, store {
- id: object::UID
- }
+#[test_only]
+public struct Test has key, store {
+ id: object::UID,
+}
- #[test]
- fun test_borrow() {
- let ctx = &mut sui::tx_context::dummy();
- let mut ref = new(Test { id: object::new(ctx) }, ctx);
+#[test]
+fun test_borrow() {
+ let ctx = &mut sui::tx_context::dummy();
+ let mut ref = new(Test { id: object::new(ctx) }, ctx);
- let (value, borrow) = borrow(&mut ref);
- put_back(&mut ref, value, borrow);
+ let (value, borrow) = borrow(&mut ref);
+ put_back(&mut ref, value, borrow);
- let Test { id } = destroy(ref);
- id.delete();
- }
+ let Test { id } = destroy(ref);
+ id.delete();
+}
- #[test]
- #[expected_failure(abort_code = EWrongValue)]
- /// The `value` is swapped with another instance of the type `T`.
- fun test_object_swap() {
- let ctx = &mut sui::tx_context::dummy();
- let mut ref_1 = new(Test { id: object::new(ctx) }, ctx);
- let mut ref_2 = new(Test { id: object::new(ctx) }, ctx);
+#[test]
+#[expected_failure(abort_code = EWrongValue)]
+/// The `value` is swapped with another instance of the type `T`.
+fun test_object_swap() {
+ let ctx = &mut sui::tx_context::dummy();
+ let mut ref_1 = new(Test { id: object::new(ctx) }, ctx);
+ let mut ref_2 = new(Test { id: object::new(ctx) }, ctx);
- let (v_1, b_1) = borrow(&mut ref_1);
- let (v_2, b_2) = borrow(&mut ref_2);
+ let (v_1, b_1) = borrow(&mut ref_1);
+ let (v_2, b_2) = borrow(&mut ref_2);
- put_back(&mut ref_1, v_2, b_1);
- put_back(&mut ref_2, v_1, b_2);
+ put_back(&mut ref_1, v_2, b_1);
+ put_back(&mut ref_2, v_1, b_2);
- let Test { id } = destroy(ref_1);
- id.delete();
+ let Test { id } = destroy(ref_1);
+ id.delete();
- let Test { id } = destroy(ref_2);
- id.delete();
- }
+ let Test { id } = destroy(ref_2);
+ id.delete();
+}
- #[test]
- #[expected_failure(abort_code = EWrongBorrow)]
- /// The both `borrow` and `value` are swapped with another `Referent`.
- fun test_borrow_fail() {
- let ctx = &mut sui::tx_context::dummy();
- let mut ref_1 = new(Test { id: object::new(ctx) }, ctx);
- let mut ref_2 = new(Test { id: object::new(ctx) }, ctx);
+#[test]
+#[expected_failure(abort_code = EWrongBorrow)]
+/// The both `borrow` and `value` are swapped with another `Referent`.
+fun test_borrow_fail() {
+ let ctx = &mut sui::tx_context::dummy();
+ let mut ref_1 = new(Test { id: object::new(ctx) }, ctx);
+ let mut ref_2 = new(Test { id: object::new(ctx) }, ctx);
- let (v_1, b_1) = borrow(&mut ref_1);
- let (v_2, b_2) = borrow(&mut ref_2);
+ let (v_1, b_1) = borrow(&mut ref_1);
+ let (v_2, b_2) = borrow(&mut ref_2);
- put_back(&mut ref_1, v_2, b_2);
- put_back(&mut ref_2, v_1, b_1);
+ put_back(&mut ref_1, v_2, b_2);
+ put_back(&mut ref_2, v_1, b_1);
- let Test { id } = destroy(ref_1);
- id.delete();
+ let Test { id } = destroy(ref_1);
+ id.delete();
- let Test { id } = destroy(ref_2);
- id.delete();
- }
+ let Test { id } = destroy(ref_2);
+ id.delete();
}
diff --git a/crates/sui-framework/packages/sui-framework/sources/clock.move b/crates/sui-framework/packages/sui-framework/sources/clock.move
index 9cfa08c9c6872..11b72322248a1 100644
--- a/crates/sui-framework/packages/sui-framework/sources/clock.move
+++ b/crates/sui-framework/packages/sui-framework/sources/clock.move
@@ -3,91 +3,86 @@
/// APIs for accessing time from move calls, via the `Clock`: a unique
/// shared object that is created at 0x6 during genesis.
-module sui::clock {
+module sui::clock;
- /// Sender is not @0x0 the system address.
- const ENotSystemAddress: u64 = 0;
+/// Sender is not @0x0 the system address.
+const ENotSystemAddress: u64 = 0;
- /// Singleton shared object that exposes time to Move calls. This
- /// object is found at address 0x6, and can only be read (accessed
- /// via an immutable reference) by entry functions.
- ///
- /// Entry Functions that attempt to accept `Clock` by mutable
- /// reference or value will fail to verify, and honest validators
- /// will not sign or execute transactions that use `Clock` as an
- /// input parameter, unless it is passed by immutable reference.
- public struct Clock has key {
- id: UID,
- /// The clock's timestamp, which is set automatically by a
- /// system transaction every time consensus commits a
- /// schedule, or by `sui::clock::increment_for_testing` during
- /// testing.
- timestamp_ms: u64,
- }
+/// Singleton shared object that exposes time to Move calls. This
+/// object is found at address 0x6, and can only be read (accessed
+/// via an immutable reference) by entry functions.
+///
+/// Entry Functions that attempt to accept `Clock` by mutable
+/// reference or value will fail to verify, and honest validators
+/// will not sign or execute transactions that use `Clock` as an
+/// input parameter, unless it is passed by immutable reference.
+public struct Clock has key {
+ id: UID,
+ /// The clock's timestamp, which is set automatically by a
+ /// system transaction every time consensus commits a
+ /// schedule, or by `sui::clock::increment_for_testing` during
+ /// testing.
+ timestamp_ms: u64,
+}
- /// The `clock`'s current timestamp as a running total of
- /// milliseconds since an arbitrary point in the past.
- public fun timestamp_ms(clock: &Clock): u64 {
- clock.timestamp_ms
- }
+/// The `clock`'s current timestamp as a running total of
+/// milliseconds since an arbitrary point in the past.
+public fun timestamp_ms(clock: &Clock): u64 {
+ clock.timestamp_ms
+}
- #[allow(unused_function)]
- /// Create and share the singleton Clock -- this function is
- /// called exactly once, during genesis.
- fun create(ctx: &TxContext) {
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
+#[allow(unused_function)]
+/// Create and share the singleton Clock -- this function is
+/// called exactly once, during genesis.
+fun create(ctx: &TxContext) {
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
- transfer::share_object(Clock {
- id: object::clock(),
- // Initialised to zero, but set to a real timestamp by a
- // system transaction before it can be witnessed by a move
- // call.
- timestamp_ms: 0,
- })
- }
+ transfer::share_object(Clock {
+ id: object::clock(),
+ // Initialised to zero, but set to a real timestamp by a
+ // system transaction before it can be witnessed by a move
+ // call.
+ timestamp_ms: 0,
+ })
+}
- #[allow(unused_function)]
- fun consensus_commit_prologue(
- clock: &mut Clock,
- timestamp_ms: u64,
- ctx: &TxContext,
- ) {
- // Validator will make a special system call with sender set as 0x0.
- assert!(ctx.sender() == @0x0, ENotSystemAddress);
+#[allow(unused_function)]
+fun consensus_commit_prologue(clock: &mut Clock, timestamp_ms: u64, ctx: &TxContext) {
+ // Validator will make a special system call with sender set as 0x0.
+ assert!(ctx.sender() == @0x0, ENotSystemAddress);
- clock.timestamp_ms = timestamp_ms
- }
+ clock.timestamp_ms = timestamp_ms
+}
- #[test_only]
- /// Expose the functionality of `create()` (usually only done during
- /// genesis) for tests that want to create a Clock.
- public fun create_for_testing(ctx: &mut TxContext): Clock {
- Clock {
- id: object::new(ctx),
- timestamp_ms: 0,
- }
+#[test_only]
+/// Expose the functionality of `create()` (usually only done during
+/// genesis) for tests that want to create a Clock.
+public fun create_for_testing(ctx: &mut TxContext): Clock {
+ Clock {
+ id: object::new(ctx),
+ timestamp_ms: 0,
}
+}
- #[test_only]
- /// For transactional tests (if a Clock is used as a shared object).
- public fun share_for_testing(clock: Clock) {
- transfer::share_object(clock)
- }
+#[test_only]
+/// For transactional tests (if a Clock is used as a shared object).
+public fun share_for_testing(clock: Clock) {
+ transfer::share_object(clock)
+}
- #[test_only]
- public fun increment_for_testing(clock: &mut Clock, tick: u64) {
- clock.timestamp_ms = clock.timestamp_ms + tick;
- }
+#[test_only]
+public fun increment_for_testing(clock: &mut Clock, tick: u64) {
+ clock.timestamp_ms = clock.timestamp_ms + tick;
+}
- #[test_only]
- public fun set_for_testing(clock: &mut Clock, timestamp_ms: u64) {
- assert!(timestamp_ms >= clock.timestamp_ms);
- clock.timestamp_ms = timestamp_ms;
- }
+#[test_only]
+public fun set_for_testing(clock: &mut Clock, timestamp_ms: u64) {
+ assert!(timestamp_ms >= clock.timestamp_ms);
+ clock.timestamp_ms = timestamp_ms;
+}
- #[test_only]
- public fun destroy_for_testing(clock: Clock) {
- let Clock { id, timestamp_ms: _ } = clock;
- id.delete();
- }
+#[test_only]
+public fun destroy_for_testing(clock: Clock) {
+ let Clock { id, timestamp_ms: _ } = clock;
+ id.delete();
}
diff --git a/crates/sui-framework/packages/sui-framework/sources/display.move b/crates/sui-framework/packages/sui-framework/sources/display.move
index ef590aba27b40..b09e4802600d6 100644
--- a/crates/sui-framework/packages/sui-framework/sources/display.move
+++ b/crates/sui-framework/packages/sui-framework/sources/display.move
@@ -10,218 +10,184 @@
/// substitution and filling-in the pieces using the data from the object T.
///
/// More entry functions might be added in the future depending on the use cases.
-module sui::display {
- use sui::package::Publisher;
- use sui::vec_map::{Self, VecMap};
- use sui::event;
- use std::string::String;
-
- /// For when T does not belong to the package `Publisher`.
- const ENotOwner: u64 = 0;
-
- /// For when vectors passed into one of the multiple insert functions
- /// don't match in their lengths.
- const EVecLengthMismatch: u64 = 1;
-
- /// The Display object. Defines the way a T instance should be
- /// displayed. Display object can only be created and modified with
- /// a PublisherCap, making sure that the rules are set by the owner
- /// of the type.
- ///
- /// Each of the display properties should support patterns outside
- /// of the system, making it simpler to customize Display based
- /// on the property values of an Object.
- /// ```
- /// // Example of a display object
- /// Display<0x...::capy::Capy> {
- /// fields:
- ///
- ///
- ///
- ///
- /// }
- /// ```
- ///
- /// Uses only String type due to external-facing nature of the object,
- /// the property names have a priority over their types.
- public struct Display has key, store {
- id: UID,
- /// Contains fields for display. Currently supported
- /// fields are: name, link, image and description.
- fields: VecMap,
- /// Version that can only be updated manually by the Publisher.
- version: u16
- }
-
- /// Event: emitted when a new Display object has been created for type T.
- /// Type signature of the event corresponds to the type while id serves for
- /// the discovery.
- ///
- /// Since Sui RPC supports querying events by type, finding a Display for the T
- /// would be as simple as looking for the first event with `Display`.
- public struct DisplayCreated has copy, drop {
- id: ID
- }
-
- /// Version of Display got updated -
- public struct VersionUpdated has copy, drop {
- id: ID,
- version: u16,
- fields: VecMap,
- }
+module sui::display;
- // === Initializer Methods ===
+use std::string::String;
+use sui::event;
+use sui::package::Publisher;
+use sui::vec_map::{Self, VecMap};
- /// Create an empty Display object. It can either be shared empty or filled
- /// with data right away via cheaper `set_owned` method.
- public fun new(pub: &Publisher, ctx: &mut TxContext): Display {
- assert!(is_authorized(pub), ENotOwner);
- create_internal(ctx)
- }
-
- /// Create a new Display object with a set of fields.
- public fun new_with_fields(
- pub: &Publisher, fields: vector, values: vector, ctx: &mut TxContext
- ): Display {
- let len = fields.length();
- assert!(len == values.length(), EVecLengthMismatch);
-
- let mut i = 0;
- let mut display = new(pub, ctx);
- while (i < len) {
- display.add_internal(fields[i], values[i]);
- i = i + 1;
- };
-
- display
- }
+/// For when T does not belong to the package `Publisher`.
+const ENotOwner: u64 = 0;
- // === Entry functions: Create ===
+/// For when vectors passed into one of the multiple insert functions
+/// don't match in their lengths.
+const EVecLengthMismatch: u64 = 1;
- #[allow(lint(self_transfer))]
- /// Create a new empty Display object and keep it.
- entry public fun create_and_keep(pub: &Publisher, ctx: &mut TxContext) {
- transfer::public_transfer(new(pub, ctx), ctx.sender())
- }
+/// The Display object. Defines the way a T instance should be
+/// displayed. Display object can only be created and modified with
+/// a PublisherCap, making sure that the rules are set by the owner
+/// of the type.
+///
+/// Each of the display properties should support patterns outside
+/// of the system, making it simpler to customize Display based
+/// on the property values of an Object.
+/// ```
+/// // Example of a display object
+/// Display<0x...::capy::Capy> {
+/// fields:
+///
+///
+///
+///
+/// }
+/// ```
+///
+/// Uses only String type due to external-facing nature of the object,
+/// the property names have a priority over their types.
+public struct Display has key, store {
+ id: UID,
+ /// Contains fields for display. Currently supported
+ /// fields are: name, link, image and description.
+ fields: VecMap,
+ /// Version that can only be updated manually by the Publisher.
+ version: u16,
+}
- /// Manually bump the version and emit an event with the updated version's contents.
- entry public fun update_version(
- display: &mut Display
- ) {
- display.version = display.version + 1;
- event::emit(VersionUpdated {
- version: display.version,
- fields: *&display.fields,
- id: display.id.to_inner(),
- })
- }
+/// Event: emitted when a new Display object has been created for type T.
+/// Type signature of the event corresponds to the type while id serves for
+/// the discovery.
+///
+/// Since Sui RPC supports querying events by type, finding a Display for the T
+/// would be as simple as looking for the first event with `Display`.
+public struct DisplayCreated has copy, drop {
+ id: ID,
+}
- // === Entry functions: Add/Modify fields ===
+/// Version of Display got updated -
+public struct VersionUpdated has copy, drop {
+ id: ID,
+ version: u16,
+ fields: VecMap,
+}
- /// Sets a custom `name` field with the `value`.
- entry public fun add(self: &mut Display, name: String, value: String) {
- self.add_internal(name, value)
- }
+// === Initializer Methods ===
- /// Sets multiple `fields` with `values`.
- entry public fun add_multiple(
- self: &mut Display, fields: vector, values: vector
- ) {
- let len = fields.length();
- assert!(len == values.length(), EVecLengthMismatch);
-
- let mut i = 0;
- while (i < len) {
- self.add_internal(fields[i], values[i]);
- i = i + 1;
- };
- }
+/// Create an empty Display object. It can either be shared empty or filled
+/// with data right away via cheaper `set_owned` method.
+public fun new(pub: &Publisher, ctx: &mut TxContext): Display {
+ assert!(is_authorized(pub), ENotOwner);
+ create_internal(ctx)
+}
- /// Change the value of the field.
- /// TODO (long run): version changes;
- entry public fun edit(self: &mut Display, name: String, value: String) {
- let (_, _) = self.fields.remove(&name);
- self.add_internal(name, value)
- }
+/// Create a new Display object with a set of fields.
+public fun new_with_fields(
+ pub: &Publisher,
+ fields: vector,
+ values: vector,
+ ctx: &mut TxContext,
+): Display {
+ let len = fields.length();
+ assert!(len == values.length(), EVecLengthMismatch);
+
+ let mut i = 0;
+ let mut display = new(pub, ctx);
+ while (i < len) {
+ display.add_internal(fields[i], values[i]);
+ i = i + 1;
+ };
+
+ display
+}
- /// Remove the key from the Display.
- entry public fun remove(self: &mut Display, name: String) {
- self.fields.remove(&name);
- }
+// === Entry functions: Create ===
- // === Access fields ===
+#[allow(lint(self_transfer))]
+/// Create a new empty Display object and keep it.
+public entry fun create_and_keep(pub: &Publisher, ctx: &mut TxContext) {
+ transfer::public_transfer(new(pub, ctx), ctx.sender())
+}
- /// Authorization check; can be performed externally to implement protection rules for Display.
- public fun is_authorized(pub: &Publisher): bool {
- pub.from_package()
- }
+/// Manually bump the version and emit an event with the updated version's contents.
+public entry fun update_version(display: &mut Display) {
+ display.version = display.version + 1;
+ event::emit(VersionUpdated {
+ version: display.version,
+ fields: *&display.fields,
+ id: display.id.to_inner(),
+ })
+}
- /// Read the `version` field.
- public fun version(d: &Display): u16 {
- d.version
- }
+// === Entry functions: Add/Modify fields ===
- /// Read the `fields` field.
- public fun fields(d: &Display): &VecMap {
- &d.fields
- }
+/// Sets a custom `name` field with the `value`.
+public entry fun add(self: &mut Display, name: String, value: String) {
+ self.add_internal(name, value)
+}
- // === Private functions ===
+/// Sets multiple `fields` with `values`.
+public entry fun add_multiple(
+ self: &mut Display,
+ fields: vector,
+ values: vector,
+) {
+ let len = fields.length();
+ assert!(len == values.length(), EVecLengthMismatch);
+
+ let mut i = 0;
+ while (i < len) {
+ self.add_internal(fields[i], values[i]);
+ i = i + 1;
+ };
+}
- /// Internal function to create a new `Display`.
- fun create_internal(ctx: &mut TxContext): Display {
- let uid = object::new(ctx);
+/// Change the value of the field.
+/// TODO (long run): version changes;
+public entry fun edit