Skip to content

Commit

Permalink
feat: update extrinsic call weights
Browse files Browse the repository at this point in the history
  • Loading branch information
neutrinoks committed May 20, 2024
1 parent 2079c29 commit bfb0f1f
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 103 deletions.
11 changes: 11 additions & 0 deletions pallet/src/assets/move-projects/developer-bundle/Move.toml
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
@@ -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<Balance>(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<Balance>(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<Balance>(MODULE_OWNER), MODULE_NOT_INITIALIZED);

// Verify, that this user does exist / is registered.
assert!(exists<Balance>(signer::address_of(user)), USER_DOES_NOT_EXIST);

// Verify, that enough coins are available.
let coins = borrow_global<Balance>(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<Balance>(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<Balance>(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<Balance>(dst).coins;
assert!(coins_dst + count <= 255, COIN_LIMIT_REACHED);

// Withdraw `count` washing coin(s).
let coins_ref = &mut borrow_global_mut<Balance>(src).coins;
*coins_ref = coins_src - count;

// Deposit `count` washing coin(s).
let coins_ref = &mut borrow_global_mut<Balance>(dst).coins;
*coins_ref = coins_dst + count;
}
}
70 changes: 70 additions & 0 deletions pallet/src/assets/move-projects/developer-bundle/sources/Dorm.move
Original file line number Diff line number Diff line change
@@ -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<address>
}

/// All tenant groups will be registered here.
struct Dorm has key {
groups: vector<Group>
}

/// 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<Dorm>(signer::address_of(module_owner)), MODULE_ALREADY_INITIALIZED);
move_to(module_owner, Dorm { groups: vector::empty<Group>() });
}

/// 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<Dorm>(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<address>();
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<Dorm>(MODULE_OWNER).groups;
vector::push_back(groups_ref, group);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module DeveloperBob::EmptyBob {
struct EmptyStruct {
}
}
1 change: 1 addition & 0 deletions pallet/src/assets/move-projects/smove-build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ build_dir=(
"signer-scripts"
)
bundle_dir=(
"developer-bundle",
"prohibited-bundle"
"testing-move-stdlib"
"testing-substrate-stdlib"
Expand Down
18 changes: 13 additions & 5 deletions pallet/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -169,12 +167,22 @@ mod benchmarks {
}

#[benchmark]
fn publish_module_bundle() {
fn publish_module_bundle(n: Linear<0, 1>) {
let bob_32 = utils::account::<T>(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]
Expand Down
8 changes: 5 additions & 3 deletions pallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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<T>,
bundle: Vec<u8>,
Expand Down Expand Up @@ -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,
),
})
}

Expand Down
Loading

0 comments on commit bfb0f1f

Please sign in to comment.