From bfb0f1f408bb114fc11cdcb406d08405eb165566 Mon Sep 17 00:00:00 2001 From: Michael Eberhardt <64731211+neutrinoks@users.noreply.github.com> Date: Sun, 19 May 2024 21:29:17 +0400 Subject: [PATCH] feat: update extrinsic call weights --- .../move-projects/developer-bundle/Move.toml | 11 ++ .../developer-bundle/sources/CarWash.move | 97 +++++++++++++ .../developer-bundle/sources/Dorm.move | 70 +++++++++ .../developer-bundle/sources/EmptyBob.move | 4 + .../assets/move-projects/smove-build-all.sh | 1 + pallet/src/benchmarking.rs | 18 ++- pallet/src/lib.rs | 8 +- pallet/src/weights.rs | 136 ++++++------------ 8 files changed, 242 insertions(+), 103 deletions(-) create mode 100644 pallet/src/assets/move-projects/developer-bundle/Move.toml create mode 100644 pallet/src/assets/move-projects/developer-bundle/sources/CarWash.move create mode 100644 pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move create mode 100644 pallet/src/assets/move-projects/developer-bundle/sources/EmptyBob.move diff --git a/pallet/src/assets/move-projects/developer-bundle/Move.toml b/pallet/src/assets/move-projects/developer-bundle/Move.toml new file mode 100644 index 0000000..c81ba6c --- /dev/null +++ b/pallet/src/assets/move-projects/developer-bundle/Move.toml @@ -0,0 +1,11 @@ +[package] +name = "developer-bundle" +version = "0.0.0" + +[dependencies] +MoveStdlib = { git = "https://github.com/eigerco/move-stdlib", rev = "main" } +SubstrateStdlib = { git = "https://github.com/eigerco/substrate-stdlib.git", rev = "main" } + +[addresses] +std = "0x1" +DeveloperBob = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" diff --git a/pallet/src/assets/move-projects/developer-bundle/sources/CarWash.move b/pallet/src/assets/move-projects/developer-bundle/sources/CarWash.move new file mode 100644 index 0000000..24ed654 --- /dev/null +++ b/pallet/src/assets/move-projects/developer-bundle/sources/CarWash.move @@ -0,0 +1,97 @@ +/// Not a perfect but simple example, for usage in tutorial only! +module DeveloperBob::CarWash { + use std::signer; + use substrate::balance; + + /// Address of the owner of this module. + const MODULE_OWNER: address = @DeveloperBob; + + /// Simple solution, fixed price for one washing coin. + const COIN_PRICE: u128 = 1000000000000; // equals 1 UNIT + + /// Error codes + const NOT_MODULE_OWNER: u64 = 0; + const MODULE_NOT_INITIALIZED: u64 = 1; + const MODULE_ALREADY_INITIALIZED: u64 = 2; + const USER_ALREADY_EXISTS: u64 = 3; + const USER_DOES_NOT_EXIST: u64 = 4; + const NO_COINS_AVAILABLE: u64 = 5; + const COIN_LIMIT_REACHED: u64 = 6; + const NOT_ENOUGH_COINS_AVAILABLE: u64 = 7; + + /// Struct stores number of coins for each user. + struct Balance has key, store { + coins: u8 + } + + /// Method executes the ICO without money. The module owner (also car wash owner) gets deposited the minted washing coins. + public fun initial_coin_minting(module_owner: &signer) { + // Only the owner of the module can initialize this module + assert!(signer::address_of(module_owner) == MODULE_OWNER, NOT_MODULE_OWNER); + + // Do not initialize the module twice! + assert!(!exists(signer::address_of(module_owner)), MODULE_ALREADY_INITIALIZED); + + // Deposit maximum number of coins to module owner's account. + move_to(module_owner, Balance { coins: 255 }); + } + + /// Registers a new user. The account address will be added to the storage Balance with zero initial washing coins. + public fun register_new_user(account: &signer) { + // Verify user does not already exist. + assert!(!exists(signer::address_of(account)), USER_ALREADY_EXISTS); + + // Store new account with zero coins to storage. + move_to(account, Balance { coins: 0 }); + } + + /// Buys `count` washing coin(s) for the car wash. Therfore, `COIN_PRICE` * `count` will be withdrawn from the user's account. + public fun buy_coin(user: &signer, count: u8) acquires Balance { + // Verify, module has been initialized. + assert!(exists(MODULE_OWNER), MODULE_NOT_INITIALIZED); + + // Verify, that this user does exist / is registered. + assert!(exists(signer::address_of(user)), USER_DOES_NOT_EXIST); + + // Verify, that enough coins are available. + let coins = borrow_global(MODULE_OWNER).coins; + assert!(coins >= count, NOT_ENOUGH_COINS_AVAILABLE); + + // Transfer coin price * count from user to car-wash-and-module-owner + balance::transfer(user, MODULE_OWNER, (count as u128)*COIN_PRICE); + + // After success, we deposit `count` more washing coin(s) at the user's account. + transfer_coin(MODULE_OWNER, signer::address_of(user), count); + } + + /// Initiates the washing process by paying one washing coin. + public fun wash_car(user: &signer) acquires Balance { + let user_addr = signer::address_of(user); + + // Verify, that user is registerd / exists. + assert!(exists(user_addr), USER_DOES_NOT_EXIST); + + // Successful transfer of one coin will automatically start the washing process. + transfer_coin(user_addr, MODULE_OWNER, 1); + } + + /// Generic coin transfer function. Transfers `count` washing coin(s). + /// Requires both accounts to exist! For module internal usage only! + fun transfer_coin(src: address, dst: address, count: u8) acquires Balance { + // Check that source account has at least `count` washing coin. + let coins_src = borrow_global(src).coins; + assert!(coins_src >= count, NO_COINS_AVAILABLE); + + // Check that the destination will have less than the maximum number of coins. + let coins_dst = borrow_global(dst).coins; + assert!(coins_dst + count <= 255, COIN_LIMIT_REACHED); + + // Withdraw `count` washing coin(s). + let coins_ref = &mut borrow_global_mut(src).coins; + *coins_ref = coins_src - count; + + // Deposit `count` washing coin(s). + let coins_ref = &mut borrow_global_mut(dst).coins; + *coins_ref = coins_dst + count; + } +} diff --git a/pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move b/pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move new file mode 100644 index 0000000..33f3518 --- /dev/null +++ b/pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move @@ -0,0 +1,70 @@ +/// Bob's dorm. He offers several hireable flats / apartments for student groups. +module DeveloperBob::Dorm { + use std::signer; + use std::vector; + use substrate::balance; + + /// Address of the owner of this module. + const MODULE_OWNER: address = @DeveloperBob; + + /// Simple solution, fixed price for a flat per month. + const FLAT_PRICE_PM: u128 = 90000000000000; // equals 90 UNIT + + /// Error codes. + const NOT_MODULE_OWNER: u64 = 0; + const MODULE_NOT_INITIALIZED: u64 = 1; + const MODULE_ALREADY_INITIALIZED: u64 = 2; + const NOT_ENOUGH_MONEY: u64 = 3; + + /// Group of students, which rent a flat together. + struct Group has store { + list: vector
+ } + + /// All tenant groups will be registered here. + struct Dorm has key { + groups: vector + } + + /// Initialization method for module owner. + public fun init_module(module_owner: &signer) { + assert!(signer::address_of(module_owner) == MODULE_OWNER, NOT_MODULE_OWNER); + assert!(!exists(signer::address_of(module_owner)), MODULE_ALREADY_INITIALIZED); + move_to(module_owner, Dorm { groups: vector::empty() }); + } + + /// Creates a new tenant group and signs a rental agreement. + public fun rent_apartment( + student1: &signer, + student2: &signer, + student3: &signer, + months: u8) acquires Dorm + { + assert!(exists(MODULE_OWNER), MODULE_NOT_INITIALIZED); + + // Check that all of the students have enough money. + let per_person = FLAT_PRICE_PM * (months as u128) / 3; + + let address1 = signer::address_of(student1); + let address2 = signer::address_of(student2); + let address3 = signer::address_of(student3); + + assert!(balance::cheque_amount(address1) >= per_person, NOT_ENOUGH_MONEY); + assert!(balance::cheque_amount(address2) >= per_person, NOT_ENOUGH_MONEY); + assert!(balance::cheque_amount(address3) >= per_person, NOT_ENOUGH_MONEY); + + // Transfer the money and register the new tenant group. + balance::transfer(student1, MODULE_OWNER, per_person); + balance::transfer(student2, MODULE_OWNER, per_person); + balance::transfer(student3, MODULE_OWNER, per_person); + + let list = vector::empty
(); + vector::push_back(&mut list, address1); + vector::push_back(&mut list, address2); + vector::push_back(&mut list, address3); + let group = Group { list: list }; + + let groups_ref = &mut borrow_global_mut(MODULE_OWNER).groups; + vector::push_back(groups_ref, group); + } +} diff --git a/pallet/src/assets/move-projects/developer-bundle/sources/EmptyBob.move b/pallet/src/assets/move-projects/developer-bundle/sources/EmptyBob.move new file mode 100644 index 0000000..441c46c --- /dev/null +++ b/pallet/src/assets/move-projects/developer-bundle/sources/EmptyBob.move @@ -0,0 +1,4 @@ +module DeveloperBob::EmptyBob { + struct EmptyStruct { + } +} diff --git a/pallet/src/assets/move-projects/smove-build-all.sh b/pallet/src/assets/move-projects/smove-build-all.sh index b1f53c4..07c2905 100755 --- a/pallet/src/assets/move-projects/smove-build-all.sh +++ b/pallet/src/assets/move-projects/smove-build-all.sh @@ -14,6 +14,7 @@ build_dir=( "signer-scripts" ) bundle_dir=( + "developer-bundle", "prohibited-bundle" "testing-move-stdlib" "testing-substrate-stdlib" diff --git a/pallet/src/benchmarking.rs b/pallet/src/benchmarking.rs index cbb7e35..a5f3c06 100644 --- a/pallet/src/benchmarking.rs +++ b/pallet/src/benchmarking.rs @@ -1,8 +1,6 @@ //! Benchmarking setup for pallet-move. use frame_benchmarking::v2::*; -// #[cfg(test)] -// use frame_benchmarking::v2::test; use frame_system::{Config as SysConfig, RawOrigin}; use move_vm_backend::types::MAX_GAS_AMOUNT; use pallet_balances::{Config as BalancesConfig, Pallet as Balances}; @@ -169,12 +167,22 @@ mod benchmarks { } #[benchmark] - fn publish_module_bundle() { + fn publish_module_bundle(n: Linear<0, 1>) { let bob_32 = utils::account::(utils::BOB_ADDR); - let bundle = core::include_bytes!("assets/move-projects/using_stdlib_natives/build/using_stdlib_natives/bundles/using_stdlib_natives.mvb").to_vec(); + + let bundles = [ + core::include_bytes!("assets/move-projects/using_stdlib_natives/build/using_stdlib_natives/bundles/using_stdlib_natives.mvb").to_vec(), + core::include_bytes!("assets/move-projects/developer-bundle/build/developer-bundle/bundles/developer-bundle.mvb").to_vec(), + ]; + + let gas = [528, 1500]; #[extrinsic_call] - publish_module_bundle(RawOrigin::Signed(bob_32), bundle, 1_500_000); + publish_module_bundle( + RawOrigin::Signed(bob_32), + bundles[n as usize].clone(), + gas[n as usize], + ); } #[benchmark] diff --git a/pallet/src/lib.rs b/pallet/src/lib.rs index 931159e..8ff0632 100644 --- a/pallet/src/lib.rs +++ b/pallet/src/lib.rs @@ -35,7 +35,7 @@ pub mod weight_info { pub trait WeightInfo { fn execute(gas: u32) -> Weight; fn publish_module(gas: u32) -> Weight; - fn publish_module_bundle() -> Weight; + fn publish_module_bundle(gas: u32) -> Weight; fn update_stdlib_bundle() -> Weight; } } @@ -383,7 +383,7 @@ pub mod pallet { /// Bundle is just a set of multiple modules. // TODO(eiger) in M3: ensure the weight depends on basic extrinsic cost + gas_limit #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::publish_module_bundle())] + #[pallet::weight(T::WeightInfo::publish_module_bundle(*gas_limit as u32))] pub fn publish_module_bundle( origin: OriginFor, bundle: Vec, @@ -672,7 +672,9 @@ pub mod pallet { Ok(MoveApiEstimation { vm_status_code: vm_result.status_code.into(), gas_used: vm_result.gas_used, - total_weight_including_gas_used: T::WeightInfo::publish_module_bundle(), + total_weight_including_gas_used: T::WeightInfo::publish_module_bundle( + vm_result.gas_used as u32, + ), }) } diff --git a/pallet/src/weights.rs b/pallet/src/weights.rs index ff93d12..ee0beef 100644 --- a/pallet/src/weights.rs +++ b/pallet/src/weights.rs @@ -1,10 +1,10 @@ //! Autogenerated weights for `pallet_move` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-04-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-05-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `michaelardtsMBP`, CPU: `` +//! HOSTNAME: `michaeleberhardts-MacBook-Pro.local`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 // Executed Command: @@ -38,125 +38,71 @@ pub struct SubstrateWeight(PhantomData); impl crate::weight_info::WeightInfo for SubstrateWeight { /// Storage: `MoveModule::MultisigStorage` (r:1 w:1) /// Proof: `MoveModule::MultisigStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) + /// Storage: `Balances::Locks` (r:3 w:3) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) + /// Storage: `Balances::Freezes` (r:3 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) + /// Storage: `System::Account` (r:4 w:4) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `MoveModule::ChoreOnIdleStorage` (r:1 w:1) - /// Proof: `MoveModule::ChoreOnIdleStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `MoveModule::VMStorage` (r:3 w:2) + /// Storage: `MoveModule::VMStorage` (r:2 w:1) /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `n` is `[0, 7]`. + /// The range of component `n` is `[0, 9]`. fn execute(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `8700` - // Estimated: `14577 + n * (812 ±0)` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(552_887_566, 0) - .saturating_add(Weight::from_parts(0, 14577)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `9476` + // Estimated: `17211 + n * (1491 ±0)` + // Minimum execution time: 32_000_000 picoseconds. + Weight::from_parts(33_000_000, 0) + .saturating_add(Weight::from_parts(0, 17211)) + // Standard Error: 294_087_970 + .saturating_add(Weight::from_parts(5_303_315_471, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 812).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 1491).saturating_mul(n.into())) } /// Storage: `MoveModule::VMStorage` (r:2 w:1) /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `n` is `[0, 3]`. fn publish_module(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `111 + n * (3506 ±0)` - // Estimated: `2180 + n * (4531 ±116)` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(25_415_305, 0) - .saturating_add(Weight::from_parts(0, 2180)) - // Standard Error: 1_274_995 - .saturating_add(Weight::from_parts(132_265_386, 0).saturating_mul(n.into())) + // Measured: `111 + n * (3842 ±0)` + // Estimated: `2081 + n * (4852 ±124)` + // Minimum execution time: 39_000_000 picoseconds. + Weight::from_parts(27_615_954, 0) + .saturating_add(Weight::from_parts(0, 2081)) + // Standard Error: 1_243_108 + .saturating_add(Weight::from_parts(126_870_632, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) - .saturating_add(Weight::from_parts(0, 4531).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 4852).saturating_mul(n.into())) } - /// Storage: `MoveModule::VMStorage` (r:1 w:1) + /// Storage: `MoveModule::VMStorage` (r:2 w:1) /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn publish_module_bundle() -> Weight { + /// The range of component `n` is `[0, 1]`. + fn publish_module_bundle(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `111` - // Estimated: `3576` - // Minimum execution time: 161_000_000 picoseconds. - Weight::from_parts(168_000_000, 0) + // Measured: `111 + n * (7685 ±0)` + // Estimated: `3576 + n * (10160 ±0)` + // Minimum execution time: 157_000_000 picoseconds. + Weight::from_parts(159_189_795, 0) .saturating_add(Weight::from_parts(0, 3576)) + // Standard Error: 131_387 + .saturating_add(Weight::from_parts(389_710_204, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_parts(0, 10160).saturating_mul(n.into())) } /// Storage: `MoveModule::VMStorage` (r:1 w:1) /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) fn update_stdlib_bundle() -> Weight { // Proof Size summary in bytes: - // Measured: `7123` - // Estimated: `10588` - // Minimum execution time: 197_000_000 picoseconds. - Weight::from_parts(201_000_000, 0) - .saturating_add(Weight::from_parts(0, 10588)) + // Measured: `7796` + // Estimated: `11261` + // Minimum execution time: 204_000_000 picoseconds. + Weight::from_parts(205_000_000, 0) + .saturating_add(Weight::from_parts(0, 11261)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } } - -impl crate::weight_info::WeightInfo for () { - /// Storage: `MoveModule::MultisigStorage` (r:1 w:1) - /// Proof: `MoveModule::MultisigStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(49), added: 2524, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:1) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `MoveModule::ChoreOnIdleStorage` (r:1 w:1) - /// Proof: `MoveModule::ChoreOnIdleStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `MoveModule::VMStorage` (r:3 w:2) - /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `n` is `[0, 7]`. - fn execute(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `8700` - // Estimated: `14577 + n * (812 ±0)` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(552_887_566, 0) - .saturating_add(Weight::from_parts(0, 14577)) - .saturating_add(Weight::from_parts(0, 812).saturating_mul(n.into())) - } - /// Storage: `MoveModule::VMStorage` (r:2 w:1) - /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `n` is `[0, 3]`. - fn publish_module(n: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `111 + n * (3506 ±0)` - // Estimated: `2180 + n * (4531 ±116)` - // Minimum execution time: 36_000_000 picoseconds. - Weight::from_parts(25_415_305, 0) - .saturating_add(Weight::from_parts(0, 2180)) - // Standard Error: 1_274_995 - .saturating_add(Weight::from_parts(132_265_386, 0).saturating_mul(n.into())) - .saturating_add(Weight::from_parts(0, 4531).saturating_mul(n.into())) - } - /// Storage: `MoveModule::VMStorage` (r:1 w:1) - /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn publish_module_bundle() -> Weight { - // Proof Size summary in bytes: - // Measured: `111` - // Estimated: `3576` - // Minimum execution time: 161_000_000 picoseconds. - Weight::from_parts(168_000_000, 0) - .saturating_add(Weight::from_parts(0, 3576)) - } - /// Storage: `MoveModule::VMStorage` (r:1 w:1) - /// Proof: `MoveModule::VMStorage` (`max_values`: None, `max_size`: None, mode: `Measured`) - fn update_stdlib_bundle() -> Weight { - // Proof Size summary in bytes: - // Measured: `7123` - // Estimated: `10588` - // Minimum execution time: 197_000_000 picoseconds. - Weight::from_parts(201_000_000, 0) - .saturating_add(Weight::from_parts(0, 10588)) - } -}