From fc6bdfa1f275995f405c4eb3af88ab43778b0c3a Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Mon, 4 Nov 2024 12:13:02 +0200 Subject: [PATCH 1/8] feat(iota-framework): added and integrated `SystemDisplayCap` --- .../iota-framework/sources/display.move | 96 +++++++++++++------ .../packages/iota-system/sources/genesis.move | 3 + .../iota-system/sources/iota_system.move | 11 +++ .../sources/iota_system_display.move | 37 +++++++ .../tests/governance_test_utils.move | 2 + 5 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 crates/iota-framework/packages/iota-system/sources/iota_system_display.move diff --git a/crates/iota-framework/packages/iota-framework/sources/display.move b/crates/iota-framework/packages/iota-framework/sources/display.move index bf6cc92765a..80008d0c471 100644 --- a/crates/iota-framework/packages/iota-framework/sources/display.move +++ b/crates/iota-framework/packages/iota-framework/sources/display.move @@ -2,13 +2,13 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -/// Defines a Display struct which defines the way an Object +/// Defines a `Display` struct which defines the way an Object /// should be displayed. The intention is to keep data as independent /// from its display as possible, protecting the development process /// and keeping it separate from the ecosystem agreements. /// -/// Each of the fields of the Display object should allow for pattern -/// substitution and filling-in the pieces using the data from the object T. +/// Each of the fields of the `Display` object should allow for pattern +/// 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 iota::display { @@ -17,20 +17,20 @@ module iota::display { use iota::event; use std::string::String; - /// For when T does not belong to the package `Publisher`. + /// 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. + /// The `Display` object. Defines the way a `T` instance should be + /// displayed. `Display` object can only be created and modified with + /// ether a `Publisher` cap or `SystemDisplayCap`, making sure that + /// the rules are set by the owner of the type or the system object. /// /// Each of the display properties should support patterns outside - /// of the system, making it simpler to customize Display based + /// of the system, making it simpler to customize `Display` based /// on the property values of an Object. /// ``` /// // Example of a display object @@ -43,64 +43,72 @@ module iota::display { /// } /// ``` /// - /// Uses only String type due to external-facing nature of the object, + /// 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 that can only be updated manually by the `Publisher`. version: u16 } - /// Event: emitted when a new Display object has been created for type T. + /// 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 Iota RPC supports querying events by type, finding a Display for the T + /// Since Iota 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 - + /// Version of `Display` got updated. public struct VersionUpdated has copy, drop { id: ID, version: u16, fields: VecMap, } + /// `SystemDisplayCap` allows to create a `Display` object. + public struct SystemDisplayCap has store {} + // === Initializer Methods === - /// Create an empty Display object. It can either be shared empty or filled - /// with data right away via cheaper `set_owned` method. + /// Create an empty `Display` object with `Publisher`. 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. + /// Create a new `Display` object with a set of fields using `Publisher`. 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; - }; + add_multiple(&mut display, fields, values); + display + } + /// Create an empty `Display` object with `SystemDisplayCap`. + public fun system_new(_: &SystemDisplayCap, ctx: &mut TxContext): Display { + create_internal(ctx) + } + + /// Create a new Display object with a set of fields using `SystemDisplayCap`. + public fun system_new_with_fields( + cap: &SystemDisplayCap, fields: vector, values: vector, ctx: &mut TxContext + ): Display { + let mut display = system_new(cap, ctx); + add_multiple(&mut display, fields, values); display } // === Entry functions: Create === #[allow(lint(self_transfer))] - /// Create a new empty Display object and keep it. + /// 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()) } @@ -145,14 +153,14 @@ module iota::display { self.add_internal(name, value) } - /// Remove the key from the Display. + /// Remove the key from the `Display`. entry public fun remove(self: &mut Display, name: String) { self.fields.remove(&name); } // === Access fields === - /// Authorization check; can be performed externally to implement protection rules for Display. + /// Authorization check; can be performed externally to implement protection rules for `Display`. public fun is_authorized(pub: &Publisher): bool { pub.from_package() } @@ -188,14 +196,23 @@ module iota::display { fun add_internal(display: &mut Display, name: String, value: String) { display.fields.insert(name, value) } + + #[test_only] + /// Create a `SystemDisplayCap` for testing purposes. + public fun new_system_display_cap_for_testing(): SystemDisplayCap { + SystemDisplayCap { } + } } #[test_only] module iota::display_tests { - use iota::test_scenario as test; use std::string::String; - use iota::package; + use iota::display; + use iota::package; + + use iota::test_scenario as test; + use iota::test_utils; #[allow(unused_field)] /// An example object. @@ -225,4 +242,23 @@ module iota::display_tests { transfer::public_transfer(display, @0x2); test.end(); } + + #[test] + fun nft_test_sys_init() { + let mut test = test::begin(@0x2); + let cap = display::new_system_display_cap_for_testing(); + + // create a new display object + let mut display = display::system_new(&cap, test.ctx()); + + display.add(b"name".to_string(), b"IOTEST Nft {name}".to_string()); + display.add(b"link".to_string(), b"https://iotestnft.com/nft/{id}".to_string()); + display.add(b"image".to_string(), b"https://api.iotestnft.com/nft/{id}/svg".to_string()); + display.add(b"description".to_string(), b"One of many Iotest Nfts".to_string()); + + transfer::public_transfer(display, @0x2); + + test_utils::destroy(cap); + test.end(); + } } diff --git a/crates/iota-framework/packages/iota-system/sources/genesis.move b/crates/iota-framework/packages/iota-system/sources/genesis.move index 804298911cb..e6e3bb74e68 100644 --- a/crates/iota-framework/packages/iota-system/sources/genesis.move +++ b/crates/iota-framework/packages/iota-system/sources/genesis.move @@ -7,6 +7,7 @@ module iota_system::genesis { use std::string::String; use iota::balance; + use iota::display::SystemDisplayCap; use iota::iota::{Self, IotaTreasuryCap}; use iota::timelock::SystemTimelockCap; use iota_system::iota_system; @@ -86,6 +87,7 @@ module iota_system::genesis { token_distribution_schedule: TokenDistributionSchedule, timelock_genesis_label: Option, system_timelock_cap: SystemTimelockCap, + system_display_cap: SystemDisplayCap, ctx: &mut TxContext, ) { // Ensure this is only called at genesis @@ -185,6 +187,7 @@ module iota_system::genesis { genesis_chain_parameters.chain_start_timestamp_ms, system_parameters, system_timelock_cap, + system_display_cap, ctx, ); } diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index 09da71387a4..5b51e63471d 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -43,6 +43,7 @@ module iota_system::iota_system { use iota::balance::Balance; use iota::coin::Coin; + use iota::display::SystemDisplayCap; use iota_system::staking_pool::StakedIota; use iota::iota::{IOTA, IotaTreasuryCap}; use iota::table::Table; @@ -67,6 +68,7 @@ module iota_system::iota_system { const EWrongInnerVersion: u64 = 1; const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; + const SYSTEM_DISPLAY_CAP_DF_KEY: vector = b"sys_display_cap"; // ==== functions that can only be called by genesis ==== @@ -81,6 +83,7 @@ module iota_system::iota_system { epoch_start_timestamp_ms: u64, parameters: SystemParametersV1, system_timelock_cap: SystemTimelockCap, + system_display_cap: SystemDisplayCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -99,6 +102,7 @@ module iota_system::iota_system { }; dynamic_field::add(&mut self.id, version, system_state); dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); + dynamic_field::add(&mut self.id, SYSTEM_DISPLAY_CAP_DF_KEY, system_display_cap); transfer::share_object(self); } @@ -569,6 +573,13 @@ module iota_system::iota_system { ) } + public(package) fun load_system_display_cap(self: &IotaSystemState): &SystemDisplayCap { + dynamic_field::borrow( + &self.id, + SYSTEM_DISPLAY_CAP_DF_KEY + ) + } + #[allow(unused_function)] /// Returns the voting power of the active validators, values are voting power in the scale of 10000. fun validator_voting_powers(wrapper: &mut IotaSystemState): VecMap { diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move new file mode 100644 index 00000000000..66a6d778ba9 --- /dev/null +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move @@ -0,0 +1,37 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module iota_system::iota_system_display { + + use std::string::String; + + use iota::display::{Self, Display}; + + use iota_system::iota_system::IotaSystemState; + + /// Create an empty `Display` object with `SystemDisplayCap`. + public(package) fun system_new( + iota_system: &IotaSystemState, + ctx: &mut TxContext + ): Display { + // Load the `SystemDisplayCap` instance. + let sys_display_cap = iota_system.load_system_display_cap(); + + // Create a `Display` object. + display::system_new(sys_display_cap, ctx) + } + + /// Create a new Display object with a set of fields using `SystemDisplayCap`. + public(package) fun system_new_with_fields( + iota_system: &IotaSystemState, + fields: vector, + values: vector, + ctx: &mut TxContext + ): Display { + // Load the `SystemDisplayCap` instance. + let sys_display_cap = iota_system.load_system_display_cap(); + + // Create a `Display` object with fields. + display::system_new_with_fields(sys_display_cap, fields, values, ctx) + } +} diff --git a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move index 97d3af016ca..c2c2005ea91 100644 --- a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move +++ b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move @@ -6,6 +6,7 @@ module iota_system::governance_test_utils { use iota::address; use iota::balance; + use iota::display; use iota::iota::{Self, IOTA}; use iota::coin::{Self, Coin}; use iota_system::staking_pool::{StakedIota, StakingPoolV1}; @@ -95,6 +96,7 @@ module iota_system::governance_test_utils { 0, // chain_start_timestamp_ms system_parameters, timelock::new_system_timelock_cap_for_testing(), + display::new_system_display_cap_for_testing(), ctx, ) } From f6abe208c384f8b38204b4c24b1459efb4a921ad Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 5 Nov 2024 15:00:52 +0200 Subject: [PATCH 2/8] feat(iota-framework): added `IotaSystemAdminCap` --- .../iota-framework/sources/display.move | 28 +++++------- .../sources/system_admin_cap.move | 30 +++++++++++++ .../iota-framework/sources/timelock.move | 40 ++++-------------- .../packages/iota-system/sources/genesis.move | 9 ++-- .../iota-system/sources/iota_system.move | 26 +++--------- .../sources/iota_system_display.move | 20 ++++----- .../sources/iota_system_state_inner.move | 12 +++++- .../sources/timelocked_staking.move | 8 ++-- .../tests/governance_test_utils.move | 17 +++----- .../packages_compiled/iota-framework | Bin 69915 -> 70167 bytes .../packages_compiled/iota-system | Bin 42328 -> 42939 bytes crates/iota-framework/published_api.txt | 29 ++++++++++--- 12 files changed, 110 insertions(+), 109 deletions(-) create mode 100644 crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move diff --git a/crates/iota-framework/packages/iota-framework/sources/display.move b/crates/iota-framework/packages/iota-framework/sources/display.move index 80008d0c471..8acd7442ae8 100644 --- a/crates/iota-framework/packages/iota-framework/sources/display.move +++ b/crates/iota-framework/packages/iota-framework/sources/display.move @@ -12,10 +12,12 @@ /// /// More entry functions might be added in the future depending on the use cases. module iota::display { + use std::string::String; + + use iota::event; use iota::package::Publisher; + use iota::system_admin_cap::IotaSystemAdminCap; use iota::vec_map::{Self, VecMap}; - use iota::event; - use std::string::String; /// For when `T` does not belong to the package `Publisher`. const ENotOwner: u64 = 0; @@ -26,7 +28,7 @@ module iota::display { /// The `Display` object. Defines the way a `T` instance should be /// displayed. `Display` object can only be created and modified with - /// ether a `Publisher` cap or `SystemDisplayCap`, making sure that + /// ether a `Publisher` cap or `IotaSystemAdminCap`, making sure that /// the rules are set by the owner of the type or the system object. /// /// Each of the display properties should support patterns outside @@ -71,9 +73,6 @@ module iota::display { fields: VecMap, } - /// `SystemDisplayCap` allows to create a `Display` object. - public struct SystemDisplayCap has store {} - // === Initializer Methods === /// Create an empty `Display` object with `Publisher`. @@ -91,14 +90,14 @@ module iota::display { display } - /// Create an empty `Display` object with `SystemDisplayCap`. - public fun system_new(_: &SystemDisplayCap, ctx: &mut TxContext): Display { + /// Create an empty `Display` object with `IotaSystemAdminCap`. + public fun system_new(_: &IotaSystemAdminCap, ctx: &mut TxContext): Display { create_internal(ctx) } - /// Create a new Display object with a set of fields using `SystemDisplayCap`. + /// Create a new Display object with a set of fields using `IotaSystemAdminCap`. public fun system_new_with_fields( - cap: &SystemDisplayCap, fields: vector, values: vector, ctx: &mut TxContext + cap: &IotaSystemAdminCap, fields: vector, values: vector, ctx: &mut TxContext ): Display { let mut display = system_new(cap, ctx); add_multiple(&mut display, fields, values); @@ -196,12 +195,6 @@ module iota::display { fun add_internal(display: &mut Display, name: String, value: String) { display.fields.insert(name, value) } - - #[test_only] - /// Create a `SystemDisplayCap` for testing purposes. - public fun new_system_display_cap_for_testing(): SystemDisplayCap { - SystemDisplayCap { } - } } #[test_only] @@ -210,6 +203,7 @@ module iota::display_tests { use iota::display; use iota::package; + use iota::system_admin_cap; use iota::test_scenario as test; use iota::test_utils; @@ -246,7 +240,7 @@ module iota::display_tests { #[test] fun nft_test_sys_init() { let mut test = test::begin(@0x2); - let cap = display::new_system_display_cap_for_testing(); + let cap = system_admin_cap::new_system_admin_cap_for_testing(); // create a new display object let mut display = display::system_new(&cap, test.ctx()); diff --git a/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move b/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move new file mode 100644 index 00000000000..e07573ca936 --- /dev/null +++ b/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move @@ -0,0 +1,30 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/// A system admin capability implementation. +module iota::system_admin_cap { + + /// The `new` function was called at a non-genesis epoch. + const ENotCalledAtGenesis: u64 = 0; + /// Sender is not @0x0 the system address. + const ENotSystemAddress: u64 = 1; + + /// `IotaSystemAdminCap` allows to perform privileged IOTA system operations. + public struct IotaSystemAdminCap has store {} + + #[allow(unused_function)] + /// Create a `IotaSystemAdminCap`. + /// This should be called only once during genesis creation. + fun new_system_admin_cap(ctx: &TxContext): IotaSystemAdminCap { + assert!(ctx.sender() == @0x0, ENotSystemAddress); + assert!(ctx.epoch() == 0, ENotCalledAtGenesis); + + IotaSystemAdminCap {} + } + + #[test_only] + /// Create a `IotaSystemAdminCap` for testing purposes. + public fun new_system_admin_cap_for_testing(): IotaSystemAdminCap { + IotaSystemAdminCap { } + } +} diff --git a/crates/iota-framework/packages/iota-framework/sources/timelock.move b/crates/iota-framework/packages/iota-framework/sources/timelock.move index 154635e0435..2651e782f0a 100644 --- a/crates/iota-framework/packages/iota-framework/sources/timelock.move +++ b/crates/iota-framework/packages/iota-framework/sources/timelock.move @@ -8,19 +8,16 @@ module iota::timelock { use iota::balance::Balance; use iota::labeler::LabelerCap; - - /// The `new` function was called at a non-genesis epoch. - const ENotCalledAtGenesis: u64 = 0; - /// Sender is not @0x0 the system address. - const ENotSystemAddress: u64 = 1; + use iota::system_admin_cap::IotaSystemAdminCap; + /// Expiration timestamp of the lock is in the past. - const EExpireEpochIsPast: u64 = 2; + const EExpireEpochIsPast: u64 = 0; /// The lock has not expired yet. - const ENotExpiredYet: u64 = 3; + const ENotExpiredYet: u64 = 1; /// For when trying to join two time-locked balances with different expiration time. - const EDifferentExpirationTime: u64 = 4; + const EDifferentExpirationTime: u64 = 2; /// For when trying to join two time-locked balances with different labels. - const EDifferentLabels: u64 = 5; + const EDifferentLabels: u64 = 3; /// `TimeLock` struct that holds a locked object. public struct TimeLock has key { @@ -33,9 +30,6 @@ module iota::timelock { label: Option, } - /// `SystemTimelockCap` allows to `pack` and `unpack` TimeLocks - public struct SystemTimelockCap has store {} - // === TimeLock lock and unlock === /// Function to lock an object till a unix timestamp in milliseconds. @@ -153,7 +147,7 @@ module iota::timelock { /// A utility function to pack a `TimeLock` that can be invoked only by a system package. public fun system_pack( - _: &SystemTimelockCap, + _: &IotaSystemAdminCap, locked: T, expiration_timestamp_ms: u64, label: Option, @@ -163,7 +157,7 @@ module iota::timelock { } /// An utility function to unpack a `TimeLock` that can be invoked only by a system package. - public fun system_unpack(_: &SystemTimelockCap, lock: TimeLock): (T, u64, Option) { + public fun system_unpack(_: &IotaSystemAdminCap, lock: TimeLock): (T, u64, Option) { unpack(lock) } @@ -267,22 +261,4 @@ module iota::timelock { // Check that `expiration_timestamp_ms` is valid. assert!(expiration_timestamp_ms > epoch_timestamp_ms, EExpireEpochIsPast); } - - // === SystemTimelockCap === - - #[allow(unused_function)] - /// Create a `SystemTimelockCap`. - /// This should be called only once during genesis creation. - fun new_system_timelock_cap(ctx: &TxContext): SystemTimelockCap { - assert!(ctx.sender() == @0x0, ENotSystemAddress); - assert!(ctx.epoch() == 0, ENotCalledAtGenesis); - - SystemTimelockCap {} - } - - #[test_only] - /// Create a `SystemTimelockCap` for testing purposes. - public fun new_system_timelock_cap_for_testing(): SystemTimelockCap { - SystemTimelockCap { } - } } diff --git a/crates/iota-framework/packages/iota-system/sources/genesis.move b/crates/iota-framework/packages/iota-system/sources/genesis.move index e6e3bb74e68..2358e520f6d 100644 --- a/crates/iota-framework/packages/iota-system/sources/genesis.move +++ b/crates/iota-framework/packages/iota-system/sources/genesis.move @@ -7,9 +7,8 @@ module iota_system::genesis { use std::string::String; use iota::balance; - use iota::display::SystemDisplayCap; use iota::iota::{Self, IotaTreasuryCap}; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::iota_system; use iota_system::validator::{Self, ValidatorV1}; use iota_system::validator_set; @@ -86,8 +85,7 @@ module iota_system::genesis { genesis_validators: vector, token_distribution_schedule: TokenDistributionSchedule, timelock_genesis_label: Option, - system_timelock_cap: SystemTimelockCap, - system_display_cap: SystemDisplayCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { // Ensure this is only called at genesis @@ -186,8 +184,7 @@ module iota_system::genesis { genesis_chain_parameters.protocol_version, genesis_chain_parameters.chain_start_timestamp_ms, system_parameters, - system_timelock_cap, - system_display_cap, + iota_system_admin_cap, ctx, ); } diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index 5b51e63471d..dc8801f5be5 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -43,11 +43,10 @@ module iota_system::iota_system { use iota::balance::Balance; use iota::coin::Coin; - use iota::display::SystemDisplayCap; use iota_system::staking_pool::StakedIota; use iota::iota::{IOTA, IotaTreasuryCap}; use iota::table::Table; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::ValidatorV1; use iota_system::validator_cap::UnverifiedValidatorOperationCap; use iota_system::iota_system_state_inner::{Self, SystemParametersV1, IotaSystemStateV1}; @@ -67,9 +66,6 @@ module iota_system::iota_system { const ENotSystemAddress: u64 = 0; const EWrongInnerVersion: u64 = 1; - const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; - const SYSTEM_DISPLAY_CAP_DF_KEY: vector = b"sys_display_cap"; - // ==== functions that can only be called by genesis ==== /// Create a new IotaSystemState object and make it shared. @@ -82,8 +78,7 @@ module iota_system::iota_system { protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: SystemParametersV1, - system_timelock_cap: SystemTimelockCap, - system_display_cap: SystemDisplayCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -93,6 +88,7 @@ module iota_system::iota_system { protocol_version, epoch_start_timestamp_ms, parameters, + iota_system_admin_cap, ctx, ); let version = iota_system_state_inner::genesis_system_state_version(); @@ -101,8 +97,6 @@ module iota_system::iota_system { version, }; dynamic_field::add(&mut self.id, version, system_state); - dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); - dynamic_field::add(&mut self.id, SYSTEM_DISPLAY_CAP_DF_KEY, system_display_cap); transfer::share_object(self); } @@ -566,18 +560,8 @@ module iota_system::iota_system { inner } - public(package) fun load_system_timelock_cap(self: &IotaSystemState): &SystemTimelockCap { - dynamic_field::borrow( - &self.id, - SYSTEM_TIMELOCK_CAP_DF_KEY - ) - } - - public(package) fun load_system_display_cap(self: &IotaSystemState): &SystemDisplayCap { - dynamic_field::borrow( - &self.id, - SYSTEM_DISPLAY_CAP_DF_KEY - ) + public(package) fun load_iota_system_admin_cap(self: &mut IotaSystemState): &IotaSystemAdminCap { + self.load_system_state().iota_system_admin_cap() } #[allow(unused_function)] diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move index 66a6d778ba9..bc1249d6388 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move @@ -9,29 +9,29 @@ module iota_system::iota_system_display { use iota_system::iota_system::IotaSystemState; - /// Create an empty `Display` object with `SystemDisplayCap`. + /// Create an empty `Display` object with `IotaSystemAdminCap`. public(package) fun system_new( - iota_system: &IotaSystemState, + iota_system: &mut IotaSystemState, ctx: &mut TxContext ): Display { - // Load the `SystemDisplayCap` instance. - let sys_display_cap = iota_system.load_system_display_cap(); + // Load the `IotaSystemAdminCap` instance. + let sys_admin_cap = iota_system.load_iota_system_admin_cap(); // Create a `Display` object. - display::system_new(sys_display_cap, ctx) + display::system_new(sys_admin_cap, ctx) } - /// Create a new Display object with a set of fields using `SystemDisplayCap`. + /// Create a new Display object with a set of fields using `IotaSystemAdminCap`. public(package) fun system_new_with_fields( - iota_system: &IotaSystemState, + iota_system: &mut IotaSystemState, fields: vector, values: vector, ctx: &mut TxContext ): Display { - // Load the `SystemDisplayCap` instance. - let sys_display_cap = iota_system.load_system_display_cap(); + // Load the `IotaSystemAdminCap` instance. + let sys_admin_cap = iota_system.load_iota_system_admin_cap(); // Create a `Display` object with fields. - display::system_new_with_fields(sys_display_cap, fields, values, ctx) + display::system_new_with_fields(sys_admin_cap, fields, values, ctx) } } diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index ba74ebc9bf8..5e701a31961 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -5,13 +5,13 @@ module iota_system::iota_system_state_inner { use iota::balance::{Self, Balance}; use iota::coin::Coin; - use iota_system::staking_pool::StakedIota; use iota::iota::{IOTA, IotaTreasuryCap}; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::{Self, ValidatorV1}; use iota_system::validator_set::{Self, ValidatorSetV1}; use iota_system::validator_cap::{UnverifiedValidatorOperationCap, ValidatorOperationCap}; use iota_system::storage_fund::{Self, StorageFundV1}; - use iota_system::staking_pool::PoolTokenExchangeRate; + use iota_system::staking_pool::{PoolTokenExchangeRate, StakedIota}; use iota::vec_map::{Self, VecMap}; use iota::vec_set::{Self, VecSet}; use iota::event; @@ -76,6 +76,8 @@ module iota_system::iota_system_state_inner { storage_fund: StorageFundV1, /// A list of system config parameters. parameters: SystemParametersV1, + /// A capability allows to perform privileged IOTA system operations. + iota_system_admin_cap: IotaSystemAdminCap, /// The reference gas price for the current epoch. reference_gas_price: u64, /// A map storing the records of validator reporting each other. @@ -146,6 +148,7 @@ module iota_system::iota_system_state_inner { protocol_version: u64, epoch_start_timestamp_ms: u64, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ): IotaSystemStateV1 { let validators = validator_set::new(validators, ctx); @@ -159,6 +162,7 @@ module iota_system::iota_system_state_inner { validators, storage_fund: storage_fund::new(initial_storage_fund), parameters, + iota_system_admin_cap, reference_gas_price, validator_report_records: vec_map::empty(), safe_mode: false, @@ -781,6 +785,10 @@ module iota_system::iota_system_state_inner { self.system_state_version } + public(package) fun iota_system_admin_cap(self: &IotaSystemStateV1): &IotaSystemAdminCap { + &self.iota_system_admin_cap + } + /// This function always return the genesis system state version, which is used to create the system state in genesis. /// It should never change for a given network. public(package) fun genesis_system_state_version(): u64 { diff --git a/crates/iota-framework/packages/iota-system/sources/timelocked_staking.move b/crates/iota-framework/packages/iota-system/sources/timelocked_staking.move index 9788e123a18..6e614014614 100644 --- a/crates/iota-framework/packages/iota-system/sources/timelocked_staking.move +++ b/crates/iota-framework/packages/iota-system/sources/timelocked_staking.move @@ -107,8 +107,8 @@ module iota_system::timelocked_staking { assert!(timelocked_balance.is_locked(ctx), ETimeLockShouldNotBeExpired); // Unpack the time-locked balance. - let sys_timelock_cap = iota_system.load_system_timelock_cap(); - let (balance, expiration_timestamp_ms, label) = timelock::system_unpack(sys_timelock_cap, timelocked_balance); + let sys_admin_cap = iota_system.load_iota_system_admin_cap(); + let (balance, expiration_timestamp_ms, label) = timelock::system_unpack(sys_admin_cap, timelocked_balance); // Stake the time-locked balance. let staked_iota = iota_system.request_add_stake_non_entry( @@ -181,8 +181,8 @@ module iota_system::timelocked_staking { let principal = withdraw_stake.split(principal); // Pack and return a time-locked balance, and the reward. - let sys_timelock_cap = iota_system.load_system_timelock_cap(); - (timelock::system_pack(sys_timelock_cap, principal, expiration_timestamp_ms, label, ctx), withdraw_stake) + let sys_admin_cap = iota_system.load_iota_system_admin_cap(); + (timelock::system_pack(sys_admin_cap, principal, expiration_timestamp_ms, label, ctx), withdraw_stake) } // === TimelockedStakedIota balance functions === diff --git a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move index c2c2005ea91..6c708b04546 100644 --- a/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move +++ b/crates/iota-framework/packages/iota-system/tests/governance_test_utils.move @@ -5,19 +5,17 @@ #[test_only] module iota_system::governance_test_utils { use iota::address; - use iota::balance; - use iota::display; - use iota::iota::{Self, IOTA}; + use iota::balance::{Self, Balance}; use iota::coin::{Self, Coin}; + use iota::iota::{Self, IOTA}; + use iota::system_admin_cap; + use iota::test_scenario::{Self, Scenario}; + use iota::test_utils::{Self, assert_eq}; + use iota_system::staking_pool::{StakedIota, StakingPoolV1}; - use iota::test_utils::assert_eq; use iota_system::validator::{Self, ValidatorV1}; use iota_system::iota_system::{Self, IotaSystemState}; use iota_system::iota_system_state_inner; - use iota::test_scenario::{Self, Scenario}; - use iota::test_utils; - use iota::balance::Balance; - use iota::timelock; const NANOS_PER_IOTA: u64 = 1_000_000_000; @@ -95,8 +93,7 @@ module iota_system::governance_test_utils { 1, // protocol version 0, // chain_start_timestamp_ms system_parameters, - timelock::new_system_timelock_cap_for_testing(), - display::new_system_display_cap_for_testing(), + system_admin_cap::new_system_admin_cap_for_testing(), ctx, ) } diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index 4747e245c42c814cc448815252715c0ad7a20e44..2c66d13a041446362f9a6551ad09fffc2f0bd559 100644 GIT binary patch delta 2092 zcmZuyU1(fI6h7z7%$>PEyZ7GRyMM`Mlg-~I{Ylf-CL2-gkBIFT9W7L27)cwu&GKQltnX=#z*Kf{Lj0sUoP*r^f!!2hVIa^`~8yZ_b=KbLPyM z^PRi)u6*;d#OaUm(E0Y4^iK6p-vIy@L6S5g2vu*O8^_E!9B@9uDeqTQ!S6T;4rl-g zh}0PXg`Fu7fQ~^lz!Ma?gUhRPN6xIQwifrzFD@({m^`KRecFt~?Jvw*NS!pfJw_b|=uTP&ivM1eJ_R{9X!974o z$bkbDJcvnCT{_D10W~&!h|ylE^Q+59Fo|C=qIS@h~dZ7w+7={rT!vTN*4RTH_ zx)zBvkd`2108&VB90F~$4Y>_QaV{&IO9MS*aZp$sk`^5VeIrnw^0v$uKF&Njl zU2(&Np5I*H!cmCmbj&fsf+1^;_AuAhl}1G_D9UWEI7Xro=o7D#;6%Hf9i)Aeh8N17 zVRIMxJd^IcFqD5tIi@#W?@gC4{IUCi^76X%#wA(&N1Q#iuzGx>W>?b5g(O{k>+D3) z$fO(6c!uk+Xatd99M5d(DMC&s@O!JYwpKojT${dVQXn(Z=L#q1LUSZ;n?+AEO?#Q968gB?NPw!a zrZvT_5@5Gu^IYPJ1Sq=}$1Krc+_UneV@S3a0p&3hnVa6pmJ&3%*cD@~%nO({D=8me<4Z6~X z$Ie7Cx7nkw(HM5etwpA<-aI(P3ho6ic9=~ZN2hIUI`5oiK?t#V0H2Aevpz6xb=Dn+ z!9nW%b0_AOjO2>IR zeS3bc$_#313@8vjb0V&eNMB{_r$~_ESFa6uFwr!YSaoR>GXpg>tj=YfTbGF{Tb-~Z z@sJ%cIe^LRBa<6oAia0{EcT_Z+!+(Y@nHJlo$Xjnf4cKHj-;i#lh5>QkaY$qVH%Bd zt{(*s1_KdSd~Ps4QGpjEGnEf0P?0CGZv(X_`83QydHj*IG$j6}*RFhZ_ek+?ReSaz delta 1858 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 OFYx>)CpNrrxA;G`;4^;! diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index 7b25f4da602..b48aed22add 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -739,6 +739,9 @@ protocol_version system_state_version public(package) fun 0x3::iota_system_state_inner +iota_system_admin_cap + public(package) fun + 0x3::iota_system_state_inner genesis_system_state_version public(package) fun 0x3::iota_system_state_inner @@ -898,7 +901,7 @@ load_system_state_mut load_inner_maybe_upgrade fun 0x3::iota_system -load_system_timelock_cap +load_iota_system_admin_cap public(package) fun 0x3::iota_system validator_voting_powers @@ -997,6 +1000,12 @@ allocate_tokens activate_validators fun 0x3::genesis +system_new + public(package) fun + 0x3::iota_system_display +system_new_with_fields + public(package) fun + 0x3::iota_system_display secp256k1_ecrecover public fun 0x2::ecdsa_k1 @@ -2227,6 +2236,12 @@ get_entry_by_idx_mut remove_entry_by_idx public fun 0x2::vec_map +IotaSystemAdminCap + public struct + 0x2::system_admin_cap +new_system_admin_cap + fun + 0x2::system_admin_cap Publisher public struct 0x2::package @@ -2326,6 +2341,12 @@ new new_with_fields public fun 0x2::display +system_new + public fun + 0x2::display +system_new_with_fields + public fun + 0x2::display create_and_keep public entry fun 0x2::display @@ -3067,9 +3088,6 @@ swap_remove TimeLock public struct 0x2::timelock -SystemTimelockCap - public struct - 0x2::timelock lock public fun 0x2::timelock @@ -3139,9 +3157,6 @@ transfer check_expiration_timestamp_ms fun 0x2::timelock -new_system_timelock_cap - fun - 0x2::timelock Token public struct 0x2::token From cff774d4cbbefcd56472b973971e8f3e94e0eca1 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 5 Nov 2024 15:37:57 +0200 Subject: [PATCH 3/8] feat: add and integrate `IotaSystemAdminCap` rust module --- .../base/sources/genesis.move | 6 ++-- .../base/sources/iota_system.move | 8 ++--- .../base/sources/iota_system_state_inner.move | 4 +++ .../deep_upgrade/sources/genesis.move | 6 ++-- .../deep_upgrade/sources/iota_system.move | 8 ++--- .../sources/iota_system_state_inner.move | 7 ++++ .../safe_mode/sources/genesis.move | 6 ++-- .../safe_mode/sources/iota_system.move | 8 ++--- .../sources/iota_system_state_inner.move | 4 +++ .../shallow_upgrade/sources/genesis.move | 6 ++-- .../shallow_upgrade/sources/iota_system.move | 8 ++--- .../sources/iota_system_state_inner.move | 7 ++++ crates/iota-genesis-builder/src/lib.rs | 11 +++--- crates/iota-json-rpc/src/coin_api.rs | 2 ++ .../iota_system_state_inner_v1.rs | 3 ++ .../simtest_iota_system_state_inner.rs | 3 ++ crates/iota-types/src/lib.rs | 1 + crates/iota-types/src/system_admin_cap.rs | 34 +++++++++++++++++++ 18 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 crates/iota-types/src/system_admin_cap.rs diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/genesis.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/genesis.move index f4d69976b8b..c5a91d91351 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/genesis.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/genesis.move @@ -7,7 +7,7 @@ module iota_system::genesis { use iota::balance; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::iota_system; use iota_system::validator; @@ -67,7 +67,7 @@ module iota_system::genesis { genesis_validators: vector, _token_distribution_schedule: TokenDistributionSchedule, _timelock_genesis_label: Option, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { assert!(tx_context::epoch(ctx) == 0, 0); @@ -118,7 +118,7 @@ module iota_system::genesis { genesis_chain_parameters.protocol_version, genesis_chain_parameters.chain_start_timestamp_ms, genesis_chain_parameters.epoch_duration_ms, - system_timelock_cap, + iota_system_admin_cap, ctx, ); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system.move index 9054f11b4a6..b615e565ac1 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system.move @@ -7,13 +7,11 @@ module iota_system::iota_system { use iota::dynamic_field; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::ValidatorV1; use iota_system::iota_system_state_inner::{Self, IotaSystemStateV1}; - const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; - public struct IotaSystemState has key { id: UID, version: u64, @@ -27,7 +25,7 @@ module iota_system::iota_system { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -37,6 +35,7 @@ module iota_system::iota_system { protocol_version, epoch_start_timestamp_ms, epoch_duration_ms, + iota_system_admin_cap, ctx, ); let version = iota_system_state_inner::genesis_system_state_version(); @@ -45,7 +44,6 @@ module iota_system::iota_system { version, }; dynamic_field::add(&mut self.id, version, system_state); - dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); transfer::share_object(self); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system_state_inner.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system_state_inner.move index e3abf0b3c56..14f0d9e0186 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system_state_inner.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/base/sources/iota_system_state_inner.move @@ -8,6 +8,7 @@ module iota_system::iota_system_state_inner { use iota::event; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota::table::{Self, Table}; use iota_system::validator::ValidatorV1; @@ -50,6 +51,7 @@ module iota_system::iota_system_state_inner { validators: ValidatorSetV1, storage_fund: Balance, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, reference_gas_price: u64, safe_mode: bool, epoch_start_timestamp_ms: u64, @@ -63,6 +65,7 @@ module iota_system::iota_system_state_inner { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ): IotaSystemStateV1 { let validators = new_validator_set(validators, ctx); @@ -77,6 +80,7 @@ module iota_system::iota_system_state_inner { epoch_duration_ms, extra_fields: bag::new(ctx), }, + iota_system_admin_cap, reference_gas_price: 1, safe_mode: false, epoch_start_timestamp_ms, diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/genesis.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/genesis.move index f4d69976b8b..c5a91d91351 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/genesis.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/genesis.move @@ -7,7 +7,7 @@ module iota_system::genesis { use iota::balance; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::iota_system; use iota_system::validator; @@ -67,7 +67,7 @@ module iota_system::genesis { genesis_validators: vector, _token_distribution_schedule: TokenDistributionSchedule, _timelock_genesis_label: Option, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { assert!(tx_context::epoch(ctx) == 0, 0); @@ -118,7 +118,7 @@ module iota_system::genesis { genesis_chain_parameters.protocol_version, genesis_chain_parameters.chain_start_timestamp_ms, genesis_chain_parameters.epoch_duration_ms, - system_timelock_cap, + iota_system_admin_cap, ctx, ); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system.move index 549ba9c21a3..2d34ba2c6be 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system.move @@ -7,13 +7,11 @@ module iota_system::iota_system { use iota::dynamic_field; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::ValidatorV1; use iota_system::iota_system_state_inner::{Self, IotaSystemStateV1, IotaSystemStateV2}; - const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; - public struct IotaSystemState has key { id: UID, version: u64, @@ -27,7 +25,7 @@ module iota_system::iota_system { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -37,6 +35,7 @@ module iota_system::iota_system { protocol_version, epoch_start_timestamp_ms, epoch_duration_ms, + iota_system_admin_cap, ctx, ); let version = iota_system_state_inner::genesis_system_state_version(); @@ -45,7 +44,6 @@ module iota_system::iota_system { version, }; dynamic_field::add(&mut self.id, version, system_state); - dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); transfer::share_object(self); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system_state_inner.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system_state_inner.move index a1f64c1602d..f7d69dd771f 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system_state_inner.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/deep_upgrade/sources/iota_system_state_inner.move @@ -8,6 +8,7 @@ module iota_system::iota_system_state_inner { use iota::event; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota::table::{Self, Table}; use iota_system::validator::{ValidatorV1, ValidatorV2}; @@ -58,6 +59,7 @@ module iota_system::iota_system_state_inner { validators: ValidatorSetV1, storage_fund: Balance, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, reference_gas_price: u64, safe_mode: bool, epoch_start_timestamp_ms: u64, @@ -73,6 +75,7 @@ module iota_system::iota_system_state_inner { validators: ValidatorSetV2, storage_fund: Balance, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, reference_gas_price: u64, safe_mode: bool, epoch_start_timestamp_ms: u64, @@ -86,6 +89,7 @@ module iota_system::iota_system_state_inner { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ): IotaSystemStateV1 { let validators = new_validator_set(validators, ctx); @@ -100,6 +104,7 @@ module iota_system::iota_system_state_inner { epoch_duration_ms, extra_fields: bag::new(ctx), }, + iota_system_admin_cap, reference_gas_price: 1, safe_mode: false, epoch_start_timestamp_ms, @@ -178,6 +183,7 @@ module iota_system::iota_system_state_inner { validators, storage_fund, parameters, + iota_system_admin_cap, reference_gas_price, safe_mode, epoch_start_timestamp_ms, @@ -194,6 +200,7 @@ module iota_system::iota_system_state_inner { validators: new_validator_set, storage_fund, parameters, + iota_system_admin_cap, reference_gas_price, safe_mode, epoch_start_timestamp_ms, diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/genesis.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/genesis.move index f4d69976b8b..c5a91d91351 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/genesis.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/genesis.move @@ -7,7 +7,7 @@ module iota_system::genesis { use iota::balance; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::iota_system; use iota_system::validator; @@ -67,7 +67,7 @@ module iota_system::genesis { genesis_validators: vector, _token_distribution_schedule: TokenDistributionSchedule, _timelock_genesis_label: Option, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { assert!(tx_context::epoch(ctx) == 0, 0); @@ -118,7 +118,7 @@ module iota_system::genesis { genesis_chain_parameters.protocol_version, genesis_chain_parameters.chain_start_timestamp_ms, genesis_chain_parameters.epoch_duration_ms, - system_timelock_cap, + iota_system_admin_cap, ctx, ); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system.move index 113afd557ce..701a2597b6d 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system.move @@ -7,13 +7,11 @@ module iota_system::iota_system { use iota::dynamic_field; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::ValidatorV1; use iota_system::iota_system_state_inner::{Self, IotaSystemStateV1}; - const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; - public struct IotaSystemState has key { id: UID, version: u64, @@ -27,7 +25,7 @@ module iota_system::iota_system { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -37,6 +35,7 @@ module iota_system::iota_system { protocol_version, epoch_start_timestamp_ms, epoch_duration_ms, + iota_system_admin_cap, ctx, ); let version = iota_system_state_inner::genesis_system_state_version(); @@ -45,7 +44,6 @@ module iota_system::iota_system { version, }; dynamic_field::add(&mut self.id, version, system_state); - dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); transfer::share_object(self); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system_state_inner.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system_state_inner.move index a2ea7aa1f8d..df1cc71f995 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system_state_inner.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/safe_mode/sources/iota_system_state_inner.move @@ -8,6 +8,7 @@ module iota_system::iota_system_state_inner { use iota::event; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota::table::{Self, Table}; use iota_system::validator::ValidatorV1; @@ -47,6 +48,7 @@ module iota_system::iota_system_state_inner { iota_treasury_cap: IotaTreasuryCap, validators: ValidatorSetV1, storage_fund: Balance, + iota_system_admin_cap: IotaSystemAdminCap, parameters: SystemParametersV1, reference_gas_price: u64, safe_mode: bool, @@ -61,6 +63,7 @@ module iota_system::iota_system_state_inner { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ): IotaSystemStateV1 { let system_state = IotaSystemStateV1 { @@ -78,6 +81,7 @@ module iota_system::iota_system_state_inner { epoch_duration_ms, extra_fields: bag::new(ctx), }, + iota_system_admin_cap, reference_gas_price: 1, safe_mode: false, epoch_start_timestamp_ms, diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/genesis.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/genesis.move index f4d69976b8b..c5a91d91351 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/genesis.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/genesis.move @@ -7,7 +7,7 @@ module iota_system::genesis { use iota::balance; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::iota_system; use iota_system::validator; @@ -67,7 +67,7 @@ module iota_system::genesis { genesis_validators: vector, _token_distribution_schedule: TokenDistributionSchedule, _timelock_genesis_label: Option, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { assert!(tx_context::epoch(ctx) == 0, 0); @@ -118,7 +118,7 @@ module iota_system::genesis { genesis_chain_parameters.protocol_version, genesis_chain_parameters.chain_start_timestamp_ms, genesis_chain_parameters.epoch_duration_ms, - system_timelock_cap, + iota_system_admin_cap, ctx, ); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system.move index 549ba9c21a3..2d34ba2c6be 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system.move @@ -7,13 +7,11 @@ module iota_system::iota_system { use iota::dynamic_field; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; - use iota::timelock::SystemTimelockCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota_system::validator::ValidatorV1; use iota_system::iota_system_state_inner::{Self, IotaSystemStateV1, IotaSystemStateV2}; - const SYSTEM_TIMELOCK_CAP_DF_KEY: vector = b"sys_timelock_cap"; - public struct IotaSystemState has key { id: UID, version: u64, @@ -27,7 +25,7 @@ module iota_system::iota_system { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, - system_timelock_cap: SystemTimelockCap, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ) { let system_state = iota_system_state_inner::create( @@ -37,6 +35,7 @@ module iota_system::iota_system { protocol_version, epoch_start_timestamp_ms, epoch_duration_ms, + iota_system_admin_cap, ctx, ); let version = iota_system_state_inner::genesis_system_state_version(); @@ -45,7 +44,6 @@ module iota_system::iota_system { version, }; dynamic_field::add(&mut self.id, version, system_state); - dynamic_field::add(&mut self.id, SYSTEM_TIMELOCK_CAP_DF_KEY, system_timelock_cap); transfer::share_object(self); } diff --git a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system_state_inner.move b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system_state_inner.move index 18c0632784c..21473700282 100644 --- a/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system_state_inner.move +++ b/crates/iota-e2e-tests/tests/framework_upgrades/mock_iota_systems/shallow_upgrade/sources/iota_system_state_inner.move @@ -8,6 +8,7 @@ module iota_system::iota_system_state_inner { use iota::event; use iota::iota::IOTA; use iota::iota::IotaTreasuryCap; + use iota::system_admin_cap::IotaSystemAdminCap; use iota::table::{Self, Table}; use iota_system::validator::ValidatorV1; @@ -49,6 +50,7 @@ module iota_system::iota_system_state_inner { validators: ValidatorSetV1, storage_fund: Balance, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, reference_gas_price: u64, safe_mode: bool, epoch_start_timestamp_ms: u64, @@ -64,6 +66,7 @@ module iota_system::iota_system_state_inner { validators: ValidatorSetV1, storage_fund: Balance, parameters: SystemParametersV1, + iota_system_admin_cap: IotaSystemAdminCap, reference_gas_price: u64, safe_mode: bool, epoch_start_timestamp_ms: u64, @@ -77,6 +80,7 @@ module iota_system::iota_system_state_inner { protocol_version: u64, epoch_start_timestamp_ms: u64, epoch_duration_ms: u64, + iota_system_admin_cap: IotaSystemAdminCap, ctx: &mut TxContext, ): IotaSystemStateV1 { let validators = new_validator_set(validators, ctx); @@ -91,6 +95,7 @@ module iota_system::iota_system_state_inner { epoch_duration_ms, extra_fields: bag::new(ctx), }, + iota_system_admin_cap, reference_gas_price: 1, safe_mode: false, epoch_start_timestamp_ms, @@ -167,6 +172,7 @@ module iota_system::iota_system_state_inner { validators, storage_fund, parameters, + iota_system_admin_cap, reference_gas_price, safe_mode, epoch_start_timestamp_ms, @@ -182,6 +188,7 @@ module iota_system::iota_system_state_inner { validators, storage_fund, parameters, + iota_system_admin_cap, reference_gas_price, safe_mode, epoch_start_timestamp_ms, diff --git a/crates/iota-genesis-builder/src/lib.rs b/crates/iota-genesis-builder/src/lib.rs index 27f77ebf443..a4d0f17607c 100644 --- a/crates/iota-genesis-builder/src/lib.rs +++ b/crates/iota-genesis-builder/src/lib.rs @@ -64,6 +64,7 @@ use iota_types::{ programmable_transaction_builder::ProgrammableTransactionBuilder, randomness_state::{RANDOMNESS_MODULE_NAME, RANDOMNESS_STATE_CREATE_FUNCTION_NAME}, stardust::stardust_to_iota_address, + system_admin_cap::IOTA_SYSTEM_ADMIN_CAP_MODULE_NAME, timelock::{ stardust_upgrade_label::STARDUST_UPGRADE_LABEL_VALUE, timelocked_staked_iota::TimelockedStakedIota, @@ -1470,11 +1471,11 @@ pub fn generate_genesis_system_object( vec![pre_minted_supply], ); - // Step 5: Create System Timelock Cap. - let system_timelock_cap = builder.programmable_move_call( + // Step 5: Create System Admin Cap. + let system_admin_cap = builder.programmable_move_call( IOTA_FRAMEWORK_PACKAGE_ID, - ident_str!("timelock").to_owned(), - ident_str!("new_system_timelock_cap").to_owned(), + IOTA_SYSTEM_ADMIN_CAP_MODULE_NAME.to_owned(), + ident_str!("new_system_admin_cap").to_owned(), vec![], vec![], ); @@ -1493,7 +1494,7 @@ pub fn generate_genesis_system_object( .map(|a| builder.input(a)) .collect::>()?; arguments.append(&mut call_arg_arguments); - arguments.push(system_timelock_cap); + arguments.push(system_admin_cap); builder.programmable_move_call( IOTA_SYSTEM_ADDRESS.into(), ident_str!("genesis").to_owned(), diff --git a/crates/iota-json-rpc/src/coin_api.rs b/crates/iota-json-rpc/src/coin_api.rs index 0acf253cbd1..226c0ba2935 100644 --- a/crates/iota-json-rpc/src/coin_api.rs +++ b/crates/iota-json-rpc/src/coin_api.rs @@ -1261,6 +1261,7 @@ mod tests { IotaSystemStateV1, StorageFundV1, SystemParametersV1, ValidatorSetV1, }, }, + system_admin_cap::IotaSystemAdminCap, }; use mockall::predicate; @@ -1427,6 +1428,7 @@ mod tests { validator_low_stake_grace_period: Default::default(), extra_fields: Default::default(), }, + iota_system_admin_cap: IotaSystemAdminCap {}, reference_gas_price: Default::default(), validator_report_records: VecMap { contents: Default::default(), diff --git a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs index cd5f6ba87ef..f4797f3f4e2 100644 --- a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs +++ b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs @@ -28,6 +28,7 @@ use crate::{ iota_system_state::epoch_start_iota_system_state::EpochStartSystemState, multiaddr::Multiaddr, storage::ObjectStore, + system_admin_cap::IotaSystemAdminCap, }; const E_METADATA_INVALID_POP: u64 = 0; @@ -444,6 +445,7 @@ pub struct IotaSystemStateV1 { pub validators: ValidatorSetV1, pub storage_fund: StorageFundV1, pub parameters: SystemParametersV1, + pub iota_system_admin_cap: IotaSystemAdminCap, pub reference_gas_price: u64, pub validator_report_records: VecMap>, pub safe_mode: bool, @@ -617,6 +619,7 @@ impl IotaSystemStateTrait for IotaSystemStateV1 { validator_low_stake_grace_period, extra_fields: _, }, + iota_system_admin_cap: _, reference_gas_price, validator_report_records: VecMap { diff --git a/crates/iota-types/src/iota_system_state/simtest_iota_system_state_inner.rs b/crates/iota-types/src/iota_system_state/simtest_iota_system_state_inner.rs index e5b5a5376f8..3f88e8be2b4 100644 --- a/crates/iota-types/src/iota_system_state/simtest_iota_system_state_inner.rs +++ b/crates/iota-types/src/iota_system_state/simtest_iota_system_state_inner.rs @@ -32,6 +32,7 @@ pub struct SimTestIotaSystemStateV1 { pub validators: SimTestValidatorSetV1, pub storage_fund: Balance, pub parameters: SimTestSystemParametersV1, + pub iota_system_admin_cap: IotaSystemAdminCap, pub reference_gas_price: u64, pub safe_mode: bool, pub epoch_start_timestamp_ms: u64, @@ -231,6 +232,7 @@ pub struct SimTestIotaSystemStateShallowV1 { pub validators: SimTestValidatorSetV1, pub storage_fund: Balance, pub parameters: SimTestSystemParametersV1, + pub iota_system_admin_cap: IotaSystemAdminCap, pub reference_gas_price: u64, pub safe_mode: bool, pub epoch_start_timestamp_ms: u64, @@ -373,6 +375,7 @@ pub struct SimTestIotaSystemStateDeepV1 { pub validators: SimTestValidatorSetDeepV1, pub storage_fund: Balance, pub parameters: SimTestSystemParametersV1, + pub iota_system_admin_cap: IotaSystemAdminCap, pub reference_gas_price: u64, pub safe_mode: bool, pub epoch_start_timestamp_ms: u64, diff --git a/crates/iota-types/src/lib.rs b/crates/iota-types/src/lib.rs index 985c0f23a4f..962434c3c2b 100644 --- a/crates/iota-types/src/lib.rs +++ b/crates/iota-types/src/lib.rs @@ -85,6 +85,7 @@ pub mod signature_verification; pub mod stardust; pub mod storage; pub mod supported_protocol_versions; +pub mod system_admin_cap; pub mod timelock; pub mod traffic_control; pub mod transaction; diff --git a/crates/iota-types/src/system_admin_cap.rs b/crates/iota-types/src/system_admin_cap.rs new file mode 100644 index 00000000000..0d68982a0f7 --- /dev/null +++ b/crates/iota-types/src/system_admin_cap.rs @@ -0,0 +1,34 @@ +// Copyright (c) 2024 IOTA Stiftung +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use move_core_types::{ident_str, identifier::IdentStr}; + +pub const IOTA_SYSTEM_ADMIN_CAP_MODULE_NAME: &IdentStr = ident_str!("system_admin_cap"); +pub const IOTA_SYSTEM_ADMIN_CAP_STRUCT_NAME: &IdentStr = ident_str!("IotaSystemAdminCap"); + +pub use checked::*; + +#[iota_macros::with_checked_arithmetic] +mod checked { + use move_core_types::language_storage::StructTag; + use serde::{Deserialize, Serialize}; + + use super::*; + use crate::IOTA_FRAMEWORK_ADDRESS; + + // Rust version of the IotaSystemAdminCap type + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] + pub struct IotaSystemAdminCap {} + + impl IotaSystemAdminCap { + pub fn type_() -> StructTag { + StructTag { + address: IOTA_FRAMEWORK_ADDRESS, + module: IOTA_SYSTEM_ADMIN_CAP_MODULE_NAME.to_owned(), + name: IOTA_SYSTEM_ADMIN_CAP_STRUCT_NAME.to_owned(), + type_params: Vec::new(), + } + } + } +} From 0fa27f654e4786b264220fc06d7902e176ccd694 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 5 Nov 2024 16:40:25 +0200 Subject: [PATCH 4/8] feat(iota-framework): store system display objects in the system state --- .../iota-system/sources/iota_system.move | 37 ++++++++++++++-- .../sources/iota_system_display.move | 40 +++++++++++++++++- .../sources/iota_system_state_inner.move | 25 +++++++++++ .../packages_compiled/iota-system | Bin 42939 -> 43793 bytes crates/iota-framework/published_api.txt | 36 ++++++++++++++-- 5 files changed, 129 insertions(+), 9 deletions(-) diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index dc8801f5be5..813fbc0c81a 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -500,6 +500,39 @@ module iota_system::iota_system { self.active_validator_addresses() } + /// Returns the IOTA system admin capability reference. + public(package) fun load_iota_system_admin_cap(self: &mut IotaSystemState): &IotaSystemAdminCap { + self.load_system_state().iota_system_admin_cap() + } + + /// Add an object with the specified key to the extra fields collection. + public(package) fun add_extra_field( + wrapper: &mut IotaSystemState, + key: K, + value: V, + ) { + let self = load_system_state_mut(wrapper); + self.add_extra_field(key, value); + } + + /// Immutable borrows the value associated with the key in the extra fields. + public(package) fun borrow_extra_field( + wrapper: &mut IotaSystemState, + key: K, + ): &V { + let self = load_system_state(wrapper); + self.borrow_extra_field(key) + } + + /// Mutable borrows the value associated with the key in the extra fields. + public(package) fun borrow_extra_field_mut( + wrapper: &mut IotaSystemState, + key: K, + ): &mut V { + let self = load_system_state_mut(wrapper); + self.borrow_extra_field_mut(key) + } + #[allow(unused_function)] /// This function should be called at the end of an epoch, and advances the system to the next epoch. /// It does the following things: @@ -560,10 +593,6 @@ module iota_system::iota_system { inner } - public(package) fun load_iota_system_admin_cap(self: &mut IotaSystemState): &IotaSystemAdminCap { - self.load_system_state().iota_system_admin_cap() - } - #[allow(unused_function)] /// Returns the voting power of the active validators, values are voting power in the scale of 10000. fun validator_voting_powers(wrapper: &mut IotaSystemState): VecMap { diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move index bc1249d6388..a751e0ec855 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_display.move @@ -3,7 +3,7 @@ module iota_system::iota_system_display { - use std::string::String; + use std::string::{Self, String}; use iota::display::{Self, Display}; @@ -21,7 +21,7 @@ module iota_system::iota_system_display { display::system_new(sys_admin_cap, ctx) } - /// Create a new Display object with a set of fields using `IotaSystemAdminCap`. + /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. public(package) fun system_new_with_fields( iota_system: &mut IotaSystemState, fields: vector, @@ -34,4 +34,40 @@ module iota_system::iota_system_display { // Create a `Display` object with fields. display::system_new_with_fields(sys_admin_cap, fields, values, ctx) } + + /// Add a display object to the system state store. + public(package) fun add_display_object( + iota_system: &mut IotaSystemState, + display: Display + ) { + // Get a display object unique key. + let key = display_object_key(); + + // Store the display object. + iota_system.add_extra_field(key, display); + } + + /// Borrow an immutable display object from the system state store. + public(package) fun borrow_display_object(iota_system: &mut IotaSystemState): &Display { + // Get a display object unique key. + let key = display_object_key(); + + // Borrow the display object. + iota_system.borrow_extra_field(key) + } + + /// Borrow a mutable display object from the system state store. + public(package) fun borrow_display_object_mut(iota_system: &mut IotaSystemState): &mut Display { + // Get a display object unique key. + let key = display_object_key(); + + // Borrow the display object. + iota_system.borrow_extra_field_mut(key) + } + + /// Return a fully qualified type name with the original package IDs + /// that is used as a display object key. + fun display_object_key(): String { + string::from_ascii(std::type_name::get_with_original_ids().into_string()) + } } diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index 5e701a31961..4decabb15a3 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -442,6 +442,31 @@ module iota_system::iota_system_state_inner { } } + /// Add an object with the specified key to the extra fields collection. + public(package) fun add_extra_field( + self: &mut IotaSystemStateV1, + key: K, + value: V, + ) { + self.extra_fields.add(key, value); + } + + /// Immutable borrows the value associated with the key in the extra fields. + public(package) fun borrow_extra_field( + self: &IotaSystemStateV1, + key: K, + ): &V { + self.extra_fields.borrow(key) + } + + /// Mutable borrows the value associated with the key in the extra fields. + public(package) fun borrow_extra_field_mut( + self: &mut IotaSystemStateV1, + key: K, + ): &mut V { + self.extra_fields.borrow_mut(key) + } + // ==== validator metadata management functions ==== /// Create a new `UnverifiedValidatorOperationCap`, transfer it to the diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index 4030df4d729ca96768670124f066bc0cae74ae8b..6413665c0ac2ed210acfb3f72c230d2aef0c5231 100644 GIT binary patch delta 5385 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 delta 4486 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 diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index b48aed22add..00caaee365a 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -673,6 +673,15 @@ report_validator_impl undo_report_validator_impl fun 0x3::iota_system_state_inner +add_extra_field + public(package) fun + 0x3::iota_system_state_inner +borrow_extra_field + public(package) fun + 0x3::iota_system_state_inner +borrow_extra_field_mut + public(package) fun + 0x3::iota_system_state_inner rotate_operation_cap public(package) fun 0x3::iota_system_state_inner @@ -889,6 +898,18 @@ pool_exchange_rates active_validator_addresses public fun 0x3::iota_system +load_iota_system_admin_cap + public(package) fun + 0x3::iota_system +add_extra_field + public(package) fun + 0x3::iota_system +borrow_extra_field + public(package) fun + 0x3::iota_system +borrow_extra_field_mut + public(package) fun + 0x3::iota_system advance_epoch fun 0x3::iota_system @@ -901,9 +922,6 @@ load_system_state_mut load_inner_maybe_upgrade fun 0x3::iota_system -load_iota_system_admin_cap - public(package) fun - 0x3::iota_system validator_voting_powers fun 0x3::iota_system @@ -1006,6 +1024,18 @@ system_new system_new_with_fields public(package) fun 0x3::iota_system_display +add_display_object + public(package) fun + 0x3::iota_system_display +borrow_display_object + public(package) fun + 0x3::iota_system_display +borrow_display_object_mut + public(package) fun + 0x3::iota_system_display +display_object_key + fun + 0x3::iota_system_display secp256k1_ecrecover public fun 0x2::ecdsa_k1 From 121180fae37870358e4842ce7788f271118f4a08 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 5 Nov 2024 17:45:29 +0200 Subject: [PATCH 5/8] refactor(iota-framework): rename `iota_system_display` to `system_display` --- ...ystem_display.move => system_display.move} | 6 +++--- .../packages_compiled/iota-system | Bin 43793 -> 43803 bytes crates/iota-framework/published_api.txt | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) rename crates/iota-framework/packages/iota-system/sources/{iota_system_display.move => system_display.move} (94%) diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move b/crates/iota-framework/packages/iota-system/sources/system_display.move similarity index 94% rename from crates/iota-framework/packages/iota-system/sources/iota_system_display.move rename to crates/iota-framework/packages/iota-system/sources/system_display.move index a751e0ec855..cb06891bc2a 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_display.move +++ b/crates/iota-framework/packages/iota-system/sources/system_display.move @@ -1,7 +1,7 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -module iota_system::iota_system_display { +module iota_system::system_display { use std::string::{Self, String}; @@ -10,7 +10,7 @@ module iota_system::iota_system_display { use iota_system::iota_system::IotaSystemState; /// Create an empty `Display` object with `IotaSystemAdminCap`. - public(package) fun system_new( + public(package) fun new( iota_system: &mut IotaSystemState, ctx: &mut TxContext ): Display { @@ -22,7 +22,7 @@ module iota_system::iota_system_display { } /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. - public(package) fun system_new_with_fields( + public(package) fun new_with_fields( iota_system: &mut IotaSystemState, fields: vector, values: vector, diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index 6413665c0ac2ed210acfb3f72c230d2aef0c5231..1aff414566787f1bc8ec150867c2ec23d8e5b76c 100644 GIT binary patch delta 487 zcmZY5&1(~35C-sPCY#+&HtDWuK6d+|p{=dcN};f!BhH^PYQnfAh@13&XrQ=C{ZE@k@)otFNtm zrRCbcb6e&QzZ`!S*ooJ{iJ5$!H{6$b6C<4Cejemup5Uu|jo0})Z(wyN}2^jSkcT!g=Ni*Da@J{P_QK}#)QkUI56!CAJLs>5MKxI;%@ICm%0*J}~YDz?j--4<#>+6D8~`Lqv9LNj+{atxc6&IMcHP zXJ*2JQG6^uAx#pe%N_&i`|~)L36ME zuv%+0A8p?~P)~RJL+h1o(OT%K2Wfhzo^;Qy9!2cW(XB+stik7`z9CX%Q|1wco;Q#;t delta 499 zcmZwDOG_J36bJBgPHtuS997n%-GGPoL#F%z*kz_7{H8%0fCH{Of@jRz=q1hkcF@(C-8QPvv~GBk{Zs(K2Q_5RKTR{MxL|4pnS0hf4@%v0n$X zG{BU*`B>>>s;V04Vn%zJu^wi;7zeYadQ+-59o{!Lg_~Ym-&$U*@6@+eKQFGV)i*vZ z@5ns*VPpRt$#0vvkPZzUdqPuwbn#ejpS8FCiWuk7C2LPxfixv3O97 Date: Wed, 6 Nov 2024 11:14:21 +0200 Subject: [PATCH 6/8] feat(iota-framework): added `contains_display_object` function --- .../iota-system/sources/iota_system.move | 9 +++++++++ .../sources/iota_system_state_inner.move | 8 ++++++++ .../iota-system/sources/system_display.move | 9 +++++++++ .../packages_compiled/iota-system | Bin 43803 -> 43987 bytes crates/iota-framework/published_api.txt | 9 +++++++++ 5 files changed, 35 insertions(+) diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index 813fbc0c81a..e8bb079eccc 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -533,6 +533,15 @@ module iota_system::iota_system { self.borrow_extra_field_mut(key) } + /// Returns true if there is an extra field associated with the key. + public(package) fun contains_extra_field( + wrapper: &mut IotaSystemState, + key: K, + ): bool { + let self = load_system_state_mut(wrapper); + self.contains_extra_field(key) + } + #[allow(unused_function)] /// This function should be called at the end of an epoch, and advances the system to the next epoch. /// It does the following things: diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index 4decabb15a3..49315a79e60 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -467,6 +467,14 @@ module iota_system::iota_system_state_inner { self.extra_fields.borrow_mut(key) } + /// Returns true if there is an extra field associated with the key. + public(package) fun contains_extra_field( + self: &IotaSystemStateV1, + key: K, + ): bool { + self.extra_fields.contains(key) + } + // ==== validator metadata management functions ==== /// Create a new `UnverifiedValidatorOperationCap`, transfer it to the diff --git a/crates/iota-framework/packages/iota-system/sources/system_display.move b/crates/iota-framework/packages/iota-system/sources/system_display.move index cb06891bc2a..92c7c2ada6a 100644 --- a/crates/iota-framework/packages/iota-system/sources/system_display.move +++ b/crates/iota-framework/packages/iota-system/sources/system_display.move @@ -65,6 +65,15 @@ module iota_system::system_display { iota_system.borrow_extra_field_mut(key) } + /// Returns true if the related display object exists. + public(package) fun contains_display_object(iota_system: &mut IotaSystemState): bool { + // Get a display object unique key. + let key = display_object_key(); + + // Check if the related display object exists. + iota_system.contains_extra_field(key) + } + /// Return a fully qualified type name with the original package IDs /// that is used as a display object key. fun display_object_key(): String { diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index 1aff414566787f1bc8ec150867c2ec23d8e5b76c..c8bcab19473e4052d13337b4ce630ccacc8c70aa 100644 GIT binary patch delta 4510 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 JRYbW6{{u$v#>4;s diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index 789dfd366b4..dcfa87048bb 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -682,6 +682,9 @@ borrow_extra_field borrow_extra_field_mut public(package) fun 0x3::iota_system_state_inner +contains_extra_field + public(package) fun + 0x3::iota_system_state_inner rotate_operation_cap public(package) fun 0x3::iota_system_state_inner @@ -910,6 +913,9 @@ borrow_extra_field borrow_extra_field_mut public(package) fun 0x3::iota_system +contains_extra_field + public(package) fun + 0x3::iota_system advance_epoch fun 0x3::iota_system @@ -1033,6 +1039,9 @@ borrow_display_object borrow_display_object_mut public(package) fun 0x3::system_display +contains_display_object + public(package) fun + 0x3::system_display display_object_key fun 0x3::system_display From 52355007d9afc174700b5d0962c29a63095b520e Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 8 Nov 2024 14:25:39 +0200 Subject: [PATCH 7/8] feat: improved system displays implementation --- .../authority/authority_per_epoch_store.rs | 21 +++- .../authority/epoch_start_configuration.rs | 24 +++- .../iota-framework/sources/display.move | 5 + .../sources/system_admin_cap.move | 3 +- .../iota-system/sources/iota_system.move | 74 +++++++------ .../sources/iota_system_state_inner.move | 104 +++++++++++++----- .../iota-system/sources/system_display.move | 82 -------------- .../packages_compiled/iota-framework | Bin 70167 -> 70208 bytes .../packages_compiled/iota-system | Bin 43987 -> 43700 bytes crates/iota-framework/published_api.txt | 55 +++++---- crates/iota-json-rpc/src/coin_api.rs | 3 + crates/iota-types/src/display.rs | 4 +- .../iota_system_state_inner_v1.rs | 2 + .../iota-types/src/iota_system_state/mod.rs | 44 +++++++- 14 files changed, 241 insertions(+), 180 deletions(-) delete mode 100644 crates/iota-framework/packages/iota-system/sources/system_display.move diff --git a/crates/iota-core/src/authority/authority_per_epoch_store.rs b/crates/iota-core/src/authority/authority_per_epoch_store.rs index cc6340a840e..f5468bf9032 100644 --- a/crates/iota-core/src/authority/authority_per_epoch_store.rs +++ b/crates/iota-core/src/authority/authority_per_epoch_store.rs @@ -41,8 +41,9 @@ use iota_types::{ effects::TransactionEffects, error::{IotaError, IotaResult}, executable_transaction::{TrustedExecutableTransaction, VerifiedExecutableTransaction}, - iota_system_state::epoch_start_iota_system_state::{ - EpochStartSystemState, EpochStartSystemStateTrait, + iota_system_state::{ + display_object_key, + epoch_start_iota_system_state::{EpochStartSystemState, EpochStartSystemStateTrait}, }, message_envelope::TrustedEnvelope, messages_checkpoint::{ @@ -62,6 +63,7 @@ use iota_types::{ }; use itertools::{Itertools, izip}; use move_bytecode_utils::module_cache::SyncModuleCache; +use move_core_types::language_storage::StructTag; use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use prometheus::IntCounter; use serde::{Deserialize, Serialize}; @@ -959,6 +961,21 @@ impl AuthorityPerEpochStore { self.epoch_start_configuration.bridge_committee_initiated() } + pub fn system_display_object_created(&self, ty: StructTag, version: u16) -> bool { + let key = display_object_key(ty); + + let object_version = self + .epoch_start_configuration + .system_display_object_version(&key) + .cloned(); + + let Some(object_version) = object_version else { + return false; + }; + + version <= object_version + } + pub fn get_parent_path(&self) -> PathBuf { self.parent_path.clone() } diff --git a/crates/iota-core/src/authority/epoch_start_configuration.rs b/crates/iota-core/src/authority/epoch_start_configuration.rs index 7ae6446577a..c496cddb139 100644 --- a/crates/iota-core/src/authority/epoch_start_configuration.rs +++ b/crates/iota-core/src/authority/epoch_start_configuration.rs @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::fmt; +use std::{collections::HashMap, fmt}; use enum_dispatch::enum_dispatch; use iota_config::{ExecutionCacheConfig, NodeConfig}; @@ -13,8 +13,9 @@ use iota_types::{ deny_list_v1::get_deny_list_obj_initial_shared_version, epoch_data::EpochData, error::IotaResult, - iota_system_state::epoch_start_iota_system_state::{ - EpochStartSystemState, EpochStartSystemStateTrait, + iota_system_state::{ + epoch_start_iota_system_state::{EpochStartSystemState, EpochStartSystemStateTrait}, + get_system_display_objects, }, messages_checkpoint::{CheckpointDigest, CheckpointTimestamp}, randomness_state::get_randomness_state_obj_initial_shared_version, @@ -34,6 +35,8 @@ pub trait EpochStartConfigTrait { fn coin_deny_list_obj_initial_shared_version(&self) -> SequenceNumber; fn bridge_obj_initial_shared_version(&self) -> Option; fn bridge_committee_initiated(&self) -> bool; + fn system_display_object_versions(&self) -> impl Iterator; + fn system_display_object_version(&self, key: &str) -> Option<&u16>; fn execution_cache_type(&self) -> ExecutionCacheConfigType { if self.flags().contains(&EpochFlag::WritebackCacheEnabled) { @@ -115,6 +118,10 @@ impl EpochStartConfiguration { let bridge_obj_initial_shared_version = get_bridge_obj_initial_shared_version(object_store)?; let bridge_committee_initiated = is_bridge_committee_initiated(object_store)?; + let system_display_object_versions = get_system_display_objects(object_store)? + .into_iter() + .map(|(key, display)| (key, display.version)) + .collect(); Ok(Self::V1(EpochStartConfigurationV1 { system_state, epoch_digest, @@ -124,6 +131,7 @@ impl EpochStartConfiguration { coin_deny_list_obj_initial_shared_version, bridge_obj_initial_shared_version, bridge_committee_initiated, + system_display_object_versions, })) } @@ -143,6 +151,7 @@ impl EpochStartConfiguration { .coin_deny_list_obj_initial_shared_version, bridge_obj_initial_shared_version: config.bridge_obj_initial_shared_version, bridge_committee_initiated: config.bridge_committee_initiated, + system_display_object_versions: config.system_display_object_versions.clone(), }), _ => panic!( "This function is only implemented for the latest version of EpochStartConfiguration" @@ -174,6 +183,7 @@ pub struct EpochStartConfigurationV1 { coin_deny_list_obj_initial_shared_version: SequenceNumber, bridge_obj_initial_shared_version: Option, bridge_committee_initiated: bool, + system_display_object_versions: HashMap, } impl EpochStartConfigTrait for EpochStartConfigurationV1 { @@ -208,4 +218,12 @@ impl EpochStartConfigTrait for EpochStartConfigurationV1 { fn bridge_committee_initiated(&self) -> bool { self.bridge_committee_initiated } + + fn system_display_object_versions(&self) -> impl Iterator { + self.system_display_object_versions.iter() + } + + fn system_display_object_version(&self, key: &str) -> Option<&u16> { + self.system_display_object_versions.get(key) + } } diff --git a/crates/iota-framework/packages/iota-framework/sources/display.move b/crates/iota-framework/packages/iota-framework/sources/display.move index 8acd7442ae8..037889fcacf 100644 --- a/crates/iota-framework/packages/iota-framework/sources/display.move +++ b/crates/iota-framework/packages/iota-framework/sources/display.move @@ -164,6 +164,11 @@ module iota::display { pub.from_package() } + /// Read the `id` field. + public fun id(d: &Display): &ID { + d.id.uid_as_inner() + } + /// Read the `version` field. public fun version(d: &Display): u16 { d.version diff --git a/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move b/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move index 2483ca4927a..97a696bddb1 100644 --- a/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move +++ b/crates/iota-framework/packages/iota-framework/sources/system_admin_cap.move @@ -10,7 +10,8 @@ module iota::system_admin_cap { const ENotSystemAddress: u64 = 1; /// `IotaSystemAdminCap` allows to perform privileged IOTA system operations. - /// For example, packing and unpacking `TimeLock`s during staking, etc. + /// For example, packing and unpacking `TimeLock`s during staking, + /// creating `Display` objects without `Publisher`, etc. public struct IotaSystemAdminCap has store {} #[allow(unused_function)] diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index e8bb079eccc..8c7103a94b6 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -41,19 +41,21 @@ module iota_system::iota_system { use iota::balance::Balance; + use std::string::String; use iota::coin::Coin; - use iota_system::staking_pool::StakedIota; + use iota::display::Display; use iota::iota::{IOTA, IotaTreasuryCap}; use iota::table::Table; use iota::system_admin_cap::IotaSystemAdminCap; - use iota_system::validator::ValidatorV1; - use iota_system::validator_cap::UnverifiedValidatorOperationCap; - use iota_system::iota_system_state_inner::{Self, SystemParametersV1, IotaSystemStateV1}; - use iota_system::staking_pool::PoolTokenExchangeRate; use iota::dynamic_field; use iota::vec_map::VecMap; + use iota_system::iota_system_state_inner::{Self, SystemParametersV1, IotaSystemStateV1}; + use iota_system::staking_pool::{PoolTokenExchangeRate, StakedIota}; + use iota_system::validator::ValidatorV1; + use iota_system::validator_cap::UnverifiedValidatorOperationCap; + #[test_only] use iota::balance; #[test_only] use iota_system::validator_set::ValidatorSetV1; #[test_only] use iota::vec_set::VecSet; @@ -505,41 +507,51 @@ module iota_system::iota_system { self.load_system_state().iota_system_admin_cap() } - /// Add an object with the specified key to the extra fields collection. - public(package) fun add_extra_field( + /// Create an empty `Display` object with `IotaSystemAdminCap`. + public(package) fun new_system_display( wrapper: &mut IotaSystemState, - key: K, - value: V, - ) { - let self = load_system_state_mut(wrapper); - self.add_extra_field(key, value); + ctx: &mut TxContext, + ): Display { + let self = wrapper.load_system_state(); + self.new_system_display(ctx) } - /// Immutable borrows the value associated with the key in the extra fields. - public(package) fun borrow_extra_field( + /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. + public(package) fun new_system_display_with_fields( wrapper: &mut IotaSystemState, - key: K, - ): &V { - let self = load_system_state(wrapper); - self.borrow_extra_field(key) + fields: vector, + values: vector, + ctx: &mut TxContext, + ): Display { + let self = wrapper.load_system_state(); + self.new_system_display_with_fields(fields, values, ctx) } - /// Mutable borrows the value associated with the key in the extra fields. - public(package) fun borrow_extra_field_mut( + /// Insert a display object. + public(package) fun insert_display_object( wrapper: &mut IotaSystemState, - key: K, - ): &mut V { - let self = load_system_state_mut(wrapper); - self.borrow_extra_field_mut(key) + display: Display, + ) { + let self = wrapper.load_system_state_mut(); + self.insert_display_object(display); } - /// Returns true if there is an extra field associated with the key. - public(package) fun contains_extra_field( - wrapper: &mut IotaSystemState, - key: K, - ): bool { - let self = load_system_state_mut(wrapper); - self.contains_extra_field(key) + /// Borrow an immutable display object. + public(package) fun borrow_display_object(wrapper: &mut IotaSystemState): &Display { + let self = wrapper.load_system_state(); + self.borrow_display_object() + } + + /// Borrow a mutable display object. + public(package) fun borrow_display_object_mut(wrapper: &mut IotaSystemState): &mut Display { + let self = wrapper.load_system_state_mut(); + self.borrow_display_object_mut() + } + + /// Returns true if the related display object exists. + public(package) fun contains_display_object(wrapper: &mut IotaSystemState): bool { + let self = wrapper.load_system_state(); + self.contains_display_object() } #[allow(unused_function)] diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index 49315a79e60..f092e1ba699 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -3,21 +3,24 @@ // SPDX-License-Identifier: Apache-2.0 module iota_system::iota_system_state_inner { + use std::string::{Self, String}; + use iota::balance::{Self, Balance}; use iota::coin::Coin; + use iota::display::{Self, Display}; use iota::iota::{IOTA, IotaTreasuryCap}; use iota::system_admin_cap::IotaSystemAdminCap; + use iota::vec_map::{Self, VecMap}; + use iota::vec_set::{Self, VecSet}; + use iota::event; + use iota::table::Table; + use iota::bag::{Self, Bag}; + use iota_system::validator::{Self, ValidatorV1}; use iota_system::validator_set::{Self, ValidatorSetV1}; use iota_system::validator_cap::{UnverifiedValidatorOperationCap, ValidatorOperationCap}; use iota_system::storage_fund::{Self, StorageFundV1}; use iota_system::staking_pool::{PoolTokenExchangeRate, StakedIota}; - use iota::vec_map::{Self, VecMap}; - use iota::vec_set::{Self, VecSet}; - use iota::event; - use iota::table::Table; - use iota::bag::Bag; - use iota::bag; // same as in validator_set const ACTIVE_VALIDATOR_ONLY: u8 = 1; @@ -104,6 +107,10 @@ module iota_system::iota_system_state_inner { /// Unix timestamp of the current epoch start epoch_start_timestamp_ms: u64, + + /// A map contains the system display object IDs stored in the extra fields. + system_display_objects: VecMap, + /// Any extra fields that's not defined statically. extra_fields: Bag, } @@ -171,6 +178,7 @@ module iota_system::iota_system_state_inner { safe_mode_storage_rebates: 0, safe_mode_non_refundable_storage_fee: 0, epoch_start_timestamp_ms, + system_display_objects: vec_map::empty(), extra_fields: bag::new(ctx), }; system_state @@ -442,37 +450,75 @@ module iota_system::iota_system_state_inner { } } - /// Add an object with the specified key to the extra fields collection. - public(package) fun add_extra_field( - self: &mut IotaSystemStateV1, - key: K, - value: V, - ) { - self.extra_fields.add(key, value); + /// Create an empty `Display` object with `IotaSystemAdminCap`. + public(package) fun new_system_display( + self: &IotaSystemStateV1, + ctx: &mut TxContext, + ): Display { + display::system_new(&self.iota_system_admin_cap, ctx) } - /// Immutable borrows the value associated with the key in the extra fields. - public(package) fun borrow_extra_field( + /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. + public(package) fun new_system_display_with_fields( self: &IotaSystemStateV1, - key: K, - ): &V { - self.extra_fields.borrow(key) + fields: vector, + values: vector, + ctx: &mut TxContext, + ): Display { + display::system_new_with_fields(&self.iota_system_admin_cap, fields, values, ctx) } - /// Mutable borrows the value associated with the key in the extra fields. - public(package) fun borrow_extra_field_mut( + /// Insert a display object. + public(package) fun insert_display_object( self: &mut IotaSystemStateV1, - key: K, - ): &mut V { - self.extra_fields.borrow_mut(key) + display: Display, + ) { + // Get a display object unique key. + let key = display_object_key(); + let display_id = *display.id(); + + // Store the display object. + self.system_display_objects.insert(key, display_id); + self.extra_fields.add(display_id, display); } - /// Returns true if there is an extra field associated with the key. - public(package) fun contains_extra_field( - self: &IotaSystemStateV1, - key: K, - ): bool { - self.extra_fields.contains(key) + /// Borrow an immutable display object. + public(package) fun borrow_display_object(self: &IotaSystemStateV1): &Display { + // Get a display object unique key. + let key = display_object_key(); + + // Get the id. + let display_id = *self.system_display_objects.get(&key); + + // Borrow the display object. + self.extra_fields.borrow(display_id) + } + + /// Borrow a mutable display object. + public(package) fun borrow_display_object_mut(self: &mut IotaSystemStateV1): &mut Display { + // Get a display object unique key. + let key = display_object_key(); + + // Get the id. + let display_id = *self.system_display_objects.get(&key); + + // Borrow the display object. + self.extra_fields.borrow_mut(display_id) + } + + /// Returns true if the related display object exists. + public(package) fun contains_display_object(self: &IotaSystemStateV1): bool { + // Get a display object unique key. + let key = display_object_key(); + + // Check if the related display object exists. + self.system_display_objects.contains(&key) + } + + /// Return a fully qualified type name with the original package IDs + /// that is used as a display object key. + fun display_object_key(): String { + string::from_ascii(std::type_name::get_with_original_ids().into_string()) } // ==== validator metadata management functions ==== diff --git a/crates/iota-framework/packages/iota-system/sources/system_display.move b/crates/iota-framework/packages/iota-system/sources/system_display.move deleted file mode 100644 index 92c7c2ada6a..00000000000 --- a/crates/iota-framework/packages/iota-system/sources/system_display.move +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2024 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -module iota_system::system_display { - - use std::string::{Self, String}; - - use iota::display::{Self, Display}; - - use iota_system::iota_system::IotaSystemState; - - /// Create an empty `Display` object with `IotaSystemAdminCap`. - public(package) fun new( - iota_system: &mut IotaSystemState, - ctx: &mut TxContext - ): Display { - // Load the `IotaSystemAdminCap` instance. - let sys_admin_cap = iota_system.load_iota_system_admin_cap(); - - // Create a `Display` object. - display::system_new(sys_admin_cap, ctx) - } - - /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. - public(package) fun new_with_fields( - iota_system: &mut IotaSystemState, - fields: vector, - values: vector, - ctx: &mut TxContext - ): Display { - // Load the `IotaSystemAdminCap` instance. - let sys_admin_cap = iota_system.load_iota_system_admin_cap(); - - // Create a `Display` object with fields. - display::system_new_with_fields(sys_admin_cap, fields, values, ctx) - } - - /// Add a display object to the system state store. - public(package) fun add_display_object( - iota_system: &mut IotaSystemState, - display: Display - ) { - // Get a display object unique key. - let key = display_object_key(); - - // Store the display object. - iota_system.add_extra_field(key, display); - } - - /// Borrow an immutable display object from the system state store. - public(package) fun borrow_display_object(iota_system: &mut IotaSystemState): &Display { - // Get a display object unique key. - let key = display_object_key(); - - // Borrow the display object. - iota_system.borrow_extra_field(key) - } - - /// Borrow a mutable display object from the system state store. - public(package) fun borrow_display_object_mut(iota_system: &mut IotaSystemState): &mut Display { - // Get a display object unique key. - let key = display_object_key(); - - // Borrow the display object. - iota_system.borrow_extra_field_mut(key) - } - - /// Returns true if the related display object exists. - public(package) fun contains_display_object(iota_system: &mut IotaSystemState): bool { - // Get a display object unique key. - let key = display_object_key(); - - // Check if the related display object exists. - iota_system.contains_extra_field(key) - } - - /// Return a fully qualified type name with the original package IDs - /// that is used as a display object key. - fun display_object_key(): String { - string::from_ascii(std::type_name::get_with_original_ids().into_string()) - } -} diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index 2c66d13a041446362f9a6551ad09fffc2f0bd559..e6ebfffe882ed98e816da31bf7c6224239e4e278 100644 GIT binary patch delta 433 zcmWlVzfK!L5XNU_Z~ypqZ|%K1pY5|TA>pr6M2alsoGKuMkkUj#NIU^Azylx}(nL|D zEdmKf0?{HN`~XRlE-9kWqV&+Eb48Zs_sx9LjAp*i7t!~N=<59F-EV!?yVn8$5`>h} zmu&qjMt`y7Q@la>i(NDIAl`^?GLQerMLm_mJjnMfIn=^_2!nOVpbI^igLznh760#O z3zz-I@w5HHB&c9uY+!EcfwqBxT5?qA97jf-MjvRgNPw1#7O-Zl5%^5b(TLeJ1DWzC zgdkgU{89S7nIN&V4xDu4n%HR9U8kG7#%!zG?vhYkDv27f2LASVhY7_d!!LK}KV`~y zPCoVr2@)2H5wXBQl50h(rfTFcEcHK5c56k&iDLv!KO8@Oo@vxHf=ZAG9_Jb!jY^UX zZD+yaYH6Z4vb0+IgYmp7b4xK>EB)no`!%_g3dvoo{anVp?ouWi<`9rDJaO9AUt1VsqCNKt+Q@B_%7phMb%B#I;D zC8dm%f)3FlQBb5qDUd6KL_tZF3C(wO&(+a=d^wLko<~=w``ef1WboT404bs1VqI)~ zpy-DB@(+C{{aIXyc&47IGhHU1^s2el%FgsZPHz+CW{EHrvz1$GIWH6V!@T@T4@jH)_o~ln+)MZB{l)BFCFmGo3ESRp~ep&#UI^ zboUiXwggCF@RT?WUmRM4+*@*#=M$>KX|;I?OqgBhN@ehb{tvJWM#v&8#{PQm_}jZX DiC{UJ diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index c8bcab19473e4052d13337b4ce630ccacc8c70aa..9441eaaaf92c1a30285eb1b25104b5416bc220e7 100644 GIT binary patch delta 7045 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, diff --git a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs index f4797f3f4e2..5191be6c45e 100644 --- a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs +++ b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs @@ -454,6 +454,7 @@ pub struct IotaSystemStateV1 { pub safe_mode_storage_rebates: u64, pub safe_mode_non_refundable_storage_fee: u64, pub epoch_start_timestamp_ms: u64, + pub system_display_objects: VecMap, pub extra_fields: Bag, // TODO: Use getters instead of all pub. } @@ -631,6 +632,7 @@ impl IotaSystemStateTrait for IotaSystemStateV1 { safe_mode_storage_rebates, safe_mode_non_refundable_storage_fee, epoch_start_timestamp_ms, + system_display_objects: _, extra_fields: _, } = self; IotaSystemStateSummary { diff --git a/crates/iota-types/src/iota_system_state/mod.rs b/crates/iota-types/src/iota_system_state/mod.rs index 5e5634a53d5..89b0ac84888 100644 --- a/crates/iota-types/src/iota_system_state/mod.rs +++ b/crates/iota-types/src/iota_system_state/mod.rs @@ -2,7 +2,7 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::fmt; +use std::{collections::HashMap, fmt}; use anyhow::Result; use enum_dispatch::enum_dispatch; @@ -18,6 +18,7 @@ use crate::{ IOTA_SYSTEM_ADDRESS, IOTA_SYSTEM_STATE_OBJECT_ID, MoveTypeTagTrait, base_types::ObjectID, committee::CommitteeWithNetworkMetadata, + display::DisplayObject, dynamic_field::{Field, get_dynamic_field_from_store, get_dynamic_field_object_from_store}, error::IotaError, id::UID, @@ -392,6 +393,47 @@ where Ok(validators) } +/// Get the system display objects stored in the system state. +pub fn get_system_display_objects( + object_store: &dyn ObjectStore, +) -> Result, IotaError> { + let system_state = get_iota_system_state(object_store)?; + + match system_state { + IotaSystemState::V1(inner) => inner + .system_display_objects + .contents + .into_iter() + .map(|entry| { + let display_object_id = entry.value.bytes; + + let display_object: DisplayObject = get_dynamic_field_from_store( + object_store, + *inner.extra_fields.id.object_id(), + &display_object_id, + ) + .map_err(|err| { + IotaError::DynamicFieldRead(format!( + "Failed to load a system display object with ID {display_object_id:?}: {err}", + )) + })?; + + Ok((entry.key, display_object)) + }) + .collect::, _>>(), + #[cfg(msim)] + _ => unimplemented!("System display objects are not implemented for mock system states"), + } +} + +/// Get a system display object unique key. +/// * ty - is a type for which a display object is created. +pub fn display_object_key(ty: StructTag) -> String { + let with_prefix = false; + + ty.to_canonical_string(with_prefix) +} + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Default)] pub struct PoolTokenExchangeRate { iota_amount: u64, From 8f82d05d29811e4829effffce13d9224a48fb6c0 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Wed, 13 Nov 2024 15:55:10 +0200 Subject: [PATCH 8/8] feat: improved system displays implementation --- crates/iota-core/src/authority.rs | 74 +++++ .../authority/authority_per_epoch_store.rs | 6 +- crates/iota-core/src/generate_format.rs | 5 +- .../iota-system/sources/iota_system.move | 45 +-- .../sources/iota_system_state_inner.move | 237 ++++++++++----- .../iota-system/sources/system_display.move | 100 +++++++ .../packages_compiled/iota-system | Bin 43700 -> 45355 bytes crates/iota-framework/published_api.txt | 33 ++- crates/iota-genesis-builder/src/lib.rs | 3 +- .../transaction_block_kind/end_of_epoch.rs | 1 + .../src/iota_transaction.rs | 38 ++- crates/iota-json-rpc/src/coin_api.rs | 3 - crates/iota-protocol-config/src/lib.rs | 35 ++- ...tocol_config__test__Mainnet_version_2.snap | 272 +++++++++++++++++ ...tocol_config__test__Testnet_version_2.snap | 272 +++++++++++++++++ ...iota_protocol_config__test__version_2.snap | 280 ++++++++++++++++++ .../iota-types/src/iota_sdk2_conversions.rs | 1 + .../iota_system_state_inner_v1.rs | 2 - .../iota_system_state_inner_v2.rs | 276 +++++++++++++++++ .../iota-types/src/iota_system_state/mod.rs | 47 ++- crates/iota-types/src/transaction.rs | 50 ++++ .../iota-adapter/src/execution_engine.rs | 72 ++++- 22 files changed, 1722 insertions(+), 130 deletions(-) create mode 100644 crates/iota-framework/packages/iota-system/sources/system_display.move create mode 100644 crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Mainnet_version_2.snap create mode 100644 crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Testnet_version_2.snap create mode 100644 crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__version_2.snap create mode 100644 crates/iota-types/src/iota_system_state/iota_system_state_inner_v2.rs diff --git a/crates/iota-core/src/authority.rs b/crates/iota-core/src/authority.rs index ea62b573629..433966c099b 100644 --- a/crates/iota-core/src/authority.rs +++ b/crates/iota-core/src/authority.rs @@ -54,6 +54,7 @@ use iota_types::committee::CommitteeTrait; use iota_types::{ IOTA_SYSTEM_ADDRESS, TypeTag, authenticator_state::get_authenticator_state, + balance::Balance, base_types::*, committee::{Committee, EpochId, ProtocolVersion}, crypto::{AuthoritySignInfo, AuthoritySignature, RandomnessRound, Signer, default_hash}, @@ -71,6 +72,8 @@ use iota_types::{ execution_status::ExecutionStatus, fp_ensure, gas::{GasCostSummary, IotaGasStatus}, + gas_coin::GAS, + governance::StakedIota, inner_temporary_store::{ InnerTemporaryStore, ObjectMap, PackageStoreWithFallback, TemporaryModuleResolver, TxCoins, WrittenObjects, @@ -100,6 +103,7 @@ use iota_types::{ BackingPackageStore, BackingStore, ObjectKey, ObjectOrTombstone, ObjectStore, WriteKind, }, supported_protocol_versions::{ProtocolConfig, SupportedProtocolVersions}, + timelock::{timelock::TimeLock, timelocked_staked_iota::TimelockedStakedIota}, transaction::*, }; use itertools::Itertools; @@ -4490,6 +4494,73 @@ impl AuthorityState { Some(tx) } + #[instrument(level = "debug", skip_all)] + fn create_system_display_txs( + &self, + epoch_store: &Arc, + ) -> Option { + let txs = [ + self.create_staked_iota_display_tx_v1(epoch_store), + self.create_staked_timelocked_iota_display_tx_v1(epoch_store), + self.create_timelocked_iota_display_tx_v1(epoch_store), + ] + .iter() + .filter_map(|f| f.clone()) + .collect::>(); + + if txs.is_empty() { + return None; + } + + info!("Creating system display transactions"); + Some(EndOfEpochTransactionKind::system_display(txs)) + } + + #[instrument(level = "debug", skip_all)] + fn create_staked_iota_display_tx_v1( + &self, + epoch_store: &Arc, + ) -> Option { + let tag = StakedIota::type_(); + + if epoch_store.is_system_display_object_created(tag, 1) { + return None; + } + + info!("Creating `StakedIota` system display v1 transaction"); + Some(SystemDisplayTransactionKind::StakedIotaV1) + } + + #[instrument(level = "debug", skip_all)] + fn create_staked_timelocked_iota_display_tx_v1( + &self, + epoch_store: &Arc, + ) -> Option { + let tag = TimelockedStakedIota::type_(); + + if epoch_store.is_system_display_object_created(tag, 1) { + return None; + } + + info!("Creating `TimelockedStakedIota` system display v1 transaction"); + Some(SystemDisplayTransactionKind::TimelockedStakedIotaV1) + } + + #[instrument(level = "debug", skip_all)] + fn create_timelocked_iota_display_tx_v1( + &self, + epoch_store: &Arc, + ) -> Option { + let tag = TimeLock::::type_(Balance::type_(GAS::type_().into()).into()); + + if epoch_store.is_system_display_object_created(tag, 1) { + return None; + } + + info!("Creating `TimeLock>` system display v1 transaction"); + Some(SystemDisplayTransactionKind::TimelockedIotaV1) + } + /// Creates and execute the advance epoch transaction to effects without /// committing it to the database. The effects of the change epoch tx /// are only written to the database after a certified checkpoint has been @@ -4525,6 +4596,9 @@ impl AuthorityState { if let Some(tx) = self.init_bridge_committee_tx(epoch_store) { txns.push(tx); } + if let Some(tx) = self.create_system_display_txs(epoch_store) { + txns.push(tx); + } let next_epoch = epoch_store.epoch() + 1; diff --git a/crates/iota-core/src/authority/authority_per_epoch_store.rs b/crates/iota-core/src/authority/authority_per_epoch_store.rs index f5468bf9032..6aa963eb5c8 100644 --- a/crates/iota-core/src/authority/authority_per_epoch_store.rs +++ b/crates/iota-core/src/authority/authority_per_epoch_store.rs @@ -42,8 +42,8 @@ use iota_types::{ error::{IotaError, IotaResult}, executable_transaction::{TrustedExecutableTransaction, VerifiedExecutableTransaction}, iota_system_state::{ - display_object_key, epoch_start_iota_system_state::{EpochStartSystemState, EpochStartSystemStateTrait}, + system_display_object_key, }, message_envelope::TrustedEnvelope, messages_checkpoint::{ @@ -961,8 +961,8 @@ impl AuthorityPerEpochStore { self.epoch_start_configuration.bridge_committee_initiated() } - pub fn system_display_object_created(&self, ty: StructTag, version: u16) -> bool { - let key = display_object_key(ty); + pub fn is_system_display_object_created(&self, tag: StructTag, version: u16) -> bool { + let key = system_display_object_key(tag); let object_version = self .epoch_start_configuration diff --git a/crates/iota-core/src/generate_format.rs b/crates/iota-core/src/generate_format.rs index 1f0ff6e1ee5..07ce5e9057f 100644 --- a/crates/iota-core/src/generate_format.rs +++ b/crates/iota-core/src/generate_format.rs @@ -33,8 +33,8 @@ use iota_types::{ signature::GenericSignature, storage::DeleteKind, transaction::{ - Argument, CallArg, Command, EndOfEpochTransactionKind, ObjectArg, TransactionExpiration, - TransactionKind, + Argument, CallArg, Command, EndOfEpochTransactionKind, ObjectArg, + SystemDisplayTransactionKind, TransactionExpiration, TransactionKind, }, utils::DEFAULT_ADDRESS_SEED, }; @@ -172,6 +172,7 @@ fn get_registry() -> Result { tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; + tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; tracer.trace_type::(&samples)?; diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system.move b/crates/iota-framework/packages/iota-system/sources/iota_system.move index 8c7103a94b6..b125488a991 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system.move @@ -51,7 +51,7 @@ module iota_system::iota_system { use iota::dynamic_field; use iota::vec_map::VecMap; - use iota_system::iota_system_state_inner::{Self, SystemParametersV1, IotaSystemStateV1}; + use iota_system::iota_system_state_inner::{Self, SystemParametersV1, IotaSystemStateV1, IotaSystemStateV2}; use iota_system::staking_pool::{PoolTokenExchangeRate, StakedIota}; use iota_system::validator::ValidatorV1; use iota_system::validator_cap::UnverifiedValidatorOperationCap; @@ -507,7 +507,7 @@ module iota_system::iota_system { self.load_system_state().iota_system_admin_cap() } - /// Create an empty `Display` object with `IotaSystemAdminCap`. + /// Create an empty system `Display` object with `IotaSystemAdminCap`. public(package) fun new_system_display( wrapper: &mut IotaSystemState, ctx: &mut TxContext, @@ -516,7 +516,7 @@ module iota_system::iota_system { self.new_system_display(ctx) } - /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. + /// Create a new system `Display` object with a set of fields using `IotaSystemAdminCap`. public(package) fun new_system_display_with_fields( wrapper: &mut IotaSystemState, fields: vector, @@ -527,31 +527,31 @@ module iota_system::iota_system { self.new_system_display_with_fields(fields, values, ctx) } - /// Insert a display object. - public(package) fun insert_display_object( + /// Insert a system display object. + public(package) fun insert_system_display_object( wrapper: &mut IotaSystemState, display: Display, ) { let self = wrapper.load_system_state_mut(); - self.insert_display_object(display); + self.insert_system_display_object(display); } - /// Borrow an immutable display object. - public(package) fun borrow_display_object(wrapper: &mut IotaSystemState): &Display { + /// Borrow an immutable system display object. + public(package) fun borrow_system_display_object(wrapper: &mut IotaSystemState): &Display { let self = wrapper.load_system_state(); - self.borrow_display_object() + self.borrow_system_display_object() } - /// Borrow a mutable display object. - public(package) fun borrow_display_object_mut(wrapper: &mut IotaSystemState): &mut Display { + /// Borrow a mutable system display object. + public(package) fun borrow_system_display_object_mut(wrapper: &mut IotaSystemState): &mut Display { let self = wrapper.load_system_state_mut(); - self.borrow_display_object_mut() + self.borrow_system_display_object_mut() } - /// Returns true if the related display object exists. - public(package) fun contains_display_object(wrapper: &mut IotaSystemState): bool { + /// Returns true if the related system display object exists. + public(package) fun contains_system_display_object(wrapper: &mut IotaSystemState): bool { let self = wrapper.load_system_state(); - self.contains_display_object() + self.contains_system_display_object() } #[allow(unused_function)] @@ -597,16 +597,23 @@ module iota_system::iota_system { storage_rebate } - fun load_system_state(self: &mut IotaSystemState): &IotaSystemStateV1 { + fun load_system_state(self: &mut IotaSystemState): &IotaSystemStateV2 { load_inner_maybe_upgrade(self) } - fun load_system_state_mut(self: &mut IotaSystemState): &mut IotaSystemStateV1 { + fun load_system_state_mut(self: &mut IotaSystemState): &mut IotaSystemStateV2 { load_inner_maybe_upgrade(self) } - fun load_inner_maybe_upgrade(self: &mut IotaSystemState): &mut IotaSystemStateV1 { - let inner: &mut IotaSystemStateV1 = dynamic_field::borrow_mut( + fun load_inner_maybe_upgrade(self: &mut IotaSystemState): &mut IotaSystemStateV2 { + if (self.version == 1) { + let v1: IotaSystemStateV1 = dynamic_field::remove(&mut self.id, self.version); + let v2 = v1.v1_to_v2(); + self.version = 2; + dynamic_field::add(&mut self.id, self.version, v2); + }; + + let inner: &mut IotaSystemStateV2 = dynamic_field::borrow_mut( &mut self.id, self.version ); diff --git a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move index f092e1ba699..68baf6c068d 100644 --- a/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move +++ b/crates/iota-framework/packages/iota-system/sources/iota_system_state_inner.move @@ -108,6 +108,57 @@ module iota_system::iota_system_state_inner { /// Unix timestamp of the current epoch start epoch_start_timestamp_ms: u64, + /// Any extra fields that's not defined statically. + extra_fields: Bag, + } + + /// The top-level object containing all information of the Iota system. + public struct IotaSystemStateV2 has store { + /// The current epoch ID, starting from 0. + epoch: u64, + /// The current protocol version, starting from 1. + protocol_version: u64, + /// The current version of the system state data structure type. + /// This is always the same as IotaSystemState.version. Keeping a copy here so that + /// we know what version it is by inspecting IotaSystemStateV2 as well. + system_state_version: u64, + /// The IOTA's TreasuryCap. + iota_treasury_cap: IotaTreasuryCap, + /// Contains all information about the validators. + validators: ValidatorSetV1, + /// The storage fund. + storage_fund: StorageFundV1, + /// A list of system config parameters. + parameters: SystemParametersV1, + /// A capability allows to perform privileged IOTA system operations. + iota_system_admin_cap: IotaSystemAdminCap, + /// The reference gas price for the current epoch. + reference_gas_price: u64, + /// A map storing the records of validator reporting each other. + /// There is an entry in the map for each validator that has been reported + /// at least once. The entry VecSet contains all the validators that reported + /// them. If a validator has never been reported they don't have an entry in this map. + /// This map persists across epoch: a peer continues being in a reported state until the + /// reporter doesn't explicitly remove their report. + /// Note that in case we want to support validator address change in future, + /// the reports should be based on validator ids + validator_report_records: VecMap>, + + /// Whether the system is running in a downgraded safe mode due to a non-recoverable bug. + /// This is set whenever we failed to execute advance_epoch, and ended up executing advance_epoch_safe_mode. + /// It can be reset once we are able to successfully execute advance_epoch. + /// The rest of the fields starting with `safe_mode_` are accmulated during safe mode + /// when advance_epoch_safe_mode is executed. They will eventually be processed once we + /// are out of safe mode. + safe_mode: bool, + safe_mode_storage_charges: Balance, + safe_mode_computation_rewards: Balance, + safe_mode_storage_rebates: u64, + safe_mode_non_refundable_storage_fee: u64, + + /// Unix timestamp of the current epoch start + epoch_start_timestamp_ms: u64, + /// A map contains the system display object IDs stored in the extra fields. system_display_objects: VecMap, @@ -178,7 +229,6 @@ module iota_system::iota_system_state_inner { safe_mode_storage_rebates: 0, safe_mode_non_refundable_storage_fee: 0, epoch_start_timestamp_ms, - system_display_objects: vec_map::empty(), extra_fields: bag::new(ctx), }; system_state @@ -207,6 +257,49 @@ module iota_system::iota_system_state_inner { } } + public(package) fun v1_to_v2(self: IotaSystemStateV1): IotaSystemStateV2 { + let IotaSystemStateV1 { + epoch, + protocol_version, + system_state_version: _, + iota_treasury_cap, + validators, + storage_fund, + parameters, + iota_system_admin_cap, + reference_gas_price, + validator_report_records, + safe_mode, + safe_mode_storage_charges, + safe_mode_computation_rewards, + safe_mode_storage_rebates, + safe_mode_non_refundable_storage_fee, + epoch_start_timestamp_ms, + extra_fields, + } = self; + + IotaSystemStateV2 { + epoch, + protocol_version, + system_state_version: 2, + iota_treasury_cap, + validators, + storage_fund, + parameters, + iota_system_admin_cap, + reference_gas_price, + validator_report_records, + safe_mode, + safe_mode_storage_charges, + safe_mode_computation_rewards, + safe_mode_storage_rebates, + safe_mode_non_refundable_storage_fee, + epoch_start_timestamp_ms, + system_display_objects: vec_map::empty(), + extra_fields, + } + } + // ==== public(package) functions ==== /// Can be called by anyone who wishes to become a validator candidate and starts accuring delegated @@ -216,7 +309,7 @@ module iota_system::iota_system_state_inner { /// Note: `proof_of_possession` MUST be a valid signature using iota_address and authority_pubkey_bytes. /// To produce a valid PoP, run [fn test_proof_of_possession]. public(package) fun request_add_validator_candidate( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, authority_pubkey_bytes: vector, network_pubkey_bytes: vector, protocol_pubkey_bytes: vector, @@ -256,7 +349,7 @@ module iota_system::iota_system_state_inner { /// Called by a validator candidate to remove themselves from the candidacy. After this call /// their staking pool becomes deactivate. public(package) fun request_remove_validator_candidate( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, ctx: &mut TxContext, ) { self.validators.request_remove_validator_candidate(ctx); @@ -267,7 +360,7 @@ module iota_system::iota_system_state_inner { /// stake the validator has doesn't meet the min threshold, or if the number of new validators for the next /// epoch has already reached the maximum. public(package) fun request_add_validator( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, ctx: &TxContext, ) { assert!( @@ -284,7 +377,7 @@ module iota_system::iota_system_state_inner { /// At the end of the epoch, the `validator` object will be returned to the iota_address /// of the validator. public(package) fun request_remove_validator( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, ctx: &TxContext, ) { // Only check min validator condition if the current number of validators satisfy the constraint. @@ -303,7 +396,7 @@ module iota_system::iota_system_state_inner { /// A validator can call this function to submit a new gas price quote, to be /// used for the reference gas price calculation at the end of the epoch. public(package) fun request_set_gas_price( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, cap: &UnverifiedValidatorOperationCap, new_gas_price: u64, ) { @@ -316,7 +409,7 @@ module iota_system::iota_system_state_inner { /// This function is used to set new gas price for candidate validators public(package) fun set_candidate_validator_gas_price( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, cap: &UnverifiedValidatorOperationCap, new_gas_price: u64, ) { @@ -329,7 +422,7 @@ module iota_system::iota_system_state_inner { /// A validator can call this function to set a new commission rate, updated at the end of /// the epoch. public(package) fun request_set_commission_rate( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, new_commission_rate: u64, ctx: &TxContext, ) { @@ -341,7 +434,7 @@ module iota_system::iota_system_state_inner { /// This function is used to set new commission rate for candidate validators public(package) fun set_candidate_validator_commission_rate( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, new_commission_rate: u64, ctx: &TxContext, ) { @@ -351,7 +444,7 @@ module iota_system::iota_system_state_inner { /// Add stake to a validator's staking pool. public(package) fun request_add_stake( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, stake: Coin, validator_address: address, ctx: &mut TxContext, @@ -365,7 +458,7 @@ module iota_system::iota_system_state_inner { /// Add stake to a validator's staking pool using multiple coins. public(package) fun request_add_stake_mul_coin( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, stakes: vector>, stake_amount: option::Option, validator_address: address, @@ -377,7 +470,7 @@ module iota_system::iota_system_state_inner { /// Withdraw some portion of a stake from a validator's staking pool. public(package) fun request_withdraw_stake( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, staked_iota: StakedIota, ctx: &TxContext, ) : Balance { @@ -391,7 +484,7 @@ module iota_system::iota_system_state_inner { /// 3. the cap object is still valid. /// This function is idempotent. public(package) fun report_validator( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, cap: &UnverifiedValidatorOperationCap, reportee_addr: address, ) { @@ -408,7 +501,7 @@ module iota_system::iota_system_state_inner { /// 2. the sender has not previously reported the `reportee_addr`, or /// 3. the cap is not valid public(package) fun undo_report_validator( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, cap: &UnverifiedValidatorOperationCap, reportee_addr: address, ) { @@ -450,17 +543,17 @@ module iota_system::iota_system_state_inner { } } - /// Create an empty `Display` object with `IotaSystemAdminCap`. + /// Create an empty system `Display` object with `IotaSystemAdminCap`. public(package) fun new_system_display( - self: &IotaSystemStateV1, + self: &IotaSystemStateV2, ctx: &mut TxContext, ): Display { display::system_new(&self.iota_system_admin_cap, ctx) } - /// Create a new `Display` object with a set of fields using `IotaSystemAdminCap`. + /// Create a new system `Display` object with a set of fields using `IotaSystemAdminCap`. public(package) fun new_system_display_with_fields( - self: &IotaSystemStateV1, + self: &IotaSystemStateV2, fields: vector, values: vector, ctx: &mut TxContext, @@ -468,13 +561,13 @@ module iota_system::iota_system_state_inner { display::system_new_with_fields(&self.iota_system_admin_cap, fields, values, ctx) } - /// Insert a display object. - public(package) fun insert_display_object( - self: &mut IotaSystemStateV1, + /// Insert a system display object. + public(package) fun insert_system_display_object( + self: &mut IotaSystemStateV2, display: Display, ) { // Get a display object unique key. - let key = display_object_key(); + let key = system_display_object_key(); let display_id = *display.id(); // Store the display object. @@ -482,10 +575,10 @@ module iota_system::iota_system_state_inner { self.extra_fields.add(display_id, display); } - /// Borrow an immutable display object. - public(package) fun borrow_display_object(self: &IotaSystemStateV1): &Display { + /// Borrow an immutable system display object. + public(package) fun borrow_system_display_object(self: &IotaSystemStateV2): &Display { // Get a display object unique key. - let key = display_object_key(); + let key = system_display_object_key(); // Get the id. let display_id = *self.system_display_objects.get(&key); @@ -494,10 +587,10 @@ module iota_system::iota_system_state_inner { self.extra_fields.borrow(display_id) } - /// Borrow a mutable display object. - public(package) fun borrow_display_object_mut(self: &mut IotaSystemStateV1): &mut Display { + /// Borrow a mutable system display object. + public(package) fun borrow_system_display_object_mut(self: &mut IotaSystemStateV2): &mut Display { // Get a display object unique key. - let key = display_object_key(); + let key = system_display_object_key(); // Get the id. let display_id = *self.system_display_objects.get(&key); @@ -506,10 +599,10 @@ module iota_system::iota_system_state_inner { self.extra_fields.borrow_mut(display_id) } - /// Returns true if the related display object exists. - public(package) fun contains_display_object(self: &IotaSystemStateV1): bool { + /// Returns true if the related system display object exists. + public(package) fun contains_system_display_object(self: &IotaSystemStateV2): bool { // Get a display object unique key. - let key = display_object_key(); + let key = system_display_object_key(); // Check if the related display object exists. self.system_display_objects.contains(&key) @@ -517,7 +610,7 @@ module iota_system::iota_system_state_inner { /// Return a fully qualified type name with the original package IDs /// that is used as a display object key. - fun display_object_key(): String { + fun system_display_object_key(): String { string::from_ascii(std::type_name::get_with_original_ids().into_string()) } @@ -526,7 +619,7 @@ module iota_system::iota_system_state_inner { /// Create a new `UnverifiedValidatorOperationCap`, transfer it to the /// validator and registers it. The original object is thus revoked. public(package) fun rotate_operation_cap( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, ctx: &mut TxContext, ) { let validator = self.validators.get_validator_mut_with_ctx_including_candidates(ctx); @@ -535,7 +628,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's name. public(package) fun update_validator_name( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, name: vector, ctx: &TxContext, ) { @@ -546,7 +639,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's description public(package) fun update_validator_description( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, description: vector, ctx: &TxContext, ) { @@ -556,7 +649,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's image url public(package) fun update_validator_image_url( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, image_url: vector, ctx: &TxContext, ) { @@ -566,7 +659,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's project url public(package) fun update_validator_project_url( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, project_url: vector, ctx: &TxContext, ) { @@ -577,7 +670,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's network address. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_network_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, network_address: vector, ctx: &TxContext, ) { @@ -589,7 +682,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's network address. public(package) fun update_candidate_validator_network_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, network_address: vector, ctx: &TxContext, ) { @@ -600,7 +693,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's p2p address. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_p2p_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, p2p_address: vector, ctx: &TxContext, ) { @@ -612,7 +705,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's p2p address. public(package) fun update_candidate_validator_p2p_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, p2p_address: vector, ctx: &TxContext, ) { @@ -623,7 +716,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's primary address. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_primary_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, primary_address: vector, ctx: &TxContext, ) { @@ -633,7 +726,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's primary address. public(package) fun update_candidate_validator_primary_address( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, primary_address: vector, ctx: &TxContext, ) { @@ -644,7 +737,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's public key of authority key and proof of possession. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_authority_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, authority_pubkey: vector, proof_of_possession: vector, ctx: &TxContext, @@ -657,7 +750,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's public key of authority key and proof of possession. public(package) fun update_candidate_validator_authority_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, authority_pubkey: vector, proof_of_possession: vector, ctx: &TxContext, @@ -669,7 +762,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's public key of protocol key. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_protocol_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, protocol_pubkey: vector, ctx: &TxContext, ) { @@ -681,7 +774,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's public key of protocol key. public(package) fun update_candidate_validator_protocol_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, protocol_pubkey: vector, ctx: &TxContext, ) { @@ -692,7 +785,7 @@ module iota_system::iota_system_state_inner { /// Update a validator's public key of network key. /// The change will only take effects starting from the next epoch. public(package) fun update_validator_next_epoch_network_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, network_pubkey: vector, ctx: &TxContext, ) { @@ -704,7 +797,7 @@ module iota_system::iota_system_state_inner { /// Update candidate validator's public key of network key. public(package) fun update_candidate_validator_network_pubkey( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, network_pubkey: vector, ctx: &TxContext, ) { @@ -723,7 +816,7 @@ module iota_system::iota_system_state_inner { /// 5. Burn any leftover rewards. /// 6. Update all validators. public(package) fun advance_epoch( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, new_epoch: u64, next_protocol_version: u64, validator_target_reward: u64, @@ -852,19 +945,19 @@ module iota_system::iota_system_state_inner { /// Return the current epoch number. Useful for applications that need a coarse-grained concept of time, /// since epochs are ever-increasing and epoch changes are intended to happen every 24 hours. - public(package) fun epoch(self: &IotaSystemStateV1): u64 { + public(package) fun epoch(self: &IotaSystemStateV2): u64 { self.epoch } - public(package) fun protocol_version(self: &IotaSystemStateV1): u64 { + public(package) fun protocol_version(self: &IotaSystemStateV2): u64 { self.protocol_version } - public(package) fun system_state_version(self: &IotaSystemStateV1): u64 { + public(package) fun system_state_version(self: &IotaSystemStateV2): u64 { self.system_state_version } - public(package) fun iota_system_admin_cap(self: &IotaSystemStateV1): &IotaSystemAdminCap { + public(package) fun iota_system_admin_cap(self: &IotaSystemStateV2): &IotaSystemAdminCap { &self.iota_system_admin_cap } @@ -875,19 +968,19 @@ module iota_system::iota_system_state_inner { } /// Returns unix timestamp of the start of current epoch - public(package) fun epoch_start_timestamp_ms(self: &IotaSystemStateV1): u64 { + public(package) fun epoch_start_timestamp_ms(self: &IotaSystemStateV2): u64 { self.epoch_start_timestamp_ms } /// Returns the total amount staked with `validator_addr`. /// Aborts if `validator_addr` is not an active validator. - public(package) fun validator_stake_amount(self: &IotaSystemStateV1, validator_addr: address): u64 { + public(package) fun validator_stake_amount(self: &IotaSystemStateV2, validator_addr: address): u64 { self.validators.validator_total_stake_amount(validator_addr) } /// Returns the voting power for `validator_addr`. /// Aborts if `validator_addr` is not an active validator. - public(package) fun active_validator_voting_powers(self: &IotaSystemStateV1): VecMap { + public(package) fun active_validator_voting_powers(self: &IotaSystemStateV2): VecMap { let mut active_validators = active_validator_addresses(self); let mut voting_powers = vec_map::empty(); while (!vector::is_empty(&active_validators)) { @@ -900,24 +993,24 @@ module iota_system::iota_system_state_inner { /// Returns the staking pool id of a given validator. /// Aborts if `validator_addr` is not an active validator. - public(package) fun validator_staking_pool_id(self: &IotaSystemStateV1, validator_addr: address): ID { + public(package) fun validator_staking_pool_id(self: &IotaSystemStateV2, validator_addr: address): ID { self.validators.validator_staking_pool_id(validator_addr) } /// Returns reference to the staking pool mappings that map pool ids to active validator addresses - public(package) fun validator_staking_pool_mappings(self: &IotaSystemStateV1): &Table { + public(package) fun validator_staking_pool_mappings(self: &IotaSystemStateV2): &Table { self.validators.staking_pool_mappings() } /// Returns the total iota supply. - public(package) fun get_total_iota_supply(self: &IotaSystemStateV1): u64 { + public(package) fun get_total_iota_supply(self: &IotaSystemStateV2): u64 { self.iota_treasury_cap.total_supply() } /// Returns all the validators who are currently reporting `addr` - public(package) fun get_reporters_of(self: &IotaSystemStateV1, addr: address): VecSet
{ + public(package) fun get_reporters_of(self: &IotaSystemStateV2, addr: address): VecSet
{ if (self.validator_report_records.contains(&addr)) { self.validator_report_records[&addr] @@ -926,23 +1019,23 @@ module iota_system::iota_system_state_inner { } } - public(package) fun get_storage_fund_total_balance(self: &IotaSystemStateV1): u64 { + public(package) fun get_storage_fund_total_balance(self: &IotaSystemStateV2): u64 { self.storage_fund.total_balance() } - public(package) fun get_storage_fund_object_rebates(self: &IotaSystemStateV1): u64 { + public(package) fun get_storage_fund_object_rebates(self: &IotaSystemStateV2): u64 { self.storage_fund.total_object_storage_rebates() } public(package) fun pool_exchange_rates( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, pool_id: &ID ): &Table { let validators = &mut self.validators; validators.pool_exchange_rates(pool_id) } - public(package) fun active_validator_addresses(self: &IotaSystemStateV1): vector
{ + public(package) fun active_validator_addresses(self: &IotaSystemStateV2): vector
{ let validator_set = &self.validators; validator_set.active_validator_addresses() } @@ -972,36 +1065,36 @@ module iota_system::iota_system_state_inner { #[test_only] /// Return the current validator set - public(package) fun validators(self: &IotaSystemStateV1): &ValidatorSetV1 { + public(package) fun validators(self: &IotaSystemStateV2): &ValidatorSetV1 { &self.validators } #[test_only] /// Return the currently active validator by address - public(package) fun active_validator_by_address(self: &IotaSystemStateV1, validator_address: address): &ValidatorV1 { + public(package) fun active_validator_by_address(self: &IotaSystemStateV2, validator_address: address): &ValidatorV1 { self.validators().get_active_validator_ref(validator_address) } #[test_only] /// Return the currently pending validator by address - public(package) fun pending_validator_by_address(self: &IotaSystemStateV1, validator_address: address): &ValidatorV1 { + public(package) fun pending_validator_by_address(self: &IotaSystemStateV2, validator_address: address): &ValidatorV1 { self.validators().get_pending_validator_ref(validator_address) } #[test_only] /// Return the currently candidate validator by address - public(package) fun candidate_validator_by_address(self: &IotaSystemStateV1, validator_address: address): &ValidatorV1 { + public(package) fun candidate_validator_by_address(self: &IotaSystemStateV2, validator_address: address): &ValidatorV1 { validators(self).get_candidate_validator_ref(validator_address) } #[test_only] - public(package) fun set_epoch_for_testing(self: &mut IotaSystemStateV1, epoch_num: u64) { + public(package) fun set_epoch_for_testing(self: &mut IotaSystemStateV2, epoch_num: u64) { self.epoch = epoch_num } #[test_only] public(package) fun request_add_validator_for_testing( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, min_joining_stake_for_testing: u64, ctx: &TxContext, ) { @@ -1018,7 +1111,7 @@ module iota_system::iota_system_state_inner { // in the process. #[test_only] public(package) fun request_add_validator_candidate_for_testing( - self: &mut IotaSystemStateV1, + self: &mut IotaSystemStateV2, pubkey_bytes: vector, network_pubkey_bytes: vector, protocol_pubkey_bytes: vector, diff --git a/crates/iota-framework/packages/iota-system/sources/system_display.move b/crates/iota-framework/packages/iota-system/sources/system_display.move new file mode 100644 index 00000000000..96d00965a6d --- /dev/null +++ b/crates/iota-framework/packages/iota-system/sources/system_display.move @@ -0,0 +1,100 @@ +// Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module iota_system::system_display { + + use std::string; + + use iota::balance::Balance; + use iota::iota::IOTA; + use iota::timelock::TimeLock; + + use iota_system::iota_system::IotaSystemState; + use iota_system::staking_pool::StakedIota; + use iota_system::timelocked_staking::TimelockedStakedIota; + + #[allow(unused_function)] + /// Create a `Display` object for the `StakedIota` type. + fun create_staked_iota_display_v1( + iota_system: &mut IotaSystemState, + ctx: &mut TxContext, + ) { + // A display object content. + let keys = vector[ + string::utf8(b"principal"), + string::utf8(b"stake_activation_epoch"), + ]; + + let values = vector[ + string::utf8(b"{principal}"), + string::utf8(b"{stake_activation_epoch}"), + ]; + + // Create a display object. + let mut display = iota_system.new_system_display_with_fields(keys, values, ctx); + + // Commit the display object to apply changes. + display.update_version(); + + // Store the display object. + iota_system.insert_system_display_object(display); + } + + #[allow(unused_function)] + /// Create a `Display` object for the `TimelockedStakedIota` type. + fun create_timelocked_staked_iota_display_v1( + iota_system: &mut IotaSystemState, + ctx: &mut TxContext, + ) { + // A display object content. + let keys = vector[ + string::utf8(b"principal"), + string::utf8(b"stake_activation_epoch"), + string::utf8(b"expiration_timestamp_ms"), + string::utf8(b"label"), + ]; + + let values = vector[ + string::utf8(b"{staked_iota.principal}"), + string::utf8(b"{staked_iota.stake_activation_epoch}"), + string::utf8(b"{expiration_timestamp_ms}"), + string::utf8(b"{label}"), + ]; + + // Create a display object. + let mut display = iota_system.new_system_display_with_fields(keys, values, ctx); + + // Commit the display object to apply changes. + display.update_version(); + + // Store the display object. + iota_system.insert_system_display_object(display); + } + + #[allow(unused_function)] + /// Create a `Display` object for the `TimeLock>` type. + fun create_timelocked_iota_display_v1( + iota_system: &mut IotaSystemState, + ctx: &mut TxContext, + ) { + // A display object content. + let keys = vector[ + string::utf8(b"locked"), + string::utf8(b"expiration_timestamp_ms"), + ]; + + let values = vector[ + string::utf8(b"{locked}"), + string::utf8(b"{expiration_timestamp_ms}"), + ]; + + // Create a display object. + let mut display = iota_system.new_system_display_with_fields>>(keys, values, ctx); + + // Commit the display object to apply changes. + display.update_version(); + + // Store the display object. + iota_system.insert_system_display_object(display); + } +} diff --git a/crates/iota-framework/packages_compiled/iota-system b/crates/iota-framework/packages_compiled/iota-system index 9441eaaaf92c1a30285eb1b25104b5416bc220e7..78c9afff440ea27a2ddb33f3eb58653f7dc37ecf 100644 GIT binary patch delta 7251 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 inner, - #[cfg(msim)] _ => { - // Types other than V1 used in simtests do not need to be validated. + // Types other than V1 and used in simtests do not need to be validated. return; } }; diff --git a/crates/iota-graphql-rpc/src/types/transaction_block_kind/end_of_epoch.rs b/crates/iota-graphql-rpc/src/types/transaction_block_kind/end_of_epoch.rs index 45df35c47bd..89fe92df60f 100644 --- a/crates/iota-graphql-rpc/src/types/transaction_block_kind/end_of_epoch.rs +++ b/crates/iota-graphql-rpc/src/types/transaction_block_kind/end_of_epoch.rs @@ -287,6 +287,7 @@ impl EndOfEpochTransactionKind { checkpoint_viewed_at, }) } + N::SystemDisplay(_) => todo!(), } } } diff --git a/crates/iota-json-rpc-types/src/iota_transaction.rs b/crates/iota-json-rpc-types/src/iota_transaction.rs index 23e4cdfc8c0..42b1da949ec 100644 --- a/crates/iota-json-rpc-types/src/iota_transaction.rs +++ b/crates/iota-json-rpc-types/src/iota_transaction.rs @@ -37,7 +37,8 @@ use iota_types::{ transaction::{ Argument, CallArg, ChangeEpoch, Command, EndOfEpochTransactionKind, GenesisObject, InputObjectKind, ObjectArg, ProgrammableMoveCall, ProgrammableTransaction, - SenderSignedData, TransactionData, TransactionDataAPI, TransactionKind, + SenderSignedData, SystemDisplayTransactionKind, TransactionData, TransactionDataAPI, + TransactionKind, }, }; use move_binary_format::CompiledModule; @@ -528,6 +529,11 @@ impl IotaTransactionBlockKind { ) => IotaEndOfEpochTransactionKind::BridgeCommitteeUpdate( bridge_shared_version, ), + EndOfEpochTransactionKind::SystemDisplay(vec) => { + IotaEndOfEpochTransactionKind::SystemDisplay( + vec.into_iter().map(|t| t.into()).collect(), + ) + } }) .collect(), }) @@ -612,6 +618,11 @@ impl IotaTransactionBlockKind { EndOfEpochTransactionKind::BridgeCommitteeInit(seq) => { IotaEndOfEpochTransactionKind::BridgeCommitteeUpdate(seq) } + EndOfEpochTransactionKind::SystemDisplay(vec) => { + IotaEndOfEpochTransactionKind::SystemDisplay( + vec.into_iter().map(|t| t.into()).collect(), + ) + } }) .collect(), }) @@ -1607,6 +1618,30 @@ pub struct IotaEndOfEpochTransaction { pub transactions: Vec, } +#[serde_as] +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub enum IotaSystemDisplayTransactionKind { + StakedIotaV1, + TimelockedStakedIotaV1, + TimelockedIotaV1, +} + +impl From for IotaSystemDisplayTransactionKind { + fn from(input: SystemDisplayTransactionKind) -> Self { + match input { + SystemDisplayTransactionKind::StakedIotaV1 => { + IotaSystemDisplayTransactionKind::StakedIotaV1 + } + SystemDisplayTransactionKind::TimelockedStakedIotaV1 => { + IotaSystemDisplayTransactionKind::TimelockedStakedIotaV1 + } + SystemDisplayTransactionKind::TimelockedIotaV1 => { + IotaSystemDisplayTransactionKind::TimelockedIotaV1 + } + } + } +} + #[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] pub enum IotaEndOfEpochTransactionKind { @@ -1615,6 +1650,7 @@ pub enum IotaEndOfEpochTransactionKind { AuthenticatorStateExpire(IotaAuthenticatorStateExpire), BridgeStateCreate(CheckpointDigest), BridgeCommitteeUpdate(SequenceNumber), + SystemDisplay(Vec), } #[serde_as] diff --git a/crates/iota-json-rpc/src/coin_api.rs b/crates/iota-json-rpc/src/coin_api.rs index f201f714a98..90d9a114c45 100644 --- a/crates/iota-json-rpc/src/coin_api.rs +++ b/crates/iota-json-rpc/src/coin_api.rs @@ -1438,9 +1438,6 @@ mod tests { safe_mode_storage_rebates: Default::default(), safe_mode_non_refundable_storage_fee: Default::default(), epoch_start_timestamp_ms: Default::default(), - system_display_objects: VecMap { - contents: Default::default(), - }, extra_fields: Default::default(), } } diff --git a/crates/iota-protocol-config/src/lib.rs b/crates/iota-protocol-config/src/lib.rs index 3ca28d34e66..e5b4a9b70b0 100644 --- a/crates/iota-protocol-config/src/lib.rs +++ b/crates/iota-protocol-config/src/lib.rs @@ -16,7 +16,7 @@ use tracing::{info, warn}; /// The minimum and maximum protocol versions supported by this build. const MIN_PROTOCOL_VERSION: u64 = 1; -pub const MAX_PROTOCOL_VERSION: u64 = 1; +pub const MAX_PROTOCOL_VERSION: u64 = 2; // Record history of protocol version allocations here: // @@ -180,6 +180,18 @@ struct FeatureFlags { // This flag is used to provide the correct MoveVM configuration for clients. #[serde(skip_serializing_if = "is_true")] rethrow_serialization_type_layout_errors: bool, + + // Enable the `StakedIota` display object V1. + #[serde(skip_serializing_if = "is_false")] + enable_staked_iota_display_v1: bool, + + // Enable the `TimelockedStakedIota` display object V1. + #[serde(skip_serializing_if = "is_false")] + enable_timelocked_staked_iota_display_v1: bool, + + // Enable the `Timelock>` display object V1. + #[serde(skip_serializing_if = "is_false")] + enable_timelocked_iota_display_v1: bool, } fn is_true(b: &bool) -> bool { @@ -1050,6 +1062,18 @@ impl ProtocolConfig { pub fn rethrow_serialization_type_layout_errors(&self) -> bool { self.feature_flags.rethrow_serialization_type_layout_errors } + + pub fn enable_staked_iota_display_v1(&self) -> bool { + self.feature_flags.enable_staked_iota_display_v1 + } + + pub fn enable_timelocked_staked_iota_display_v1(&self) -> bool { + self.feature_flags.enable_timelocked_staked_iota_display_v1 + } + + pub fn enable_timelocked_iota_display_v1(&self) -> bool { + self.feature_flags.enable_timelocked_iota_display_v1 + } } #[cfg(not(msim))] @@ -1630,13 +1654,16 @@ impl ProtocolConfig { } // Ignore this check for the fake versions for - // `test_choose_next_system_packages`. TODO: remove the never_loop - // attribute when the version 2 is added. - #[allow(clippy::never_loop)] + // `test_choose_next_system_packages`. #[cfg(not(msim))] for cur in 2..=version.0 { match cur { 1 => unreachable!(), + 2 => { + cfg.feature_flags.enable_staked_iota_display_v1 = true; + cfg.feature_flags.enable_timelocked_staked_iota_display_v1 = true; + cfg.feature_flags.enable_timelocked_iota_display_v1 = true; + } // Use this template when making changes: // diff --git a/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Mainnet_version_2.snap b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Mainnet_version_2.snap new file mode 100644 index 00000000000..4f800ce47dd --- /dev/null +++ b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Mainnet_version_2.snap @@ -0,0 +1,272 @@ +--- +source: crates/iota-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 2 +feature_flags: + consensus_transaction_ordering: ByGasPrice + per_object_congestion_control_mode: TotalTxCount + zklogin_max_epoch_upper_bound_delta: 30 + enable_staked_iota_display_v1: true + enable_timelocked_staked_iota_display_v1: true + enable_timelocked_iota_display_v1: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +gas_model_version: 1 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 10000 +reward_slashing_rate: 10000 +storage_gas_price: 76 +validator_target_reward: 767000000000000 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 52 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 52 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 52 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 52 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 52 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 52 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 52 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 52 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 52 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 52 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 52 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 52 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 52 +groth16_prepare_verifying_key_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 52 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 52 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +group_ops_bls12381_decode_scalar_cost: 52 +group_ops_bls12381_decode_g1_cost: 52 +group_ops_bls12381_decode_g2_cost: 52 +group_ops_bls12381_decode_gt_cost: 52 +group_ops_bls12381_scalar_add_cost: 52 +group_ops_bls12381_g1_add_cost: 52 +group_ops_bls12381_g2_add_cost: 52 +group_ops_bls12381_gt_add_cost: 52 +group_ops_bls12381_scalar_sub_cost: 52 +group_ops_bls12381_g1_sub_cost: 52 +group_ops_bls12381_g2_sub_cost: 52 +group_ops_bls12381_gt_sub_cost: 52 +group_ops_bls12381_scalar_mul_cost: 52 +group_ops_bls12381_g1_mul_cost: 52 +group_ops_bls12381_g2_mul_cost: 52 +group_ops_bls12381_gt_mul_cost: 52 +group_ops_bls12381_scalar_div_cost: 52 +group_ops_bls12381_g1_div_cost: 52 +group_ops_bls12381_g2_div_cost: 52 +group_ops_bls12381_gt_div_cost: 52 +group_ops_bls12381_g1_hash_to_base_cost: 52 +group_ops_bls12381_g2_hash_to_base_cost: 52 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 52 +group_ops_bls12381_g2_msm_base_cost: 52 +group_ops_bls12381_g1_msm_base_cost_per_input: 52 +group_ops_bls12381_g2_msm_base_cost_per_input: 52 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 52 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 1 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 1000 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +max_deferral_rounds_for_congestion_control: 10 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: false +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 10 diff --git a/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Testnet_version_2.snap b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Testnet_version_2.snap new file mode 100644 index 00000000000..9446a6cdf19 --- /dev/null +++ b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__Testnet_version_2.snap @@ -0,0 +1,272 @@ +--- +source: crates/iota-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 2 +feature_flags: + consensus_transaction_ordering: ByGasPrice + per_object_congestion_control_mode: TotalTxCount + zklogin_max_epoch_upper_bound_delta: 30 + enable_staked_iota_display_v1: true + enable_timelocked_staked_iota_display_v1: true + enable_timelocked_iota_display_v1: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +gas_model_version: 1 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 10000 +reward_slashing_rate: 10000 +storage_gas_price: 76 +validator_target_reward: 767000000000000 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 52 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 52 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 52 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 52 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 52 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 52 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 52 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 52 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 52 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 52 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 52 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 52 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 52 +groth16_prepare_verifying_key_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 52 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 52 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +group_ops_bls12381_decode_scalar_cost: 52 +group_ops_bls12381_decode_g1_cost: 52 +group_ops_bls12381_decode_g2_cost: 52 +group_ops_bls12381_decode_gt_cost: 52 +group_ops_bls12381_scalar_add_cost: 52 +group_ops_bls12381_g1_add_cost: 52 +group_ops_bls12381_g2_add_cost: 52 +group_ops_bls12381_gt_add_cost: 52 +group_ops_bls12381_scalar_sub_cost: 52 +group_ops_bls12381_g1_sub_cost: 52 +group_ops_bls12381_g2_sub_cost: 52 +group_ops_bls12381_gt_sub_cost: 52 +group_ops_bls12381_scalar_mul_cost: 52 +group_ops_bls12381_g1_mul_cost: 52 +group_ops_bls12381_g2_mul_cost: 52 +group_ops_bls12381_gt_mul_cost: 52 +group_ops_bls12381_scalar_div_cost: 52 +group_ops_bls12381_g1_div_cost: 52 +group_ops_bls12381_g2_div_cost: 52 +group_ops_bls12381_gt_div_cost: 52 +group_ops_bls12381_g1_hash_to_base_cost: 52 +group_ops_bls12381_g2_hash_to_base_cost: 52 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 52 +group_ops_bls12381_g2_msm_base_cost: 52 +group_ops_bls12381_g1_msm_base_cost_per_input: 52 +group_ops_bls12381_g2_msm_base_cost_per_input: 52 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 52 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 1 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 1000 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +max_deferral_rounds_for_congestion_control: 10 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: true +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 10 diff --git a/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__version_2.snap b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__version_2.snap new file mode 100644 index 00000000000..a9cb62bf643 --- /dev/null +++ b/crates/iota-protocol-config/src/snapshots/iota_protocol_config__test__version_2.snap @@ -0,0 +1,280 @@ +--- +source: crates/iota-protocol-config/src/lib.rs +expression: "ProtocolConfig::get_for_version(cur, *chain_id)" +--- +version: 2 +feature_flags: + consensus_transaction_ordering: ByGasPrice + enable_poseidon: true + enable_group_ops_native_function_msm: true + per_object_congestion_control_mode: TotalTxCount + zklogin_max_epoch_upper_bound_delta: 30 + enable_vdf: true + passkey_auth: true + enable_staked_iota_display_v1: true + enable_timelocked_staked_iota_display_v1: true + enable_timelocked_iota_display_v1: true +max_tx_size_bytes: 131072 +max_input_objects: 2048 +max_size_written_objects: 5000000 +max_size_written_objects_system_tx: 50000000 +max_serialized_tx_effects_size_bytes: 524288 +max_serialized_tx_effects_size_bytes_system_tx: 8388608 +max_gas_payment_objects: 256 +max_modules_in_publish: 64 +max_package_dependencies: 32 +max_arguments: 512 +max_type_arguments: 16 +max_type_argument_depth: 16 +max_pure_argument_size: 16384 +max_programmable_tx_commands: 1024 +move_binary_format_version: 7 +min_move_binary_format_version: 6 +binary_module_handles: 100 +binary_struct_handles: 300 +binary_function_handles: 1500 +binary_function_instantiations: 750 +binary_signatures: 1000 +binary_constant_pool: 4000 +binary_identifiers: 10000 +binary_address_identifiers: 100 +binary_struct_defs: 200 +binary_struct_def_instantiations: 100 +binary_function_defs: 1000 +binary_field_handles: 500 +binary_field_instantiations: 250 +binary_friend_decls: 100 +max_move_object_size: 256000 +max_move_package_size: 102400 +max_publish_or_upgrade_per_ptb: 5 +max_tx_gas: 50000000000 +max_gas_price: 100000 +max_gas_computation_bucket: 5000000 +gas_rounding_step: 1000 +max_loop_depth: 5 +max_generic_instantiation_length: 32 +max_function_parameters: 128 +max_basic_blocks: 1024 +max_value_stack_size: 1024 +max_type_nodes: 256 +max_push_size: 10000 +max_struct_definitions: 200 +max_function_definitions: 1000 +max_fields_in_struct: 32 +max_dependency_depth: 100 +max_num_event_emit: 1024 +max_num_new_move_object_ids: 2048 +max_num_new_move_object_ids_system_tx: 32768 +max_num_deleted_move_object_ids: 2048 +max_num_deleted_move_object_ids_system_tx: 32768 +max_num_transferred_move_object_ids: 2048 +max_num_transferred_move_object_ids_system_tx: 32768 +max_event_emit_size: 256000 +max_event_emit_size_total: 65536000 +max_move_vector_len: 262144 +max_move_identifier_len: 128 +max_move_value_depth: 128 +max_back_edges_per_function: 10000 +max_back_edges_per_module: 10000 +max_verifier_meter_ticks_per_function: 16000000 +max_meter_ticks_per_module: 16000000 +max_meter_ticks_per_package: 16000000 +object_runtime_max_num_cached_objects: 1000 +object_runtime_max_num_cached_objects_system_tx: 16000 +object_runtime_max_num_store_entries: 1000 +object_runtime_max_num_store_entries_system_tx: 16000 +base_tx_cost_fixed: 1000 +package_publish_cost_fixed: 1000 +base_tx_cost_per_byte: 0 +package_publish_cost_per_byte: 80 +obj_access_cost_read_per_byte: 15 +obj_access_cost_mutate_per_byte: 40 +obj_access_cost_delete_per_byte: 40 +obj_access_cost_verify_per_byte: 200 +gas_model_version: 1 +obj_data_cost_refundable: 100 +obj_metadata_cost_non_refundable: 50 +storage_rebate_rate: 10000 +reward_slashing_rate: 10000 +storage_gas_price: 76 +validator_target_reward: 767000000000000 +max_transactions_per_checkpoint: 10000 +max_checkpoint_size_bytes: 31457280 +buffer_stake_for_protocol_upgrade_bps: 5000 +address_from_bytes_cost_base: 52 +address_to_u256_cost_base: 52 +address_from_u256_cost_base: 52 +config_read_setting_impl_cost_base: 100 +config_read_setting_impl_cost_per_byte: 40 +dynamic_field_hash_type_and_key_cost_base: 100 +dynamic_field_hash_type_and_key_type_cost_per_byte: 2 +dynamic_field_hash_type_and_key_value_cost_per_byte: 2 +dynamic_field_hash_type_and_key_type_tag_cost_per_byte: 2 +dynamic_field_add_child_object_cost_base: 100 +dynamic_field_add_child_object_type_cost_per_byte: 10 +dynamic_field_add_child_object_value_cost_per_byte: 10 +dynamic_field_add_child_object_struct_tag_cost_per_byte: 10 +dynamic_field_borrow_child_object_cost_base: 100 +dynamic_field_borrow_child_object_child_ref_cost_per_byte: 10 +dynamic_field_borrow_child_object_type_cost_per_byte: 10 +dynamic_field_remove_child_object_cost_base: 100 +dynamic_field_remove_child_object_child_cost_per_byte: 2 +dynamic_field_remove_child_object_type_cost_per_byte: 2 +dynamic_field_has_child_object_cost_base: 100 +dynamic_field_has_child_object_with_ty_cost_base: 100 +dynamic_field_has_child_object_with_ty_type_cost_per_byte: 2 +dynamic_field_has_child_object_with_ty_type_tag_cost_per_byte: 2 +event_emit_cost_base: 52 +event_emit_value_size_derivation_cost_per_byte: 2 +event_emit_tag_size_derivation_cost_per_byte: 5 +event_emit_output_cost_per_byte: 10 +object_borrow_uid_cost_base: 52 +object_delete_impl_cost_base: 52 +object_record_new_uid_cost_base: 52 +transfer_transfer_internal_cost_base: 52 +transfer_freeze_object_cost_base: 52 +transfer_share_object_cost_base: 52 +transfer_receive_object_cost_base: 52 +tx_context_derive_id_cost_base: 52 +types_is_one_time_witness_cost_base: 52 +types_is_one_time_witness_type_tag_cost_per_byte: 2 +types_is_one_time_witness_type_cost_per_byte: 2 +validator_validate_metadata_cost_base: 52 +validator_validate_metadata_data_cost_per_byte: 2 +crypto_invalid_arguments_cost: 100 +bls12381_bls12381_min_sig_verify_cost_base: 52 +bls12381_bls12381_min_sig_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_sig_verify_msg_cost_per_block: 2 +bls12381_bls12381_min_pk_verify_cost_base: 52 +bls12381_bls12381_min_pk_verify_msg_cost_per_byte: 2 +bls12381_bls12381_min_pk_verify_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_keccak256_cost_base: 52 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_k1_ecrecover_sha256_cost_base: 52 +ecdsa_k1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_k1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_k1_decompress_pubkey_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_cost_base: 52 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_k1_secp256k1_verify_sha256_cost_base: 52 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_k1_secp256k1_verify_sha256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_keccak256_cost_base: 52 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_keccak256_msg_cost_per_block: 2 +ecdsa_r1_ecrecover_sha256_cost_base: 52 +ecdsa_r1_ecrecover_sha256_msg_cost_per_byte: 2 +ecdsa_r1_ecrecover_sha256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_keccak256_cost_base: 52 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_keccak256_msg_cost_per_block: 2 +ecdsa_r1_secp256r1_verify_sha256_cost_base: 52 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_byte: 2 +ecdsa_r1_secp256r1_verify_sha256_msg_cost_per_block: 2 +ecvrf_ecvrf_verify_cost_base: 52 +ecvrf_ecvrf_verify_alpha_string_cost_per_byte: 2 +ecvrf_ecvrf_verify_alpha_string_cost_per_block: 2 +ed25519_ed25519_verify_cost_base: 52 +ed25519_ed25519_verify_msg_cost_per_byte: 2 +ed25519_ed25519_verify_msg_cost_per_block: 2 +groth16_prepare_verifying_key_bls12381_cost_base: 52 +groth16_prepare_verifying_key_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_base: 52 +groth16_verify_groth16_proof_internal_bls12381_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_bn254_cost_base: 52 +groth16_verify_groth16_proof_internal_bn254_cost_per_public_input: 2 +groth16_verify_groth16_proof_internal_public_input_cost_per_byte: 2 +hash_blake2b256_cost_base: 52 +hash_blake2b256_data_cost_per_byte: 2 +hash_blake2b256_data_cost_per_block: 2 +hash_keccak256_cost_base: 52 +hash_keccak256_data_cost_per_byte: 2 +hash_keccak256_data_cost_per_block: 2 +poseidon_bn254_cost_base: 260 +poseidon_bn254_cost_per_block: 10 +group_ops_bls12381_decode_scalar_cost: 52 +group_ops_bls12381_decode_g1_cost: 52 +group_ops_bls12381_decode_g2_cost: 52 +group_ops_bls12381_decode_gt_cost: 52 +group_ops_bls12381_scalar_add_cost: 52 +group_ops_bls12381_g1_add_cost: 52 +group_ops_bls12381_g2_add_cost: 52 +group_ops_bls12381_gt_add_cost: 52 +group_ops_bls12381_scalar_sub_cost: 52 +group_ops_bls12381_g1_sub_cost: 52 +group_ops_bls12381_g2_sub_cost: 52 +group_ops_bls12381_gt_sub_cost: 52 +group_ops_bls12381_scalar_mul_cost: 52 +group_ops_bls12381_g1_mul_cost: 52 +group_ops_bls12381_g2_mul_cost: 52 +group_ops_bls12381_gt_mul_cost: 52 +group_ops_bls12381_scalar_div_cost: 52 +group_ops_bls12381_g1_div_cost: 52 +group_ops_bls12381_g2_div_cost: 52 +group_ops_bls12381_gt_div_cost: 52 +group_ops_bls12381_g1_hash_to_base_cost: 52 +group_ops_bls12381_g2_hash_to_base_cost: 52 +group_ops_bls12381_g1_hash_to_cost_per_byte: 2 +group_ops_bls12381_g2_hash_to_cost_per_byte: 2 +group_ops_bls12381_g1_msm_base_cost: 52 +group_ops_bls12381_g2_msm_base_cost: 52 +group_ops_bls12381_g1_msm_base_cost_per_input: 52 +group_ops_bls12381_g2_msm_base_cost_per_input: 52 +group_ops_bls12381_msm_max_len: 32 +group_ops_bls12381_pairing_cost: 52 +hmac_hmac_sha3_256_cost_base: 52 +hmac_hmac_sha3_256_input_cost_per_byte: 2 +hmac_hmac_sha3_256_input_cost_per_block: 2 +check_zklogin_id_cost_base: 200 +check_zklogin_issuer_cost_base: 200 +vdf_verify_vdf_cost: 1500 +vdf_hash_to_input_cost: 100 +bcs_per_byte_serialized_cost: 2 +bcs_legacy_min_output_size_cost: 1 +bcs_failure_cost: 52 +hash_sha2_256_base_cost: 52 +hash_sha2_256_per_byte_cost: 2 +hash_sha2_256_legacy_min_input_len_cost: 1 +hash_sha3_256_base_cost: 52 +hash_sha3_256_per_byte_cost: 2 +hash_sha3_256_legacy_min_input_len_cost: 1 +type_name_get_base_cost: 52 +type_name_get_per_byte_cost: 2 +string_check_utf8_base_cost: 52 +string_check_utf8_per_byte_cost: 2 +string_is_char_boundary_base_cost: 52 +string_sub_string_base_cost: 52 +string_sub_string_per_byte_cost: 2 +string_index_of_base_cost: 52 +string_index_of_per_byte_pattern_cost: 2 +string_index_of_per_byte_searched_cost: 2 +vector_empty_base_cost: 52 +vector_length_base_cost: 52 +vector_push_back_base_cost: 52 +vector_push_back_legacy_per_abstract_memory_unit_cost: 2 +vector_borrow_base_cost: 52 +vector_pop_back_base_cost: 52 +vector_destroy_empty_base_cost: 52 +vector_swap_base_cost: 52 +debug_print_base_cost: 52 +debug_print_stack_trace_base_cost: 52 +execution_version: 1 +consensus_bad_nodes_stake_threshold: 20 +max_jwk_votes_per_validator_per_epoch: 240 +max_age_of_jwk_in_epochs: 1 +random_beacon_reduction_allowed_delta: 800 +random_beacon_reduction_lower_bound: 1000 +random_beacon_dkg_timeout_round: 3000 +random_beacon_min_round_interval_ms: 500 +random_beacon_dkg_version: 1 +consensus_max_transaction_size_bytes: 262144 +consensus_max_transactions_in_block_bytes: 524288 +consensus_max_num_transactions_in_block: 512 +max_deferral_rounds_for_congestion_control: 10 +min_checkpoint_interval_ms: 200 +checkpoint_summary_version_specific_data: 1 +max_soft_bundle_size: 5 +bridge_should_try_to_finalize_committee: true +max_accumulated_txn_cost_per_object_in_mysticeti_commit: 10 diff --git a/crates/iota-types/src/iota_sdk2_conversions.rs b/crates/iota-types/src/iota_sdk2_conversions.rs index 4ca1631cc76..36190a8feae 100644 --- a/crates/iota-types/src/iota_sdk2_conversions.rs +++ b/crates/iota-types/src/iota_sdk2_conversions.rs @@ -534,6 +534,7 @@ impl From for EndOfEpochTransacti bridge_object_version: sequence_number.value(), } } + crate::transaction::EndOfEpochTransactionKind::SystemDisplay(_) => todo!(), } } } diff --git a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs index 5191be6c45e..f4797f3f4e2 100644 --- a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs +++ b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v1.rs @@ -454,7 +454,6 @@ pub struct IotaSystemStateV1 { pub safe_mode_storage_rebates: u64, pub safe_mode_non_refundable_storage_fee: u64, pub epoch_start_timestamp_ms: u64, - pub system_display_objects: VecMap, pub extra_fields: Bag, // TODO: Use getters instead of all pub. } @@ -632,7 +631,6 @@ impl IotaSystemStateTrait for IotaSystemStateV1 { safe_mode_storage_rebates, safe_mode_non_refundable_storage_fee, epoch_start_timestamp_ms, - system_display_objects: _, extra_fields: _, } = self; IotaSystemStateSummary { diff --git a/crates/iota-types/src/iota_system_state/iota_system_state_inner_v2.rs b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v2.rs new file mode 100644 index 00000000000..e0b416645b8 --- /dev/null +++ b/crates/iota-types/src/iota_system_state/iota_system_state_inner_v2.rs @@ -0,0 +1,276 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2024 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::Result; +use serde::{Deserialize, Serialize}; + +use super::{ + AdvanceEpochParams, IotaSystemStateTrait, + epoch_start_iota_system_state::EpochStartValidatorInfoV1, + get_validators_from_table_vec, + iota_system_state_inner_v1::{StorageFundV1, SystemParametersV1, ValidatorSetV1, ValidatorV1}, + iota_system_state_summary::{IotaSystemStateSummary, IotaValidatorSummary}, +}; +use crate::{ + balance::Balance, + base_types::IotaAddress, + collection_types::{Bag, Table, TableVec, VecMap, VecSet}, + committee::{CommitteeWithNetworkMetadata, NetworkMetadata}, + error::IotaError, + gas_coin::IotaTreasuryCap, + id::ID, + iota_system_state::epoch_start_iota_system_state::EpochStartSystemState, + storage::ObjectStore, + system_admin_cap::IotaSystemAdminCap, +}; + +/// Rust version of the Move iota_system::iota_system::IotaSystemStateV2 type +#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] +pub struct IotaSystemStateV2 { + pub epoch: u64, + pub protocol_version: u64, + pub system_state_version: u64, + pub iota_treasury_cap: IotaTreasuryCap, + pub validators: ValidatorSetV1, + pub storage_fund: StorageFundV1, + pub parameters: SystemParametersV1, + pub iota_system_admin_cap: IotaSystemAdminCap, + pub reference_gas_price: u64, + pub validator_report_records: VecMap>, + pub safe_mode: bool, + pub safe_mode_storage_charges: Balance, + pub safe_mode_computation_rewards: Balance, + pub safe_mode_storage_rebates: u64, + pub safe_mode_non_refundable_storage_fee: u64, + pub epoch_start_timestamp_ms: u64, + pub system_display_objects: VecMap, + pub extra_fields: Bag, + // TODO: Use getters instead of all pub. +} + +impl IotaSystemStateTrait for IotaSystemStateV2 { + fn epoch(&self) -> u64 { + self.epoch + } + + fn reference_gas_price(&self) -> u64 { + self.reference_gas_price + } + + fn protocol_version(&self) -> u64 { + self.protocol_version + } + + fn system_state_version(&self) -> u64 { + self.system_state_version + } + + fn epoch_start_timestamp_ms(&self) -> u64 { + self.epoch_start_timestamp_ms + } + + fn epoch_duration_ms(&self) -> u64 { + self.parameters.epoch_duration_ms + } + + fn safe_mode(&self) -> bool { + self.safe_mode + } + + fn advance_epoch_safe_mode(&mut self, params: &AdvanceEpochParams) { + self.epoch = params.epoch; + self.safe_mode = true; + self.safe_mode_storage_charges + .deposit_for_safe_mode(params.storage_charge); + self.safe_mode_storage_rebates += params.storage_rebate; + self.safe_mode_computation_rewards + .deposit_for_safe_mode(params.computation_charge); + self.safe_mode_non_refundable_storage_fee += params.non_refundable_storage_fee; + self.epoch_start_timestamp_ms = params.epoch_start_timestamp_ms; + self.protocol_version = params.next_protocol_version.as_u64(); + } + + fn get_current_epoch_committee(&self) -> CommitteeWithNetworkMetadata { + let validators = self + .validators + .active_validators + .iter() + .map(|validator| { + let verified_metadata = validator.verified_metadata(); + let name = verified_metadata.iota_pubkey_bytes(); + ( + name, + (validator.voting_power, NetworkMetadata { + network_address: verified_metadata.net_address.clone(), + primary_address: verified_metadata.primary_address.clone(), + }), + ) + }) + .collect(); + CommitteeWithNetworkMetadata::new(self.epoch, validators) + } + + fn get_pending_active_validators( + &self, + object_store: &S, + ) -> Result, IotaError> { + let table_id = self.validators.pending_active_validators.contents.id; + let table_size = self.validators.pending_active_validators.contents.size; + let validators: Vec = + get_validators_from_table_vec(&object_store, table_id, table_size)?; + Ok(validators + .into_iter() + .map(|v| v.into_iota_validator_summary()) + .collect()) + } + + fn into_epoch_start_state(self) -> EpochStartSystemState { + EpochStartSystemState::new_v1( + self.epoch, + self.protocol_version, + self.reference_gas_price, + self.safe_mode, + self.epoch_start_timestamp_ms, + self.parameters.epoch_duration_ms, + self.validators + .active_validators + .iter() + .map(|validator| { + let metadata = validator.verified_metadata(); + EpochStartValidatorInfoV1 { + iota_address: metadata.iota_address, + authority_pubkey: metadata.authority_pubkey.clone(), + network_pubkey: metadata.network_pubkey.clone(), + protocol_pubkey: metadata.protocol_pubkey.clone(), + iota_net_address: metadata.net_address.clone(), + p2p_address: metadata.p2p_address.clone(), + primary_address: metadata.primary_address.clone(), + voting_power: validator.voting_power, + hostname: metadata.name.clone(), + } + }) + .collect(), + ) + } + + fn into_iota_system_state_summary(self) -> IotaSystemStateSummary { + // If you are making any changes to IotaSystemStateV2 or any of its dependent + // types before mainnet, please also update IotaSystemStateSummary and + // its corresponding TS type. Post-mainnet, we will need to introduce a + // new version. + let Self { + epoch, + protocol_version, + system_state_version, + iota_treasury_cap, + validators: + ValidatorSetV1 { + total_stake, + active_validators, + pending_active_validators: + TableVec { + contents: + Table { + id: pending_active_validators_id, + size: pending_active_validators_size, + }, + }, + pending_removals, + staking_pool_mappings: + Table { + id: staking_pool_mappings_id, + size: staking_pool_mappings_size, + }, + inactive_validators: + Table { + id: inactive_pools_id, + size: inactive_pools_size, + }, + validator_candidates: + Table { + id: validator_candidates_id, + size: validator_candidates_size, + }, + at_risk_validators: + VecMap { + contents: at_risk_validators, + }, + extra_fields: _, + }, + storage_fund, + parameters: + SystemParametersV1 { + epoch_duration_ms, + min_validator_count, + max_validator_count, + min_validator_joining_stake, + validator_low_stake_threshold, + validator_very_low_stake_threshold, + validator_low_stake_grace_period, + extra_fields: _, + }, + iota_system_admin_cap: _, + reference_gas_price, + validator_report_records: + VecMap { + contents: validator_report_records, + }, + safe_mode, + safe_mode_storage_charges, + safe_mode_computation_rewards, + safe_mode_storage_rebates, + safe_mode_non_refundable_storage_fee, + epoch_start_timestamp_ms, + system_display_objects: _, + extra_fields: _, + } = self; + IotaSystemStateSummary { + epoch, + protocol_version, + system_state_version, + iota_total_supply: iota_treasury_cap.total_supply().value, + iota_treasury_cap_id: iota_treasury_cap.id().to_owned(), + storage_fund_total_object_storage_rebates: storage_fund + .total_object_storage_rebates + .value(), + storage_fund_non_refundable_balance: storage_fund.non_refundable_balance.value(), + reference_gas_price, + safe_mode, + safe_mode_storage_charges: safe_mode_storage_charges.value(), + safe_mode_computation_rewards: safe_mode_computation_rewards.value(), + safe_mode_storage_rebates, + safe_mode_non_refundable_storage_fee, + epoch_start_timestamp_ms, + epoch_duration_ms, + total_stake, + active_validators: active_validators + .into_iter() + .map(|v| v.into_iota_validator_summary()) + .collect(), + pending_active_validators_id, + pending_active_validators_size, + pending_removals, + staking_pool_mappings_id, + staking_pool_mappings_size, + inactive_pools_id, + inactive_pools_size, + validator_candidates_id, + validator_candidates_size, + at_risk_validators: at_risk_validators + .into_iter() + .map(|e| (e.key, e.value)) + .collect(), + validator_report_records: validator_report_records + .into_iter() + .map(|e| (e.key, e.value.contents)) + .collect(), + min_validator_count, + max_validator_count, + min_validator_joining_stake, + validator_low_stake_threshold, + validator_very_low_stake_threshold, + validator_low_stake_grace_period, + } + } +} diff --git a/crates/iota-types/src/iota_system_state/mod.rs b/crates/iota-types/src/iota_system_state/mod.rs index 89b0ac84888..f6e894ea44e 100644 --- a/crates/iota-types/src/iota_system_state/mod.rs +++ b/crates/iota-types/src/iota_system_state/mod.rs @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize, de::DeserializeOwned}; use self::{ iota_system_state_inner_v1::{IotaSystemStateV1, ValidatorV1}, + iota_system_state_inner_v2::IotaSystemStateV2, iota_system_state_summary::{IotaSystemStateSummary, IotaValidatorSummary}, }; use crate::{ @@ -30,6 +31,7 @@ use crate::{ pub mod epoch_start_iota_system_state; pub mod iota_system_state_inner_v1; +pub mod iota_system_state_inner_v2; pub mod iota_system_state_summary; #[cfg(msim)] @@ -46,6 +48,13 @@ pub const IOTA_SYSTEM_MODULE_NAME: &IdentStr = ident_str!("iota_system"); pub const ADVANCE_EPOCH_FUNCTION_NAME: &IdentStr = ident_str!("advance_epoch"); pub const ADVANCE_EPOCH_SAFE_MODE_FUNCTION_NAME: &IdentStr = ident_str!("advance_epoch_safe_mode"); +pub const IOTA_SYSTEM_DISPLAY_MODULE_NAME: &IdentStr = ident_str!("system_display"); +pub const CREATE_STAKED_IOTA_DISPLAY_V1: &IdentStr = ident_str!("create_staked_iota_display_v1"); +pub const CREATE_TIMELOCKED_STAKED_IOTA_DISPLAY_V1: &IdentStr = + ident_str!("create_timelocked_staked_iota_display_v1"); +pub const CREATE_TIMELOCKED_IOTA_DISPLAY_V1: &IdentStr = + ident_str!("create_timelocked_iota_display_v1"); + #[cfg(msim)] pub const IOTA_SYSTEM_STATE_SIM_TEST_V1: u64 = 18446744073709551605; // u64::MAX - 10 #[cfg(msim)] @@ -103,6 +112,13 @@ impl IotaSystemStateWrapper { protocol_config, ); } + 2 => { + Self::advance_epoch_safe_mode_impl::( + move_object, + params, + protocol_config, + ); + } #[cfg(msim)] IOTA_SYSTEM_STATE_SIM_TEST_V1 => { Self::advance_epoch_safe_mode_impl::( @@ -191,6 +207,7 @@ pub trait IotaSystemStateTrait { #[enum_dispatch(IotaSystemStateTrait)] pub enum IotaSystemState { V1(IotaSystemStateV1), + V2(IotaSystemStateV2), #[cfg(msim)] SimTestV1(SimTestIotaSystemStateV1), #[cfg(msim)] @@ -212,11 +229,8 @@ impl IotaSystemState { pub fn into_genesis_version_for_tooling(self) -> IotaSystemStateInnerGenesis { match self { IotaSystemState::V1(inner) => inner, - #[cfg(msim)] - _ => { - // Types other than V1 used in simtests should be unreachable - unreachable!() - } + // Types other than V1 and used in simtests should be unreachable + _ => unreachable!(), } } @@ -260,6 +274,18 @@ pub fn get_iota_system_state(object_store: &dyn ObjectStore) -> Result { + let result: IotaSystemStateV2 = + get_dynamic_field_from_store(object_store, id, &wrapper.version).map_err( + |err| { + IotaError::DynamicFieldRead(format!( + "Failed to load iota system state inner object with ID {:?} and version {:?}: {:?}", + id, wrapper.version, err + )) + }, + )?; + Ok(IotaSystemState::V2(result)) + } #[cfg(msim)] IOTA_SYSTEM_STATE_SIM_TEST_V1 => { let result: SimTestIotaSystemStateV1 = @@ -400,12 +426,13 @@ pub fn get_system_display_objects( let system_state = get_iota_system_state(object_store)?; match system_state { - IotaSystemState::V1(inner) => inner + IotaSystemState::V1(_) => Ok(HashMap::new()), + IotaSystemState::V2(inner) => inner .system_display_objects .contents .into_iter() .map(|entry| { - let display_object_id = entry.value.bytes; + let display_object_id = entry.value; let display_object: DisplayObject = get_dynamic_field_from_store( object_store, @@ -427,11 +454,11 @@ pub fn get_system_display_objects( } /// Get a system display object unique key. -/// * ty - is a type for which a display object is created. -pub fn display_object_key(ty: StructTag) -> String { +/// * tag - is a tag of a type for which the display object is created. +pub fn system_display_object_key(tag: StructTag) -> String { let with_prefix = false; - ty.to_canonical_string(with_prefix) + tag.to_canonical_string(with_prefix) } #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Default)] diff --git a/crates/iota-types/src/transaction.rs b/crates/iota-types/src/transaction.rs index f8ff33452b3..daf7e3bd43f 100644 --- a/crates/iota-types/src/transaction.rs +++ b/crates/iota-types/src/transaction.rs @@ -292,6 +292,14 @@ pub enum TransactionKind { // .. more transaction types go here } +/// SystemDisplayTransactionKind +#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, IntoStaticStr)] +pub enum SystemDisplayTransactionKind { + StakedIotaV1, + TimelockedStakedIotaV1, + TimelockedIotaV1, +} + /// EndOfEpochTransactionKind #[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, IntoStaticStr)] pub enum EndOfEpochTransactionKind { @@ -300,6 +308,7 @@ pub enum EndOfEpochTransactionKind { AuthenticatorStateExpire(AuthenticatorStateExpire), BridgeStateCreate(ChainIdentifier), BridgeCommitteeInit(SequenceNumber), + SystemDisplay(Vec), } impl EndOfEpochTransactionKind { @@ -347,6 +356,10 @@ impl EndOfEpochTransactionKind { Self::BridgeCommitteeInit(bridge_shared_version) } + pub fn system_display(txs: Vec) -> Self { + Self::SystemDisplay(txs) + } + fn input_objects(&self) -> Vec { match self { Self::ChangeEpoch(_) => { @@ -377,6 +390,13 @@ impl EndOfEpochTransactionKind { mutable: true, }, ], + Self::SystemDisplay(_) => { + vec![InputObjectKind::SharedMoveObject { + id: IOTA_SYSTEM_STATE_OBJECT_ID, + initial_shared_version: IOTA_SYSTEM_STATE_OBJECT_SHARED_VERSION, + mutable: true, + }] + } } } @@ -406,6 +426,9 @@ impl EndOfEpochTransactionKind { ] .into_iter(), ), + Self::SystemDisplay(_) => { + Either::Left(vec![SharedInputObject::IOTA_SYSTEM_OBJ].into_iter()) + } } } @@ -438,6 +461,33 @@ impl EndOfEpochTransactionKind { )); } } + Self::SystemDisplay(txs) => { + for tx in txs { + match tx { + SystemDisplayTransactionKind::StakedIotaV1 => { + if !config.enable_staked_iota_display_v1() { + return Err(UserInputError::Unsupported( + "`StakedIota` display is not enabled".to_string(), + )); + } + } + SystemDisplayTransactionKind::TimelockedStakedIotaV1 => { + if !config.enable_timelocked_staked_iota_display_v1() { + return Err(UserInputError::Unsupported( + "`TimelockedStakedIota` display is not enabled".to_string(), + )); + } + } + SystemDisplayTransactionKind::TimelockedIotaV1 => { + if !config.enable_timelocked_iota_display_v1() { + return Err(UserInputError::Unsupported( + "`TimeLock>` display is not enabled".to_string(), + )); + } + } + } + } + } } Ok(()) } diff --git a/iota-execution/latest/iota-adapter/src/execution_engine.rs b/iota-execution/latest/iota-adapter/src/execution_engine.rs index 26353e36d0a..0cdfb2650e3 100644 --- a/iota-execution/latest/iota-adapter/src/execution_engine.rs +++ b/iota-execution/latest/iota-adapter/src/execution_engine.rs @@ -16,7 +16,7 @@ mod checked { use iota_types::{ BRIDGE_ADDRESS, IOTA_AUTHENTICATOR_STATE_OBJECT_ID, IOTA_BRIDGE_OBJECT_ID, IOTA_FRAMEWORK_ADDRESS, IOTA_FRAMEWORK_PACKAGE_ID, IOTA_RANDOMNESS_STATE_OBJECT_ID, - IOTA_SYSTEM_PACKAGE_ID, + IOTA_SYSTEM_ADDRESS, IOTA_SYSTEM_PACKAGE_ID, authenticator_state::{ AUTHENTICATOR_STATE_CREATE_FUNCTION_NAME, AUTHENTICATOR_STATE_EXPIRE_JWKS_FUNCTION_NAME, AUTHENTICATOR_STATE_MODULE_NAME, @@ -46,7 +46,9 @@ mod checked { id::UID, inner_temporary_store::InnerTemporaryStore, iota_system_state::{ - ADVANCE_EPOCH_FUNCTION_NAME, AdvanceEpochParams, IOTA_SYSTEM_MODULE_NAME, + ADVANCE_EPOCH_FUNCTION_NAME, AdvanceEpochParams, CREATE_STAKED_IOTA_DISPLAY_V1, + CREATE_TIMELOCKED_IOTA_DISPLAY_V1, CREATE_TIMELOCKED_STAKED_IOTA_DISPLAY_V1, + IOTA_SYSTEM_DISPLAY_MODULE_NAME, IOTA_SYSTEM_MODULE_NAME, }, messages_checkpoint::CheckpointTimestamp, metrics::LimitsMetrics, @@ -57,7 +59,8 @@ mod checked { transaction::{ Argument, AuthenticatorStateExpire, AuthenticatorStateUpdateV1, CallArg, ChangeEpoch, CheckedInputObjects, Command, EndOfEpochTransactionKind, GenesisTransaction, ObjectArg, - ProgrammableTransaction, RandomnessStateUpdate, TransactionKind, + ProgrammableTransaction, RandomnessStateUpdate, SystemDisplayTransactionKind, + TransactionKind, }, }; use move_binary_format::CompiledModule; @@ -696,6 +699,9 @@ mod checked { assert!(protocol_config.should_try_to_finalize_bridge_committee()); builder = setup_bridge_committee_update(builder, bridge_shared_version) } + EndOfEpochTransactionKind::SystemDisplay(txs) => { + builder = setup_system_display_objects(builder, protocol_config, txs) + } } } unreachable!( @@ -1232,4 +1238,64 @@ mod checked { pt, ) } + + /// Configures a `ProgrammableTransactionBuilder` to update the system + /// display objects. + fn setup_system_display_objects( + mut builder: ProgrammableTransactionBuilder, + protocol_config: &ProtocolConfig, + txs: Vec, + ) -> ProgrammableTransactionBuilder { + for tx in txs { + match tx { + SystemDisplayTransactionKind::StakedIotaV1 => { + assert!(protocol_config.enable_staked_iota_display_v1()); + + let system_state = builder + .obj(ObjectArg::IOTA_SYSTEM_MUT) + .expect("Unable to create System State object arg!"); + + builder.programmable_move_call( + IOTA_SYSTEM_ADDRESS.into(), + IOTA_SYSTEM_DISPLAY_MODULE_NAME.to_owned(), + CREATE_STAKED_IOTA_DISPLAY_V1.to_owned(), + vec![], + vec![system_state], + ); + } + SystemDisplayTransactionKind::TimelockedStakedIotaV1 => { + assert!(protocol_config.enable_timelocked_staked_iota_display_v1()); + + let system_state = builder + .obj(ObjectArg::IOTA_SYSTEM_MUT) + .expect("Unable to create System State object arg!"); + + builder.programmable_move_call( + IOTA_SYSTEM_ADDRESS.into(), + IOTA_SYSTEM_DISPLAY_MODULE_NAME.to_owned(), + CREATE_TIMELOCKED_STAKED_IOTA_DISPLAY_V1.to_owned(), + vec![], + vec![system_state], + ); + } + SystemDisplayTransactionKind::TimelockedIotaV1 => { + assert!(protocol_config.enable_timelocked_iota_display_v1()); + + let system_state = builder + .obj(ObjectArg::IOTA_SYSTEM_MUT) + .expect("Unable to create System State object arg!"); + + builder.programmable_move_call( + IOTA_SYSTEM_ADDRESS.into(), + IOTA_SYSTEM_DISPLAY_MODULE_NAME.to_owned(), + CREATE_TIMELOCKED_IOTA_DISPLAY_V1.to_owned(), + vec![], + vec![system_state], + ); + } + } + } + + builder + } }