From 4fb7ebc3e55ce4828f2ea7fe8af484d14a502774 Mon Sep 17 00:00:00 2001 From: 0xpause Date: Wed, 25 Oct 2023 23:04:23 +0800 Subject: [PATCH 1/6] add native functions for replacing identifiers and address --- .../src/natives/gas_parameter/move_module.rs | 8 +- .../src/commands/move_cli/commands/publish.rs | 1 + .../moveos-stdlib/doc/move_module.md | 95 +++++-- .../moveos-stdlib/sources/move_module.move | 88 +++++-- .../src/natives/moveos_stdlib/move_module.rs | 233 +++++++++++++++--- 5 files changed, 344 insertions(+), 81 deletions(-) diff --git a/crates/rooch-framework/src/natives/gas_parameter/move_module.rs b/crates/rooch-framework/src/natives/gas_parameter/move_module.rs index fbd839c343..8b528d7d26 100644 --- a/crates/rooch-framework/src/natives/gas_parameter/move_module.rs +++ b/crates/rooch-framework/src/natives/gas_parameter/move_module.rs @@ -13,6 +13,10 @@ crate::natives::gas_parameter::native::define_gas_parameters_for_natives!(GasPar [.request_init_functions.per_byte, "request_init_functions.per_byte", (5 + 1) * MUL], [.check_compatibililty_inner.base, "check_compatibililty_inner.base", (5 + 1) * MUL], [.check_compatibililty_inner.per_byte, "check_compatibililty_inner.per_byte", (5 + 1) * MUL], - [.remap_module_addresses_inner.base, "remap_module_addresses_inner.base", (5 + 1) * MUL], - [.remap_module_addresses_inner.per_byte, "remap_module_addresses_inner.per_byte", (5 + 1) * MUL], + [.replace_address_identifiers.base, "replace_address_identifiers.base", (5 + 1) * MUL], + [.replace_address_identifiers.per_byte, "replace_address_identifiers.per_byte", (5 + 1) * MUL], + [.replace_addresses_constant.base, "replace_addresses_constant.base", (5 + 1) * MUL], + [.replace_addresses_constant.per_byte, "replace_addresses_constant.per_byte", (5 + 1) * MUL], + [.replace_identifiers.base, "replace_identifiers.base", (5 + 1) * MUL], + [.replace_identifiers.per_byte, "replace_identifiers.per_byte", (5 + 1) * MUL], ]); diff --git a/crates/rooch/src/commands/move_cli/commands/publish.rs b/crates/rooch/src/commands/move_cli/commands/publish.rs index 2801148ff3..733575503e 100644 --- a/crates/rooch/src/commands/move_cli/commands/publish.rs +++ b/crates/rooch/src/commands/move_cli/commands/publish.rs @@ -90,6 +90,7 @@ impl CommandAction for Publish { let empty_modules = modules.iter_modules_owned().is_empty(); let pkg_address = if !empty_modules { let first_module = &modules.iter_modules_owned()[0]; + println!("compiled module: {:?}", first_module.clone()); first_module.self_id().address().to_owned() } else { return Err(RoochError::MoveCompilationError(format!( diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md index 75d63747ae..b100aeeea1 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md @@ -12,12 +12,13 @@ - [Function `module_name`](#0x2_move_module_module_name) - [Function `sort_and_verify_modules`](#0x2_move_module_sort_and_verify_modules) - [Function `check_comatibility`](#0x2_move_module_check_comatibility) -- [Function `remap_module_addresses`](#0x2_move_module_remap_module_addresses) +- [Function `binding_module_address`](#0x2_move_module_binding_module_address) +- [Function `replace_module_name`](#0x2_move_module_replace_module_name) - [Function `request_init_functions`](#0x2_move_module_request_init_functions) -
use 0x1::error;
-use 0x1::string;
+
use 0x1::string;
+use 0x1::vector;
 
@@ -207,15 +208,14 @@ Abort if the new module is not compatible with the old module. - + -## Function `remap_module_addresses` +## Function `binding_module_address` -Remap addresses in module binary where the length of -old_addresses must equal to that of new_addresses. +Binding given module's address to the new address -
public fun remap_module_addresses(modules: vector<move_module::MoveModule>, old_addresses: vector<address>, new_addresses: vector<address>): vector<move_module::MoveModule>
+
public fun binding_module_address(modules: vector<move_module::MoveModule>, old_address: address, new_address: address): vector<move_module::MoveModule>
 
@@ -224,15 +224,11 @@ Remap addresses in module binary where the length of Implementation -
public fun remap_module_addresses(
+
public fun binding_module_address(
     modules: vector<MoveModule>,
-    old_addresses: vector<address>,
-    new_addresses: vector<address>,
+    old_address: address,
+    new_address: address,
 ): vector<MoveModule> {
-    assert!(
-        vector::length(&old_addresses) == vector::length(&new_addresses),
-        error::invalid_argument(ErrorLengthNotMatch)
-    );
     let bytes_vec = vector::empty<vector<u8>>();
     let i = 0u64;
     let len = vector::length(&modules);
@@ -240,19 +236,72 @@ Remap addresses in module binary where the length of
         vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes);
         i = i + 1;
     };
-    let remapped_bytes = remap_module_addresses_inner(bytes_vec, old_addresses, new_addresses);
-    // let remapped_bytes = remap_module_addresses_inner(bytes_vec);
-    let remapped_modules = vector::empty<MoveModule>();
+    let old_addresses = vector::singleton(old_address);
+    let new_addresses = vector::singleton(new_address);
+
+    let rebinded_bytes = replace_address_identifiers(bytes_vec, old_addresses, new_addresses);
+    let rebinded_bytes = replace_addresses_constant(rebinded_bytes, old_addresses, new_addresses);
+    let rebinded_modules = vector::empty<MoveModule>();
+    i = 0u64;
+    let len = vector::length(&rebinded_bytes);
+    while (i < len) {
+        vector::push_back(&mut rebinded_modules, MoveModule {
+            byte_codes: vector::pop_back(&mut rebinded_bytes),
+        });
+        i = i + 1;
+    };
+    vector::destroy_empty(rebinded_bytes);
+    rebinded_modules
+}
+
+ + + + + + + +## Function `replace_module_name` + +Binding given module's address to the new address + + +
public fun replace_module_name(modules: vector<move_module::MoveModule>, old_name: string::String, new_name: string::String): vector<move_module::MoveModule>
+
+ + + +
+Implementation + + +
public fun replace_module_name(
+    modules: vector<MoveModule>,
+    old_name: String,
+    new_name: String,
+): vector<MoveModule> {
+    let bytes_vec = vector::empty<vector<u8>>();
+    let i = 0u64;
+    let len = vector::length(&modules);
+    while (i < len) {
+        vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes);
+        i = i + 1;
+    };
+    let old_names = vector::singleton(old_name);
+    let new_names = vector::singleton(new_name);
+
+    let rebinded_bytes = replace_identifiers(bytes_vec, old_names, new_names);
+    let rebinded_modules = vector::empty<MoveModule>();
     i = 0u64;
-    let len = vector::length(&remapped_bytes);
+    let len = vector::length(&rebinded_bytes);
     while (i < len) {
-        vector::push_back(&mut remapped_modules, MoveModule {
-            byte_codes: vector::pop_back(&mut remapped_bytes),
+        vector::push_back(&mut rebinded_modules, MoveModule {
+            byte_codes: vector::pop_back(&mut rebinded_bytes),
         });
         i = i + 1;
     };
-    vector::destroy_empty(remapped_bytes);
-    remapped_modules
+    vector::destroy_empty(rebinded_bytes);
+    rebinded_modules
 }
 
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move index e805b3c91f..fd349ba11f 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move @@ -55,17 +55,12 @@ module moveos_std::move_module { check_compatibililty_inner(new_module.byte_codes, old_module.byte_codes); } - /// Remap addresses in module binary where the length of - /// `old_addresses` must equal to that of `new_addresses`. - public fun remap_module_addresses( + /// Binding given module's address to the new address + public fun binding_module_address( modules: vector, - old_addresses: vector
, - new_addresses: vector
, + old_address: address, + new_address: address, ): vector { - assert!( - vector::length(&old_addresses) == vector::length(&new_addresses), - error::invalid_argument(ErrorLengthNotMatch) - ); let bytes_vec = vector::empty>(); let i = 0u64; let len = vector::length(&modules); @@ -73,19 +68,52 @@ module moveos_std::move_module { vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes); i = i + 1; }; - let remapped_bytes = remap_module_addresses_inner(bytes_vec, old_addresses, new_addresses); - // let remapped_bytes = remap_module_addresses_inner(bytes_vec); - let remapped_modules = vector::empty(); + let old_addresses = vector::singleton(old_address); + let new_addresses = vector::singleton(new_address); + + let rebinded_bytes = replace_address_identifiers(bytes_vec, old_addresses, new_addresses); + let rebinded_bytes = replace_addresses_constant(rebinded_bytes, old_addresses, new_addresses); + let rebinded_modules = vector::empty(); i = 0u64; - let len = vector::length(&remapped_bytes); + let len = vector::length(&rebinded_bytes); while (i < len) { - vector::push_back(&mut remapped_modules, MoveModule { - byte_codes: vector::pop_back(&mut remapped_bytes), + vector::push_back(&mut rebinded_modules, MoveModule { + byte_codes: vector::pop_back(&mut rebinded_bytes), }); i = i + 1; }; - vector::destroy_empty(remapped_bytes); - remapped_modules + vector::destroy_empty(rebinded_bytes); + rebinded_modules + } + + /// Binding given module's name to the new name + public fun binding_module_name( + modules: vector, + old_name: String, + new_name: String, + ): vector { + let bytes_vec = vector::empty>(); + let i = 0u64; + let len = vector::length(&modules); + while (i < len) { + vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes); + i = i + 1; + }; + let old_names = vector::singleton(old_name); + let new_names = vector::singleton(new_name); + + let rebinded_bytes = replace_identifiers(bytes_vec, old_names, new_names); + let rebinded_modules = vector::empty(); + i = 0u64; + let len = vector::length(&rebinded_bytes); + while (i < len) { + vector::push_back(&mut rebinded_modules, MoveModule { + byte_codes: vector::pop_back(&mut rebinded_bytes), + }); + i = i + 1; + }; + vector::destroy_empty(rebinded_bytes); + rebinded_modules } native fun module_name_inner(byte_codes: &vector): String; @@ -101,14 +129,28 @@ module moveos_std::move_module { native fun check_compatibililty_inner(new_bytecodes: vector, old_bytecodes: vector); - /// Native function to remap addresses in module binary where the length of - /// `old_addresses` must equal to that of `new_addresses`. - native fun remap_module_addresses_inner( + /// Native function to replace addresses identifier in module binary where the length of + /// `old_addresses` must equal to that of `new_addresses`. + native fun replace_address_identifiers( bytes: vector>, old_addresses: vector
, new_addresses: vector
, ): vector>; + /// Native function to replace the name identifier `old_name` to `new_name` in module binary. + native fun replace_identifiers( + bytes: vector>, + old_idents: vector, + new_idents: vector, + ): vector>; + + /// Native function to replace constant addresses in module binary where the length of + /// `old_addresses` must equal to that of `new_addresses`. + native fun replace_addresses_constant( + bytes: vector>, + old_addresses: vector
, + new_addresses: vector
, + ): vector>; #[test_only] use std::debug; @@ -168,9 +210,9 @@ module moveos_std::move_module { let module_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c7d08e9014006a902220acb02050cd002560da6030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c090002060801050106090007636f756e7465720f6163636f756e745f73746f7261676507636f6e7465787407436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000004200020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; let m: MoveModule = Self::new(module_bytes); let modules = vector::singleton(m); - let new_addresses = vector::singleton(addr); - let old_addresses = vector::singleton(@0x42); - let remapped_modules = Self::remap_module_addresses(modules, old_addresses, new_addresses); + let new_address = addr; + let old_address = @0x42; + let remapped_modules = Self::binding_module_address(modules, old_address, new_address); // In `sort_and_verify_modules`, addresses of modules are ensured to be the same with signer address // So if the remapping is failed, the verification will fail let (module_names, _module_names_with_init_fn) = Self::sort_and_verify_modules(&remapped_modules, addr); diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs index c89fdc7ef2..ce5752d754 100644 --- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs @@ -204,19 +204,9 @@ fn request_init_functions( let account_address = pop_arg!(args, AccountAddress); let module_context = context.extensions_mut().get_mut::(); for name_str in pop_arg!(args, Vec) { - let mut fields = name_str.value_as::()?.unpack()?; // std::string::String; - let val = fields.next().ok_or_else(|| { - PartialVMError::new(StatusCode::TYPE_RESOLUTION_FAILURE) - .with_message("There must have only one field".to_owned()) - })?; - let name_bytes = val.value_as::>()?; - cost += gas_params.per_byte * NumBytes::new(name_bytes.len() as u64); - let module_id = ModuleId::new( - account_address, - Identifier::from_utf8(name_bytes).map_err(|e| { - PartialVMError::new(StatusCode::TYPE_RESOLUTION_FAILURE).with_message(e.to_string()) - })?, - ); + let name_ident = unpack_string_to_identifier(name_str)?; + cost += gas_params.per_byte * NumBytes::new(1u64); + let module_id = ModuleId::new(account_address, name_ident); module_context.init_functions.insert(module_id); } Ok(NativeResult::ok(cost, smallvec![])) @@ -270,22 +260,22 @@ fn check_compatibililty_inner( } /*************************************************************************************************** - * native fun remap_module_addresses_inner( + * native fun replace_address_identifiers( * bytes: vector>, * old_addresses: vector
, * new_addresses: vector
, - * ): (vector, vector>); + * ): vector>; * Native function to remap addresses in module binary where the length of * `old_addresses` must equal to that of `new_addresses`. **************************************************************************************************/ #[derive(Debug, Clone)] -pub struct RemapAddressesGasParameters { +pub struct ReplaceAddressIdentifierGasParameters { pub base: InternalGas, pub per_byte: InternalGasPerByte, } -fn remap_module_addresses_inner( - gas_params: &RemapAddressesGasParameters, +fn replace_address_identifiers( + gas_params: &ReplaceAddressIdentifierGasParameters, _context: &mut NativeContext, _ty_args: Vec, mut args: VecDeque, @@ -321,39 +311,175 @@ fn remap_module_addresses_inner( cost += gas_params.per_byte * NumBytes::new(byte_codes.len() as u64); bundle.push(byte_codes); } - let mut compiled_modules = bundle + let output_modules = modify_modules(bundle, |module| { + module_replace_address_identifiers(module, &address_mapping) + })?; + Ok(NativeResult::ok(cost, smallvec![output_modules])) +} + +/*************************************************************************************************** + * native fun replace_addresses_constant( + * bytes: vector>, + * old_addresses: vector
, + * new_addresses: vector
, + * ): (vector, vector>); + * Native function to replace constant addresses in module binary where the length of + * `old_addresses` must equal to that of `new_addresses`. + **************************************************************************************************/ +#[derive(Debug, Clone)] +pub struct ReplaceAddressConstantGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + +fn replace_addresses_constant( + gas_params: &ReplaceAddressConstantGasParameters, + _context: &mut NativeContext, + _ty_args: Vec, + mut args: VecDeque, +) -> PartialVMResult { + debug_assert!(args.len() == 3, "Wrong number of arguments"); + let mut cost = gas_params.base; + let new_address_vec = pop_arg!(args, Vector); + let old_address_vec = pop_arg!(args, Vector); + let num_addresses = new_address_vec.elem_views().len(); + if num_addresses != old_address_vec.elem_views().len() { + return Ok(NativeResult::err( + cost, + moveos_types::move_std::error::invalid_argument(E_LENTH_NOT_MATCH), + )); + }; + let num_addresses = num_addresses as u64; + let new_addresses = new_address_vec.unpack(&Type::Address, num_addresses)?; + let old_addresses = old_address_vec.unpack(&Type::Address, num_addresses)?; + + let address_mapping: HashMap = + zip_eq(old_addresses, new_addresses) + .map(|(a, b)| { + Ok(( + a.value_as::()?, + b.value_as::()?, + )) + }) + .collect::>()?; + + let mut bundle = vec![]; + for module in pop_arg!(args, Vec) { + let byte_codes = module.value_as::>()?; + cost += gas_params.per_byte * NumBytes::new(byte_codes.len() as u64); + bundle.push(byte_codes); + } + let output_modules = modify_modules(bundle, |module| { + module_replace_constant_addresses(module, &address_mapping) + })?; + Ok(NativeResult::ok(cost, smallvec![output_modules])) +} + +/*************************************************************************************************** + * native fun replace_identifiers( + * bytes: vector>, + * old_idents: vector, + * new_idents: vector, + * ): vector>; + * Native function to replace the name identifier `old_idents` to `new_idents` in module binary. + **************************************************************************************************/ +#[derive(Debug, Clone)] +pub struct ReplaceIdentifierGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + +fn replace_identifiers( + gas_params: &ReplaceIdentifierGasParameters, + _context: &mut NativeContext, + _ty_args: Vec, + mut args: VecDeque, +) -> PartialVMResult { + debug_assert!(args.len() == 3, "Wrong number of arguments"); + let mut cost = gas_params.base; + + let new_identifiers = pop_arg!(args, Vec); + let old_identifiers = pop_arg!(args, Vec); + let num_identifiers = new_identifiers.len(); + if num_identifiers != old_identifiers.len() { + return Ok(NativeResult::err( + cost, + moveos_types::move_std::error::invalid_argument(E_LENTH_NOT_MATCH), + )); + }; + + let identifier_mapping: HashMap = + zip_eq(old_identifiers, new_identifiers) + .map(|(a, b)| { + Ok(( + unpack_string_to_identifier(a)?, + unpack_string_to_identifier(b)?, + )) + }) + .collect::>()?; + + let mut bundle = vec![]; + for module in pop_arg!(args, Vec) { + let byte_codes = module.value_as::>()?; + cost += gas_params.per_byte * NumBytes::new(byte_codes.len() as u64); + bundle.push(byte_codes); + } + let output_modules = modify_modules(bundle, |module| { + module_replace_identifiers(module, &identifier_mapping) + })?; + Ok(NativeResult::ok(cost, smallvec![output_modules])) +} + +fn modify_modules( + module_bundles: Vec>, + replace_fn: impl Fn(&mut CompiledModule) -> PartialVMResult<()>, +) -> PartialVMResult { + let mut compiled_modules = module_bundles .into_iter() .map(|b| CompiledModule::deserialize(&b)) .collect::>>()?; let mut remapped_bubdles = vec![]; - for m in compiled_modules.iter_mut() { - // TODO: charge gas - module_remap_addresses(m, &address_mapping)?; + for module in compiled_modules.iter_mut() { + replace_fn(module)?; let mut binary: Vec = vec![]; - m.serialize(&mut binary).map_err(|e| { + module.serialize(&mut binary).map_err(|e| { PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR).with_message(e.to_string()) })?; let value = Value::vector_u8(binary); remapped_bubdles.push(value); } let output_modules = Vector::pack(&Type::Vector(Box::new(Type::U8)), remapped_bubdles)?; - Ok(NativeResult::ok(cost, smallvec![output_modules])) + Ok(output_modules) } -fn module_remap_constant_addresses(value: &mut MoveValue, f: &dyn Fn(&mut AccountAddress)) { +fn movevalue_replace_addresses(value: &mut MoveValue, f: &dyn Fn(&mut AccountAddress)) { match value { MoveValue::Address(addr) => f(addr), MoveValue::Vector(vals) => { vals.iter_mut() - .for_each(|val| module_remap_constant_addresses(val, f)); + .for_each(|val| movevalue_replace_addresses(val, f)); } // TODO: handle constant addresses in Other struct _ => {} } } -fn module_remap_addresses( +fn module_replace_identifiers( + module: &mut CompiledModule, + identifier_mapping: &HashMap, +) -> PartialVMResult<()> { + for i in 0..module.identifiers.len() { + if let Some(new_ident) = identifier_mapping.get(&module.identifiers[i]) { + module.identifiers[i] = Identifier::new(new_ident.to_string()).map_err(|e| { + PartialVMError::new(StatusCode::TYPE_RESOLUTION_FAILURE).with_message(e.to_string()) + })?; + } + } + Ok(()) +} + +fn module_replace_address_identifiers( module: &mut CompiledModule, address_mapping: &HashMap, ) -> PartialVMResult<()> { @@ -363,6 +489,13 @@ fn module_remap_addresses( *addr = *new_addr; } } + Ok(()) +} + +fn module_replace_constant_addresses( + module: &mut CompiledModule, + address_mapping: &HashMap, +) -> PartialVMResult<()> { // replace addresses in constant. for constant in module.constant_pool.iter_mut() { let mut constant_value = constant.deserialize_constant().ok_or_else(|| { @@ -370,7 +503,7 @@ fn module_remap_addresses( .with_message("cannot deserialize constant".to_string()) })?; - module_remap_constant_addresses(&mut constant_value, &|addr| { + movevalue_replace_addresses(&mut constant_value, &|addr| { if let Some(new_addr) = address_mapping.get(addr) { *addr = *new_addr; } @@ -385,6 +518,19 @@ fn module_remap_addresses( Ok(()) } +/// Unpack input `std::string::String` to identifier. +fn unpack_string_to_identifier(value: Value) -> PartialVMResult { + let mut fields = value.value_as::()?.unpack()?; // std::string::String; + let val = fields.next().ok_or_else(|| { + PartialVMError::new(StatusCode::TYPE_RESOLUTION_FAILURE) + .with_message("There must have only one field".to_owned()) + })?; + let bytes = val.value_as::>()?; + let ident = Identifier::from_utf8(bytes).map_err(|e| { + PartialVMError::new(StatusCode::TYPE_RESOLUTION_FAILURE).with_message(e.to_string()) + })?; + Ok(ident) +} /*************************************************************************************************** * module * @@ -395,7 +541,9 @@ pub struct GasParameters { pub sort_and_verify_modules_inner: VerifyModulesGasParameters, pub request_init_functions: RequestInitFunctionsGasParameters, pub check_compatibililty_inner: CheckCompatibilityInnerGasParameters, - pub remap_module_addresses_inner: RemapAddressesGasParameters, + pub replace_address_identifiers: ReplaceAddressIdentifierGasParameters, + pub replace_addresses_constant: ReplaceAddressConstantGasParameters, + pub replace_identifiers: ReplaceIdentifierGasParameters, } impl GasParameters { @@ -417,7 +565,15 @@ impl GasParameters { base: 0.into(), per_byte: 0.into(), }, - remap_module_addresses_inner: RemapAddressesGasParameters { + replace_address_identifiers: ReplaceAddressIdentifierGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + replace_addresses_constant: ReplaceAddressConstantGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, + replace_identifiers: ReplaceIdentifierGasParameters { base: 0.into(), per_byte: 0.into(), }, @@ -450,12 +606,23 @@ pub fn make_all(gas_params: GasParameters) -> impl Iterator Date: Thu, 26 Oct 2023 21:18:56 +0800 Subject: [PATCH 2/6] add replace_bytes_constant and unit test --- .../src/natives/gas_parameter/move_module.rs | 2 + examples/publish_modules/sources/publish.move | 8 +- .../moveos-stdlib/doc/move_module.md | 127 +++++++++++++++++- .../moveos-stdlib/sources/move_module.move | 93 ++++++++++++- .../src/natives/moveos_stdlib/move_module.rs | 93 +++++++++++++ 5 files changed, 306 insertions(+), 17 deletions(-) diff --git a/crates/rooch-framework/src/natives/gas_parameter/move_module.rs b/crates/rooch-framework/src/natives/gas_parameter/move_module.rs index 8b528d7d26..f6756ead71 100644 --- a/crates/rooch-framework/src/natives/gas_parameter/move_module.rs +++ b/crates/rooch-framework/src/natives/gas_parameter/move_module.rs @@ -19,4 +19,6 @@ crate::natives::gas_parameter::native::define_gas_parameters_for_natives!(GasPar [.replace_addresses_constant.per_byte, "replace_addresses_constant.per_byte", (5 + 1) * MUL], [.replace_identifiers.base, "replace_identifiers.base", (5 + 1) * MUL], [.replace_identifiers.per_byte, "replace_identifiers.per_byte", (5 + 1) * MUL], + [.replace_bytes_constant.base, "replace_bytes_constant.base", (5 + 1) * MUL], + [.replace_bytes_constant.per_byte, "replace_bytes_constant.per_byte", (5 + 1) * MUL], ]); diff --git a/examples/publish_modules/sources/publish.move b/examples/publish_modules/sources/publish.move index e2ebcc1c8a..a7def98aeb 100644 --- a/examples/publish_modules/sources/publish.move +++ b/examples/publish_modules/sources/publish.move @@ -5,7 +5,7 @@ /// If the entry functions argument type is changed or the bytecode of the module is changed, and the tests are not updated, the tests will fail. /// Please update the tests as follows: /// 1. Compile the example/counter with `./target/debug/rooch move test -p examples/counter -d` -/// 2. Run the following command to get the bytecode of the compiled module: `xxd -c 0 -p examples/counter/build/counter/bytecode_modules/counter.mv` +/// 2. Run the following command to get the bytecode of the compiled module: `xxd -c 99999 -p examples/counter/build/counter/bytecode_modules/counter.mv` /// 3. Copy the bytecode of the compiled module from the output of the above command, and update the `module_bytes` variable in the tests below. module rooch_examples::publish { use std::vector; @@ -26,9 +26,9 @@ module rooch_examples::publish { // with account 0x42 let module_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c7d08e9014006a902220acb02050cd002560da6030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c090002060801050106090007636f756e7465720f6163636f756e745f73746f7261676507636f6e7465787407436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000004200020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; let modules = vector::singleton(move_module::new(module_bytes)); - let old_addresses = vector::singleton(@0x42); - let new_addresses = vector::singleton(signer::address_of(account)); - let remapped_modules = move_module::remap_module_addresses(modules, old_addresses, new_addresses); + let old_address = @0x42; + let new_address = signer::address_of(account); + let remapped_modules = move_module::binding_module_address(modules, old_address, new_address); account_storage::publish_modules(ctx, account, remapped_modules); } } diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md index b100aeeea1..8a43b6e9ce 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md @@ -13,8 +13,12 @@ - [Function `sort_and_verify_modules`](#0x2_move_module_sort_and_verify_modules) - [Function `check_comatibility`](#0x2_move_module_check_comatibility) - [Function `binding_module_address`](#0x2_move_module_binding_module_address) -- [Function `replace_module_name`](#0x2_move_module_replace_module_name) +- [Function `binding_module_name`](#0x2_move_module_binding_module_name) - [Function `request_init_functions`](#0x2_move_module_request_init_functions) +- [Function `replace_address_identifiers`](#0x2_move_module_replace_address_identifiers) +- [Function `replace_identifiers`](#0x2_move_module_replace_identifiers) +- [Function `replace_addresses_constant`](#0x2_move_module_replace_addresses_constant) +- [Function `replace_bytes_constant`](#0x2_move_module_replace_bytes_constant)
use 0x1::string;
@@ -259,14 +263,14 @@ Binding given module's address to the new address
 
 
- + -## Function `replace_module_name` +## Function `binding_module_name` -Binding given module's address to the new address +Binding given module's name to the new name -
public fun replace_module_name(modules: vector<move_module::MoveModule>, old_name: string::String, new_name: string::String): vector<move_module::MoveModule>
+
public fun binding_module_name(modules: vector<move_module::MoveModule>, old_name: string::String, new_name: string::String): vector<move_module::MoveModule>
 
