From 99fb387be8036417321688a8dd7c3630827775d8 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 2 Dec 2025 13:43:12 +0200 Subject: [PATCH 01/21] feat: replace `AuthenticatorInfoV1CompatibilityProof` with native functions --- .../iota-framework/sources/account.move | 73 ++++---- .../iota-framework/tests/account_tests.move | 163 ++++++++---------- .../packages_compiled/iota-framework | Bin 79787 -> 79612 bytes crates/iota-framework/published_api.txt | 19 +- .../sources/dynamic_multisig_account.move | 18 +- .../function_keys/sources/function_keys.move | 10 +- .../move/iotaccount/sources/iotaccount.move | 33 ++-- .../iotaccount/sources/keyed_iotaccount.move | 5 +- .../tests/iotaccount_builder_tests.move | 15 +- .../move/iotaccount/tests/test_utils.move | 11 +- .../move/time_locked/sources/account.move | 10 +- .../latest/iota-move-natives/src/lib.rs | 15 ++ 12 files changed, 169 insertions(+), 203 deletions(-) diff --git a/crates/iota-framework/packages/iota-framework/sources/account.move b/crates/iota-framework/packages/iota-framework/sources/account.move index 7b5e6b2c748..4f9fe1a74c0 100644 --- a/crates/iota-framework/packages/iota-framework/sources/account.move +++ b/crates/iota-framework/packages/iota-framework/sources/account.move @@ -15,10 +15,7 @@ const EAuthenticatorInfoV1AlreadyAttached: vector = const EAuthenticatorInfoV1NotAttached: vector = b"'AuthenticatorInfoV1' is not attached to the account."; #[error(code = 2)] -const EAuthenticatorInfoV1CompatibilityNotProven: vector = - b"An `AuthenticatorInfoV1` instance is not verified to be attached to the account."; -#[error(code = 3)] -const EAuthenticatorInfoNotCompatibileWithAccount: vector = +const EAuthenticatorInfoNotCompatibleWithAccount: vector = b"The provided `AuthenticatorInfoV1` is not compatible with the account type."; /// Dynamic field key, where the system will look for a potential @@ -33,12 +30,6 @@ public struct AuthenticatorInfoV1 has copy, drop, store { function_name: ascii::String, } -/// Represents a proof of compatibility between `AuthenticatorInfoV1` and an account. -public struct AuthenticatorInfoV1CompatibilityProof has drop { - account_id: ID, - authenticator: AuthenticatorInfoV1, -} - /// Create an "AuthenticatorInfoV1" using an `authenticate` function defined outside of this version of the package /// /// The referred `package`, `module_name`, `function_name` can refer to any valid `authenticate` function, @@ -65,7 +56,7 @@ public fun create_auth_info_v1( assert!( type_name::get() == authenticator_metadata.account_type(), - EAuthenticatorInfoNotCompatibileWithAccount, + EAuthenticatorInfoNotCompatibleWithAccount, ); AuthenticatorInfoV1 { package: package_metadata.storage_id(), @@ -74,38 +65,36 @@ public fun create_auth_info_v1( } } -/// Checks that the provided `authenticator` is compatible with the given `account`. -/// Returns a proof that can be used to attach or rotate the `authenticator` to the `account`. -public fun check_auth_info_v1_compatibility( - account: &Account, +/// Create a mutable shared account with the the provided `authenticator`. +/// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. +public fun create_shared_account_v1( + mut account: Account, authenticator: AuthenticatorInfoV1, -): AuthenticatorInfoV1CompatibilityProof { - AuthenticatorInfoV1CompatibilityProof { - account_id: object::id(account), - authenticator, - } +) { + attach_auth_info_v1(&mut account, authenticator); + + create_shared_account_v1_impl(account); } -/// Attach the `authenticator` instance to the account. It uses a `AuthenticatorInfoV1CompatibilityProof` to obtain that instance. -/// It will be added as a dynamic field specified by the `AuthenticatorInfoV1Key` name. -public fun attach_auth_info_v1( - account_id: &mut UID, - proof: AuthenticatorInfoV1CompatibilityProof, +/// Create an immutable account with the the provided `authenticator`. +/// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. +public fun create_immutable_account_v1( + mut account: Account, + authenticator: AuthenticatorInfoV1, ) { - assert!(account_id.as_inner() == proof.account_id, EAuthenticatorInfoV1CompatibilityNotProven); - assert!(!has_auth_info_v1(account_id), EAuthenticatorInfoV1AlreadyAttached); + attach_auth_info_v1(&mut account, authenticator); - dynamic_field::add(account_id, auth_info_v1_key(), proof.authenticator); + create_immutable_account_v1_impl(account); } /// Rotate the account-related authenticator. -/// The `authenticator` instance will replace the account dynamic field specified by the `AuthenticatorInfoV1Key` name; -/// It uses a `AuthenticatorInfoV1CompatibilityProof` to obtain the new instance. +/// The `authenticator` instance will replace the account dynamic field specified by the `AuthenticatorInfoV1Key` name. public fun rotate_auth_info_v1( - account_id: &mut UID, - proof: AuthenticatorInfoV1CompatibilityProof, + account: &mut Account, + authenticator: AuthenticatorInfoV1, ): AuthenticatorInfoV1 { - assert!(account_id.as_inner() == proof.account_id, EAuthenticatorInfoV1CompatibilityNotProven); + let account_id = borrow_account_uid(account); + assert!(has_auth_info_v1(account_id), EAuthenticatorInfoV1NotAttached); let name = auth_info_v1_key(); @@ -114,7 +103,7 @@ public fun rotate_auth_info_v1( account_id, name, ); - dynamic_field::add(account_id, name, proof.authenticator); + dynamic_field::add(account_id, name, authenticator); previous_authenticator_info } @@ -134,6 +123,22 @@ fun auth_info_v1_key(): AuthenticatorInfoV1Key { AuthenticatorInfoV1Key {} } +fun attach_auth_info_v1( + account: &mut Account, + authenticator: AuthenticatorInfoV1, +) { + let account_id = borrow_account_uid(account); + + assert!(!has_auth_info_v1(account_id), EAuthenticatorInfoV1AlreadyAttached); + + dynamic_field::add(account_id, auth_info_v1_key(), authenticator); +} + +native fun borrow_account_uid(account: &mut Account): &mut UID; + +native fun create_shared_account_v1_impl(account: Account); +native fun create_immutable_account_v1_impl(account: Account); + /// Creates an `AuthenticatorInfoV1` instance for testing, skipping validation. #[test_only] public fun create_auth_info_v1_for_testing( diff --git a/crates/iota-framework/packages/iota-framework/tests/account_tests.move b/crates/iota-framework/packages/iota-framework/tests/account_tests.move index 85eac11a33c..d926540a50d 100644 --- a/crates/iota-framework/packages/iota-framework/tests/account_tests.move +++ b/crates/iota-framework/packages/iota-framework/tests/account_tests.move @@ -18,24 +18,20 @@ fun id(self: &TestAccount): &UID { &self.id } -fun id_mut(self: &mut TestAccount): &mut UID { - &mut self.id -} - #[test] -fun authenticator_info_v1_happy_path() { - account_test_mut!(|_, account| { +fun authenticator_info_v1_shared_account_happy_path() { + account_test!(|scenario, account| { let default_authenticator_info = create_default_authenticator_info_v1_for_testing(); // Check that there is no an attached `AuthenticatorInfoV1` just after creation. assert_eq(account::has_auth_info_v1(account.id()), false); - // Attach an `AuthenticatorInfoV1` instance to the account. - let compatibility_proof = account::check_auth_info_v1_compatibility( - account, - default_authenticator_info, - ); - account::attach_auth_info_v1(account.id_mut(), compatibility_proof); + // Create a shared account with an attached `AuthenticatorInfoV1` instance. + account::create_shared_account_v1(account, default_authenticator_info); + + scenario.next_tx(@0x0); + + let mut account = scenario.take_shared(); assert_eq(account::has_auth_info_v1(account.id()), true); assert_ref_eq(account::borrow_auth_info_v1(account.id()), &default_authenticator_info); @@ -46,27 +42,46 @@ fun authenticator_info_v1_happy_path() { ascii::string(b"module2"), ascii::string(b"function2"), ); - - let compatibility_proof = account::check_auth_info_v1_compatibility( - account, - updated_authenticator_info, - ); let previous_authenticator_info = account::rotate_auth_info_v1( - account.id_mut(), - compatibility_proof, + &mut account, + updated_authenticator_info, ); assert_eq(previous_authenticator_info, default_authenticator_info); assert_eq(account::has_auth_info_v1(account.id()), true); assert_ref_eq(account::borrow_auth_info_v1(account.id()), &updated_authenticator_info); + + test_scenario::return_shared(account); + }); +} + +#[test] +fun authenticator_info_v1_immutable_account_happy_path() { + account_test!(|scenario, account| { + let default_authenticator_info = create_default_authenticator_info_v1_for_testing(); + + // Check that there is no an attached `AuthenticatorInfoV1` just after creation. + assert_eq(account::has_auth_info_v1(account.id()), false); + + // Create an immutable account with an attached `AuthenticatorInfoV1` instance. + account::create_immutable_account_v1(account, default_authenticator_info); + + scenario.next_tx(@0x0); + + let account = scenario.take_immutable(); + + assert_eq(account::has_auth_info_v1(account.id()), true); + assert_ref_eq(account::borrow_auth_info_v1(account.id()), &default_authenticator_info); + + test_scenario::return_immutable(account); }); } #[test] #[expected_failure(abort_code = account::EAuthenticatorInfoV1AlreadyAttached)] -fun authenticator_info_v1_double_attach() { - account_test_mut!(|_, account| { +fun authenticator_info_v1_double_shared_account_creation() { + account_test!(|scenario, account| { let authenticator_info_1 = create_default_authenticator_info_v1_for_testing(); let authenticator_info_2 = account::create_auth_info_v1_for_testing( @0x2, @@ -74,80 +89,58 @@ fun authenticator_info_v1_double_attach() { ascii::string(b"function2"), ); - let compatibility_proof_1 = account::check_auth_info_v1_compatibility( - account, - authenticator_info_1, - ); - account::attach_auth_info_v1(account.id_mut(), compatibility_proof_1); - // Attach another `AuthenticatorInfoV1` instance that is forbidden. - let compatibility_proof_2 = account::check_auth_info_v1_compatibility( - account, - authenticator_info_2, - ); - account::attach_auth_info_v1(account.id_mut(), compatibility_proof_2); - }); -} + account::create_shared_account_v1(account, authenticator_info_1); -#[test] -#[expected_failure(abort_code = account::EAuthenticatorInfoV1CompatibilityNotProven)] -fun authenticator_info_v1_not_proven_attach() { - account_test_mut!(|scenario, account| { - let authenticator_info = create_default_authenticator_info_v1_for_testing(); + scenario.next_tx(@0x0); - let account_2 = create_test_account(scenario); - let compatibility_proof = account::check_auth_info_v1_compatibility( - &account_2, - authenticator_info, - ); - // Attach a not proven `AuthenticatorInfoV1` instance. - account::attach_auth_info_v1(account.id_mut(), compatibility_proof); - test_utils::destroy(account_2); + let account = scenario.take_shared(); + + // Call `account::create_account_v1` one more time for the same object that is forbidden. + account::create_shared_account_v1(account, authenticator_info_2); }); } #[test] -#[expected_failure(abort_code = account::EAuthenticatorInfoV1NotAttached)] -fun authenticator_info_v1_borrow_non_existent() { - account_test!(|_, account_id| { - // Borrow a non-existing `AuthenticatorInfoV1` instance. - account::borrow_auth_info_v1(account_id); +#[expected_failure(abort_code = account::EAuthenticatorInfoV1AlreadyAttached)] +fun authenticator_info_v1_double_immutable_account_creation() { + account_test!(|scenario, account| { + let authenticator_info_1 = create_default_authenticator_info_v1_for_testing(); + let authenticator_info_2 = account::create_auth_info_v1_for_testing( + @0x2, + ascii::string(b"module2"), + ascii::string(b"function2"), + ); + + account::create_immutable_account_v1(account, authenticator_info_1); + + scenario.next_tx(@0x0); + + let account = scenario.take_immutable(); + // Call `account::create_account_v1` one more time for the same object that is forbidden. + account::create_immutable_account_v1(account, authenticator_info_2); }); } #[test] #[expected_failure(abort_code = account::EAuthenticatorInfoV1NotAttached)] -fun authenticator_info_v1_rotate_non_existent() { - account_test_mut!(|_, account| { - let authenticator_info = create_default_authenticator_info_v1_for_testing(); +fun authenticator_info_v1_borrow_non_attached() { + account_test!(|_, account| { + // Borrow a non-attached `AuthenticatorInfoV1` instance. + account::borrow_auth_info_v1(account.id()); - let compatibility_proof = account::check_auth_info_v1_compatibility( - account, - authenticator_info, - ); - account::rotate_auth_info_v1(account.id_mut(), compatibility_proof); + test_utils::destroy(account); }); } #[test] -#[expected_failure(abort_code = account::EAuthenticatorInfoV1CompatibilityNotProven)] -fun authenticator_info_v1_rotate_not_proven() { - account_test_mut!(|scenario, account| { +#[expected_failure(abort_code = account::EAuthenticatorInfoV1NotAttached)] +fun authenticator_info_v1_rotate_non_attached() { + account_test!(|_, mut account| { let authenticator_info = create_default_authenticator_info_v1_for_testing(); - let compatibility_proof = account::check_auth_info_v1_compatibility( - account, - authenticator_info, - ); - account::attach_auth_info_v1(account.id_mut(), compatibility_proof); + account::rotate_auth_info_v1(&mut account, authenticator_info); - let account_2 = create_test_account(scenario); - let compatibility_proof = account::check_auth_info_v1_compatibility( - &account_2, - authenticator_info, - ); - // Rotate a not proven `AuthenticatorInfoV1` instance. - account::rotate_auth_info_v1(account.id_mut(), compatibility_proof); - test_utils::destroy(account_2); + test_utils::destroy(account); }); } @@ -163,26 +156,12 @@ fun create_default_authenticator_info_v1_for_testing(): AuthenticatorInfoV1xk;L)FKw%BDlI|4OHErj1Em2GNBs<^BRi za3P2yD0Wp`Nc|5kT?iuL-i32w3U#52Gc)I#`Mz`J-Z?LR$Y0;(tCx#|&;H5GH>Ux> zA$amj;!}5L(MS?t$C4+`y1ZC!QfDMi_Dt zM98E7=m<+U``P7MlI_&?v#+)5IGOFwR0iq6nr?Qw-Ok`3HbZSFt0v~{(;w^JQe+}Un)H#bgE zXaAK*TTIJdA5Ud(mshec%X@Dc7Z%Xn?(}YT+Ix*&tC=M$>7a@{BJ-BcSTh~|03d*` z#E{1%$x~ABq7F_ZWAoCh0%x@X3D)94 z=_#g*iIP@%M>x;|2%3OLwM2UnQ!MJrOGi$yn0At6kn%AwMJgL^5E%P`!8g!#Ln>6r z;l@&UH$p^39v+V3;;AF&WTbL@rsjHh0KfuNN_ed5nnxqNAA*?I{lnFFhpYHA{tZb5 Bio*Z^ delta 1008 zcmZ`%J7^S96utMp&%Bv8Gn+{^8?#At6OFt1AfymiurO#Nh-hOwZZ;b-s5`n&B7(Yw zrJd6VS}5501q<6078Z6^R)VdFh^?r1)(-}BVBWj;ynD_)@ALJeeE3N|dotU<8Q!1# zU^M^)2tN6XqPZ^bp|2j{ZFFAJQ)#~F!}_`NT6o{RDSOvS|DJt7!OK8~uL21k?0_1~ zV2FEx9M*BrARzHb(gAWM2;qQG{A&Z!aX=Zas{o>b{wN8aN>cH-M;1_7vjR+VEet6a zFsLYUB#u-kifO!R(81k1#yO#>;Rp@Ybs2>3l|T#!9*AAm2QfPoftpYygebJ3GwO|+ zQP*Vyj^Ph2q6?&5=no>aROF74g8)z)iTdYKVTp4^%+*ZQMsui(kj)vF0ro49#mI02 zj*K7!1GZpE7hIHsm0w`dhp8^I&T|A8Gz&tGU| z$x3oA$*!F2rRiFJsD9CUt#&)z=w@-Unm?`|Dg~{-<;L@ila*TyZ~w?j+Uup4<6<>V zxJkUZRBNwy+Gn>xar^Hs`BI~tUwc>0-!v8kaf5G-3%Uwcldr{)ownsurjKg7bh|^+@~D15Y-E&lc@*`AgU;l7(;IgGfoK o%x~7!g2lVjO-ZV#kb{IDDBDxQ9R?!aGapfS!!EwCi}>050UY9&ivR!s diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index 5874962c9bd..e91147961a0 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -1426,16 +1426,13 @@ AuthenticatorInfoV1Key AuthenticatorInfoV1 public struct 0x2::account -AuthenticatorInfoV1CompatibilityProof - public struct - 0x2::account create_auth_info_v1 public fun 0x2::account -check_auth_info_v1_compatibility +create_shared_account_v1 public fun 0x2::account -attach_auth_info_v1 +create_immutable_account_v1 public fun 0x2::account rotate_auth_info_v1 @@ -1450,6 +1447,18 @@ has_auth_info_v1 auth_info_v1_key fun 0x2::account +attach_auth_info_v1 + fun + 0x2::account +borrow_account_uid + fun + 0x2::account +create_shared_account_v1_impl + fun + 0x2::account +create_immutable_account_v1_impl + fun + 0x2::account ProgrammableMoveCall public struct 0x2::programmable_transaction diff --git a/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move b/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move index 86cec7237bd..2f63f2eeef3 100644 --- a/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move +++ b/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move @@ -64,16 +64,10 @@ public fun create( dynamic_field::add(&mut id, threshold_key(), threshold); dynamic_field::add(&mut id, transactions_key(), transactions::create(ctx)); - let mut account = DynamicMultisigAccount { id }; - - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = DynamicMultisigAccount { id }; // Create a mutable shared account object. - iota::transfer::share_object(account); + account::create_shared_account_v1(account, authenticator); } // --------------------------------------- View Functions --------------------------------------- @@ -195,17 +189,13 @@ public fun update_account_data( // Verify the provided data consistency. verify_threshold(&members, threshold); - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - self, - authenticator, - ); - let account_id = &mut self.id; // Update the dynamic fields. It is expected that the fields already exist. update_dynamic_field(account_id, members_key(), members); update_dynamic_field(account_id, threshold_key(), threshold); - account::rotate_auth_info_v1(account_id, authenticator_compatibility_proof); + + account::rotate_auth_info_v1(self, authenticator); } /// A transaction authenticator. diff --git a/examples/move/function_keys/sources/function_keys.move b/examples/move/function_keys/sources/function_keys.move index f6a14c913f2..2b20c87541b 100644 --- a/examples/move/function_keys/sources/function_keys.move +++ b/examples/move/function_keys/sources/function_keys.move @@ -66,11 +66,10 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let account = builder(authenticator, ctx) + builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) .add_dynamic_field(fk_store_key(), build_fn_keys_store(ctx)) - .finish(); - account.share(); + .build_shared(); } /// Grants (allows) a `FunctionKey` under a specific `pub_key`. @@ -180,8 +179,5 @@ public fun create_without_fk_store( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let account = builder(authenticator, ctx) - .add_dynamic_field(OwnerPublicKey {}, public_key) - .finish(); - account.share(); + builder(authenticator, ctx).add_dynamic_field(OwnerPublicKey {}, public_key).build_shared(); } diff --git a/examples/move/iotaccount/sources/iotaccount.move b/examples/move/iotaccount/sources/iotaccount.move index 9f23c2b44e2..ae8b50fb06c 100644 --- a/examples/move/iotaccount/sources/iotaccount.move +++ b/examples/move/iotaccount/sources/iotaccount.move @@ -23,6 +23,7 @@ const ETransactionSenderIsNotTheAccount: vector = b"Transaction must be sign /// add the desired authenticator info and dynamic fields. public struct IOTAccountBuilder { account: IOTAccount, + authenticator: AuthenticatorInfoV1, } /// This struct represents an abstract IOTA account. @@ -48,16 +49,10 @@ public fun builder( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): IOTAccountBuilder { - let mut builder = IOTAccountBuilder { + IOTAccountBuilder { account: IOTAccount { id: object::new(ctx) }, - }; - - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &builder.account, authenticator, - ); - account::attach_auth_info_v1(&mut builder.account.id, authenticator_compatibility_proof); - builder + } } /// Attach a `Value` as a dynamic field to the account being built. @@ -70,15 +65,15 @@ public fun add_dynamic_field( self } -/// Finish building the `IOTAccount` and share the object. -public fun finish(self: IOTAccountBuilder): IOTAccount { - let IOTAccountBuilder { account } = self; - account -} +/// Finish building a shared `IOTAccount` instance. +public fun build_shared(self: IOTAccountBuilder): address { + let IOTAccountBuilder { account, authenticator } = self; -/// Share IOTAccount. -public fun share(self: IOTAccount) { - iota::transfer::share_object(self); + let account_address = account.account_address(); + + account::create_shared_account_v1(account, authenticator); + + account_address } /// Adds a new dynamic field to the account. @@ -155,11 +150,7 @@ public fun rotate_auth_info_v1( ): AuthenticatorInfoV1 { ensure_tx_sender_is_account(self, ctx); - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - self, - authenticator, - ); - account::rotate_auth_info_v1(&mut self.id, authenticator_compatibility_proof) + account::rotate_auth_info_v1(self, authenticator) } // === Public-View Functions === diff --git a/examples/move/iotaccount/sources/keyed_iotaccount.move b/examples/move/iotaccount/sources/keyed_iotaccount.move index ff9a358d7a3..f2abca94abc 100644 --- a/examples/move/iotaccount/sources/keyed_iotaccount.move +++ b/examples/move/iotaccount/sources/keyed_iotaccount.move @@ -50,10 +50,9 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let account = iotaccount::builder(authenticator, ctx) + iotaccount::builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) - .finish(); - account.share(); + .build_shared(); } /// Ed25519 signature authenticator. diff --git a/examples/move/iotaccount/tests/iotaccount_builder_tests.move b/examples/move/iotaccount/tests/iotaccount_builder_tests.move index 10311632dba..c551815e48d 100644 --- a/examples/move/iotaccount/tests/iotaccount_builder_tests.move +++ b/examples/move/iotaccount/tests/iotaccount_builder_tests.move @@ -26,10 +26,7 @@ fun builder_all_mandatory_fields_set() { let authenticator = create_authenticator_info_v1_for_testing(); // Any field value can be set as a dynamic field, and for the purposes of this test // the exact value doesn't matter. - let account = iotaccount::builder(authenticator, ctx) - .add_dynamic_field(dynamic_field_key, 6) - .finish(); - account.share(); + iotaccount::builder(authenticator, ctx).add_dynamic_field(dynamic_field_key, 6).build_shared(); scenario.next_tx(@0x0); { @@ -62,14 +59,13 @@ fun attempting_to_add_same_dynamic_field_twice() { let authenticator = create_authenticator_info_v1_for_testing(); let field_name = b"SomeData".to_ascii_string(); - let account = iotaccount::builder(authenticator, ctx) + iotaccount::builder(authenticator, ctx) .add_dynamic_field(field_name, 3) .add_dynamic_field( field_name, 3, ) - .finish(); - account.share(); + .build_shared(); test_scenario::end(scenario_val); } @@ -87,7 +83,7 @@ fun dynamic_fields_observe_the_value_not_just_the_type() { // are different. let field_name = b"SomeData".to_ascii_string(); let another_name = b"DifferentData".to_ascii_string(); - let account = iotaccount::builder(authenticator, ctx) + iotaccount::builder(authenticator, ctx) .add_dynamic_field( field_name, 3, @@ -96,8 +92,7 @@ fun dynamic_fields_observe_the_value_not_just_the_type() { another_name, 3, ) - .finish(); - account.share(); + .build_shared(); test_scenario::end(scenario_val); } diff --git a/examples/move/iotaccount/tests/test_utils.move b/examples/move/iotaccount/tests/test_utils.move index c6732c4fa91..d7dad56f3c8 100644 --- a/examples/move/iotaccount/tests/test_utils.move +++ b/examples/move/iotaccount/tests/test_utils.move @@ -5,21 +5,14 @@ module iotaccount::test_utils; use iota::account; -use iotaccount::iotaccount::{builder, share, IOTAccount}; +use iotaccount::iotaccount::{builder, IOTAccount}; public fun create_iotaccount_for_testing(scenario: &mut iota::test_scenario::Scenario): address { let ctx = iota::test_scenario::ctx(scenario); let authenticator = create_authenticator_info_v1_for_testing(); - let account = builder(authenticator, ctx) - .add_dynamic_field(b"SomeData".to_ascii_string(), 3u8) - .finish(); - let account_address = account.account_address(); - - share(account); - - account_address + builder(authenticator, ctx).add_dynamic_field(b"SomeData".to_ascii_string(), 3u8).build_shared() } public fun create_authenticator_info_v1_for_testing(): account::AuthenticatorInfoV1 { diff --git a/examples/move/time_locked/sources/account.move b/examples/move/time_locked/sources/account.move index d7fa08fc474..6d5a4788d27 100644 --- a/examples/move/time_locked/sources/account.move +++ b/examples/move/time_locked/sources/account.move @@ -45,15 +45,9 @@ public fun create( owner_public_key::attach(&mut id, public_key); unlock_time::attach(&mut id, unlock_time); - let mut account = TimeLocked { id }; + let account = TimeLocked { id }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); - - iota::transfer::share_object(account); + account::create_shared_account_v1(account, authenticator); } /// Authenticate access for the `Time locked account`. diff --git a/iota-execution/latest/iota-move-natives/src/lib.rs b/iota-execution/latest/iota-move-natives/src/lib.rs index 671e92fd65f..a49688bb3a7 100644 --- a/iota-execution/latest/iota-move-natives/src/lib.rs +++ b/iota-execution/latest/iota-move-natives/src/lib.rs @@ -777,6 +777,21 @@ pub fn all_natives(silent: bool, protocol_config: &ProtocolConfig) -> NativeFunc ("address", "from_bytes", make_native!(address::from_bytes)), ("address", "to_u256", make_native!(address::to_u256)), ("address", "from_u256", make_native!(address::from_u256)), + ( + "account", + "borrow_account_uid", + make_native!(object::borrow_uid), + ), + ( + "account", + "create_shared_account_v1_impl", + make_native!(transfer::share_object), + ), + ( + "account", + "create_immutable_account_v1_impl", + make_native!(transfer::freeze_object), + ), ("hash", "blake2b256", make_native!(hash::blake2b256)), ( "bls12381", From 13e48d68f875252e3b38e45dfda5f88996fcea9b Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 2 Dec 2025 13:52:02 +0200 Subject: [PATCH 02/21] fix: update framework snapshots --- ...000000000000000000000000000000000000000002 | Bin 79852 -> 79677 bytes crates/iota-framework-snapshot/manifest.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 b/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 index 6b9133ccf62b226eb809abcedace3ce09c845113..8ed1cac95affc1343010f217c8235670b6eb2d7a 100644 GIT binary patch delta 923 zcmaJ=J#Q015S^Lb+ugfeJHE5yIA7oZi4!G43YGaNK=g=)`eY|Tu@uLNu|sJgC_ti# z?iYZNXz36IQlLPgL876EXrKi_O~+z0PiDSZ z1ppSoky{WK`tms@!7F@(`YpYa=Api-4)uGA_M_N7jmSNV?h%AA2~{|Q4i^A5^EDbI zp@ED9K^lbQ6&R38L!h~$2#5yCB-oaQ_M9AeCE!T{u?FNwp5?S%F5xVLC0 zSXW}9GU?q^MWe>E<7M86$Q3}0jX4mfb9oT+aRR}NC?FKAwxNxzvH6lMxl+yuWt7oI zqeTn{Kp}UIApq%7gvtn1LlFJ-kQ1mGW2cNH=Cc5Y0f&JPjo}^l!0j7uU`VB7&kz$s z^tlj1WReF|h{bFD>{cz#9@lm=vv>t3v;CR!Al+M4%}%%5xtsiPX=81z)8Fo;{nmQ% z80z;n)7JLw4p$e~x*Lt&M%p-mO^>ivyWQ_Knp>P5iR`Ub|C38wm)bj9l~Ki=%|>@) z{RDOPUx~EEwCv;IRQ73cIg?8}*%z#4H-A;LH%njbjZW`+r@hnYwVK)LayqCWPs*I3 zQ$|nw9{~v9$`Rx-j`I{3oT!5p@z|VnL4mU>0120Y4r&(S#G<8(K*%Jaa{RUHtWYPS zzX8D`#zR-(oOBe?`8bd!aF%eO1Q0X<4{EV;BBDst11Bw6!D7lvl3vP1z!Vu6e*@3h z^$fm&s%r{-g&b}S`R5}$L<9X15$L$MB2sSrOj-u)6J50D@%JPyQ}HB#p!=w$J6zV zR+cO$my+z-nO>T%=I0xit=DR|)6H%cCoB2e#?eyH`crN!zdcdS>oeY=;pMc~ORvVo za-49Ncx$oVUhA|k{sqPDKilMIXDa!<_qF`%%)B7(uzPmH_cxQ3xOIg^x}E$+yp+G2 z{V;KE@h^X;(~K={b-Es%J(GW%oi2CNtiILhC96qirJkkrW#-O})53gye{K?!{KZ_{ zA4McFWyEe{YQ_+eH6r?X7a@g!0AAID5TjB^QRs^%SP=zN(pN*4&(Z-6CqQgBEJQ<= zZ}tcfGD#^5O}_XeNW|&zUJnjNzAr*N3>BZO2x&?ND(V*^3M9lp+l`_~)#a!fFJR`u z1%QFJW+GOa#P1hibml*5zr-&67L!#~D^LLh>ww#hNc++QPd0_m7VRmyBWxAP!nf~1 rq@+~l7wdY#;@#<{Bvn+%LBcPT?J41wfr$6aM-<+iUwA&hfMxpwIZT(* diff --git a/crates/iota-framework-snapshot/manifest.json b/crates/iota-framework-snapshot/manifest.json index 8908359efde..bf33ff1ed36 100644 --- a/crates/iota-framework-snapshot/manifest.json +++ b/crates/iota-framework-snapshot/manifest.json @@ -415,7 +415,7 @@ ] }, "16": { - "git_revision": "1a516653b610f38977cd4465d3392e69d7b92523", + "git_revision": "a47c5fb11b8addf6bf0064e26c3e9dd56cd9ffa0", "packages": [ { "name": "MoveStdlib", From 8471df223033a9ee34efefbf0eaad09a372ed126 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 2 Dec 2025 14:16:50 +0200 Subject: [PATCH 03/21] fix: update test snapshots --- ..._populated_genesis_snapshot_matches-2.snap | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index 0432ac0daf6..31c11d8bcbe 100644 --- a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -8,7 +8,7 @@ system_state_version: 1 iota_treasury_cap: inner: id: - id: "0x87c5ea4916fc3b461c09c7658e0c1bc26d0870ab3d94e3585beea7c25124e97a" + id: "0x78c953e9ba50858a73a5ccdb4c5ca6b06d1bb190f6d86585aa73ef3168c84bde" total_supply: value: "751500000000000000" validators: @@ -244,13 +244,13 @@ validators: next_epoch_primary_address: ~ extra_fields: id: - id: "0x948ecfff10a09397e826bc81f9ea7012b0cabec165c29b68c269c6c4582fdcd4" + id: "0x2152ad2957f72b96335efd49de4c7266ed6ef5e4163a020adeb0696831db2555" size: 0 voting_power: 10000 - operation_cap_id: "0x171ac0a062f7463e9f52122b6adc40dd4cf0ac0f97f5bf8acfc4dcb2aa94e53d" + operation_cap_id: "0x29baf5aaba6bc94a2b375ad05890dc0b2dce0fe4f6620f728f91e9d45edca3b3" gas_price: 1000 staking_pool: - id: "0x6e1fa56e748c508a5eba8e097d70f369b8f01fcf5507696ce1dc03048739bfa1" + id: "0x04517c81060f703a708ea01ff1b90f7b384291ab1f84f3b7f1aef951b5c5354a" activation_epoch: 0 deactivation_epoch: ~ iota_balance: 1500000000000000 @@ -258,14 +258,14 @@ validators: value: 0 pool_token_balance: 1500000000000000 exchange_rates: - id: "0x888114e0d92bbd1afe58010b4f69db71e9b3bcffcac599d6b00a9f489574817b" + id: "0x74f060aace7823cbae9a2614696d21e85ed5f85cfd63368be3e3ffd19ea028cf" size: 1 pending_stake: 0 pending_total_iota_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0x23a265df00831684eec17a1079b3a702a8ae6ce926b22bee3e08c3f27b0ef1bd" + id: "0xda67279834b329f1b5f61971f0173f6b417b6528ff5b55287c37ac325e388759" size: 0 commission_rate: 200 next_epoch_stake: 1500000000000000 @@ -273,27 +273,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0x269cb2c93c70d886f3b46a5d7ca00d99be9d876d5008370a1512ec777f5839a8" + id: "0xfa6000fa82d1dd26b656247de4f7b826209771a6cac17f71075390a92a37b74b" size: 0 pending_active_validators: contents: - id: "0x499ae2276ba137a096e04c8be9d782110fbb905a15352f769f7f69349e124a9a" + id: "0x3cfeb86bf86fd404c9429e6ea97616ce3760dfe052b89f85aaf67b8567aed2d9" size: 0 pending_removals: [] staking_pool_mappings: - id: "0x59f538e0c227ae703f862e2b81e901f39326f3987bb74ba55fae02f67223a2a7" + id: "0x99a3ff9742e0659dd41641f9ed583066d62041f9a9c961afaef67973a6c9b75c" size: 1 inactive_validators: - id: "0x0ef65b097fd491266ed3424d18b443f953b18f8879dea0dd738043f768cd22e0" + id: "0x2175f1ce2609edd51f99b1c0565dbb4e0c3c8bcf7fe323bcb84fe7e9ce104525" size: 0 validator_candidates: - id: "0xca36d5ab23d0485c71c35e8191a1c806c39996dc1608044a857298e07d728820" + id: "0xa623ab97869ded845381a6e2b46ce2fa538bd44629d4f0cbac680d1b3446d1b5" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0xc7b233c28a5ffc1e2bc9e77bd5e34021e7ebcc105681b16a3bdbb4cafd275551" + id: "0x35f04bbba1e56ba3f514409c054e7f7ebf8c39a9c3468bc2edd311c46614e8d2" size: 0 storage_fund: total_object_storage_rebates: @@ -310,7 +310,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0xc08d1f4d667924fbed5042fbaec90a2d0df5428cbb31a8bbc0756e3f2c0df603" + id: "0x82cb899d0f7f2a4c0ac388fece469b19f9376ebf3c36df25bd83f33cbc9d6a22" size: 0 iota_system_admin_cap: dummy_field: false @@ -327,5 +327,5 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0x4c58f26ad1b83a5fb2bb76e94d34f7a24e3f22bb24f4610a86b3a4a12834d59d" + id: "0x6c01b35600ed97df1531cbdc5e0d683354fc2c869a77b1d779c254d12cf2a1f6" size: 0 From 313be18b041b1a85021b1e68a41cd670686e08c6 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 2 Dec 2025 14:17:31 +0200 Subject: [PATCH 04/21] fix: abstract account e2e tests --- .../sources/abstract_account.move | 23 ++++++------------- .../sources/basic_keyed_aa.move | 5 ++-- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move index f966ce752b4..a12ee64b76b 100644 --- a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move +++ b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move @@ -25,6 +25,7 @@ const ETransactionSenderIsNotTheAccount: vector = b"Transaction must be sign /// add the desired authenticator info and dynamic fields. public struct AbstractAccountBuilder { account: AbstractAccount, + authenticator: AuthenticatorInfoV1, } /// This struct represents an abstract account. @@ -50,16 +51,10 @@ public fun builder( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): AbstractAccountBuilder { - let mut builder = AbstractAccountBuilder { + AbstractAccountBuilder { account: AbstractAccount { id: object::new(ctx) }, - }; - - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &builder.account, authenticator, - ); - account::attach_auth_info_v1(&mut builder.account.id, authenticator_compatibility_proof); - builder + } } /// Attach a `Value` as a dynamic field to the account being built. @@ -73,9 +68,9 @@ public fun add_dynamic_field( } /// Finish building the `AbstractAccount` and share the object. -public fun finish(self: AbstractAccountBuilder): AbstractAccount { - let AbstractAccountBuilder { account } = self; - account +public fun build_shared(self: AbstractAccountBuilder) { + let AbstractAccountBuilder { account, authenticator } = self; + account::create_shared_account_v1(account, authenticator); } /// Share AbstractAccount. @@ -157,11 +152,7 @@ public fun rotate_auth_info_v1( ): AuthenticatorInfoV1 { ensure_tx_sender_is_account(self, ctx); - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - self, - authenticator, - ); - account::rotate_auth_info_v1(&mut self.id, authenticator_compatibility_proof) + account::rotate_auth_info_v1(self, authenticator) } // === Public-View Functions === diff --git a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move index 0bf8297b4cc..a64fd0d2879 100644 --- a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move +++ b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move @@ -50,10 +50,9 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let account = abstract_account::builder(authenticator, ctx) + abstract_account::builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) - .finish(); - account.share(); + .build_shared(); } /// Rotates the account owner public key to a new one as well as the authenticator. From aef66047ec05cb29de4f3261632cf38bd051c3a4 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 2 Dec 2025 16:03:12 +0200 Subject: [PATCH 05/21] feat: implement protected account function verification --- .../crates/move-compiler/src/iota_mode/mod.rs | 21 ++++++++ .../move-compiler/src/iota_mode/typing.rs | 54 ++++++++++++++++++- .../move/crates/move-symbol-pool/src/lib.rs | 4 ++ .../programmable_transactions/execution.rs | 15 +++++- .../iota-verifier/src/private_generics.rs | 54 +++++++++++++++++++ 5 files changed, 146 insertions(+), 2 deletions(-) diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs index b1e1cd0da66..451df6de20a 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs @@ -73,6 +73,12 @@ pub const SHARE_FUNCTION_NAME: Symbol = symbol!("share_object"); pub const RECEIVE_FUNCTION_NAME: Symbol = symbol!("receive"); pub const RECEIVING_TYPE_NAME: Symbol = symbol!("Receiving"); +pub const ACCOUNT_MODULE_NAME: Symbol = symbol!("account"); +pub const CREATE_SHARED_ACCOUNT_V1_FUNCTION_NAME: Symbol = symbol!("create_shared_account_v1"); +pub const CREATE_IMMUTABLE_ACCOUNT_V1_FUNCTION_NAME: Symbol = + symbol!("create_immutable_account_v1"); +pub const ROTATE_AUTH_INFO_V1_FUNCTION_NAME: Symbol = symbol!("rotate_auth_info_v1"); + pub const PRIVATE_TRANSFER_FUNCTIONS: &[Symbol] = &[ TRANSFER_FUNCTION_NAME, FREEZE_FUNCTION_NAME, @@ -80,6 +86,12 @@ pub const PRIVATE_TRANSFER_FUNCTIONS: &[Symbol] = &[ RECEIVE_FUNCTION_NAME, ]; +pub const PRIVATE_ACCOUNT_FUNCTIONS: &[Symbol] = &[ + CREATE_SHARED_ACCOUNT_V1_FUNCTION_NAME, + CREATE_IMMUTABLE_ACCOUNT_V1_FUNCTION_NAME, + ROTATE_AUTH_INFO_V1_FUNCTION_NAME, +]; + //************************************************************************************************** // Diagnostics //************************************************************************************************** @@ -172,6 +184,15 @@ pub const PRIVATE_TRANSFER_CALL_DIAG: DiagnosticInfo = custom( 9, "invalid private transfer call", ); +pub const PRIVATE_ACCOUNT_CALL_DIAG: DiagnosticInfo = custom( + IOTA_DIAG_PREFIX, + Severity::NonblockingError, + // category + TYPING, + // code + 10, + "invalid private account call", +); // Bridge supported asset pub const BRIDGE_SUPPORTED_ASSET: &[&str] = &["btc", "eth", "usdc", "usdt"]; diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs b/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs index e01d2085a51..8279575aa9d 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/typing.rs @@ -979,6 +979,10 @@ fn exp(context: &mut Context, e: &T::Exp) { if is_transfer_module && PRIVATE_TRANSFER_FUNCTIONS.contains(&name.value()) { check_private_transfer(context, e.exp.loc, mcall) } + let is_account_module = module.value.is(&IOTA_ADDR_VALUE, ACCOUNT_MODULE_NAME); + if is_account_module && PRIVATE_ACCOUNT_FUNCTIONS.contains(&name.value()) { + check_private_account(context, e.exp.loc, mcall) + } } T::UnannotatedExp_::Pack(m, s, _, _) => { if !context.in_test @@ -1050,7 +1054,7 @@ fn check_private_transfer(context: &mut Context, loc: Loc, mcall: &ModuleCall) { let current_module = context.current_module(); if current_module .value - .is(&IOTA_ADDR_VALUE, TRANSFER_FUNCTION_NAME) + .is(&IOTA_ADDR_VALUE, TRANSFER_MODULE_NAME) { // inside the transfer module, so no private transfer rules return; @@ -1114,6 +1118,54 @@ fn check_private_transfer(context: &mut Context, loc: Loc, mcall: &ModuleCall) { } } +fn check_private_account(context: &mut Context, loc: Loc, mcall: &ModuleCall) { + let ModuleCall { + module, + name, + type_arguments, + .. + } = mcall; + let current_module = context.current_module(); + if current_module + .value + .is(&IOTA_ADDR_VALUE, ACCOUNT_MODULE_NAME) + { + // inside the account module, so no private account rules + return; + } + let Some(first_ty) = type_arguments.first() else { + // invalid arity + debug_assert!(false, "ICE arity should have been expanded for errors"); + return; + }; + let (in_current_module, first_ty_tn) = match first_ty.value.type_name() { + Some(sp!(_, TypeName_::Multiple(_))) | Some(sp!(_, TypeName_::Builtin(_))) | None => { + (false, None) + } + Some(sp!(_, TypeName_::ModuleType(m, n))) => (m == current_module, Some((m, n))), + }; + if !in_current_module { + let mut msg = format!( + "Invalid private account call. \ + The function '{}::{}' is restricted to being called in the object's module", + module, name, + ); + if let Some((first_ty_module, _)) = &first_ty_tn { + msg = format!("{}, '{}'", msg, first_ty_module); + }; + let ty_msg = format!( + "The type {} is not declared in the current module", + error_format(first_ty, &Subst::empty()), + ); + let diag = diag!( + PRIVATE_ACCOUNT_CALL_DIAG, + (loc, msg), + (first_ty.loc, ty_msg) + ); + context.add_diag(diag) + } +} + /// Checks the `authenticator` attribute for a valid version field. /// Only accepts #[authenticator], #[authenticator = ], or /// #[authenticator(version = )]. diff --git a/external-crates/move/crates/move-symbol-pool/src/lib.rs b/external-crates/move/crates/move-symbol-pool/src/lib.rs index 9624017bf3e..c966a87235d 100644 --- a/external-crates/move/crates/move-symbol-pool/src/lib.rs +++ b/external-crates/move/crates/move-symbol-pool/src/lib.rs @@ -96,6 +96,10 @@ static_symbols!( "migration", "beta", "development", + "account", + "create_shared_account_v1", + "create_immutable_account_v1", + "rotate_auth_info_v1", ); /// The global, unique cache of strings. diff --git a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs index b7258bdfe9d..5304a9d0584 100644 --- a/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs +++ b/iota-execution/latest/iota-adapter/src/programmable_transactions/execution.rs @@ -40,7 +40,10 @@ mod checked { }; use iota_verifier::{ INIT_FN_NAME, - private_generics::{EVENT_MODULE, PRIVATE_TRANSFER_FUNCTIONS, TRANSFER_MODULE}, + private_generics::{ + ACCOUNT_MODULE, EVENT_MODULE, PRIVATE_ACCOUNT_FUNCTIONS, PRIVATE_TRANSFER_FUNCTIONS, + TRANSFER_MODULE, + }, }; use move_binary_format::{ CompiledModule, @@ -1470,6 +1473,16 @@ mod checked { )); } + if module_ident == (&IOTA_FRAMEWORK_ADDRESS, ACCOUNT_MODULE) + && PRIVATE_ACCOUNT_FUNCTIONS.contains(&function) + { + let msg = format!("Cannot directly call iota::{ACCOUNT_MODULE}::{function}."); + return Err(ExecutionError::new_with_source( + ExecutionErrorKind::NonEntryFunctionInvoked, + msg, + )); + } + Ok(()) } diff --git a/iota-execution/latest/iota-verifier/src/private_generics.rs b/iota-execution/latest/iota-verifier/src/private_generics.rs index 3d7f3154ed7..690448c4cd7 100644 --- a/iota-execution/latest/iota-verifier/src/private_generics.rs +++ b/iota-execution/latest/iota-verifier/src/private_generics.rs @@ -16,6 +16,7 @@ use move_core_types::{account_address::AccountAddress, ident_str, identifier::Id use crate::{TEST_SCENARIO_MODULE_NAME, verification_failure}; pub const TRANSFER_MODULE: &IdentStr = ident_str!("transfer"); +pub const ACCOUNT_MODULE: &IdentStr = ident_str!("account"); pub const EVENT_MODULE: &IdentStr = ident_str!("event"); pub const EVENT_FUNCTION: &IdentStr = ident_str!("emit"); pub const GET_EVENTS_TEST_FUNCTION: &IdentStr = ident_str!("events_by_type"); @@ -39,6 +40,17 @@ pub const TRANSFER_IMPL_FUNCTIONS: &[&IdentStr] = &[ ident_str!("receive_impl"), ]; +pub const PUBLIC_ACCOUNT_FUNCTIONS: &[&IdentStr] = &[ + ident_str!("create_auth_info_v1"), + ident_str!("borrow_auth_info_v1"), + ident_str!("has_auth_info_v1"), +]; +pub const PRIVATE_ACCOUNT_FUNCTIONS: &[&IdentStr] = &[ + ident_str!("create_shared_account_v1"), + ident_str!("create_immutable_account_v1"), + ident_str!("rotate_auth_info_v1"), +]; + /// All transfer functions (the functions in `iota::transfer`) are "private" in /// that they are restricted to the module. /// For example, with `transfer::transfer(...)`, either: @@ -93,6 +105,8 @@ fn verify_function(view: &CompiledModule, fdef: &FunctionDefinition) -> Result<( verify_private_transfer(view, fhandle, type_arguments)? } else if ident == (IOTA_FRAMEWORK_ADDRESS, EVENT_MODULE) { verify_private_event_emit(view, fhandle, type_arguments)? + } else if ident == (IOTA_FRAMEWORK_ADDRESS, ACCOUNT_MODULE) { + verify_private_account(view, fhandle, type_arguments)? } } } @@ -140,6 +154,46 @@ fn verify_private_transfer( Ok(()) } +fn verify_private_account( + view: &CompiledModule, + fhandle: &FunctionHandle, + type_arguments: &[SignatureToken], +) -> Result<(), String> { + let self_handle = view.module_handle_at(view.self_handle_idx()); + if addr_module(view, self_handle) == (IOTA_FRAMEWORK_ADDRESS, ACCOUNT_MODULE) { + return Ok(()); + } + let fident = view.identifier_at(fhandle.name); + // public account functions have no additional rules + if PUBLIC_ACCOUNT_FUNCTIONS.contains(&fident) { + return Ok(()); + } + if !PRIVATE_ACCOUNT_FUNCTIONS.contains(&fident) { + // unknown function, so a bug in the implementation here + debug_assert!(false, "unknown account function {fident}"); + return Err(format!("Calling unknown account function, {fident}")); + }; + + if type_arguments.len() != 1 { + debug_assert!(false, "Expected 1 type argument for {fident}"); + return Err(format!("Expected 1 type argument for {fident}")); + } + + let type_arg = &type_arguments[0]; + if !is_defined_in_current_module(view, type_arg) { + return Err(format!( + "Invalid call to '{iota}::{account}::{f}' on an object of type '{t}'. \ + The account object's type must be defined in the current module.", + iota = IOTA_FRAMEWORK_ADDRESS, + account = ACCOUNT_MODULE, + f = fident, + t = format_signature_token(view, type_arg), + )); + } + + Ok(()) +} + fn verify_private_event_emit( view: &CompiledModule, fhandle: &FunctionHandle, From 812b058fb89cdab87dd79565ebccceda5a430533 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Wed, 3 Dec 2025 14:19:23 +0200 Subject: [PATCH 06/21] feat: add `iota_mode` tests to check account private functions restrictions --- .../tests/iota_mode/account/account.move | 53 ++++++++++++++++ .../tests/iota_mode/account/account.snap | 8 +++ .../iota_mode/account/account_generic.move | 52 ++++++++++++++++ .../iota_mode/account/account_generic.snap | 31 ++++++++++ .../iota_mode/account/account_store.move | 53 ++++++++++++++++ .../iota_mode/account/account_store.snap | 8 +++ .../account/account_store_generic.move | 53 ++++++++++++++++ .../account/account_store_generic.snap | 31 ++++++++++ .../iota_mode/account/external_account.move | 59 ++++++++++++++++++ .../iota_mode/account/external_account.snap | 31 ++++++++++ .../account/external_account_store.move | 60 +++++++++++++++++++ .../account/external_account_store.snap | 31 ++++++++++ 12 files changed, 470 insertions(+) create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account.snap create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.snap create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move create mode 100644 external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move new file mode 100644 index 00000000000..c6f9856b941 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move @@ -0,0 +1,53 @@ +// can use private account internal functions inside of the defining module + +module a::m { + use iota::account::{Self, AuthenticatorInfoV1}; + + struct A has key { + id: iota::object::UID, + } + + public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3(account: &mut A, authenticator: AuthenticatorInfoV1): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.snap new file mode 100644 index 00000000000..5b31e67da5c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.snap @@ -0,0 +1,8 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- + diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move new file mode 100644 index 00000000000..a635d92ef76 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move @@ -0,0 +1,52 @@ +// tests modules cannot use private account internal functions outside of the defining module + +module a::m { + use iota::account::{Self, AuthenticatorInfoV1}; + + public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3( + account: &mut A, + authenticator: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap new file mode 100644 index 00000000000..c8d1d0af81f --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap @@ -0,0 +1,31 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_generic.move:7:9 + │ +6 │ public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + │ - The type 'A' is not declared in the current module +7 │ account::create_shared_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_generic.move:11:9 + │ +10 │ public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + │ - The type 'A' is not declared in the current module +11 │ account::create_immutable_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_immutable_account_v1' is restricted to being called in the object's module + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_generic.move:18:9 + │ +15 │ account: &mut A, + │ - The type 'A' is not declared in the current module + · +18 │ account::rotate_auth_info_v1(account, authenticator) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::rotate_auth_info_v1' is restricted to being called in the object's module diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move new file mode 100644 index 00000000000..a51f92776a2 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move @@ -0,0 +1,53 @@ +// can use private account internal functions inside of the defining module if it has store + +module a::m { + use iota::account::{Self, AuthenticatorInfoV1}; + + struct A has key, store { + id: iota::object::UID, + } + + public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3(account: &mut A, authenticator: AuthenticatorInfoV1): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.snap new file mode 100644 index 00000000000..5b31e67da5c --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.snap @@ -0,0 +1,8 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- + diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move new file mode 100644 index 00000000000..9f7c056b075 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move @@ -0,0 +1,53 @@ +// tests modules cannot use private account internal functions outside of the defining module +// even if it has store + +module a::m { + use iota::account::{Self, AuthenticatorInfoV1}; + + public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3( + account: &mut A, + authenticator: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap new file mode 100644 index 00000000000..211f420f814 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap @@ -0,0 +1,31 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_store_generic.move:8:9 + │ +7 │ public fun t1(account: A, authenticator: AuthenticatorInfoV1) { + │ - The type 'A' is not declared in the current module +8 │ account::create_shared_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_store_generic.move:12:9 + │ +11 │ public fun t2(account: A, authenticator: AuthenticatorInfoV1) { + │ - The type 'A' is not declared in the current module +12 │ account::create_immutable_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_immutable_account_v1' is restricted to being called in the object's module + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/account_store_generic.move:19:9 + │ +16 │ account: &mut A, + │ - The type 'A' is not declared in the current module + · +19 │ account::rotate_auth_info_v1(account, authenticator) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::rotate_auth_info_v1' is restricted to being called in the object's module diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move new file mode 100644 index 00000000000..51d937a8f15 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move @@ -0,0 +1,59 @@ +// tests modules cannot use private account internal functions outside of the defining module + +module a::m { + use a::other; + use iota::account::{Self, AuthenticatorInfoV1}; + + public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3( + account: &mut other::A, + authenticator: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module a::other { + struct A has key { + id: iota::object::UID, + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap new file mode 100644 index 00000000000..db9b224d1a2 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap @@ -0,0 +1,31 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account.move:8:9 + │ +7 │ public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { + │ -------- The type 'a::other::A' is not declared in the current module +8 │ account::create_shared_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module, 'a::other' + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account.move:12:9 + │ +11 │ public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { + │ -------- The type 'a::other::A' is not declared in the current module +12 │ account::create_immutable_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_immutable_account_v1' is restricted to being called in the object's module, 'a::other' + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account.move:19:9 + │ +16 │ account: &mut other::A, + │ -------- The type 'a::other::A' is not declared in the current module + · +19 │ account::rotate_auth_info_v1(account, authenticator) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::rotate_auth_info_v1' is restricted to being called in the object's module, 'a::other' diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move new file mode 100644 index 00000000000..ab9cb7e7dbf --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move @@ -0,0 +1,60 @@ +// tests modules cannot use private account internal functions outside of the defining module +// even if it has store + +module a::m { + use a::other; + use iota::account::{Self, AuthenticatorInfoV1}; + + public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { + account::create_shared_account_v1(account, authenticator); + } + + public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { + account::create_immutable_account_v1(account, authenticator); + } + + public fun t3( + account: &mut other::A, + authenticator: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + account::rotate_auth_info_v1(account, authenticator) + } +} + +module a::other { + struct A has key, store { + id: iota::object::UID, + } +} + +module iota::object { + struct UID has store { + id: address, + } +} + +module iota::account { + use iota::object::UID; + + struct AuthenticatorInfoV1 { + id: UID, + } + + public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + abort 0 + } + + public fun create_immutable_account_v1( + _: Account, + _: AuthenticatorInfoV1, + ) { + abort 0 + } + + public fun rotate_auth_info_v1( + _: &mut Account, + _: AuthenticatorInfoV1, + ): AuthenticatorInfoV1 { + abort 0 + } +} diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap new file mode 100644 index 00000000000..9f03768ffe8 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap @@ -0,0 +1,31 @@ +--- +source: crates/move-compiler/tests/move_check_testsuite.rs +info: + flavor: iota + edition: legacy + lint: false +--- +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account_store.move:9:9 + │ +8 │ public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { + │ -------- The type 'a::other::A' is not declared in the current module +9 │ account::create_shared_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module, 'a::other' + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account_store.move:13:9 + │ +12 │ public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { + │ -------- The type 'a::other::A' is not declared in the current module +13 │ account::create_immutable_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_immutable_account_v1' is restricted to being called in the object's module, 'a::other' + +error[Iota E02010]: invalid private account call + ┌─ tests/iota_mode/account/external_account_store.move:20:9 + │ +17 │ account: &mut other::A, + │ -------- The type 'a::other::A' is not declared in the current module + · +20 │ account::rotate_auth_info_v1(account, authenticator) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::rotate_auth_info_v1' is restricted to being called in the object's module, 'a::other' From 067190c982d718c53006a3752c517f7a2b2c0890 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Thu, 4 Dec 2025 17:40:32 +0200 Subject: [PATCH 07/21] feat: add verifier transactional tests --- .../private_account_functions.move | 29 +++++ .../private_account_functions.snap | 37 ++++++ .../tests/account_functions/account.mvir | 62 ++++++++++ .../tests/account_functions/account.snap | 10 ++ .../account_functions/account_generic.mvir | 56 +++++++++ .../account_functions/account_generic.snap | 25 ++++ .../account_functions/account_store.mvir | 62 ++++++++++ .../account_functions/account_store.snap | 10 ++ .../account_store_generic.mvir | 56 +++++++++ .../account_store_generic.snap | 25 ++++ .../account_functions/external_account.mvir | 111 ++++++++++++++++++ .../account_functions/external_account.snap | 43 +++++++ .../external_account_store.mvir | 111 ++++++++++++++++++ .../external_account_store.snap | 43 +++++++ 14 files changed, 680 insertions(+) create mode 100644 crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move create mode 100644 crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir create mode 100644 crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move new file mode 100644 index 00000000000..5b771deefc7 --- /dev/null +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move @@ -0,0 +1,29 @@ +// Copyright (c) Mysten Labs, Inc. +// Modifications Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +// tests calling private account functions + +//# init --addresses test=0x0 --accounts A + +//# publish +module test::m1; + +public struct Account has key { id: UID } + +public fun account(ctx: &mut TxContext): Account { Account { id: object::new(ctx) } } + +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::create_shared_account_v1(Result(0), Result(1)); + +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::create_immutable_account_v1(Result(0)); + +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::rotate_auth_info_v1(Result(0)); diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap new file mode 100644 index 00000000000..37ddfc82c2b --- /dev/null +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap @@ -0,0 +1,37 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 5 tasks + +init: +A: object(0,0) + +task 1, lines 9-14: +//# publish +created: object(1,0) +mutated: object(0,1) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 4712000, storage_rebate: 0, non_refundable_storage_fee: 0 + +task 2, lines 16-19: +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::create_shared_account_v1(Result(0), Result(1)); +Error: Transaction Effects Status: Function Not Found. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } + +task 3, lines 21-24: +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::create_immutable_account_v1(Result(0)); +Error: Transaction Effects Status: Function Not Found. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } + +task 4, lines 26-29: +//# programmable --inputs @test "module" "function" +//> 0: test::m1::account(); +//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); +//> iota::account::rotate_auth_info_v1(Result(0)); +Error: Transaction Effects Status: Function Not Found. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir new file mode 100644 index 00000000000..414e5e2dead --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir @@ -0,0 +1,62 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.m { + import 0x2.account; + import 0x2.object; + import 0x2.package_metadata; + import 0x1.ascii; + + struct Account has key { + id: object.UID, + } + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } + + t2(account: &Self.Account): &account.AuthenticatorInfoV1 { + let a: &account.AuthenticatorInfoV1; + let id: &object.UID; + label l0: + id = &move(account).Account::id; + a = account.borrow_auth_info_v1(move(id)); + return move(a); + } + + t3(account: &Self.Account): bool { + let b: bool; + let id: &object.UID; + label l0: + id = &move(account).Account::id; + b = account.has_auth_info_v1(move(id)); + return move(b); + } + + t4(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } + + t5(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } + + t6(account: &mut Self.Account, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap new file mode 100644 index 00000000000..8bbd57514f0 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap @@ -0,0 +1,10 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 1 task + +task 0, lines 4-62: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8420800, storage_rebate: 0, non_refundable_storage_fee: 0 diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir new file mode 100644 index 00000000000..24a3f41c562 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir @@ -0,0 +1,56 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.m { + import 0x2.account; + import 0x2.package_metadata; + import 0x1.ascii; + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } +} + + +//# publish +module 0x0.m { + import 0x2.account; + + t2(account: T0, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } +} + + +//# publish +module 0x0.m { + import 0x2.account; + + t3(account: T0, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish +module 0x0.m { + import 0x2.account; + + t4(account: &mut T0, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap new file mode 100644 index 00000000000..8b74dc7ae11 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap @@ -0,0 +1,25 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 4 tasks + +task 0, lines 4-20: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5069200, storage_rebate: 0, non_refundable_storage_fee: 0 + +task 1, lines 23-32: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 2, lines 35-44: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t3. Invalid call to 'iota::account::create_immutable_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 3, lines 46-56: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::rotate_auth_info_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir new file mode 100644 index 00000000000..733ee299686 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir @@ -0,0 +1,62 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.m { + import 0x2.account; + import 0x2.object; + import 0x2.package_metadata; + import 0x1.ascii; + + struct Account has key, store { + id: object.UID, + } + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } + + t2(account: &Self.Account): &account.AuthenticatorInfoV1 { + let a: &account.AuthenticatorInfoV1; + let id: &object.UID; + label l0: + id = &move(account).Account::id; + a = account.borrow_auth_info_v1(move(id)); + return move(a); + } + + t3(account: &Self.Account): bool { + let b: bool; + let id: &object.UID; + label l0: + id = &move(account).Account::id; + b = account.has_auth_info_v1(move(id)); + return move(b); + } + + t4(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } + + t5(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } + + t6(account: &mut Self.Account, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap new file mode 100644 index 00000000000..8bbd57514f0 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap @@ -0,0 +1,10 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 1 task + +task 0, lines 4-62: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8420800, storage_rebate: 0, non_refundable_storage_fee: 0 diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir new file mode 100644 index 00000000000..95157189014 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir @@ -0,0 +1,56 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# publish +module 0x0.m { + import 0x2.account; + import 0x2.package_metadata; + import 0x1.ascii; + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } +} + + +//# publish +module 0x0.m { + import 0x2.account; + + t2(account: T0, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } +} + + +//# publish +module 0x0.m { + import 0x2.account; + + t3(account: T0, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish +module 0x0.m { + import 0x2.account; + + t4(account: &mut T0, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap new file mode 100644 index 00000000000..8b74dc7ae11 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap @@ -0,0 +1,25 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 4 tasks + +task 0, lines 4-20: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5069200, storage_rebate: 0, non_refundable_storage_fee: 0 + +task 1, lines 23-32: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 2, lines 35-44: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t3. Invalid call to 'iota::account::create_immutable_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 3, lines 46-56: +//# publish +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::rotate_auth_info_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir new file mode 100644 index 00000000000..75f66d89824 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir @@ -0,0 +1,111 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# init --addresses test=0x0 + +//# publish +module test.external { + import 0x2.object; + + struct Account has key { + id: object.UID, + } + + public uid(self: &Self.Account): &object.UID { + let id: &object.UID; + label l0: + id = &move(self).Account::id; + return move(id); + } + +} + +//# set-address test object(1,0) + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.package_metadata; + import 0x1.ascii; + import test.external; + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.object; + import test.external; + + t2(account: &external.Account): &account.AuthenticatorInfoV1 { + let a: &account.AuthenticatorInfoV1; + let id: &object.UID; + label l0: + id = external.uid(move(account)); + a = account.borrow_auth_info_v1(move(id)); + return move(a); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.object; + import test.external; + + t3(account: &external.Account): bool { + let b: bool; + let id: &object.UID; + label l0: + id = external.uid(move(account)); + b = account.has_auth_info_v1(move(id)); + return move(b); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t4(account: external.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t5(account: external.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t6(account: &mut external.Account, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap new file mode 100644 index 00000000000..4a11ab21d7f --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap @@ -0,0 +1,43 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 9 tasks + +task 1, lines 6-21: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 4575200, storage_rebate: 0, non_refundable_storage_fee: 0 + +task 3, lines 25-42: +//# publish --dependencies test +created: object(3,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6080000, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 4, lines 44-58: +//# publish --dependencies test +created: object(4,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5684800, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 5, lines 60-74: +//# publish --dependencies test +created: object(5,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5259200, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 6, lines 76-86: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 7, lines 88-98: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t5. Invalid call to 'iota::account::create_immutable_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 8, lines 100-111: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t6. Invalid call to 'iota::account::rotate_auth_info_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir new file mode 100644 index 00000000000..68b477eab14 --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir @@ -0,0 +1,111 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//# init --addresses test=0x0 + +//# publish +module test.external { + import 0x2.object; + + struct Account has key, store { + id: object.UID, + } + + public uid(self: &Self.Account): &object.UID { + let id: &object.UID; + label l0: + id = &move(self).Account::id; + return move(id); + } + +} + +//# set-address test object(1,0) + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.package_metadata; + import 0x1.ascii; + import test.external; + + t1( + package_metadata: &package_metadata.PackageMetadataV1, + module_name: ascii.String, + function_name: ascii.String, + ): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.create_auth_info_v1(move(package_metadata), move(module_name), move(function_name)); + return move(a); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.object; + import test.external; + + t2(account: &external.Account): &account.AuthenticatorInfoV1 { + let a: &account.AuthenticatorInfoV1; + let id: &object.UID; + label l0: + id = external.uid(move(account)); + a = account.borrow_auth_info_v1(move(id)); + return move(a); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import 0x2.object; + import test.external; + + t3(account: &external.Account): bool { + let b: bool; + let id: &object.UID; + label l0: + id = external.uid(move(account)); + b = account.has_auth_info_v1(move(id)); + return move(b); + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t4(account: external.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_shared_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t5(account: external.Account, authenticator: account.AuthenticatorInfoV1) { + label l0: + account.create_immutable_account_v1(move(account), move(authenticator)); + return; + } +} + +//# publish --dependencies test +module 0x0.m { + import 0x2.account; + import test.external; + + t6(account: &mut external.Account, authenticator: account.AuthenticatorInfoV1): account.AuthenticatorInfoV1 { + let a: account.AuthenticatorInfoV1; + label l0: + a = account.rotate_auth_info_v1(move(account), move(authenticator)); + return move(a); + } +} diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap new file mode 100644 index 00000000000..4a11ab21d7f --- /dev/null +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap @@ -0,0 +1,43 @@ +--- +source: external-crates/move/crates/move-transactional-test-runner/src/framework.rs +--- +processed 9 tasks + +task 1, lines 6-21: +//# publish +created: object(1,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 4575200, storage_rebate: 0, non_refundable_storage_fee: 0 + +task 3, lines 25-42: +//# publish --dependencies test +created: object(3,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6080000, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 4, lines 44-58: +//# publish --dependencies test +created: object(4,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5684800, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 5, lines 60-74: +//# publish --dependencies test +created: object(5,0) +mutated: object(0,0) +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5259200, storage_rebate: 980400, non_refundable_storage_fee: 0 + +task 6, lines 76-86: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 7, lines 88-98: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t5. Invalid call to 'iota::account::create_immutable_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } + +task 8, lines 100-111: +//# publish --dependencies test +Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t6. Invalid call to 'iota::account::rotate_auth_info_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } From 4ed8ba90e9edfed84072c785a80622c0fed709a8 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Thu, 4 Dec 2025 17:56:54 +0200 Subject: [PATCH 08/21] fix: adapter transactional account functions tests --- .../private_account_functions.move | 38 ++++++++------- .../private_account_functions.snap | 48 +++++++++---------- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move index 5b771deefc7..56c9480d517 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move @@ -1,5 +1,4 @@ -// Copyright (c) Mysten Labs, Inc. -// Modifications Copyright (c) 2025 IOTA Stiftung +// Copyright (c) 2025 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 // tests calling private account functions @@ -7,23 +6,30 @@ //# init --addresses test=0x0 --accounts A //# publish -module test::m1; +module test::account; + +use iota::auth_context::AuthContext; public struct Account has key { id: UID } -public fun account(ctx: &mut TxContext): Account { Account { id: object::new(ctx) } } +public fun create(ctx: &mut TxContext): Account { Account { id: object::new(ctx) } } + +#[authenticator] +public fun authenticate(_: &Account, _auth_ctx: &AuthContext, _ctx: &TxContext) { + abort 0 +} -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::create_shared_account_v1(Result(0), Result(1)); +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::create_shared_account_v1(Result(0), Result(1)); -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::create_immutable_account_v1(Result(0)); +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::create_immutable_account_v1(Result(0), Result(1)); -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::rotate_auth_info_v1(Result(0)); +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::rotate_auth_info_v1(Result(0), Result(1)); diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap index 37ddfc82c2b..0cb1760a7cc 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap @@ -6,32 +6,32 @@ processed 5 tasks init: A: object(0,0) -task 1, lines 9-14: +task 1, lines 8-20: //# publish -created: object(1,0) +created: object(1,0), object(1,1) mutated: object(0,1) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 4712000, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8534800, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 16-19: -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::create_shared_account_v1(Result(0), Result(1)); -Error: Transaction Effects Status: Function Not Found. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } +task 2, lines 22-25: +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::create_shared_account_v1(Result(0), Result(1)); +Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_shared_account_v1."), command: Some(2) } } -task 3, lines 21-24: -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::create_immutable_account_v1(Result(0)); -Error: Transaction Effects Status: Function Not Found. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } +task 3, lines 27-30: +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::create_immutable_account_v1(Result(0), Result(1)); +Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_immutable_account_v1."), command: Some(2) } } -task 4, lines 26-29: -//# programmable --inputs @test "module" "function" -//> 0: test::m1::account(); -//> 1: iota::account::create_auth_info_v1_for_testing(Input(0), Input(1), Input(2)); -//> iota::account::rotate_auth_info_v1(Result(0)); -Error: Transaction Effects Status: Function Not Found. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: FunctionNotFound, source: Some("Could not resolve function 'create_auth_info_v1_for_testing' in module iota::account"), command: Some(1) } } +task 4, lines 32-35: +//# programmable --inputs object(1,1) "account" "authenticate" +//> 0: test::account::create(); +//> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); +//> 2: iota::account::rotate_auth_info_v1(Result(0), Result(1)); +Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::rotate_auth_info_v1."), command: Some(2) } } From e3efb075a9a888af74b02736b36225abeb137955 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 5 Dec 2025 09:37:29 +0200 Subject: [PATCH 09/21] fix: abstract account transactional tests --- .../abstract_account/account/gasless.move | 12 ++++----- .../abstract_account/account/gasless.snap | 10 +++---- .../abstract_account/account/mutable.move | 12 ++++----- .../abstract_account/account/mutable.snap | 12 ++++----- .../account/receive_object.move | 12 ++++----- .../account/receive_object.snap | 14 +++++----- .../abstract_account/account/sponsor.move | 10 +++---- .../abstract_account/account/sponsor.snap | 12 ++++----- .../authenticator/ed25519.move | 11 ++++---- .../authenticator/ed25519.snap | 14 +++++----- .../authenticator/ed25519_wrong_digest.move | 13 +++++----- .../authenticator/ed25519_wrong_digest.snap | 12 ++++----- .../ed25519_wrong_signature.move | 11 ++++---- .../ed25519_wrong_signature.snap | 12 ++++----- .../authenticator/several_authenticators.move | 12 ++++----- .../authenticator/several_authenticators.snap | 14 +++++----- .../authenticator/simple.move | 12 ++++----- .../authenticator/simple.snap | 14 +++++----- .../authenticator/simple_fail.move | 12 ++++----- .../authenticator/simple_fail.snap | 12 ++++----- .../authenticator/without_attribute.move | 14 +++++----- .../authenticator/without_attribute.snap | 6 ++--- .../authenticator/wrong_type.move | 11 +++----- .../authenticator/wrong_type.snap | 10 +++---- .../iota-transactional-test-runner/syntax.md | 26 +++++++++---------- 25 files changed, 141 insertions(+), 169 deletions(-) diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move index 931930df6a0..e9603680909 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move @@ -20,14 +20,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap index 5a77d296a1b..f79cc9fb255 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap @@ -6,13 +6,13 @@ processed 5 tasks init: A: object(0,0) -task 1, lines 8-35: +task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11225200, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10032000, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 37-39: +task 2, lines 35-37: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -20,7 +20,7 @@ created: object(2,0), object(2,1) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5677200, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 41: +task 3, line 39: //# view-object 2,1 Owner: Shared( 3 ) Version: 3 @@ -32,6 +32,6 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 4, lines 43-45: +task 4, lines 41-43: //# abstract --account immshared(2,1) --ptb-inputs 100 @A Error: Error checking transaction input objects: GasObjectNotOwnedObject { owner: Shared { initial_shared_version: SequenceNumber(3) } } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move index 33908bbecbd..928e550d27b 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move @@ -20,14 +20,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap index 9e3b3bd7a3b..192ca3f4df9 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap @@ -6,13 +6,13 @@ processed 6 tasks init: A: object(0,0) -task 1, lines 8-35: +task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11225200, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10032000, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 37-41: +task 2, lines 35-39: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6657600, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 43: +task 3, line 41: //# view-object 2,0 Owner: Account Address ( fake(2,2) ) Version: 3 @@ -37,7 +37,7 @@ Contents: iota::coin::Coin { }, } -task 4, line 45: +task 4, line 43: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -49,6 +49,6 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 47-48: +task 5, lines 45-46: //# abstract --account object(2,2) --gas-payment 2,0 --ptb-inputs 100 @A Error: Error checking transaction input objects: Unsupported("MoveAuthenticator cannot authenticate mutable shared objects") diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move index 20cd1912e81..57ddb109afb 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move @@ -22,14 +22,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap index 31beeaa81bc..40c7247fae8 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap @@ -6,13 +6,13 @@ processed 8 tasks init: A: object(0,0) -task 1, lines 8-46: +task 1, lines 8-44: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12737600, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11696400, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 48-52: +task 2, lines 46-50: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6657600, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 54: +task 3, line 52: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -34,7 +34,7 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 58-60: +task 5, lines 56-58: //# programmable --sender A --inputs 2000000000 @a_account //> 0: SplitCoins(Gas, [Input(0)]); //> 1: TransferObjects([Result(0)], Input(1)); @@ -42,12 +42,12 @@ created: object(5,0) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 6, lines 62-63: +task 6, lines 60-61: //# abstract --account immshared(2,2) --gas-payment 2,0 --ptb-inputs object(2,2) receiving(5,0) mutated: object(2,0), object(2,2), object(5,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 3382000, storage_rebate: 3382000, non_refundable_storage_fee: 0 -task 7, line 65: +task 7, line 63: //# view-object 5,0 Owner: Account Address ( a_account ) Version: 5 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move index 0ac62ab791d..e26c80e4a66 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move @@ -20,13 +20,9 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); - iota::transfer::share_object(account); + let account = AbstractAccount { id: object::new(ctx) }; + + account::create_shared_account_v1(account, authenticator); } #[authenticator] diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap index 8fedd634d6a..2a812ffdb84 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap @@ -6,13 +6,13 @@ processed 6 tasks init: A: object(0,0) -task 1, lines 8-33: +task 1, lines 8-29: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10966800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 9720400, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 35-37: +task 2, lines 31-33: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -20,7 +20,7 @@ created: object(2,0), object(2,1) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 5677200, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 39: +task 3, line 35: //# view-object 2,1 Owner: Shared( 3 ) Version: 3 @@ -32,14 +32,14 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 4, lines 41-43: +task 4, lines 37-39: //# abstract --account immshared(2,1) --sponsor A --ptb-inputs 100 @A created: object(4,0) mutated: object(0,0) unchanged_shared: object(2,1) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 5, line 45: +task 5, line 41: //# view-object 4,0 Owner: Account Address ( A ) Version: 4 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move index 70a0274690e..b90d17a641a 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move @@ -25,14 +25,13 @@ public fun create( ctx: &mut TxContext, ): address { let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + dynamic_field::add(&mut account.id, OwnerPublicKey {}, public_key); + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap index 4f926d30147..bcdd9897526 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap @@ -6,13 +6,13 @@ processed 7 tasks init: A: object(0,0) -task 1, lines 8-57: +task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 13322800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 59-63: +task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2), object(2,3) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8816000, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 65: +task 3, line 64: //# view-object 2,3 Owner: Shared( 3 ) Version: 3 @@ -34,7 +34,7 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 4, line 67: +task 4, line 66: //# view-object 2,0 Owner: Account Address ( fake(2,3) ) Version: 3 @@ -49,14 +49,14 @@ Contents: iota::coin::Coin { }, } -task 5, lines 69-71: +task 5, lines 68-70: //# abstract --account immshared(2,3) --gas-payment 2,0 --auth-inputs x"cce72947906dbae4c166fc01fd096432784032be43db540909bc901dbc057992b4d655ca4f4355cf0868e1266baacf6919902969f063e74162f8f04bc4056105" x"315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3" --ptb-inputs 100 @A created: object(5,0) mutated: object(2,0) unchanged_shared: object(2,3) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 6, line 73: +task 6, line 72: //# view-object 5,0 Owner: Account Address ( A ) Version: 4 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move index d1ab56773ef..23087b69fd4 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move @@ -25,14 +25,13 @@ public fun create( ctx: &mut TxContext, ): address { let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + dynamic_field::add(&mut account.id, OwnerPublicKey {}, public_key); + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } @@ -68,4 +67,4 @@ public fun authenticate_ed25519( //# abstract --account immshared(2,3) --gas-payment 2,0 --auth-inputs x"cce72947906dbae4c166fc01fd096432784032be43db540909bc901dbc057992b4d655ca4f4355cf0868e1266baacf6919902969f063e74162f8f04bc4056105" x"315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c10000edd3" --ptb-inputs 100 @A //> 0: SplitCoins(Gas, [Input(0)]); -//> 1: TransferObjects([Result(0)], Input(1)); \ No newline at end of file +//> 1: TransferObjects([Result(0)], Input(1)); diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap index 2423f429710..dc67d328f06 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap @@ -6,13 +6,13 @@ processed 6 tasks init: A: object(0,0) -task 1, lines 8-57: +task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 13322800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 59-63: +task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2), object(2,3) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8816000, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 65: +task 3, line 64: //# view-object 2,3 Owner: Shared( 3 ) Version: 3 @@ -34,7 +34,7 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 4, line 67: +task 4, line 66: //# view-object 2,0 Owner: Account Address ( fake(2,3) ) Version: 3 @@ -49,6 +49,6 @@ Contents: iota::coin::Coin { }, } -task 5, lines 69-71: +task 5, lines 68-70: //# abstract --account immshared(2,3) --gas-payment 2,0 --auth-inputs x"cce72947906dbae4c166fc01fd096432784032be43db540909bc901dbc057992b4d655ca4f4355cf0868e1266baacf6919902969f063e74162f8f04bc4056105" x"315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c10000edd3" --ptb-inputs 100 @A Error: Failed to execute the Move authenticator, reason: "ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MoveAbort(MoveLocation { module: ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }, function: 1, instruction: 11, function_name: Some(\"authenticate_ed25519\") }, 0), source: Some(VMError { major_status: ABORTED, sub_status: Some(0), message: Some(\"object(1,0)::abstract_account::authenticate_ed25519 at offset 11\"), exec_state: None, location: Module(ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }), indices: [], offsets: [(FunctionDefinitionIndex(1), 11)] }), command: Some(0) } }". diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move index 30ce06ee588..148feac9c34 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move @@ -25,14 +25,13 @@ public fun create( ctx: &mut TxContext, ): address { let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + dynamic_field::add(&mut account.id, OwnerPublicKey {}, public_key); + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap index 4cdca8c6beb..84eb8c1420a 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap @@ -6,13 +6,13 @@ processed 6 tasks init: A: object(0,0) -task 1, lines 8-57: +task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 13322800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 59-63: +task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2), object(2,3) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8816000, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 65: +task 3, line 64: //# view-object 2,3 Owner: Shared( 3 ) Version: 3 @@ -34,7 +34,7 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 4, line 67: +task 4, line 66: //# view-object 2,0 Owner: Account Address ( fake(2,3) ) Version: 3 @@ -49,6 +49,6 @@ Contents: iota::coin::Coin { }, } -task 5, lines 69-71: +task 5, lines 68-70: //# abstract --account immshared(2,3) --gas-payment 2,0 --auth-inputs x"cce72947906dbae4c166fc01fd096432784032be43db540909bc901dbc057992b4d655ca4f4355cf0868e1266baacf6919902969f063e74162f8f04bc4052345" x"315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3" --ptb-inputs 100 @A Error: Failed to execute the Move authenticator, reason: "ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MoveAbort(MoveLocation { module: ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }, function: 1, instruction: 11, function_name: Some(\"authenticate_ed25519\") }, 0), source: Some(VMError { major_status: ABORTED, sub_status: Some(0), message: Some(\"object(1,0)::abstract_account::authenticate_ed25519 at offset 11\"), exec_state: None, location: Module(ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }), indices: [], offsets: [(FunctionDefinitionIndex(1), 11)] }), command: Some(0) } }". diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move index f53c37b760a..2f19026658f 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move @@ -21,14 +21,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap index c21e49c756d..2ab2ffd83f5 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap @@ -6,13 +6,13 @@ processed 7 tasks init: A: object(0,0) -task 1, lines 8-53: +task 1, lines 8-51: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 13961200, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12775600, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 55-59: +task 2, lines 53-57: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6748800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 61: +task 3, line 59: //# view-object 2,0 Owner: Account Address ( fake(2,2) ) Version: 3 @@ -37,7 +37,7 @@ Contents: iota::coin::Coin { }, } -task 4, line 63: +task 4, line 61: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -49,14 +49,14 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 65-67: +task 5, lines 63-65: //# abstract --account immshared(2,2) --gas-payment 2,0 --auth-inputs "HelloWorld" --ptb-inputs 100 @A created: object(5,0) mutated: object(2,0) unchanged_shared: object(2,2) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 6, line 69: +task 6, line 67: //# view-object 5,0 Owner: Account Address ( A ) Version: 4 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move index 01128d90c9f..0bb4b39276a 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move @@ -21,14 +21,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap index aa49540c62d..d519188c723 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap @@ -6,13 +6,13 @@ processed 7 tasks init: A: object(0,0) -task 1, lines 8-43: +task 1, lines 8-41: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12334800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11149200, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 45-49: +task 2, lines 43-47: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6748800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 51: +task 3, line 49: //# view-object 2,0 Owner: Account Address ( fake(2,2) ) Version: 3 @@ -37,7 +37,7 @@ Contents: iota::coin::Coin { }, } -task 4, line 53: +task 4, line 51: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -49,14 +49,14 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 55-57: +task 5, lines 53-55: //# abstract --account immshared(2,2) --gas-payment 2,0 --auth-inputs "HelloWorld" --ptb-inputs 100 @A created: object(5,0) mutated: object(2,0) unchanged_shared: object(2,2) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 6, line 59: +task 6, line 57: //# view-object 5,0 Owner: Account Address ( A ) Version: 4 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move index 6cd4877cb1e..22484bb9820 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move @@ -21,14 +21,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap index e74542cde5a..7ea124530a4 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap @@ -6,13 +6,13 @@ processed 6 tasks init: A: object(0,0) -task 1, lines 8-43: +task 1, lines 8-41: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12334800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11149200, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 45-49: +task 2, lines 43-47: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -22,7 +22,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6748800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 51: +task 3, line 49: //# view-object 2,0 Owner: Account Address ( fake(2,2) ) Version: 3 @@ -37,7 +37,7 @@ Contents: iota::coin::Coin { }, } -task 4, line 53: +task 4, line 51: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -49,6 +49,6 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 55-56: +task 5, lines 53-54: //# abstract --account immshared(2,2) --gas-payment 2,0 --auth-inputs "test" --ptb-inputs 100 @A Error: Failed to execute the Move authenticator, reason: "ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MoveAbort(MoveLocation { module: ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }, function: 1, instruction: 7, function_name: Some(\"authenticate_hello_world\") }, 0), source: Some(VMError { major_status: ABORTED, sub_status: Some(0), message: Some(\"object(1,0)::abstract_account::authenticate_hello_world at offset 7\"), exec_state: None, location: Module(ModuleId { address: object(1,0), name: Identifier(\"abstract_account\") }), indices: [], offsets: [(FunctionDefinitionIndex(1), 7)] }), command: Some(0) } }". diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move index a68d184db9a..896230d818e 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move @@ -21,14 +21,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } @@ -45,4 +43,4 @@ public fun authenticate_hello_world( //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); //> 2: SplitCoins(Gas, [Input(4)]); -//> 3: TransferObjects([Result(2)], Result(1)); \ No newline at end of file +//> 3: TransferObjects([Result(2)], Result(1)); diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap index 8e99fc9861a..ded6841963d 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap @@ -6,13 +6,13 @@ processed 3 tasks init: A: object(0,0) -task 1, lines 8-42: +task 1, lines 8-40: //# publish --sender A created: object(1,0) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8816000, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 7630400, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 44-48: +task 2, lines 42-46: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move index 3ef695903be..c6742908006 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move @@ -24,14 +24,9 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); - iota::transfer::share_object(account); + let account = AbstractAccount { id: object::new(ctx) }; + + account::create_shared_account_v1(account, authenticator); } #[authenticator] diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap index acd07e3c3bc..7377dd40357 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap @@ -6,15 +6,15 @@ processed 3 tasks init: A: object(0,0) -task 1, lines 8-38: +task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11666000, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10419600, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 40-42: +task 2, lines 35-37: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); -Error: Transaction Effects Status: Move Runtime Abort. Location: iota::account::create_auth_info_v1 (function index 0) at offset 15, Abort Code: 13835902772270465031 -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MoveAbort(MoveLocation { module: ModuleId { address: iota, name: Identifier("account") }, function: 0, instruction: 15, function_name: Some("create_auth_info_v1") }, 13835902772270465031), source: Some(VMError { major_status: ABORTED, sub_status: Some(13835902772270465031), message: Some("iota::account::create_auth_info_v1 at offset 15"), exec_state: None, location: Module(ModuleId { address: iota, name: Identifier("account") }), indices: [], offsets: [(FunctionDefinitionIndex(0), 15)] }), command: Some(0) } } +Error: Transaction Effects Status: Move Runtime Abort. Location: iota::account::create_auth_info_v1 (function index 0) at offset 15, Abort Code: 13835621258638917637 +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: MoveAbort(MoveLocation { module: ModuleId { address: iota, name: Identifier("account") }, function: 0, instruction: 15, function_name: Some("create_auth_info_v1") }, 13835621258638917637), source: Some(VMError { major_status: ABORTED, sub_status: Some(13835621258638917637), message: Some("iota::account::create_auth_info_v1 at offset 15"), exec_state: None, location: Module(ModuleId { address: iota, name: Identifier("account") }), indices: [], offsets: [(FunctionDefinitionIndex(0), 15)] }), command: Some(0) } } diff --git a/crates/iota-transactional-test-runner/syntax.md b/crates/iota-transactional-test-runner/syntax.md index 0e810c0c956..cea3b8f8c1b 100644 --- a/crates/iota-transactional-test-runner/syntax.md +++ b/crates/iota-transactional-test-runner/syntax.md @@ -1467,14 +1467,12 @@ public fun create( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ): address { - let mut account = AbstractAccount { id: object::new(ctx) }; - let authenticator_compatibility_proof = account::check_auth_info_v1_compatibility( - &account, - authenticator, - ); - account::attach_auth_info_v1(&mut account.id, authenticator_compatibility_proof); + let account = AbstractAccount { id: object::new(ctx) }; + let account_address = object::id_address(&account); - iota::transfer::share_object(account); + + account::create_shared_account_v1(account, authenticator); + account_address } @@ -1527,13 +1525,13 @@ processed 7 tasks init: A: object(0,0) -task 1, lines 8-43: +task 1, lines 8-41: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12334800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11149200, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 45-49: +task 2, lines 43-47: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 //> 0: iota::account::create_auth_info_v1(Input(1), Input(2), Input(3)); //> 1: test::abstract_account::create(Input(0), Result(0)); @@ -1543,7 +1541,7 @@ created: object(2,0), object(2,1), object(2,2) mutated: object(0,0) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 6748800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 3, line 51: +task 3, line 49: //# view-object 2,0 Owner: Account Address ( fake(2,2) ) Version: 3 @@ -1558,7 +1556,7 @@ Contents: iota::coin::Coin { }, } -task 4, line 53: +task 4, line 51: //# view-object 2,2 Owner: Shared( 3 ) Version: 3 @@ -1570,14 +1568,14 @@ Contents: test::abstract_account::AbstractAccount { }, } -task 5, lines 55-57: +task 5, lines 53-55: //# abstract --account immshared(2,2) --gas-payment 2,0 --auth-inputs "HelloWorld" --ptb-inputs 100 @A created: object(5,0) mutated: object(2,0) unchanged_shared: object(2,2) gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 1960800, storage_rebate: 980400, non_refundable_storage_fee: 0 -task 6, line 59: +task 6, line 57: //# view-object 5,0 Owner: Account Address ( A ) Version: 4 From 59eb660ce613d0d43f01bf2e9b6935cd14cb5c07 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 5 Dec 2025 10:14:53 +0200 Subject: [PATCH 10/21] fix: self review --- .../private_account_functions.move | 4 +-- .../private_account_functions.snap | 10 +++--- .../iota-framework/sources/account.move | 31 ++++++++++++++---- .../packages_compiled/iota-framework | Bin 79612 -> 79616 bytes crates/iota-framework/published_api.txt | 2 +- .../latest/iota-move-natives/src/lib.rs | 2 +- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move index 56c9480d517..a0be2fdf69f 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move @@ -15,9 +15,7 @@ public struct Account has key { id: UID } public fun create(ctx: &mut TxContext): Account { Account { id: object::new(ctx) } } #[authenticator] -public fun authenticate(_: &Account, _auth_ctx: &AuthContext, _ctx: &TxContext) { - abort 0 -} +public fun authenticate(_: &Account, _auth_ctx: &AuthContext, _ctx: &TxContext) {} //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap index 0cb1760a7cc..90c5c81ae38 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap @@ -6,13 +6,13 @@ processed 5 tasks init: A: object(0,0) -task 1, lines 8-20: +task 1, lines 8-18: //# publish created: object(1,0), object(1,1) mutated: object(0,1) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8534800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8466400, storage_rebate: 0, non_refundable_storage_fee: 0 -task 2, lines 22-25: +task 2, lines 20-23: //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); //> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); @@ -20,7 +20,7 @@ task 2, lines 22-25: Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_shared_account_v1."), command: Some(2) } } -task 3, lines 27-30: +task 3, lines 25-28: //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); //> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); @@ -28,7 +28,7 @@ task 3, lines 27-30: Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_immutable_account_v1."), command: Some(2) } } -task 4, lines 32-35: +task 4, lines 30-33: //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); //> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); diff --git a/crates/iota-framework/packages/iota-framework/sources/account.move b/crates/iota-framework/packages/iota-framework/sources/account.move index 4f9fe1a74c0..51153eed526 100644 --- a/crates/iota-framework/packages/iota-framework/sources/account.move +++ b/crates/iota-framework/packages/iota-framework/sources/account.move @@ -65,8 +65,10 @@ public fun create_auth_info_v1( } } -/// Create a mutable shared account with the the provided `authenticator`. +/// Create a mutable shared account with the provided `authenticator`. /// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. +/// This function has custom rules performed by the IOTA Move bytecode verifier that ensures +/// that `Account` is an object defined in the module where `create_shared_account_v1` is invoked. public fun create_shared_account_v1( mut account: Account, authenticator: AuthenticatorInfoV1, @@ -76,8 +78,10 @@ public fun create_shared_account_v1( create_shared_account_v1_impl(account); } -/// Create an immutable account with the the provided `authenticator`. +/// Create an immutable account with the provided `authenticator`. /// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. +/// This function has custom rules performed by the IOTA Move bytecode verifier that ensures +/// that `Account` is an object defined in the module where `create_immutable_account_v1` is invoked. public fun create_immutable_account_v1( mut account: Account, authenticator: AuthenticatorInfoV1, @@ -89,11 +93,13 @@ public fun create_immutable_account_v1( /// Rotate the account-related authenticator. /// The `authenticator` instance will replace the account dynamic field specified by the `AuthenticatorInfoV1Key` name. +/// This function has custom rules performed by the IOTA Move bytecode verifier that ensures +/// that `Account` is an object defined in the module where `rotate_auth_info_v1` is invoked. public fun rotate_auth_info_v1( account: &mut Account, authenticator: AuthenticatorInfoV1, ): AuthenticatorInfoV1 { - let account_id = borrow_account_uid(account); + let account_id = borrow_account_uid_mut(account); assert!(has_auth_info_v1(account_id), EAuthenticatorInfoV1NotAttached); @@ -123,23 +129,36 @@ fun auth_info_v1_key(): AuthenticatorInfoV1Key { AuthenticatorInfoV1Key {} } +/// Add `authenticator` as a dynamic field to `account`. +/// This function must be called only from the account functions protected by the compiler +/// from being called outside the `Account` module. fun attach_auth_info_v1( account: &mut Account, authenticator: AuthenticatorInfoV1, ) { - let account_id = borrow_account_uid(account); + let account_id = borrow_account_uid_mut(account); assert!(!has_auth_info_v1(account_id), EAuthenticatorInfoV1AlreadyAttached); dynamic_field::add(account_id, auth_info_v1_key(), authenticator); } -native fun borrow_account_uid(account: &mut Account): &mut UID; +/// Borrow the account `UID` mutably. +/// This function must be called only from the functions protected by the IOTA Move bytecode verifier +/// from being called outside the `Account` module. +native fun borrow_account_uid_mut(account: &mut Account): &mut UID; +/// Turn `account` into a mutable shared object. +/// This function must be called only from the functions protected by the IOTA Move bytecode verifier +/// from being called outside the `Account` module. native fun create_shared_account_v1_impl(account: Account); + +/// Turn `account` into an immutable object. +/// This function must be called only from the functions protected by the IOTA Move bytecode verifier +/// from being called outside the `Account` module. native fun create_immutable_account_v1_impl(account: Account); -/// Creates an `AuthenticatorInfoV1` instance for testing, skipping validation. +/// Create an `AuthenticatorInfoV1` instance for testing, skipping validation. #[test_only] public fun create_auth_info_v1_for_testing( package: address, diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index ea85f03a03e11892af2e15cff02a9c1e75683a0e..787fd8edc67c5eb6cbbb32a948644e42dec71819 100644 GIT binary patch delta 94 zcmV-k0HOca1PF`=KnBbQ$pQ+M3K0vY3IYtMv*RTv0v8ry zZ*p>PcVA&+V{dhCbYFF8WM6G{bh8~OVFLkZlYc8Q0e6$JD?kB_gYql4@+$!f3uYxD AmjD0& delta 90 zcmV-g0Hyzc?gaep1hB3p0o;?XB_9>W1PF)+KnBPM$pQ+I3K0vU3IYtIv*RTv0uvHq wZ*p>PcVA&+V{dhCbYFF8WV0bCVFLkTlY=WU0dbSHD?kB+gZ3-8_A3Dj3(g)Ny#N3J diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index e91147961a0..cbef72f04bb 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -1450,7 +1450,7 @@ auth_info_v1_key attach_auth_info_v1 fun 0x2::account -borrow_account_uid +borrow_account_uid_mut fun 0x2::account create_shared_account_v1_impl diff --git a/iota-execution/latest/iota-move-natives/src/lib.rs b/iota-execution/latest/iota-move-natives/src/lib.rs index a49688bb3a7..47d6f6f72fa 100644 --- a/iota-execution/latest/iota-move-natives/src/lib.rs +++ b/iota-execution/latest/iota-move-natives/src/lib.rs @@ -779,7 +779,7 @@ pub fn all_natives(silent: bool, protocol_config: &ProtocolConfig) -> NativeFunc ("address", "from_u256", make_native!(address::from_u256)), ( "account", - "borrow_account_uid", + "borrow_account_uid_mut", make_native!(object::borrow_uid), ), ( From 53ca16d2640062ba00167e2316e23714f71692c3 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 5 Dec 2025 10:15:36 +0200 Subject: [PATCH 11/21] fix: update framework snapshots --- ...000000000000000000000000000000000000000002 | Bin 79677 -> 79681 bytes crates/iota-framework-snapshot/manifest.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 b/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 index 8ed1cac95affc1343010f217c8235670b6eb2d7a..80b2a3e40a63dd4e7e79d90ed0574df80282063d 100644 GIT binary patch delta 94 zcmV-k0HOcA?gYW^1hCE}0pOF*B_9>a1PF`=KnBbQ$pQ+M3K0vY3IYtMvjZk40v8ry zZ*p>PcVA&+V{dhCbYFF8WM6G{bhAAuVFLkZlbW1PF)+KnBPM$pQ+I3K0vU3IYtIvjZk40uvHq wZ*p>PcVA&+V{dhCbYFF8WV1miVFLkTlcOs!0dbSnD?kB+gBC2e7AyfP3$sNX Date: Fri, 5 Dec 2025 10:24:25 +0200 Subject: [PATCH 12/21] fix: tests snapshots --- ..._populated_genesis_snapshot_matches-2.snap | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index 31c11d8bcbe..3c28a7cb862 100644 --- a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -8,7 +8,7 @@ system_state_version: 1 iota_treasury_cap: inner: id: - id: "0x78c953e9ba50858a73a5ccdb4c5ca6b06d1bb190f6d86585aa73ef3168c84bde" + id: "0x5ffc85c55b68c12d076506721f93de9243e4ac6d684aaa8a96bdedcfc5b763aa" total_supply: value: "751500000000000000" validators: @@ -244,13 +244,13 @@ validators: next_epoch_primary_address: ~ extra_fields: id: - id: "0x2152ad2957f72b96335efd49de4c7266ed6ef5e4163a020adeb0696831db2555" + id: "0x5bd7558660a6451c910a69fe3dd52e45ed720505b4184083f9e3bb7c41edbb07" size: 0 voting_power: 10000 - operation_cap_id: "0x29baf5aaba6bc94a2b375ad05890dc0b2dce0fe4f6620f728f91e9d45edca3b3" + operation_cap_id: "0x401f07ca6d62e3739307782b5d333d52aa78d67a9fb5720063897f58956b25f4" gas_price: 1000 staking_pool: - id: "0x04517c81060f703a708ea01ff1b90f7b384291ab1f84f3b7f1aef951b5c5354a" + id: "0x8567589b65404fd49e088ad46fae36905682bda04877c6db4998a851efc0bdab" activation_epoch: 0 deactivation_epoch: ~ iota_balance: 1500000000000000 @@ -258,14 +258,14 @@ validators: value: 0 pool_token_balance: 1500000000000000 exchange_rates: - id: "0x74f060aace7823cbae9a2614696d21e85ed5f85cfd63368be3e3ffd19ea028cf" + id: "0x3fb8206da20d6c6838a8fdf9d839b4bfb1b5fce4d7c65ee1a4f19d72ac389003" size: 1 pending_stake: 0 pending_total_iota_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0xda67279834b329f1b5f61971f0173f6b417b6528ff5b55287c37ac325e388759" + id: "0xe5683c287c7012bfd936a6e98934296d536f4ae4fd26d78fcbf98ca2c5df743e" size: 0 commission_rate: 200 next_epoch_stake: 1500000000000000 @@ -273,27 +273,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0xfa6000fa82d1dd26b656247de4f7b826209771a6cac17f71075390a92a37b74b" + id: "0xd2a6b42dc9f1afd09e5f105916ac609bc8a35215461511209076b3103eb714a4" size: 0 pending_active_validators: contents: - id: "0x3cfeb86bf86fd404c9429e6ea97616ce3760dfe052b89f85aaf67b8567aed2d9" + id: "0x7e239969e82f7cc4acbac675b322deedd482c7aba53f77257c126149868954f4" size: 0 pending_removals: [] staking_pool_mappings: - id: "0x99a3ff9742e0659dd41641f9ed583066d62041f9a9c961afaef67973a6c9b75c" + id: "0x77f6672eaebed1fafda7ea9b98f919a4f4ff515828b2a34ccb904cf05693ec0c" size: 1 inactive_validators: - id: "0x2175f1ce2609edd51f99b1c0565dbb4e0c3c8bcf7fe323bcb84fe7e9ce104525" + id: "0x48b2ac17505c6dfc04cda863d2c3dce37e3b3ba3ad39308831f4d950e641c1b7" size: 0 validator_candidates: - id: "0xa623ab97869ded845381a6e2b46ce2fa538bd44629d4f0cbac680d1b3446d1b5" + id: "0x6298cdfc1e8477f993be4980398731844aed4227a9ed58d38b58328b79e67ab5" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0x35f04bbba1e56ba3f514409c054e7f7ebf8c39a9c3468bc2edd311c46614e8d2" + id: "0xadd13f0b0b3cda929c5bde9d0f9622d86b20af58da1a939ba9ff1a0095c823c5" size: 0 storage_fund: total_object_storage_rebates: @@ -310,7 +310,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0x82cb899d0f7f2a4c0ac388fece469b19f9376ebf3c36df25bd83f33cbc9d6a22" + id: "0x178f95dbe7dd72e20596414b254c7895563a1032e72d11d980a6b2282c12e6b9" size: 0 iota_system_admin_cap: dummy_field: false @@ -327,5 +327,5 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0x6c01b35600ed97df1531cbdc5e0d683354fc2c869a77b1d779c254d12cf2a1f6" + id: "0x124dff9baec7fe9380969b347fe8b482a524a2726469588096ae05aff2d4cea6" size: 0 From 42507cd529314be27253c2130f6388271b923b2d Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Fri, 5 Dec 2025 14:52:04 +0200 Subject: [PATCH 13/21] fix: `iota-json-rpc-tests::move_utils::get_normalized_move_modules_by_package` --- crates/iota-json-rpc-tests/tests/move_utils.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/iota-json-rpc-tests/tests/move_utils.rs b/crates/iota-json-rpc-tests/tests/move_utils.rs index 4bbdd91df10..5ff68cfff14 100644 --- a/crates/iota-json-rpc-tests/tests/move_utils.rs +++ b/crates/iota-json-rpc-tests/tests/move_utils.rs @@ -38,6 +38,7 @@ async fn get_normalized_move_modules_by_package() -> Result<(), anyhow::Error> { "coin_manager", "config", "deny_list", + "derived_object", "display", "dynamic_field", "dynamic_object_field", @@ -60,6 +61,7 @@ async fn get_normalized_move_modules_by_package() -> Result<(), anyhow::Error> { "object_bag", "object_table", "package", + "package_metadata", "pay", "poseidon", "priority_queue", From 97c57fa7480b558e55599afdc21c257cbdb2e056 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Mon, 8 Dec 2025 10:46:40 +0200 Subject: [PATCH 14/21] fix: clarify the names of the protected generic functions verifiers --- .../latest/iota-verifier/src/private_generics.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iota-execution/latest/iota-verifier/src/private_generics.rs b/iota-execution/latest/iota-verifier/src/private_generics.rs index 690448c4cd7..545cd3022f5 100644 --- a/iota-execution/latest/iota-verifier/src/private_generics.rs +++ b/iota-execution/latest/iota-verifier/src/private_generics.rs @@ -102,18 +102,18 @@ fn verify_function(view: &CompiledModule, fdef: &FunctionDefinition) -> Result<( let type_arguments = &view.signature_at(*type_parameters).0; let ident = addr_module(view, mhandle); if ident == (IOTA_FRAMEWORK_ADDRESS, TRANSFER_MODULE) { - verify_private_transfer(view, fhandle, type_arguments)? + verify_private_transfer_module_functions(view, fhandle, type_arguments)? } else if ident == (IOTA_FRAMEWORK_ADDRESS, EVENT_MODULE) { verify_private_event_emit(view, fhandle, type_arguments)? } else if ident == (IOTA_FRAMEWORK_ADDRESS, ACCOUNT_MODULE) { - verify_private_account(view, fhandle, type_arguments)? + verify_private_account_module_functions(view, fhandle, type_arguments)? } } } Ok(()) } -fn verify_private_transfer( +fn verify_private_transfer_module_functions( view: &CompiledModule, fhandle: &FunctionHandle, type_arguments: &[SignatureToken], @@ -154,7 +154,7 @@ fn verify_private_transfer( Ok(()) } -fn verify_private_account( +fn verify_private_account_module_functions( view: &CompiledModule, fhandle: &FunctionHandle, type_arguments: &[SignatureToken], From 016970e0a2aa626aa7cbee33c0e9779daad230c9 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 12:42:19 +0200 Subject: [PATCH 15/21] refactor: `create_shared_account_v1` -> `create_account_v1` --- .../abstract_account/account/gasless.move | 2 +- .../abstract_account/account/mutable.move | 2 +- .../account/receive_object.move | 2 +- .../abstract_account/account/sponsor.move | 2 +- .../authenticator/ed25519.move | 2 +- .../authenticator/ed25519_wrong_digest.move | 2 +- .../ed25519_wrong_signature.move | 2 +- .../authenticator/several_authenticators.move | 2 +- .../authenticator/simple.move | 2 +- .../authenticator/simple_fail.move | 2 +- .../authenticator/without_attribute.move | 2 +- .../authenticator/wrong_type.move | 2 +- .../private_account_functions.move | 2 +- .../private_account_functions.snap | 4 ++-- .../sources/abstract_account.move | 4 ++-- .../sources/basic_keyed_aa.move | 2 +- .../iota-framework/sources/account.move | 12 ++++++------ .../iota-framework/tests/account_tests.move | 6 +++--- .../packages_compiled/iota-framework | Bin 79616 -> 79602 bytes crates/iota-framework/published_api.txt | 4 ++-- .../iota-transactional-test-runner/syntax.md | 2 +- .../tests/account_functions/account.mvir | 2 +- .../account_functions/account_generic.mvir | 2 +- .../account_functions/account_generic.snap | 2 +- .../account_functions/account_store.mvir | 2 +- .../account_store_generic.mvir | 2 +- .../account_store_generic.snap | 2 +- .../account_functions/external_account.mvir | 2 +- .../account_functions/external_account.snap | 2 +- .../external_account_store.mvir | 2 +- .../external_account_store.snap | 2 +- .../sources/dynamic_multisig_account.move | 2 +- .../function_keys/sources/function_keys.move | 4 ++-- .../move/iotaccount/sources/iotaccount.move | 4 ++-- .../iotaccount/sources/keyed_iotaccount.move | 2 +- .../tests/iotaccount_builder_tests.move | 6 +++--- .../move/iotaccount/tests/test_utils.move | 2 +- .../move/time_locked/sources/account.move | 2 +- .../crates/move-compiler/src/iota_mode/mod.rs | 4 ++-- .../tests/iota_mode/account/account.move | 4 ++-- .../iota_mode/account/account_generic.move | 4 ++-- .../iota_mode/account/account_generic.snap | 4 ++-- .../iota_mode/account/account_store.move | 4 ++-- .../account/account_store_generic.move | 4 ++-- .../account/account_store_generic.snap | 4 ++-- .../iota_mode/account/external_account.move | 4 ++-- .../iota_mode/account/external_account.snap | 4 ++-- .../account/external_account_store.move | 4 ++-- .../account/external_account_store.snap | 4 ++-- .../move/crates/move-symbol-pool/src/lib.rs | 2 +- .../latest/iota-move-natives/src/lib.rs | 2 +- .../iota-verifier/src/private_generics.rs | 2 +- 52 files changed, 76 insertions(+), 76 deletions(-) diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move index e9603680909..0c7b9eb4fd1 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.move @@ -24,7 +24,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move index 928e550d27b..aec353ff6b2 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.move @@ -24,7 +24,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move index 57ddb109afb..5fdfdb639a9 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.move @@ -26,7 +26,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move index e26c80e4a66..5525e9a6800 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.move @@ -22,7 +22,7 @@ public fun create( ) { let account = AbstractAccount { id: object::new(ctx) }; - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } #[authenticator] diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move index b90d17a641a..2f94063db2c 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.move @@ -30,7 +30,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move index 23087b69fd4..270930f7de6 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.move @@ -30,7 +30,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move index 148feac9c34..e7c07696256 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.move @@ -30,7 +30,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move index 2f19026658f..31c313975d6 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.move @@ -25,7 +25,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move index 0bb4b39276a..55704830d89 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.move @@ -25,7 +25,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move index 22484bb9820..579ebdd8de1 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.move @@ -25,7 +25,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move index 896230d818e..307a6a06b35 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.move @@ -25,7 +25,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move index c6742908006..16ee17a3b17 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.move @@ -26,7 +26,7 @@ public fun create( ) { let account = AbstractAccount { id: object::new(ctx) }; - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } #[authenticator] diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move index a0be2fdf69f..9bd7ea0f7ae 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.move @@ -20,7 +20,7 @@ public fun authenticate(_: &Account, _auth_ctx: &AuthContext, _ctx: &TxContext) //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); //> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); -//> 2: iota::account::create_shared_account_v1(Result(0), Result(1)); +//> 2: iota::account::create_account_v1(Result(0), Result(1)); //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); diff --git a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap index 90c5c81ae38..6f7c8e38494 100644 --- a/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap +++ b/crates/iota-adapter-transactional-tests/tests/programmable/private_account_functions.snap @@ -16,9 +16,9 @@ task 2, lines 20-23: //# programmable --inputs object(1,1) "account" "authenticate" //> 0: test::account::create(); //> 1: iota::account::create_auth_info_v1(Input(0), Input(1), Input(2)); -//> 2: iota::account::create_shared_account_v1(Result(0), Result(1)); +//> 2: iota::account::create_account_v1(Result(0), Result(1)); Error: Transaction Effects Status: Non Entry Function Invoked. Move Call must start with an entry function -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_shared_account_v1."), command: Some(2) } } +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: NonEntryFunctionInvoked, source: Some("Cannot directly call iota::account::create_account_v1."), command: Some(2) } } task 3, lines 25-28: //# programmable --inputs object(1,1) "account" "authenticate" diff --git a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move index a12ee64b76b..afff115f72c 100644 --- a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move +++ b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/abstract_account.move @@ -68,9 +68,9 @@ public fun add_dynamic_field( } /// Finish building the `AbstractAccount` and share the object. -public fun build_shared(self: AbstractAccountBuilder) { +public fun build(self: AbstractAccountBuilder) { let AbstractAccountBuilder { account, authenticator } = self; - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } /// Share AbstractAccount. diff --git a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move index a64fd0d2879..e26119d1ea2 100644 --- a/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move +++ b/crates/iota-e2e-tests/tests/abstract_account/abstract_account/sources/basic_keyed_aa.move @@ -52,7 +52,7 @@ public fun create( ) { abstract_account::builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) - .build_shared(); + .build(); } /// Rotates the account owner public key to a new one as well as the authenticator. diff --git a/crates/iota-framework/packages/iota-framework/sources/account.move b/crates/iota-framework/packages/iota-framework/sources/account.move index 51153eed526..ed1a217970a 100644 --- a/crates/iota-framework/packages/iota-framework/sources/account.move +++ b/crates/iota-framework/packages/iota-framework/sources/account.move @@ -65,20 +65,20 @@ public fun create_auth_info_v1( } } -/// Create a mutable shared account with the provided `authenticator`. +/// Create an account as a mutable shared object with the provided `authenticator`. /// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. /// This function has custom rules performed by the IOTA Move bytecode verifier that ensures -/// that `Account` is an object defined in the module where `create_shared_account_v1` is invoked. -public fun create_shared_account_v1( +/// that `Account` is an object defined in the module where `create_account_v1` is invoked. +public fun create_account_v1( mut account: Account, authenticator: AuthenticatorInfoV1, ) { attach_auth_info_v1(&mut account, authenticator); - create_shared_account_v1_impl(account); + create_account_v1_impl(account); } -/// Create an immutable account with the provided `authenticator`. +/// Create an account as an immutable object with the provided `authenticator`. /// The `authenticator` instance will be added to the account as a dynamic field specified by the `AuthenticatorInfoV1Key` name. /// This function has custom rules performed by the IOTA Move bytecode verifier that ensures /// that `Account` is an object defined in the module where `create_immutable_account_v1` is invoked. @@ -151,7 +151,7 @@ native fun borrow_account_uid_mut(account: &mut Account): &mut UID /// Turn `account` into a mutable shared object. /// This function must be called only from the functions protected by the IOTA Move bytecode verifier /// from being called outside the `Account` module. -native fun create_shared_account_v1_impl(account: Account); +native fun create_account_v1_impl(account: Account); /// Turn `account` into an immutable object. /// This function must be called only from the functions protected by the IOTA Move bytecode verifier diff --git a/crates/iota-framework/packages/iota-framework/tests/account_tests.move b/crates/iota-framework/packages/iota-framework/tests/account_tests.move index d926540a50d..dacf41ec9c9 100644 --- a/crates/iota-framework/packages/iota-framework/tests/account_tests.move +++ b/crates/iota-framework/packages/iota-framework/tests/account_tests.move @@ -27,7 +27,7 @@ fun authenticator_info_v1_shared_account_happy_path() { assert_eq(account::has_auth_info_v1(account.id()), false); // Create a shared account with an attached `AuthenticatorInfoV1` instance. - account::create_shared_account_v1(account, default_authenticator_info); + account::create_account_v1(account, default_authenticator_info); scenario.next_tx(@0x0); @@ -89,14 +89,14 @@ fun authenticator_info_v1_double_shared_account_creation() { ascii::string(b"function2"), ); - account::create_shared_account_v1(account, authenticator_info_1); + account::create_account_v1(account, authenticator_info_1); scenario.next_tx(@0x0); let account = scenario.take_shared(); // Call `account::create_account_v1` one more time for the same object that is forbidden. - account::create_shared_account_v1(account, authenticator_info_2); + account::create_account_v1(account, authenticator_info_2); }); } diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index 787fd8edc67c5eb6cbbb32a948644e42dec71819..891d030f5e025d094470973d5e56eef68af158cd 100644 GIT binary patch delta 127 zcmZp8$MWed%Z7ETjF%>_SCtpt!@}{8&4Fzn`$;CQb}m8g8C*;}vnD@QHRBa!U}WTA z5N2Wql46t9)YREUxIt|3%^_+J88royi&7IyQsWbolk-dSO5)25#V|zTGjj`aCYx#m OHt*HgzE^|MnGXPgv?l-n delta 125 zcmezLmZjkx%Z7ETj1MNSSCtn%#lq3U?!b12{Uj6DR4zg8Wn4@=D<(fyHRBa#U}WTA z5MyEnk|LAU)YRFv=a=S{#FrV$ QqDVB)*VsN^gE5#704Yl*H2?qr diff --git a/crates/iota-framework/published_api.txt b/crates/iota-framework/published_api.txt index cbef72f04bb..b0e3b6ded32 100644 --- a/crates/iota-framework/published_api.txt +++ b/crates/iota-framework/published_api.txt @@ -1429,7 +1429,7 @@ AuthenticatorInfoV1 create_auth_info_v1 public fun 0x2::account -create_shared_account_v1 +create_account_v1 public fun 0x2::account create_immutable_account_v1 @@ -1453,7 +1453,7 @@ attach_auth_info_v1 borrow_account_uid_mut fun 0x2::account -create_shared_account_v1_impl +create_account_v1_impl fun 0x2::account create_immutable_account_v1_impl diff --git a/crates/iota-transactional-test-runner/syntax.md b/crates/iota-transactional-test-runner/syntax.md index cea3b8f8c1b..991b49c2a91 100644 --- a/crates/iota-transactional-test-runner/syntax.md +++ b/crates/iota-transactional-test-runner/syntax.md @@ -1471,7 +1471,7 @@ public fun create( let account_address = object::id_address(&account); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir index 414e5e2dead..a5bd654f487 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account.mvir @@ -43,7 +43,7 @@ module 0x0.m { t4(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir index 24a3f41c562..92f799c3611 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.mvir @@ -26,7 +26,7 @@ module 0x0.m { t2(account: T0, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap index 8b74dc7ae11..4acc1ce2b0d 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_generic.snap @@ -12,7 +12,7 @@ gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storag task 1, lines 23-32: //# publish Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } task 2, lines 35-44: //# publish diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir index 733ee299686..147b4eb17cb 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.mvir @@ -43,7 +43,7 @@ module 0x0.m { t4(account: Self.Account, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir index 95157189014..09796be17de 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.mvir @@ -26,7 +26,7 @@ module 0x0.m { t2(account: T0, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap index 8b74dc7ae11..4acc1ce2b0d 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store_generic.snap @@ -12,7 +12,7 @@ gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storag task 1, lines 23-32: //# publish Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t2. Invalid call to 'iota::account::create_account_v1' on an object of type 'T0'. The account object's type must be defined in the current module."), command: Some(0) } } task 2, lines 35-44: //# publish diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir index 75f66d89824..61baeadb04e 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.mvir @@ -80,7 +80,7 @@ module 0x0.m { t4(account: external.Account, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap index 4a11ab21d7f..bf6cee126a4 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account.snap @@ -30,7 +30,7 @@ gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storag task 6, lines 76-86: //# publish --dependencies test Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } task 7, lines 88-98: //# publish --dependencies test diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir index 68b477eab14..7c10f888e16 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.mvir @@ -80,7 +80,7 @@ module 0x0.m { t4(account: external.Account, authenticator: account.AuthenticatorInfoV1) { label l0: - account.create_shared_account_v1(move(account), move(authenticator)); + account.create_account_v1(move(account), move(authenticator)); return; } } diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap index 4a11ab21d7f..bf6cee126a4 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/external_account_store.snap @@ -30,7 +30,7 @@ gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storag task 6, lines 76-86: //# publish --dependencies test Error: Transaction Effects Status: IOTA Move Bytecode Verification Error. Please run the IOTA Move Verifier for more information. -Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_shared_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } +Execution Error: ExecutionError: ExecutionError { inner: ExecutionErrorInner { kind: IotaMoveVerificationError, source: Some("_::m::t4. Invalid call to 'iota::account::create_account_v1' on an object of type 'test::external::Account'. The account object's type must be defined in the current module."), command: Some(0) } } task 7, lines 88-98: //# publish --dependencies test diff --git a/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move b/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move index 2f63f2eeef3..a3adfb75b59 100644 --- a/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move +++ b/examples/move/dynamic_multisig_account/sources/dynamic_multisig_account.move @@ -67,7 +67,7 @@ public fun create( let account = DynamicMultisigAccount { id }; // Create a mutable shared account object. - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } // --------------------------------------- View Functions --------------------------------------- diff --git a/examples/move/function_keys/sources/function_keys.move b/examples/move/function_keys/sources/function_keys.move index 2b20c87541b..b3e0ed0e821 100644 --- a/examples/move/function_keys/sources/function_keys.move +++ b/examples/move/function_keys/sources/function_keys.move @@ -69,7 +69,7 @@ public fun create( builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) .add_dynamic_field(fk_store_key(), build_fn_keys_store(ctx)) - .build_shared(); + .build(); } /// Grants (allows) a `FunctionKey` under a specific `pub_key`. @@ -179,5 +179,5 @@ public fun create_without_fk_store( authenticator: AuthenticatorInfoV1, ctx: &mut TxContext, ) { - builder(authenticator, ctx).add_dynamic_field(OwnerPublicKey {}, public_key).build_shared(); + builder(authenticator, ctx).add_dynamic_field(OwnerPublicKey {}, public_key).build(); } diff --git a/examples/move/iotaccount/sources/iotaccount.move b/examples/move/iotaccount/sources/iotaccount.move index ae8b50fb06c..84d6ca24435 100644 --- a/examples/move/iotaccount/sources/iotaccount.move +++ b/examples/move/iotaccount/sources/iotaccount.move @@ -66,12 +66,12 @@ public fun add_dynamic_field( } /// Finish building a shared `IOTAccount` instance. -public fun build_shared(self: IOTAccountBuilder): address { +public fun build(self: IOTAccountBuilder): address { let IOTAccountBuilder { account, authenticator } = self; let account_address = account.account_address(); - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); account_address } diff --git a/examples/move/iotaccount/sources/keyed_iotaccount.move b/examples/move/iotaccount/sources/keyed_iotaccount.move index f2abca94abc..fc25a4af3e2 100644 --- a/examples/move/iotaccount/sources/keyed_iotaccount.move +++ b/examples/move/iotaccount/sources/keyed_iotaccount.move @@ -52,7 +52,7 @@ public fun create( ) { iotaccount::builder(authenticator, ctx) .add_dynamic_field(OwnerPublicKey {}, public_key) - .build_shared(); + .build(); } /// Ed25519 signature authenticator. diff --git a/examples/move/iotaccount/tests/iotaccount_builder_tests.move b/examples/move/iotaccount/tests/iotaccount_builder_tests.move index c551815e48d..7ca6acb109d 100644 --- a/examples/move/iotaccount/tests/iotaccount_builder_tests.move +++ b/examples/move/iotaccount/tests/iotaccount_builder_tests.move @@ -26,7 +26,7 @@ fun builder_all_mandatory_fields_set() { let authenticator = create_authenticator_info_v1_for_testing(); // Any field value can be set as a dynamic field, and for the purposes of this test // the exact value doesn't matter. - iotaccount::builder(authenticator, ctx).add_dynamic_field(dynamic_field_key, 6).build_shared(); + iotaccount::builder(authenticator, ctx).add_dynamic_field(dynamic_field_key, 6).build(); scenario.next_tx(@0x0); { @@ -65,7 +65,7 @@ fun attempting_to_add_same_dynamic_field_twice() { field_name, 3, ) - .build_shared(); + .build(); test_scenario::end(scenario_val); } @@ -92,7 +92,7 @@ fun dynamic_fields_observe_the_value_not_just_the_type() { another_name, 3, ) - .build_shared(); + .build(); test_scenario::end(scenario_val); } diff --git a/examples/move/iotaccount/tests/test_utils.move b/examples/move/iotaccount/tests/test_utils.move index d7dad56f3c8..e7980b44bbc 100644 --- a/examples/move/iotaccount/tests/test_utils.move +++ b/examples/move/iotaccount/tests/test_utils.move @@ -12,7 +12,7 @@ public fun create_iotaccount_for_testing(scenario: &mut iota::test_scenario::Sce let authenticator = create_authenticator_info_v1_for_testing(); - builder(authenticator, ctx).add_dynamic_field(b"SomeData".to_ascii_string(), 3u8).build_shared() + builder(authenticator, ctx).add_dynamic_field(b"SomeData".to_ascii_string(), 3u8).build() } public fun create_authenticator_info_v1_for_testing(): account::AuthenticatorInfoV1 { diff --git a/examples/move/time_locked/sources/account.move b/examples/move/time_locked/sources/account.move index 6d5a4788d27..c7806f4aee2 100644 --- a/examples/move/time_locked/sources/account.move +++ b/examples/move/time_locked/sources/account.move @@ -47,7 +47,7 @@ public fun create( let account = TimeLocked { id }; - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } /// Authenticate access for the `Time locked account`. diff --git a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs index 451df6de20a..2b8647fd74d 100644 --- a/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs +++ b/external-crates/move/crates/move-compiler/src/iota_mode/mod.rs @@ -74,7 +74,7 @@ pub const RECEIVE_FUNCTION_NAME: Symbol = symbol!("receive"); pub const RECEIVING_TYPE_NAME: Symbol = symbol!("Receiving"); pub const ACCOUNT_MODULE_NAME: Symbol = symbol!("account"); -pub const CREATE_SHARED_ACCOUNT_V1_FUNCTION_NAME: Symbol = symbol!("create_shared_account_v1"); +pub const CREATE_ACCOUNT_V1_FUNCTION_NAME: Symbol = symbol!("create_account_v1"); pub const CREATE_IMMUTABLE_ACCOUNT_V1_FUNCTION_NAME: Symbol = symbol!("create_immutable_account_v1"); pub const ROTATE_AUTH_INFO_V1_FUNCTION_NAME: Symbol = symbol!("rotate_auth_info_v1"); @@ -87,7 +87,7 @@ pub const PRIVATE_TRANSFER_FUNCTIONS: &[Symbol] = &[ ]; pub const PRIVATE_ACCOUNT_FUNCTIONS: &[Symbol] = &[ - CREATE_SHARED_ACCOUNT_V1_FUNCTION_NAME, + CREATE_ACCOUNT_V1_FUNCTION_NAME, CREATE_IMMUTABLE_ACCOUNT_V1_FUNCTION_NAME, ROTATE_AUTH_INFO_V1_FUNCTION_NAME, ]; diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move index c6f9856b941..1f9054985b2 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account.move @@ -8,7 +8,7 @@ module a::m { } public fun t1(account: A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: A, authenticator: AuthenticatorInfoV1) { @@ -33,7 +33,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move index a635d92ef76..6a3430f7e69 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.move @@ -4,7 +4,7 @@ module a::m { use iota::account::{Self, AuthenticatorInfoV1}; public fun t1(account: A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: A, authenticator: AuthenticatorInfoV1) { @@ -32,7 +32,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap index c8d1d0af81f..4faa19f7532 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_generic.snap @@ -10,8 +10,8 @@ error[Iota E02010]: invalid private account call │ 6 │ public fun t1(account: A, authenticator: AuthenticatorInfoV1) { │ - The type 'A' is not declared in the current module -7 │ account::create_shared_account_v1(account, authenticator); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module +7 │ account::create_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_account_v1' is restricted to being called in the object's module error[Iota E02010]: invalid private account call ┌─ tests/iota_mode/account/account_generic.move:11:9 diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move index a51f92776a2..a3c6bc60750 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store.move @@ -8,7 +8,7 @@ module a::m { } public fun t1(account: A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: A, authenticator: AuthenticatorInfoV1) { @@ -33,7 +33,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move index 9f7c056b075..0d64d5d84d4 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.move @@ -5,7 +5,7 @@ module a::m { use iota::account::{Self, AuthenticatorInfoV1}; public fun t1(account: A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: A, authenticator: AuthenticatorInfoV1) { @@ -33,7 +33,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap index 211f420f814..820380d1209 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/account_store_generic.snap @@ -10,8 +10,8 @@ error[Iota E02010]: invalid private account call │ 7 │ public fun t1(account: A, authenticator: AuthenticatorInfoV1) { │ - The type 'A' is not declared in the current module -8 │ account::create_shared_account_v1(account, authenticator); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module +8 │ account::create_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_account_v1' is restricted to being called in the object's module error[Iota E02010]: invalid private account call ┌─ tests/iota_mode/account/account_store_generic.move:12:9 diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move index 51d937a8f15..f1c5c677316 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.move @@ -5,7 +5,7 @@ module a::m { use iota::account::{Self, AuthenticatorInfoV1}; public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { @@ -39,7 +39,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap index db9b224d1a2..7be269fe00f 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account.snap @@ -10,8 +10,8 @@ error[Iota E02010]: invalid private account call │ 7 │ public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { │ -------- The type 'a::other::A' is not declared in the current module -8 │ account::create_shared_account_v1(account, authenticator); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module, 'a::other' +8 │ account::create_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_account_v1' is restricted to being called in the object's module, 'a::other' error[Iota E02010]: invalid private account call ┌─ tests/iota_mode/account/external_account.move:12:9 diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move index ab9cb7e7dbf..a0591eab016 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.move @@ -6,7 +6,7 @@ module a::m { use iota::account::{Self, AuthenticatorInfoV1}; public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { - account::create_shared_account_v1(account, authenticator); + account::create_account_v1(account, authenticator); } public fun t2(account: other::A, authenticator: AuthenticatorInfoV1) { @@ -40,7 +40,7 @@ module iota::account { id: UID, } - public fun create_shared_account_v1(_: Account, _: AuthenticatorInfoV1) { + public fun create_account_v1(_: Account, _: AuthenticatorInfoV1) { abort 0 } diff --git a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap index 9f03768ffe8..f87a254c8bb 100644 --- a/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap +++ b/external-crates/move/crates/move-compiler/tests/iota_mode/account/external_account_store.snap @@ -10,8 +10,8 @@ error[Iota E02010]: invalid private account call │ 8 │ public fun t1(account: other::A, authenticator: AuthenticatorInfoV1) { │ -------- The type 'a::other::A' is not declared in the current module -9 │ account::create_shared_account_v1(account, authenticator); - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_shared_account_v1' is restricted to being called in the object's module, 'a::other' +9 │ account::create_account_v1(account, authenticator); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Invalid private account call. The function 'iota::account::create_account_v1' is restricted to being called in the object's module, 'a::other' error[Iota E02010]: invalid private account call ┌─ tests/iota_mode/account/external_account_store.move:13:9 diff --git a/external-crates/move/crates/move-symbol-pool/src/lib.rs b/external-crates/move/crates/move-symbol-pool/src/lib.rs index c966a87235d..7d75011b081 100644 --- a/external-crates/move/crates/move-symbol-pool/src/lib.rs +++ b/external-crates/move/crates/move-symbol-pool/src/lib.rs @@ -97,7 +97,7 @@ static_symbols!( "beta", "development", "account", - "create_shared_account_v1", + "create_account_v1", "create_immutable_account_v1", "rotate_auth_info_v1", ); diff --git a/iota-execution/latest/iota-move-natives/src/lib.rs b/iota-execution/latest/iota-move-natives/src/lib.rs index 47d6f6f72fa..867c55a6e22 100644 --- a/iota-execution/latest/iota-move-natives/src/lib.rs +++ b/iota-execution/latest/iota-move-natives/src/lib.rs @@ -784,7 +784,7 @@ pub fn all_natives(silent: bool, protocol_config: &ProtocolConfig) -> NativeFunc ), ( "account", - "create_shared_account_v1_impl", + "create_account_v1_impl", make_native!(transfer::share_object), ), ( diff --git a/iota-execution/latest/iota-verifier/src/private_generics.rs b/iota-execution/latest/iota-verifier/src/private_generics.rs index 545cd3022f5..edebc3b344d 100644 --- a/iota-execution/latest/iota-verifier/src/private_generics.rs +++ b/iota-execution/latest/iota-verifier/src/private_generics.rs @@ -46,7 +46,7 @@ pub const PUBLIC_ACCOUNT_FUNCTIONS: &[&IdentStr] = &[ ident_str!("has_auth_info_v1"), ]; pub const PRIVATE_ACCOUNT_FUNCTIONS: &[&IdentStr] = &[ - ident_str!("create_shared_account_v1"), + ident_str!("create_account_v1"), ident_str!("create_immutable_account_v1"), ident_str!("rotate_auth_info_v1"), ]; From 59fd879c7cf063b5a7bf11ea40e9976e9262d96d Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 12:42:57 +0200 Subject: [PATCH 16/21] fix: update framework snapshots --- ...000000000000000000000000000000000000000002 | Bin 79681 -> 79667 bytes crates/iota-framework-snapshot/manifest.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 b/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 index 80b2a3e40a63dd4e7e79d90ed0574df80282063d..c24f8a4e03898ef42f0b291b986d211f1ab9fdda 100644 GIT binary patch delta 127 zcmX^3j%D*ZmJR1r881yfuPQIPhlS%Gn*-ZE_LEFp?OcM~Gq{*|W=&>RGvgIyU}WTA z5N2Wql46tH)YREUxIt|3%_V9N88royi&7IyQsWbolk-dSO5)25#V|zTGjj`aCWmSS OHs96QepiDrg%1E{WG5v6 delta 125 zcmdn|j^*GxmJR1r86QkOuPQHkiiM+x-GS{4`$;CQsa%5G%ea_$R!nAAGvgIzU}WTA z5MyEnk|LAc)YRFv=a=S{#FrV$ QqDVCF*Vw*agRz7U024MQS^xk5 diff --git a/crates/iota-framework-snapshot/manifest.json b/crates/iota-framework-snapshot/manifest.json index f392ddc6ab2..b0328e6f451 100644 --- a/crates/iota-framework-snapshot/manifest.json +++ b/crates/iota-framework-snapshot/manifest.json @@ -415,7 +415,7 @@ ] }, "16": { - "git_revision": "59eb660ce613d0d43f01bf2e9b6935cd14cb5c07", + "git_revision": "016970e0a2aa626aa7cbee33c0e9779daad230c9", "packages": [ { "name": "MoveStdlib", From 1fa52e0c42d15d89b60697a445588cea9626acc1 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 12:49:03 +0200 Subject: [PATCH 17/21] fix: update test snapshots --- .../abstract_account/account/gasless.snap | 2 +- .../abstract_account/account/mutable.snap | 2 +- .../account/receive_object.snap | 2 +- .../abstract_account/account/sponsor.snap | 2 +- .../authenticator/ed25519.snap | 2 +- .../authenticator/ed25519_wrong_digest.snap | 2 +- .../ed25519_wrong_signature.snap | 2 +- .../authenticator/several_authenticators.snap | 2 +- .../authenticator/simple.snap | 2 +- .../authenticator/simple_fail.snap | 2 +- .../authenticator/without_attribute.snap | 2 +- .../authenticator/wrong_type.snap | 2 +- ..._populated_genesis_snapshot_matches-2.snap | 28 +++++++++---------- .../tests/account_functions/account.snap | 2 +- .../account_functions/account_store.snap | 2 +- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap index f79cc9fb255..0cb3e099c8c 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/gasless.snap @@ -10,7 +10,7 @@ task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10032000, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 9978800, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 35-37: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap index 192ca3f4df9..f66435c1ba9 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/mutable.snap @@ -10,7 +10,7 @@ task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10032000, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 9978800, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 35-39: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap index 40c7247fae8..e3384ccb264 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/receive_object.snap @@ -10,7 +10,7 @@ task 1, lines 8-44: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11696400, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11643200, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 46-50: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap index 2a812ffdb84..67d98f53d33 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/account/sponsor.snap @@ -10,7 +10,7 @@ task 1, lines 8-29: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 9720400, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 9667200, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 31-33: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap index bcdd9897526..89a1f91d3b4 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519.snap @@ -10,7 +10,7 @@ task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12129600, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap index dc67d328f06..1c930cbb849 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_digest.snap @@ -10,7 +10,7 @@ task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12129600, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap index 84eb8c1420a..7c7ede4040f 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/ed25519_wrong_signature.snap @@ -10,7 +10,7 @@ task 1, lines 8-56: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12182800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12129600, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 58-62: //# programmable --sender A --inputs x"cc62332e34bb2d5cd69f60efbb2a36cb916c7eb458301ea36636c4dbb012bd88" object(1,1) "abstract_account" "authenticate_ed25519" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap index 2ab2ffd83f5..ed0c07e92e2 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/several_authenticators.snap @@ -10,7 +10,7 @@ task 1, lines 8-51: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12775600, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 12722400, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 53-57: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap index d519188c723..f40d8662a78 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple.snap @@ -10,7 +10,7 @@ task 1, lines 8-41: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11149200, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11096000, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 43-47: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap index 7ea124530a4..427004d23e6 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/simple_fail.snap @@ -10,7 +10,7 @@ task 1, lines 8-41: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11149200, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 11096000, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 43-47: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap index ded6841963d..20f0485b0d4 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/without_attribute.snap @@ -10,7 +10,7 @@ task 1, lines 8-40: //# publish --sender A created: object(1,0) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 7630400, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 7577200, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 42-46: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate_hello_world" 7000000000 diff --git a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap index 7377dd40357..177b9832939 100644 --- a/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap +++ b/crates/iota-adapter-transactional-tests/tests/abstract_account/authenticator/wrong_type.snap @@ -10,7 +10,7 @@ task 1, lines 8-33: //# publish --sender A created: object(1,0), object(1,1) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10419600, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 10366400, storage_rebate: 0, non_refundable_storage_fee: 0 task 2, lines 35-37: //# programmable --sender A --inputs x"10" object(1,1) "abstract_account" "authenticate" diff --git a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index 3c28a7cb862..aef266697b2 100644 --- a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -8,7 +8,7 @@ system_state_version: 1 iota_treasury_cap: inner: id: - id: "0x5ffc85c55b68c12d076506721f93de9243e4ac6d684aaa8a96bdedcfc5b763aa" + id: "0x6c088ab83f83108c5f1769b0aa16af93635058847cb2b670946a3e91aaf4e951" total_supply: value: "751500000000000000" validators: @@ -244,13 +244,13 @@ validators: next_epoch_primary_address: ~ extra_fields: id: - id: "0x5bd7558660a6451c910a69fe3dd52e45ed720505b4184083f9e3bb7c41edbb07" + id: "0xc56e786292af7926d2b1b628d8eea6bd3c8c4e94ce8cd3fd402b977c5018c240" size: 0 voting_power: 10000 - operation_cap_id: "0x401f07ca6d62e3739307782b5d333d52aa78d67a9fb5720063897f58956b25f4" + operation_cap_id: "0x30d881bccc3f3d20dd7ac29cfc3b2f00d4e1459e0b984e52645773bdd99d58af" gas_price: 1000 staking_pool: - id: "0x8567589b65404fd49e088ad46fae36905682bda04877c6db4998a851efc0bdab" + id: "0x24b4bad119603e69571d58f6ac042165bde0f09344c54bbcd10ffbc4d2054cdb" activation_epoch: 0 deactivation_epoch: ~ iota_balance: 1500000000000000 @@ -258,14 +258,14 @@ validators: value: 0 pool_token_balance: 1500000000000000 exchange_rates: - id: "0x3fb8206da20d6c6838a8fdf9d839b4bfb1b5fce4d7c65ee1a4f19d72ac389003" + id: "0xb64c2d65c5022b732620043fd70768622a80230715a498e9d71cf6bba8768065" size: 1 pending_stake: 0 pending_total_iota_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0xe5683c287c7012bfd936a6e98934296d536f4ae4fd26d78fcbf98ca2c5df743e" + id: "0xb35f45bf56ba428f3754263cdf6152e4096591c0e931cb4cccd041b578f20909" size: 0 commission_rate: 200 next_epoch_stake: 1500000000000000 @@ -273,27 +273,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0xd2a6b42dc9f1afd09e5f105916ac609bc8a35215461511209076b3103eb714a4" + id: "0x0361a74d0bb951aa905538b06e01f423719db027285fdab34b74088e2dc516f6" size: 0 pending_active_validators: contents: - id: "0x7e239969e82f7cc4acbac675b322deedd482c7aba53f77257c126149868954f4" + id: "0x4ab6e9d4faf9444cad7474f40bbfb8f3764fd69fb8d2fce2faf9f45fef538bd6" size: 0 pending_removals: [] staking_pool_mappings: - id: "0x77f6672eaebed1fafda7ea9b98f919a4f4ff515828b2a34ccb904cf05693ec0c" + id: "0xae4ea3666260854089b49558d27c65f988b533035510d10a783bad03303b7e9e" size: 1 inactive_validators: - id: "0x48b2ac17505c6dfc04cda863d2c3dce37e3b3ba3ad39308831f4d950e641c1b7" + id: "0xa15660a5baf8a981dcd2744fa0019b6408f10a7678083092d0eeee52d799a853" size: 0 validator_candidates: - id: "0x6298cdfc1e8477f993be4980398731844aed4227a9ed58d38b58328b79e67ab5" + id: "0x0bd6c5133e6ad2cc0455db6f99d29e914c93aa75e7195a0296bd7488b357c132" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0xadd13f0b0b3cda929c5bde9d0f9622d86b20af58da1a939ba9ff1a0095c823c5" + id: "0xfc4040448db92e13ff4e9e001dcc6d8fda4b2352aa6f785473c674e58ffc5103" size: 0 storage_fund: total_object_storage_rebates: @@ -310,7 +310,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0x178f95dbe7dd72e20596414b254c7895563a1032e72d11d980a6b2282c12e6b9" + id: "0xfe14a4f973f97f2d7907f100c6d76de05fa317c936c40f2ebd7d992690103d46" size: 0 iota_system_admin_cap: dummy_field: false @@ -327,5 +327,5 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0x124dff9baec7fe9380969b347fe8b482a524a2726469588096ae05aff2d4cea6" + id: "0x25353d8d9f6f219a0e1b75a189e15d2dd319d8bec332eb08a3ab8043f59551c7" size: 0 diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap index 8bbd57514f0..358781194ac 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account.snap @@ -7,4 +7,4 @@ task 0, lines 4-62: //# publish created: object(1,0) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8420800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8367600, storage_rebate: 0, non_refundable_storage_fee: 0 diff --git a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap index 8bbd57514f0..358781194ac 100644 --- a/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap +++ b/crates/iota-verifier-transactional-tests/tests/account_functions/account_store.snap @@ -7,4 +7,4 @@ task 0, lines 4-62: //# publish created: object(1,0) mutated: object(0,0) -gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8420800, storage_rebate: 0, non_refundable_storage_fee: 0 +gas summary: computation_cost: 1000000, computation_cost_burned: 1000000, storage_cost: 8367600, storage_rebate: 0, non_refundable_storage_fee: 0 From 69dac61ee0d50bd424315e50767c82688f4a948e Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 13:05:43 +0200 Subject: [PATCH 18/21] fix: move tests names after renaming --- .../packages/iota-framework/tests/account_tests.move | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/iota-framework/packages/iota-framework/tests/account_tests.move b/crates/iota-framework/packages/iota-framework/tests/account_tests.move index dacf41ec9c9..cce6bab2a86 100644 --- a/crates/iota-framework/packages/iota-framework/tests/account_tests.move +++ b/crates/iota-framework/packages/iota-framework/tests/account_tests.move @@ -19,14 +19,14 @@ fun id(self: &TestAccount): &UID { } #[test] -fun authenticator_info_v1_shared_account_happy_path() { +fun authenticator_info_v1_account_happy_path() { account_test!(|scenario, account| { let default_authenticator_info = create_default_authenticator_info_v1_for_testing(); // Check that there is no an attached `AuthenticatorInfoV1` just after creation. assert_eq(account::has_auth_info_v1(account.id()), false); - // Create a shared account with an attached `AuthenticatorInfoV1` instance. + // Create an account as a shared object with an attached `AuthenticatorInfoV1` instance. account::create_account_v1(account, default_authenticator_info); scenario.next_tx(@0x0); @@ -80,7 +80,7 @@ fun authenticator_info_v1_immutable_account_happy_path() { #[test] #[expected_failure(abort_code = account::EAuthenticatorInfoV1AlreadyAttached)] -fun authenticator_info_v1_double_shared_account_creation() { +fun authenticator_info_v1_double_account_creation() { account_test!(|scenario, account| { let authenticator_info_1 = create_default_authenticator_info_v1_for_testing(); let authenticator_info_2 = account::create_auth_info_v1_for_testing( From 024c3678a48d78d9d491af01cf62caf9f55b84c1 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 13:42:19 +0200 Subject: [PATCH 19/21] refactor: the framework cleanup --- .../iota-framework/sources/account.move | 5 +---- .../packages_compiled/iota-framework | Bin 79602 -> 79602 bytes 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/iota-framework/packages/iota-framework/sources/account.move b/crates/iota-framework/packages/iota-framework/sources/account.move index ed1a217970a..9cd1b268620 100644 --- a/crates/iota-framework/packages/iota-framework/sources/account.move +++ b/crates/iota-framework/packages/iota-framework/sources/account.move @@ -105,10 +105,7 @@ public fun rotate_auth_info_v1( let name = auth_info_v1_key(); - let previous_authenticator_info = dynamic_field::remove<_, AuthenticatorInfoV1>( - account_id, - name, - ); + let previous_authenticator_info = dynamic_field::remove(account_id, name); dynamic_field::add(account_id, name, authenticator); previous_authenticator_info } diff --git a/crates/iota-framework/packages_compiled/iota-framework b/crates/iota-framework/packages_compiled/iota-framework index 891d030f5e025d094470973d5e56eef68af158cd..3666890bffb8f4c4a86147957c651d5496111356 100644 GIT binary patch delta 26 icmezLmgUo1mJQ3a8A~QF*LGm+YJQ=;{e?Co7dHU15es7g delta 26 icmezLmgUo1mJQ3a8OtXx*LGm+ZGNG>{e?Co7dHU1Ukhmf From cdbf37112c079d96b64ff02f344d12ee0328c07d Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 13:42:42 +0200 Subject: [PATCH 20/21] fix: update framework snapshots --- ...000000000000000000000000000000000000000002 | Bin 79667 -> 79667 bytes crates/iota-framework-snapshot/manifest.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 b/crates/iota-framework-snapshot/bytecode_snapshot/16/0x0000000000000000000000000000000000000000000000000000000000000002 index c24f8a4e03898ef42f0b291b986d211f1ab9fdda..35f57b2ac995658fa7c7d24c8fb8d219f31e9f58 100644 GIT binary patch delta 26 icmdn|j%D*ZmJP?W8A~P~*LGm+YUa?{&Y{Do%?$vbJ_(8d delta 26 icmdn|j%D*ZmJP?W8OtXh*LGm+ZRXI~&Y{Do%?$vbj0unc diff --git a/crates/iota-framework-snapshot/manifest.json b/crates/iota-framework-snapshot/manifest.json index b0328e6f451..c7e4529e516 100644 --- a/crates/iota-framework-snapshot/manifest.json +++ b/crates/iota-framework-snapshot/manifest.json @@ -415,7 +415,7 @@ ] }, "16": { - "git_revision": "016970e0a2aa626aa7cbee33c0e9779daad230c9", + "git_revision": "024c3678a48d78d9d491af01cf62caf9f55b84c1", "packages": [ { "name": "MoveStdlib", From 2c7f83c6c81ec2bfc14ebb022b63de1773fbe178 Mon Sep 17 00:00:00 2001 From: Valerii Reutov Date: Tue, 9 Dec 2025 13:46:46 +0200 Subject: [PATCH 21/21] fix: update test snapshots --- ..._populated_genesis_snapshot_matches-2.snap | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index aef266697b2..e884a0de289 100644 --- a/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/iota-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -8,7 +8,7 @@ system_state_version: 1 iota_treasury_cap: inner: id: - id: "0x6c088ab83f83108c5f1769b0aa16af93635058847cb2b670946a3e91aaf4e951" + id: "0x6050a2d92be4fdc113c93ab0c4ad29bbc7ad2ec96b19d5faaa4301961988ee56" total_supply: value: "751500000000000000" validators: @@ -244,13 +244,13 @@ validators: next_epoch_primary_address: ~ extra_fields: id: - id: "0xc56e786292af7926d2b1b628d8eea6bd3c8c4e94ce8cd3fd402b977c5018c240" + id: "0x8ad7191b7caca6371647cf89790e673565b8f170c6853b42219e6c03f93f0489" size: 0 voting_power: 10000 - operation_cap_id: "0x30d881bccc3f3d20dd7ac29cfc3b2f00d4e1459e0b984e52645773bdd99d58af" + operation_cap_id: "0x35b4de0285e215cb2ffe4834705a24399441d82b0e445753529a1c897b1dd53b" gas_price: 1000 staking_pool: - id: "0x24b4bad119603e69571d58f6ac042165bde0f09344c54bbcd10ffbc4d2054cdb" + id: "0x058945ebf376d4f34feaf25fcb1a8f417a56289c7466d8a789d88ba8e013faec" activation_epoch: 0 deactivation_epoch: ~ iota_balance: 1500000000000000 @@ -258,14 +258,14 @@ validators: value: 0 pool_token_balance: 1500000000000000 exchange_rates: - id: "0xb64c2d65c5022b732620043fd70768622a80230715a498e9d71cf6bba8768065" + id: "0x655395866e33cd8075b645cda45a0afa25e85acf6ef055af8e9504e6aa393474" size: 1 pending_stake: 0 pending_total_iota_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0xb35f45bf56ba428f3754263cdf6152e4096591c0e931cb4cccd041b578f20909" + id: "0x6bd6149b7963ded860532292ca54ffdc5445886ba02ea455ca3b8545fd2c8300" size: 0 commission_rate: 200 next_epoch_stake: 1500000000000000 @@ -273,27 +273,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0x0361a74d0bb951aa905538b06e01f423719db027285fdab34b74088e2dc516f6" + id: "0xb4be18e20ce6d7e93eff6973b2795d1935148045b411d559561a655c5c86c080" size: 0 pending_active_validators: contents: - id: "0x4ab6e9d4faf9444cad7474f40bbfb8f3764fd69fb8d2fce2faf9f45fef538bd6" + id: "0xb8de414b7ad627344fdf035835ef2d226109f04b27660f0bfcd3427d9d087b42" size: 0 pending_removals: [] staking_pool_mappings: - id: "0xae4ea3666260854089b49558d27c65f988b533035510d10a783bad03303b7e9e" + id: "0x678185eb2e63d5f534340a21b8206a708e06a333066632623b69d79834b1d597" size: 1 inactive_validators: - id: "0xa15660a5baf8a981dcd2744fa0019b6408f10a7678083092d0eeee52d799a853" + id: "0x2bb039550598cc3a3f5ea3596aeba0abd76b0d30beacd020ef2691c88c978b05" size: 0 validator_candidates: - id: "0x0bd6c5133e6ad2cc0455db6f99d29e914c93aa75e7195a0296bd7488b357c132" + id: "0xa6b652c628967a14f951943582d2853078467dcc386cced6f9b1c25e8158eca3" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0xfc4040448db92e13ff4e9e001dcc6d8fda4b2352aa6f785473c674e58ffc5103" + id: "0x28ad130704824e223b0998dcc01e568de1e70089ad1c2ae9e1f3bbfa97dca6d2" size: 0 storage_fund: total_object_storage_rebates: @@ -310,7 +310,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0xfe14a4f973f97f2d7907f100c6d76de05fa317c936c40f2ebd7d992690103d46" + id: "0xc1188ec9ae0abf4ae5338d6688c479f6ae01fc0c8a948640a99bb6c6c61c49fc" size: 0 iota_system_admin_cap: dummy_field: false @@ -327,5 +327,5 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0x25353d8d9f6f219a0e1b75a189e15d2dd319d8bec332eb08a3ab8043f59551c7" + id: "0x6de4f42846205d75665f88579d20d7c8d0562c9cbcb19f5f7165cf2cf7b13128" size: 0