diff --git a/Cargo.toml b/Cargo.toml index ad11350c..5880c385 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,3 @@ members = [ [profile.release] panic = 'unwind' rpath = false -# opt size: -# lto = "thin" -# opt-level = 's' diff --git a/pallets/sp-mvm/Cargo.toml b/pallets/sp-mvm/Cargo.toml index 1fb2a145..e0610150 100644 --- a/pallets/sp-mvm/Cargo.toml +++ b/pallets/sp-mvm/Cargo.toml @@ -65,6 +65,7 @@ orml-traits = { default-features = false, git = 'https://github.com/open-web3-st # serde is for lcs/bcs only # used for benchmarking (runtime, std, no-std) serde-alt = { version = "1", default-features = false, package = "alt_serde", features = ["derive", "alloc"], optional = true } + [dependencies.bcs-alt] package = "bcs" default-features = false diff --git a/pallets/sp-mvm/src/lib.rs b/pallets/sp-mvm/src/lib.rs index af5861c4..6273eba3 100644 --- a/pallets/sp-mvm/src/lib.rs +++ b/pallets/sp-mvm/src/lib.rs @@ -104,7 +104,7 @@ pub mod pallet { type GasWeightMapping: gas::GasWeightMapping; /// The AccountId that can perform a standard library update or deploy module under 0x address. - type UpdaterOrigin: EnsureOrigin; + type UpdateOrigin: EnsureOrigin; /// Describes weights for Move VM extrinsics. type WeightInfo: WeightInfo; @@ -165,9 +165,9 @@ pub mod pallet { /// [account] ModulePublished(T::AccountId), - /// Event about successful move-module publishing + /// Event about successful move-package published /// [account] - StdModulePublished, + PackagePublished(T::AccountId), } // Dispatchable functions allows users to interact with the pallet and invoke state changes. @@ -220,17 +220,18 @@ pub mod pallet { module_bc: Vec, gas_limit: u64, ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - debug!("executing `publish` with signed {:?}", who); + // Allows to update Standard Library if root. + let (sender, signer) = Self::ensure_and_convert(origin)?; + debug!("executing `publish module` with signed {:?}", sender); // Publish module. - let vm_result = Self::raw_publish_module(&who, module_bc, gas_limit, false)?; + let vm_result = Self::raw_publish_module(&signer, module_bc, gas_limit, false)?; // produce result with spended gas: let result = result::from_vm_result::(vm_result)?; // Emit an event: - Self::deposit_event(Event::ModulePublished(who)); + Self::deposit_event(Event::ModulePublished(signer)); Ok(result) } @@ -252,17 +253,8 @@ pub mod pallet { gas_limit: u64, ) -> DispatchResultWithPostInfo { // Allows to update Standard Library if root. - let sender = match T::UpdaterOrigin::ensure_origin(origin.clone()) { - Ok(_) => { - debug!("executing `publish package` with root"); - CORE_CODE_ADDRESS - } - Err(_) => { - let signer = ensure_signed(origin)?; - debug!("executing `publish package` with signed {:?}", signer); - addr::account_to_account_address(&signer) - } - }; + let (sender, signer) = Self::ensure_and_convert(origin)?; + debug!("executing `publish package` with signed {:?}", sender); let vm = Self::get_vm()?; let gas = Self::get_move_gas_limit(gas_limit)?; @@ -278,6 +270,9 @@ pub mod pallet { // produce result with spended gas: let result = result::from_vm_result::(vm_result)?; + // Emit an event: + Self::deposit_event(Event::PackagePublished(signer)); + Ok(result) } } @@ -464,6 +459,25 @@ pub mod pallet { Ok(res) } + /// Ensures origin is root or signed and returns account id with associated move-address. + pub fn ensure_and_convert( + origin: OriginFor, + ) -> Result<(AccountAddress, T::AccountId), Error> { + // Allows to update Standard Library if root. + match T::UpdateOrigin::ensure_origin(origin.clone()) { + Ok(_) => { + let signer = addr::address_to_account(&CORE_CODE_ADDRESS) + .map_err(|_| Error::::AccountAddressConversionError)?; + Ok((CORE_CODE_ADDRESS, signer)) + } + Err(_) => { + let signer = + ensure_signed(origin).map_err(|_| Error::::InvalidSignature)?; + Ok((addr::account_to_account_address(&signer), signer)) + } + } + } + /// Publish Move module script with provided account, module bytecode, gas limit, and dry run configuration. /// In case of dry run nothing would be written to storage after execution (required mostly by RPC calls, e.g. estimate gas etc). pub fn raw_publish_module( @@ -609,6 +623,8 @@ pub mod pallet { TransactionValidationError, /// Transaction signers num isn't eq signers TransactionSignersNumError, + /// AccountAddress conversion error. + AccountAddressConversionError, /// Transaction is not allowed. TransactionIsNotAllowedError, diff --git a/pallets/sp-mvm/tests/balances.rs b/pallets/sp-mvm/tests/balances.rs index 28aec3b7..76d01d5a 100644 --- a/pallets/sp-mvm/tests/balances.rs +++ b/pallets/sp-mvm/tests/balances.rs @@ -199,7 +199,7 @@ fn transfer_vested_fails() { result, DispatchError::Module { index: 6, - error: 154, + error: 155, message: Some("Aborted") } ); @@ -233,7 +233,7 @@ fn transfer_token_vested_fails() { result, DispatchError::Module { index: 6, - error: 154, + error: 155, message: Some("Aborted") } ); diff --git a/pallets/sp-mvm/tests/common/mock.rs b/pallets/sp-mvm/tests/common/mock.rs index 55bf28be..c2ff9246 100644 --- a/pallets/sp-mvm/tests/common/mock.rs +++ b/pallets/sp-mvm/tests/common/mock.rs @@ -227,7 +227,7 @@ parameter_types! { impl sp_mvm::Config for Test { type Event = Event; type GasWeightMapping = MoveVMGasWeightMapping; - type UpdaterOrigin = EnsureRoot; + type UpdateOrigin = EnsureRoot; type PalletId = MVMPalletId; type CurrencyId = CurrencyId; type Currencies = Currencies; diff --git a/pallets/sp-mvm/tests/common/utils.rs b/pallets/sp-mvm/tests/common/utils.rs index 1631b83e..4d17e384 100644 --- a/pallets/sp-mvm/tests/common/utils.rs +++ b/pallets/sp-mvm/tests/common/utils.rs @@ -9,6 +9,7 @@ use move_core_types::language_storage::StructTag; use move_core_types::language_storage::TypeTag; use move_vm::io::state::State; use move_vm::types::ModulePackage; +use move_core_types::language_storage::CORE_CODE_ADDRESS; use move_core_types::resolver::ModuleResolver; use move_core_types::resolver::ResourceResolver; @@ -41,6 +42,21 @@ pub fn publish_module_unchecked( Mvm::publish_module(Origin::signed(signer), module.bytes().to_vec(), gas_limit) } +/// Publish module as root __without__ storage check +pub fn publish_module_as_root_unchecked(module: &Asset, gas_limit: Option) -> PsResult { + let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); + Mvm::publish_module(Origin::root(), module.bytes().to_vec(), gas_limit) +} + +/// Publish module as root __with__ storage check +pub fn publish_module_as_root(module: &Asset, gas_limit: Option) -> PsResult { + let bytecode = module.bytes().to_vec(); + let name = module.name(); + let result = publish_module_as_root_unchecked(module, gas_limit)?; + check_storage_module(CORE_CODE_ADDRESS, bytecode, name); + Ok(result) +} + /// Publish package. /// /// Publish package __with__ storage check @@ -52,7 +68,22 @@ pub fn publish_package(signer: AccountId, package: &Package, gas_limit: Option) -> PsResult { + let bytecode = package.bytes().to_vec(); + let names = package.modules(); + let result = publish_package_unchecked_as_root(package, gas_limit)?; + check_storage_package(CORE_CODE_ADDRESS, bytecode, names); + Ok(result) +} + +/// Publish package as root __without__ storage checks. +pub fn publish_package_unchecked_as_root(package: &Package, gas_limit: Option) -> PsResult { + let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); + Mvm::publish_package(Origin::root(), package.bytes().to_vec(), gas_limit) +} + +/// Publish package __without__ storage check pub fn publish_package_unchecked( signer: AccountId, package: &Package, diff --git a/pallets/sp-mvm/tests/gas.rs b/pallets/sp-mvm/tests/gas.rs index 1ee2f620..89b83eef 100644 --- a/pallets/sp-mvm/tests/gas.rs +++ b/pallets/sp-mvm/tests/gas.rs @@ -6,7 +6,7 @@ use common::mock::*; use common::addr::*; use common::utils; -const OUT_OF_GAS_ERROR_CODE: u8 = 149; +const OUT_OF_GAS_ERROR_CODE: u8 = 150; const MINIMAL_GAS_LIMIT: u64 = 1; /// Check status == out of gas diff --git a/pallets/sp-mvm/tests/std.rs b/pallets/sp-mvm/tests/std.rs index 28642268..d80adbc6 100644 --- a/pallets/sp-mvm/tests/std.rs +++ b/pallets/sp-mvm/tests/std.rs @@ -13,8 +13,16 @@ use common::addr::*; use common::utils; #[test] -/// publish modules personally as root -fn publish_module() { +/// publish modules personally as root unchecked +fn publish_module_as_root() { + new_test_ext().execute_with(|| { + utils::publish_module_as_root(&modules::root::EVENT_PROXY, None).unwrap(); + }); +} + +#[test] +/// publish modules personally as root (ps) +fn publish_module_as_root_ps() { new_test_ext().execute_with(|| { let root = root_ps_acc(); utils::publish_module(root, &modules::root::EVENT_PROXY, None).unwrap(); @@ -68,7 +76,7 @@ fn execute_script_as_root() { result, DispatchError::Module { index: 6, - error: 6, + error: 7, message: Some("TransactionIsNotAllowedError") } ); @@ -76,8 +84,8 @@ fn execute_script_as_root() { } #[test] -/// publish package as root -fn publish_package_as_root() { +/// publish package as root (ps) +fn publish_package_as_root_ps() { new_test_ext().execute_with(|| { let package = &ROOT_PACKAGE; let root = root_ps_acc(); @@ -86,6 +94,16 @@ fn publish_package_as_root() { }); } +/// publish package as root. +#[test] +fn publish_package_as_root() { + new_test_ext().execute_with(|| { + let package = &ROOT_PACKAGE; + + utils::publish_package_as_root(package, None).unwrap(); + }); +} + #[test] /// publish package as origin fn publish_package_as_origin() { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4c2993b8..15724998 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -823,7 +823,7 @@ impl sp_mvm::Config for Runtime { type GasWeightMapping = MoveVMGasWeightMapping; /// Only sudo can deploy modules under 0x or update standard library. - type UpdaterOrigin = EnsureRoot; + type UpdateOrigin = EnsureRoot; /// Pallet Id. type PalletId = MVMPalletId; diff --git a/runtime/src/tests/mvm.rs b/runtime/src/tests/mvm.rs index d26d8a39..b888ce5a 100644 --- a/runtime/src/tests/mvm.rs +++ b/runtime/src/tests/mvm.rs @@ -164,7 +164,7 @@ fn transfer_vested_balance_fails() { ), DispatchError::Module { index: 67, - error: 154, + error: 155, message: Some("Aborted") }, );