diff --git a/frameworks/moveos-stdlib/doc/module_store.md b/frameworks/moveos-stdlib/doc/module_store.md index af690e19e1..c5d602d554 100644 --- a/frameworks/moveos-stdlib/doc/module_store.md +++ b/frameworks/moveos-stdlib/doc/module_store.md @@ -19,6 +19,7 @@ - [Function `publish_modules`](#0x2_module_store_publish_modules) - [Function `publish_modules_entry`](#0x2_module_store_publish_modules_entry) - [Function `publish_modules_internal`](#0x2_module_store_publish_modules_internal) +- [Function `freeze_package`](#0x2_module_store_freeze_package) - [Function `add_to_allowlist`](#0x2_module_store_add_to_allowlist) - [Function `remove_from_allowlist`](#0x2_module_store_remove_from_allowlist) - [Function `is_in_allowlist`](#0x2_module_store_is_in_allowlist) @@ -198,6 +199,17 @@ Return true if the modules are upgraded + + +## Function `freeze_package` + + + +
public fun freeze_package(package: object::Object<module_store::Package>)
+
+ + + ## Function `add_to_allowlist` diff --git a/frameworks/moveos-stdlib/sources/module_store.move b/frameworks/moveos-stdlib/sources/module_store.move index 3b3e7675a8..79c4eec699 100644 --- a/frameworks/moveos-stdlib/sources/module_store.move +++ b/frameworks/moveos-stdlib/sources/module_store.move @@ -108,18 +108,21 @@ module moveos_std::module_store { /// Publish modules to the module object's storage /// Return true if the modules are upgraded - public(friend) fun publish_modules_internal(module_object: &mut Object, package_id: address, modules: vector) : bool { + public(friend) fun publish_modules_internal( + module_object: &mut Object, package_id: address, modules: vector + ) : bool { let i = 0; let len = vector::length(&modules); let (module_names, module_names_with_init_fn, indices) = move_module::sort_and_verify_modules(&modules, package_id); + let is_upgrade = true; if (!exists_package(module_object, package_id)) { - let package = object::add_object_field_with_id(module_object, package_id, Package {}); - object::transfer_extend(package, tx_context::sender()); + // TODO: should we transfer the Package object to tx sender or package id address? + create_package(module_object, package_id, tx_context::sender()); + is_upgrade = false; }; let package = borrow_mut_package(module_object, package_id); - let upgrade_flag = false; while (i < len) { let module_name = vector::pop_back(&mut module_names); let index = vector::pop_back(&mut indices); @@ -129,7 +132,6 @@ module moveos_std::module_store { if (object::contains_field(package, module_name)) { let old_m = remove_module(package, module_name); move_module::check_comatibility(m, &old_m); - upgrade_flag = true; } else { // request init function invoking if (vector::contains(&module_names_with_init_fn, &module_name)) { @@ -140,7 +142,12 @@ module moveos_std::module_store { add_module(package, module_name, *m); i = i + 1; }; - upgrade_flag + is_upgrade + } + + fun create_package(module_object: &mut Object, package_id: address, owner: address) { + let package = object::add_object_field_with_id(module_object, package_id, Package {}); + object::transfer_extend(package, owner); } fun borrow_package(module_store: &Object, package_id: address): &Object { @@ -173,6 +180,12 @@ module moveos_std::module_store { object::borrow_mut(allowlist_obj) } + public fun freeze_package(package: Object) { + object::to_frozen(package); + } + + /************************ allowlist functions *************************/ + /// Add an account to the allowlist. Only account in allowlist can publish modules. /// This is only valid when module_publishing_allowlist_enabled feature is enabled. public fun add_to_allowlist(account: &signer, publisher: address) { @@ -213,7 +226,6 @@ module moveos_std::module_store { #[test_only] const COUNTER_MV_BYTES: vector = x"a11ceb0b060000000b01000402040403082b04330605391c07557908ce0140068e02220ab002050cb502640d9903020000010100020c000003000000000400000000050100000006010000000700020001080506010c01090700010c010a0508010c0504060407040001060c01030107080001080001050107090002060c09000106090007636f756e746572076163636f756e7407436f756e74657208696e63726561736509696e6372656173655f04696e69740d696e69745f666f725f746573740576616c756513626f72726f775f6d75745f7265736f75726365106d6f76655f7265736f757263655f746f0f626f72726f775f7265736f757263650000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000000205200000000000000000000000000000000000000000000000000000000000000042000201070300010400000211010201010000030c070038000c000a00100014060100000000000000160b000f0015020200000000050b0006000000000000000012003801020301000000050b0006000000000000000012003801020401000000050700380210001402000000"; - #[test_only] fun drop_module_store(self: Object) { let ModuleStore {} = object::drop_unchecked(self); @@ -275,5 +287,24 @@ module moveos_std::module_store { remove_from_allowlist(&system_account, @0x42); assert!(!is_in_allowlist(@0x42), 3); } + + #[test(account=@0x42)] + #[expected_failure(abort_code = 9, location = object)] + fun test_frozen_package(account: &signer) { + init_module_store(); + features::init_feature_store_for_test(); + + let module_object = borrow_mut_module_store(); + let module_bytes = COUNTER_MV_BYTES; + let m: MoveModule = move_module::new(module_bytes); + + publish_modules(module_object, account, vector::singleton(m)); + publish_modules(module_object, account, vector::singleton(m)); + + let package_obj_id = object::custom_child_object_id(object::id(module_object), signer::address_of(account)); + let (_, package) = object::take_object_extend< Package>(package_obj_id); + freeze_package(package); + publish_modules(module_object, account, vector::singleton(m)); + } }