@@ -275,7 +279,7 @@ Binding given module's address to the new address Implementation -
public fun replace_module_name(
+
public fun binding_module_name(
     modules: vector<MoveModule>,
     old_name: String,
     new_name: String,
@@ -332,4 +336,115 @@ account_address: address of all the modules
 
 
 
+
+
+
+
+## Function `replace_address_identifiers`
+
+Native function to replace addresses identifier in module binary where the length of
+old_addresses must equal to that of new_addresses.
+
+
+
public(friend) fun replace_address_identifiers(bytes: vector<vector<u8>>, old_addresses: vector<address>, new_addresses: vector<address>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
native public(friend) fun replace_address_identifiers(
+    bytes: vector<vector<u8>>,
+    old_addresses: vector<address>,
+    new_addresses: vector<address>,
+): vector<vector<u8>>;
+
+ + + +
+ + + +## Function `replace_identifiers` + +Native function to replace the name identifier old_name to new_name in module binary. + + +
public(friend) fun replace_identifiers(bytes: vector<vector<u8>>, old_idents: vector<string::String>, new_idents: vector<string::String>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
native public(friend) fun replace_identifiers(
+    bytes: vector<vector<u8>>,
+    old_idents: vector<String>,
+    new_idents: vector<String>,
+): vector<vector<u8>>;
+
+ + + +
+ + + +## Function `replace_addresses_constant` + +Native function to replace constant addresses in module binary where the length of +old_addresses must equal to that of new_addresses. + + +
public(friend) fun replace_addresses_constant(bytes: vector<vector<u8>>, old_addresses: vector<address>, new_addresses: vector<address>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
native public(friend) fun replace_addresses_constant(
+    bytes: vector<vector<u8>>,
+    old_addresses: vector<address>,
+    new_addresses: vector<address>,
+): vector<vector<u8>>;
+
+ + + +
+ + + +## Function `replace_bytes_constant` + +Native function to replace constant bytes in module binary where the length of +old_addresses must equal to that of new_addresses. + + +
public(friend) fun replace_bytes_constant(bytes: vector<vector<u8>>, old_bytes: vector<vector<u8>>, new_bytes: vector<vector<u8>>): vector<vector<u8>>
+
+ + + +
+Implementation + + +
native public(friend) fun replace_bytes_constant(
+    bytes: vector<vector<u8>>,
+    old_bytes: vector<vector<u8>>,
+    new_bytes: vector<vector<u8>>,
+): vector<vector<u8>>;
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move index fd349ba11f..bafe66f954 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move @@ -4,7 +4,6 @@ /// `move_module` provides some basic functions for handle Move module in Move. module moveos_std::move_module { use std::vector; - use std::error; use std::string::String; friend moveos_std::account_storage; @@ -131,14 +130,14 @@ module moveos_std::move_module { /// Native function to replace addresses identifier in module binary where the length of /// `old_addresses` must equal to that of `new_addresses`. - native fun replace_address_identifiers( + native public(friend) fun replace_address_identifiers( bytes: vector>, old_addresses: vector
, new_addresses: vector
, ): vector>; /// Native function to replace the name identifier `old_name` to `new_name` in module binary. - native fun replace_identifiers( + native public(friend) fun replace_identifiers( bytes: vector>, old_idents: vector, new_idents: vector, @@ -146,12 +145,20 @@ module moveos_std::move_module { /// Native function to replace constant addresses in module binary where the length of /// `old_addresses` must equal to that of `new_addresses`. - native fun replace_addresses_constant( + native public(friend) fun replace_addresses_constant( bytes: vector>, old_addresses: vector
, new_addresses: vector
, ): vector>; + /// Native function to replace constant bytes in module binary where the length of + /// `old_addresses` must equal to that of `new_addresses`. + native public(friend) fun replace_bytes_constant( + bytes: vector>, + old_bytes: vector>, + new_bytes: vector>, + ): vector>; + #[test_only] use std::debug; #[test_only] @@ -202,12 +209,17 @@ module moveos_std::move_module { } #[test(account=@0x1314)] - fun test_remap_address(account: &signer) { + fun test_binding_module_address(account: &signer) { let addr = signer::address_of(account); let ctx = context::new_test_context(addr); - // The following is the bytes and hex of the compiled module: example/counter/sources/counter.move - // with account 0x42 + // The following is the bytes and hex of the compiled module: + // example/counter/sources/counter.move with account 0x1314 + let ref_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c7d08e9014006a902220acb02050cd002560da6030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c090002060801050106090007636f756e7465720f6163636f756e745f73746f7261676507636f6e7465787407436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000131400000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000131400020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; + + // The following is the bytes and hex of the compiled module: + // example/counter/sources/counter.move with account 0x42 let module_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c7d08e9014006a902220acb02050cd002560da6030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c090002060801050106090007636f756e7465720f6163636f756e745f73746f7261676507636f6e7465787407436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000004200020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; + let m: MoveModule = Self::new(module_bytes); let modules = vector::singleton(m); let new_address = addr; @@ -216,8 +228,75 @@ module moveos_std::move_module { // In `sort_and_verify_modules`, addresses of modules are ensured to be the same with signer address // So if the remapping is failed, the verification will fail let (module_names, _module_names_with_init_fn) = Self::sort_and_verify_modules(&remapped_modules, addr); + + // compare the remapped modules bytes + let modified_bytes = vector::borrow(&remapped_modules, 0).byte_codes; + assert!(std::compare::cmp_bcs_bytes(&modified_bytes, &ref_bytes) == 0u8, 1); debug::print(&module_names); context::drop_test_context(ctx); } + + #[test(account=@0x42)] + fun test_replace_module_and_struct_name(account: &signer) { + let addr = signer::address_of(account); + let ctx = context::new_test_context(addr); + // The following is the bytes and hex of `my_counter` module with account 0x42 + // `my_counter` is from `example/counter/sources/counter.move` with the following modification: + // 1. module name: counter -> my_counter + // 2. struct name: MyCounter -> MyCounter + let ref_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c820108ee014006ae02220ad002050cd502560dab030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c09000206080105010609000a6d795f636f756e7465720f6163636f756e745f73746f7261676507636f6e74657874094d79436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000004200020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; + + // The following is the bytes and hex of the compiled module: + // example/counter/sources/counter.move with account 0x42 + let module_bytes: vector = x"a11ceb0b060000000b010006020608030e26043406053a32076c7d08e9014006a902220acb02050cd002560da6030200000101010200030c00020400000005000100000600010000070201000008030400010907080108010a09010108010b0a0b0108040605060606010708010002070801060c0106080101030107080001080002070801050107090003070801060c090002060801050106090007636f756e7465720f6163636f756e745f73746f7261676507636f6e7465787407436f756e74657207436f6e7465787408696e63726561736509696e6372656173655f04696e69740576616c756511676c6f62616c5f626f72726f775f6d75740e676c6f62616c5f6d6f76655f746f0d676c6f62616c5f626f72726f77000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000020520000000000000000000000000000000000000000000000000000000000000004200020108030001040001030b0011010201010000050d0b00070038000c010a01100014060100000000000000160b010f0015020200000001060b000b0106000000000000000012003801020301000001060b000700380210001402000000"; + + let modules = vector::singleton(module_bytes); + let new_names = vector::empty(); + vector::push_back(&mut new_names, std::string::utf8(b"my_counter")); + vector::push_back(&mut new_names, std::string::utf8(b"MyCounter")); + let old_names = vector::empty(); + vector::push_back(&mut old_names, std::string::utf8(b"counter")); + vector::push_back(&mut old_names, std::string::utf8(b"Counter")); + + let new_modules = Self::replace_identifiers(modules, old_names, new_names); + + // compare the remapped modules bytes + let modified_bytes = vector::borrow(&new_modules, 0); + assert!(std::compare::cmp_bcs_bytes(modified_bytes, &ref_bytes) == 0u8, 1); + + context::drop_test_context(ctx); + } + + + #[test(account=@0x42)] + fun test_replace_string_constant(account: &signer) { + let addr = signer::address_of(account); + let ctx = context::new_test_context(addr); + // The following is the bytes and hex of module with account 0x42 + // The module is from `examples/coins/sources/fixed_supply_coin.move` with the following modification: + // 1. constance string: "Fixed Supply Coin" -> "My Fixed Supply Coin" + // 2. constance string: "FSC" -> "MFSC" + let ref_bytes: vector = x"a11ceb0b060000000b010012021220033250048201140596017e079402bc0208d004800106d005640ab4060e0cc2067d0dbf070200000101020202030204020503060307030800090c00000a0800030b0000040f0e0100010810080007110001080101170700000c000100000d020100051204050002130708010804140a08010808150c0d010806160e01010c0118101100071912010108051a01130100071b140d0108081c0215010c081616010108021d1701010803060409050b060b080b090b0a0b0b0b0c0b0d0602070802060c000107080202050b0501080001060c010501080102070802050107090001080401070b03010900010800020708040f010b0501090003070802050b05010900030b050108000b030108040c010a02010806040708020806080602010c020708020f010b03010804020708040b0501090003070802060c09001166697865645f737570706c795f636f696e06737472696e670f6163636f756e745f73746f7261676507636f6e746578740a6f626a6563745f726566067369676e6572126163636f756e745f636f696e5f73746f726504636f696e0a636f696e5f73746f72650346534308547265617375727907436f6e746578740666617563657404696e69740b64756d6d795f6669656c64094f626a65637452656609436f696e53746f726504436f696e0a616464726573735f6f6611676c6f62616c5f626f72726f775f6d75740a626f72726f775f6d7574087769746864726177076465706f73697406537472696e6704757466380f72656769737465725f657874656e640d6d6f64756c655f7369676e65720b6d696e745f657874656e64116372656174655f636f696e5f73746f72650e676c6f62616c5f6d6f76655f746f00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030f2000b4f9e430000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000000420a0215144d7920466978656420537570706c7920436f696e0a0205044d4653430002010e01010201080b030108040001040003100b0111020c020a00070138000f0038014a102700000000000000000000000000000000000000000000000000000000000038020c030b000b020b03380302010000000f1a0a0007021107070311073101380438050c030a00070038060c010a0038070c020d0238010b0138080b000e030b021201380902010000"; + + // The following is the bytes and hex of the compiled module: + // `examples/coins/sources/fixed_supply_coin.move` with account 0x42 + let module_bytes: vector = x"a11ceb0b060000000b010012021220033250048201140596017e079402bc0208d004800106d005600ab0060e0cbe067d0dbb070200000101020202030204020503060307030800090c00000a0800030b0000040f0e0100010810080007110001080101170700000c000100000d020100051204050002130708010804140a08010808150c0d010806160e01010c0118101100071912010108051a01130100071b140d0108081c0215010c081616010108021d1701010803060409050b060b080b090b0a0b0b0b0c0b0d0602070802060c000107080202050b0501080001060c010501080102070802050107090001080401070b03010900010800020708040f010b0501090003070802050b05010900030b050108000b030108040c010a02010806040708020806080602010c020708020f010b03010804020708040b0501090003070802060c09001166697865645f737570706c795f636f696e06737472696e670f6163636f756e745f73746f7261676507636f6e746578740a6f626a6563745f726566067369676e6572126163636f756e745f636f696e5f73746f726504636f696e0a636f696e5f73746f72650346534308547265617375727907436f6e746578740666617563657404696e69740b64756d6d795f6669656c64094f626a65637452656609436f696e53746f726504436f696e0a616464726573735f6f6611676c6f62616c5f626f72726f775f6d75740a626f72726f775f6d7574087769746864726177076465706f73697406537472696e6704757466380f72656769737465725f657874656e640d6d6f64756c655f7369676e65720b6d696e745f657874656e64116372656174655f636f696e5f73746f72650e676c6f62616c5f6d6f76655f746f00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030f2000b4f9e430000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000000420a021211466978656420537570706c7920436f696e0a0204034653430002010e01010201080b030108040001040003100b0111020c020a00070138000f0038014a102700000000000000000000000000000000000000000000000000000000000038020c030b000b020b03380302010000000f1a0a0007021107070311073101380438050c030a00070038060c010a0038070c020d0238010b0138080b000e030b021201380902010000"; + + let modules = vector::singleton(module_bytes); + let new_bytes = vector::empty>(); + vector::push_back(&mut new_bytes, b"My Fixed Supply Coin"); + vector::push_back(&mut new_bytes, b"MFSC"); + let old_bytes = vector::empty>(); + vector::push_back(&mut old_bytes, b"Fixed Supply Coin"); + vector::push_back(&mut old_bytes, b"FSC"); + + let new_modules = Self::replace_bytes_constant(modules, old_bytes, new_bytes); + + // compare the remapped modules bytes + let modified_bytes = vector::borrow(&new_modules, 0); + assert!(std::compare::cmp_bcs_bytes(modified_bytes, &ref_bytes) == 0u8, 1); + + context::drop_test_context(ctx); + } } \ No newline at end of file diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs index ce5752d754..3be1e25107 100644 --- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs @@ -430,6 +430,55 @@ fn replace_identifiers( Ok(NativeResult::ok(cost, smallvec![output_modules])) } +/*************************************************************************************************** + * native public(friend) fun replace_bytes_constant( + * bytes: vector>, + * old_bytes: vector>, + * new_bytes: vector>, + * ): vector>; + * Native function to replace the name identifier `old_idents` to `new_idents` in module binary. + **************************************************************************************************/ +#[derive(Debug, Clone)] +pub struct ReplaceBytesConstantfierGasParameters { + pub base: InternalGas, + pub per_byte: InternalGasPerByte, +} + +fn replace_bytes_constant( + gas_params: &ReplaceBytesConstantfierGasParameters, + _context: &mut NativeContext, + _ty_args: Vec, + mut args: VecDeque, +) -> PartialVMResult { + debug_assert!(args.len() == 3, "Wrong number of arguments"); + let mut cost = gas_params.base; + + let new_bytes = pop_arg!(args, Vec); + let old_bytes = pop_arg!(args, Vec); + let num = new_bytes.len(); + if num != old_bytes.len() { + return Ok(NativeResult::err( + cost, + moveos_types::move_std::error::invalid_argument(E_LENTH_NOT_MATCH), + )); + }; + + let bytes_mapping: HashMap, Vec> = zip_eq(old_bytes, new_bytes) + .map(|(a, b)| Ok((a.value_as::>()?, b.value_as::>()?))) + .collect::>()?; + + let mut bundle = vec![]; + for module in pop_arg!(args, Vec) { + let byte_codes = module.value_as::>()?; + cost += gas_params.per_byte * NumBytes::new(byte_codes.len() as u64); + bundle.push(byte_codes); + } + let output_modules = modify_modules(bundle, |module| { + module_replace_constant_bytes(module, &bytes_mapping) + })?; + Ok(NativeResult::ok(cost, smallvec![output_modules])) +} + fn modify_modules( module_bundles: Vec>, replace_fn: impl Fn(&mut CompiledModule) -> PartialVMResult<()>, @@ -518,6 +567,41 @@ fn module_replace_constant_addresses( Ok(()) } +fn module_replace_constant_bytes( + module: &mut CompiledModule, + bytes_mapping: &HashMap, Vec>, +) -> PartialVMResult<()> { + // replace bytes in constant. + for constant in module.constant_pool.iter_mut() { + let constant_value = constant.deserialize_constant().ok_or_else(|| { + PartialVMError::new(StatusCode::VALUE_DESERIALIZATION_ERROR) + .with_message("cannot deserialize constant".to_string()) + })?; + + // match constant_value { + // MoveValue::Vector(vals) => MoveValue::vec_to_vec_u8(vals)?, + // } + if let MoveValue::Vector(vals) = constant_value { + match MoveValue::vec_to_vec_u8(vals) { + Ok(bytes) => { + if let Some(new_bytes) = bytes_mapping.get(&bytes) { + constant.data = MoveValue::vector_u8(new_bytes.clone()) + .simple_serialize() + .ok_or_else(|| { + PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) + .with_message("cannot serialize constant".to_string()) + })?; + } + } + Err(_) => { + // Inner type is not u8, just pass + } + } + } + } + Ok(()) +} + /// Unpack input `std::string::String` to identifier. fn unpack_string_to_identifier(value: Value) -> PartialVMResult { let mut fields = value.value_as::()?.unpack()?; // std::string::String; @@ -544,6 +628,7 @@ pub struct GasParameters { pub replace_address_identifiers: ReplaceAddressIdentifierGasParameters, pub replace_addresses_constant: ReplaceAddressConstantGasParameters, pub replace_identifiers: ReplaceIdentifierGasParameters, + pub replace_bytes_constant: ReplaceBytesConstantfierGasParameters, } impl GasParameters { @@ -577,6 +662,10 @@ impl GasParameters { base: 0.into(), per_byte: 0.into(), }, + replace_bytes_constant: ReplaceBytesConstantfierGasParameters { + base: 0.into(), + per_byte: 0.into(), + }, } } } @@ -623,6 +712,10 @@ pub fn make_all(gas_params: GasParameters) -> impl Iterator Date: Thu, 26 Oct 2023 22:06:14 +0800 Subject: [PATCH 3/6] fix --- .../src/commands/move_cli/commands/publish.rs | 1 - .../moveos-stdlib/doc/move_module.md | 55 +++++++++++++++---- .../moveos-stdlib/sources/move_module.move | 24 ++++++-- .../src/natives/moveos_stdlib/move_module.rs | 24 +++----- 4 files changed, 70 insertions(+), 34 deletions(-) diff --git a/crates/rooch/src/commands/move_cli/commands/publish.rs b/crates/rooch/src/commands/move_cli/commands/publish.rs index 733575503e..2801148ff3 100644 --- a/crates/rooch/src/commands/move_cli/commands/publish.rs +++ b/crates/rooch/src/commands/move_cli/commands/publish.rs @@ -90,7 +90,6 @@ impl CommandAction for Publish { let empty_modules = modules.iter_modules_owned().is_empty(); let pkg_address = if !empty_modules { let first_module = &modules.iter_modules_owned()[0]; - println!("compiled module: {:?}", first_module.clone()); first_module.self_id().address().to_owned() } else { return Err(RoochError::MoveCompilationError(format!( diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md index 8a43b6e9ce..7957882638 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md @@ -13,7 +13,8 @@ - [Function `sort_and_verify_modules`](#0x2_move_module_sort_and_verify_modules) - [Function `check_comatibility`](#0x2_move_module_check_comatibility) - [Function `binding_module_address`](#0x2_move_module_binding_module_address) -- [Function `binding_module_name`](#0x2_move_module_binding_module_name) +- [Function `replace_module_name`](#0x2_move_module_replace_module_name) +- [Function `replace_struct_name`](#0x2_move_module_replace_struct_name) - [Function `request_init_functions`](#0x2_move_module_request_init_functions) - [Function `replace_address_identifiers`](#0x2_move_module_replace_address_identifiers) - [Function `replace_identifiers`](#0x2_move_module_replace_identifiers) @@ -21,7 +22,8 @@ - [Function `replace_bytes_constant`](#0x2_move_module_replace_bytes_constant) -
use 0x1::string;
+
use 0x1::error;
+use 0x1::string;
 use 0x1::vector;
 
@@ -263,14 +265,14 @@ Binding given module's address to the new address - + -## Function `binding_module_name` +## Function `replace_module_name` -Binding given module's name to the new name +Replace given module's name to the new name -
public fun binding_module_name(modules: vector<move_module::MoveModule>, old_name: string::String, new_name: string::String): vector<move_module::MoveModule>
+
public fun replace_module_name(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
 
@@ -279,11 +281,15 @@ Binding given module's name to the new name Implementation -
public fun binding_module_name(
+
public fun replace_module_name(
     modules: vector<MoveModule>,
-    old_name: String,
-    new_name: String,
+    old_names: vector<String>,
+    new_names: vector<String>,
 ): vector<MoveModule> {
+    assert!(
+        vector::length(&old_names) == vector::length(&new_names),
+        error::invalid_argument(ErrorLengthNotMatch)
+    );
     let bytes_vec = vector::empty<vector<u8>>();
     let i = 0u64;
     let len = vector::length(&modules);
@@ -291,8 +297,6 @@ Binding given module's name to the new name
         vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes);
         i = i + 1;
     };
-    let old_names = vector::singleton(old_name);
-    let new_names = vector::singleton(new_name);
 
     let rebinded_bytes = replace_identifiers(bytes_vec, old_names, new_names);
     let rebinded_modules = vector::empty<MoveModule>();
@@ -311,6 +315,35 @@ Binding given module's name to the new name
 
 
 
+
+
+
+
+## Function `replace_struct_name`
+
+Replace given struct's name to the new name
+
+
+
public fun replace_struct_name(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
+
+ + + +
+Implementation + + +
public fun replace_struct_name(
+    modules: vector<MoveModule>,
+    old_names: vector<String>,
+    new_names: vector<String>,
+): vector<MoveModule> {
+    replace_module_name(modules, old_names, new_names)
+}
+
+ + +
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move index bafe66f954..57b637740d 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move @@ -4,6 +4,7 @@ /// `move_module` provides some basic functions for handle Move module in Move. module moveos_std::move_module { use std::vector; + use std::error; use std::string::String; friend moveos_std::account_storage; @@ -85,12 +86,16 @@ module moveos_std::move_module { rebinded_modules } - /// Binding given module's name to the new name - public fun binding_module_name( + /// Replace given module's name to the new name + public fun replace_module_name( modules: vector, - old_name: String, - new_name: String, + old_names: vector, + new_names: vector, ): vector { + assert!( + vector::length(&old_names) == vector::length(&new_names), + error::invalid_argument(ErrorLengthNotMatch) + ); let bytes_vec = vector::empty>(); let i = 0u64; let len = vector::length(&modules); @@ -98,8 +103,6 @@ module moveos_std::move_module { vector::push_back(&mut bytes_vec, vector::pop_back(&mut modules).byte_codes); i = i + 1; }; - let old_names = vector::singleton(old_name); - let new_names = vector::singleton(new_name); let rebinded_bytes = replace_identifiers(bytes_vec, old_names, new_names); let rebinded_modules = vector::empty(); @@ -115,6 +118,15 @@ module moveos_std::move_module { rebinded_modules } + /// Replace given struct's name to the new name + public fun replace_struct_name( + modules: vector, + old_names: vector, + new_names: vector, + ): vector { + replace_module_name(modules, old_names, new_names) + } + native fun module_name_inner(byte_codes: &vector): String; /// Sort modules by dependency order and then verify. diff --git a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs index 3be1e25107..b5bfe9b1d4 100644 --- a/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs +++ b/moveos/moveos-stdlib/src/natives/moveos_stdlib/move_module.rs @@ -578,23 +578,15 @@ fn module_replace_constant_bytes( .with_message("cannot deserialize constant".to_string()) })?; - // match constant_value { - // MoveValue::Vector(vals) => MoveValue::vec_to_vec_u8(vals)?, - // } if let MoveValue::Vector(vals) = constant_value { - match MoveValue::vec_to_vec_u8(vals) { - Ok(bytes) => { - if let Some(new_bytes) = bytes_mapping.get(&bytes) { - constant.data = MoveValue::vector_u8(new_bytes.clone()) - .simple_serialize() - .ok_or_else(|| { - PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) - .with_message("cannot serialize constant".to_string()) - })?; - } - } - Err(_) => { - // Inner type is not u8, just pass + if let Ok(bytes) = MoveValue::vec_to_vec_u8(vals) { + if let Some(new_bytes) = bytes_mapping.get(&bytes) { + constant.data = MoveValue::vector_u8(new_bytes.clone()) + .simple_serialize() + .ok_or_else(|| { + PartialVMError::new(StatusCode::VALUE_SERIALIZATION_ERROR) + .with_message("cannot serialize constant".to_string()) + })?; } } } From 9879de9dfb574584d1eebc1ad6e1161f57a0e50e Mon Sep 17 00:00:00 2001 From: 0xpause Date: Fri, 27 Oct 2023 06:55:52 +0800 Subject: [PATCH 4/6] update function name --- .../moveos-stdlib/sources/move_module.move | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move index 57b637740d..516ac6dde7 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move +++ b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move @@ -86,8 +86,8 @@ module moveos_std::move_module { rebinded_modules } - /// Replace given module's name to the new name - public fun replace_module_name( + /// Replace given module's identifier to the new ones + public fun replace_module_identiner ( modules: vector, old_names: vector, new_names: vector, @@ -118,13 +118,13 @@ module moveos_std::move_module { rebinded_modules } - /// Replace given struct's name to the new name - public fun replace_struct_name( + /// Replace given struct's identifier to the new ones + public fun replace_struct_identifier( modules: vector, old_names: vector, new_names: vector, ): vector { - replace_module_name(modules, old_names, new_names) + replace_module_identiner(modules, old_names, new_names) } native fun module_name_inner(byte_codes: &vector): String; From a98173fb205229b06ce248379f99f0928d9b2953 Mon Sep 17 00:00:00 2001 From: 0xpause Date: Fri, 27 Oct 2023 20:18:47 +0800 Subject: [PATCH 5/6] update doc --- .../moveos-stdlib/doc/move_module.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md index 7957882638..b50645d24b 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md @@ -13,8 +13,8 @@ - [Function `sort_and_verify_modules`](#0x2_move_module_sort_and_verify_modules) - [Function `check_comatibility`](#0x2_move_module_check_comatibility) - [Function `binding_module_address`](#0x2_move_module_binding_module_address) -- [Function `replace_module_name`](#0x2_move_module_replace_module_name) -- [Function `replace_struct_name`](#0x2_move_module_replace_struct_name) +- [Function `replace_module_identiner`](#0x2_move_module_replace_module_identiner) +- [Function `replace_struct_identifier`](#0x2_move_module_replace_struct_identifier) - [Function `request_init_functions`](#0x2_move_module_request_init_functions) - [Function `replace_address_identifiers`](#0x2_move_module_replace_address_identifiers) - [Function `replace_identifiers`](#0x2_move_module_replace_identifiers) @@ -265,14 +265,14 @@ Binding given module's address to the new address - + -## Function `replace_module_name` +## Function `replace_module_identiner` -Replace given module's name to the new name +Replace given module's identifier to the new ones -
public fun replace_module_name(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
+
public fun replace_module_identiner(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
 
@@ -281,7 +281,7 @@ Replace given module's name to the new name Implementation -
public fun replace_module_name(
+
public fun replace_module_identiner (
     modules: vector<MoveModule>,
     old_names: vector<String>,
     new_names: vector<String>,
@@ -317,14 +317,14 @@ Replace given module's name to the new name
 
 
 
-
+
 
-## Function `replace_struct_name`
+## Function `replace_struct_identifier`
 
-Replace given struct's name to the new name
+Replace given struct's identifier to the new ones
 
 
-
public fun replace_struct_name(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
+
public fun replace_struct_identifier(modules: vector<move_module::MoveModule>, old_names: vector<string::String>, new_names: vector<string::String>): vector<move_module::MoveModule>
 
@@ -333,12 +333,12 @@ Replace given struct's name to the new name Implementation -
public fun replace_struct_name(
+
public fun replace_struct_identifier(
     modules: vector<MoveModule>,
     old_names: vector<String>,
     new_names: vector<String>,
 ): vector<MoveModule> {
-    replace_module_name(modules, old_names, new_names)
+    replace_module_identiner(modules, old_names, new_names)
 }
 
From 7f601982ab49963d4810456138a5b5318edf8ebb Mon Sep 17 00:00:00 2001 From: 0xpause Date: Fri, 27 Oct 2023 20:55:22 +0800 Subject: [PATCH 6/6] fix typo --- moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md | 2 +- moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md index b50645d24b..65322e2fca 100644 --- a/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md +++ b/moveos/moveos-stdlib/moveos-stdlib/doc/move_module.md @@ -459,7 +459,7 @@ Native function to replace constant addresses in module binary where the length ## Function `replace_bytes_constant` Native function to replace constant bytes in module binary where the length of -old_addresses must equal to that of new_addresses. +old_bytes must equal to that of new_bytes.
public(friend) fun replace_bytes_constant(bytes: vector<vector<u8>>, old_bytes: vector<vector<u8>>, new_bytes: vector<vector<u8>>): vector<vector<u8>>
diff --git a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move
index 516ac6dde7..8a789ec3df 100644
--- a/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move
+++ b/moveos/moveos-stdlib/moveos-stdlib/sources/move_module.move
@@ -164,7 +164,7 @@ module moveos_std::move_module {
     ): vector>;
 
     /// Native function to replace constant bytes in module binary where the length of
-    /// `old_addresses` must equal to that of `new_addresses`.    
+    /// `old_bytes` must equal to that of `new_bytes`.    
     native public(friend) fun replace_bytes_constant(
         bytes: vector>,
         old_bytes: vector>,