Skip to content

Commit

Permalink
chore: benchmark updates, extrinsic type change
Browse files Browse the repository at this point in the history
- replaced `u32` with `u64` for the `gas_limit` parameter in all
  extrinsics
- updated benchmark tests trying to achieve similar gas cost for
  publishing modules and publishing bundles
- tiny fixes in assets/move-projects
  • Loading branch information
Rqnsom committed May 21, 2024
1 parent 0ce3812 commit 38ecadb
Show file tree
Hide file tree
Showing 21 changed files with 211 additions and 131 deletions.
8 changes: 4 additions & 4 deletions doc/gas-handling.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Gas Handling And Weight Costs In Pallet-Move
# Gas Handling and Weight Costs in Pallet-Move

The gas unit is an internal processing fee for publishing modules and executing scripts within the MoveVM.

In Substrate-based blockchains, another unit, `Weight`, measures and manages the time it takes to validate a block.
Substrate defines one unit of weight as one picosecond of execution time on reference hardware.

## Gas handling in Move layer
## Gas Handling in Move Layer

From within the MoveVM, there are two different sources for gas costs:
- Cost for script execution,
Expand All @@ -24,11 +24,11 @@ This value was selected during the testing and benchmarks and it is an arbitrary

All internal MoveVM gas handling costs are defined in the same [gas schedule module](https://github.com/eigerco/substrate-move/blob/main/move-vm-backend-common/src/gas_schedule.rs) so that tweaking any gas-related factor can be done from within that module.

## Extrinsic Weight Cost in Pallet layer
## Extrinsic Weight Cost in Pallet Layer

Three main extrinsics interact with MoveVM, which stores its state within the Substrate storage:
- `publish_module`
- `publish_bundle`
- `publish_module_bundle`
- `execute`

All above extrinsics have a `gas_limit` argument which is used as an input to the `MoveVM`.
Expand Down
2 changes: 1 addition & 1 deletion doc/stdlib-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ You can use these PRs as an example of how that can be done:

Whenever native functions are added, [smove](smove) needs to update dependencies so it fetches the latest MoveVM changes and then a new version of `smove` should be published.

Hopefully, pallet users won't need to add new native functions after the genesis block, otherwise the node's runtime will require and update containing the new version of the MoveVM instance with the latest code that includes added native functions.
Hopefully, pallet users won't need to add new native functions after the genesis block, otherwise the node's runtime will require an update containing the new version of the MoveVM instance with the latest code that includes added native functions.

[move-stdlib]: https://github.com/eigerco/substrate-move/tree/main/language/move-stdlib
[substrate-move]: https://github.com/eigerco/substrate-move
Expand Down
10 changes: 10 additions & 0 deletions pallet/src/assets/move-projects/basic_coin/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "basic_coin"
version = "0.0.0"

[dependencies]
MoveStdlib = { git = "https://github.com/eigerco/move-stdlib", rev = "main" }

[addresses]
std = "0x1"
CafeAccount = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
68 changes: 68 additions & 0 deletions pallet/src/assets/move-projects/basic_coin/sources/BasicCoin.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/// This module defines a minimal Coin and Balance.
module CafeAccount::BasicCoin {
use std::signer;

/// Address of the owner of this module
const MODULE_OWNER: address = @CafeAccount;

/// Error codes
const ENOT_MODULE_OWNER: u64 = 0;
const EINSUFFICIENT_BALANCE: u64 = 1;
const EALREADY_HAS_BALANCE: u64 = 2;

struct Coin has store {
value: u64
}

/// Struct representing the balance of each address.
struct Balance has key {
coin: Coin
}

/// Publish an empty balance resource under `account`'s address. This function must be called before
/// minting or transferring to the account.
/// Making this function entry allows to call it directly in the transactions
entry public fun publish_balance(account: &signer) {
let empty_coin = Coin { value: 0 };
assert!(!exists<Balance>(signer::address_of(account)), EALREADY_HAS_BALANCE);
move_to(account, Balance { coin: empty_coin });
}

/// Mint `amount` tokens to `mint_addr`. Mint must be approved by the module owner.
public fun mint(module_owner: &signer, mint_addr: address, amount: u64) acquires Balance {
// Only the owner of the module can initialize this module
assert!(signer::address_of(module_owner) == MODULE_OWNER, ENOT_MODULE_OWNER);

// Deposit `amount` of tokens to `mint_addr`'s balance
deposit(mint_addr, Coin { value: amount });
}

/// Returns the balance of `owner`.
public fun balance_of(owner: address): u64 acquires Balance {
borrow_global<Balance>(owner).coin.value
}

/// Transfers `amount` of tokens from `from` to `to`.
public fun transfer(from: &signer, to: address, amount: u64) acquires Balance {
let check = withdraw(signer::address_of(from), amount);
deposit(to, check);
}

/// Withdraw `amount` number of tokens from the balance under `addr`.
fun withdraw(addr: address, amount: u64) : Coin acquires Balance {
let balance = balance_of(addr);
// balance must be greater than the withdraw amount
assert!(balance >= amount, EINSUFFICIENT_BALANCE);
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
*balance_ref = balance - amount;
Coin { value: amount }
}

/// Deposit `amount` number of tokens to the balance under `addr`.
fun deposit(addr: address, check: Coin) acquires Balance {
let balance = balance_of(addr);
let balance_ref = &mut borrow_global_mut<Balance>(addr).coin.value;
let Coin { value } = check;
*balance_ref = balance + value;
}
}
15 changes: 15 additions & 0 deletions pallet/src/assets/move-projects/basic_coin/sources/GetCoin.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
script {
use CafeAccount::BasicCoin;

fun publish_balance(s: signer) {
BasicCoin::publish_balance(&s);
}
}

script {
use CafeAccount::BasicCoin;

fun mint_some(module_owner: signer, rx_addr: address, amount: u64) {
BasicCoin::mint(&module_owner, rx_addr, amount);
}
}
2 changes: 1 addition & 1 deletion pallet/src/assets/move-projects/car-wash-example/build.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh
cd $(dirname $0)
# Build the project
smove build
smove bundle
# Create all Script-Transactions
smove create-transaction --compiled-script-path build/car-wash-example/bytecode_scripts/initial_coin_minting.mv --args signer:5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty
smove create-transaction --compiled-script-path build/car-wash-example/bytecode_scripts/register_new_user.mv --args signer:5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
Expand Down
2 changes: 1 addition & 1 deletion pallet/src/assets/move-projects/multiple-signers/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ALICE=5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
DAVE=5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy
EVE=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw
# Build the Move sources.
smove build
smove bundle
# Generate script-transactions.
# 1. init_module(Bob)
smove create-transaction --compiled-script-path build/multiple-signers/bytecode_scripts/init_module.mv --args signer:$BOB
Expand Down
18 changes: 16 additions & 2 deletions pallet/src/assets/move-projects/smove-build-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ build_dir=(
"signer-scripts"
)
bundle_dir=(
"developer-bundle",
"prohibited-bundle"
"testing-move-stdlib"
"testing-substrate-stdlib"
"using_stdlib_natives"

"car-wash-example"
"multiple-signers"
"base58_smove_build"
"basic_coin"
)


# Info for the below actions:
# If the script needs to be bundled, it should be done in build.sh script if one exists.

# Build simple packages
for dir in "${build_dir[@]}"; do
echo $dir
Expand All @@ -36,5 +44,11 @@ done
# Build bundles
for dir in "${bundle_dir[@]}"; do
echo $dir
smove bundle -p $dir
build_script=$dir"/build.sh"
if [ -f "$build_script" ];
then
sh $build_script
else
smove bundle -p $dir
fi
done
7 changes: 6 additions & 1 deletion pallet/src/balance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
//! TODO Short introduction of this module
//! Module for handling balance functionality related to the MoveVM balance module.
//!
//! Using the MoveVM it's possible to execute balance changes, but only if the execution script
//! succeeds.
//! The possible balance changes are capped with each user's `cheque_limit` value.
use core::{cmp::Ordering, marker::PhantomData};

use codec::{Decode, Encode};
Expand Down
56 changes: 40 additions & 16 deletions pallet/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
use frame_benchmarking::v2::*;
use frame_system::{Config as SysConfig, RawOrigin};
use move_vm_backend::types::MAX_GAS_AMOUNT;
use pallet_balances::{Config as BalancesConfig, Pallet as Balances};
use sp_core::crypto::Ss58Codec;

use crate::{mock_utils as utils, *};

const LIMIT: u128 = 60_000_000_000_000;

const MAX_GAS_AMOUNT: u32 = u32::MAX;

type SourceOf<T> = <<T as SysConfig>::Lookup as sp_runtime::traits::StaticLookup>::Source;

#[benchmarks(
Expand Down Expand Up @@ -147,16 +148,16 @@ mod benchmarks {
}

#[benchmark]
fn publish_module(n: Linear<0, 3>) {
fn publish_module(n: Linear<0, 2>) {
let bob_32 = utils::account::<T>(utils::BOB_ADDR);

let module_bcs = [
move_basics_module().to_vec(),
using_stdlib_natives_module().to_vec(),
multiple_signers_module().to_vec(),
car_wash_example_module().to_vec(),
base58_smove_build_module().to_vec(),
basic_coin_module().to_vec(),
];
let gas = [101, 325, 661, 732];
let gas = [661, 732, 100, 576];

#[extrinsic_call]
publish_module(
Expand All @@ -167,15 +168,16 @@ mod benchmarks {
}

#[benchmark]
fn publish_module_bundle(n: Linear<0, 1>) {
fn publish_module_bundle(n: Linear<0, 2>) {
let bob_32 = utils::account::<T>(utils::BOB_ADDR);

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(),
multiple_signers_module_as_bundle().to_vec(),
car_wash_example_module_as_bundle().to_vec(),
base58_smove_build_module_as_bundle().to_vec(),
basic_coin_module_as_bundle().to_vec(),
];

let gas = [528, 1500];
let gas = [664, 735, 102, 579];

#[extrinsic_call]
publish_module_bundle(
Expand Down Expand Up @@ -223,16 +225,28 @@ mod benchmarks {
use benchmark_only::*;

mod benchmark_only {
// Move Basics Example
pub fn move_basics_module() -> &'static [u8] {
// Base58 build example
pub fn base58_smove_build_module() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/base58_smove_build/build/base58_smove_build/bytecode_modules/BobBase58.mv"
)
}
pub fn base58_smove_build_module_as_bundle() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/move-basics/build/move-basics/bytecode_modules/EmptyBob.mv"
"assets/move-projects/base58_smove_build/build/base58_smove_build/bundles/base58_smove_build.mvb"
)
}

// Using Stdlib Natives Example
pub fn using_stdlib_natives_module() -> &'static [u8] {
core::include_bytes!("assets/move-projects/using_stdlib_natives/build/using_stdlib_natives/bytecode_modules/Vector.mv")
// basic_coin example
pub fn basic_coin_module() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/basic_coin/build/basic_coin/bytecode_modules/BasicCoin.mv"
)
}
pub fn basic_coin_module_as_bundle() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/basic_coin/build/basic_coin/bundles/basic_coin.mvb"
)
}

// Car Wash Example
Expand All @@ -241,6 +255,11 @@ mod benchmark_only {
"assets/move-projects/car-wash-example/build/car-wash-example/bytecode_modules/CarWash.mv"
)
}
pub fn car_wash_example_module_as_bundle() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/car-wash-example/build/car-wash-example/bundles/car-wash-example.mvb"
)
}

pub fn car_wash_initial_coin_miniting() -> &'static [u8] {
core::include_bytes!("assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/initial_coin_minting.mvt")
Expand Down Expand Up @@ -268,6 +287,11 @@ mod benchmark_only {
"assets/move-projects/multiple-signers/build/multiple-signers/bytecode_modules/Dorm.mv"
)
}
pub fn multiple_signers_module_as_bundle() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/multiple-signers/build/multiple-signers/bundles/multiple-signers.mvb"
)
}

pub fn multiple_signers_init_module() -> &'static [u8] {
core::include_bytes!("assets/move-projects/multiple-signers/build/multiple-signers/script_transactions/init_module.mvt")
Expand Down
Loading

0 comments on commit 38ecadb

Please sign in to comment.