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));
+ }
}