Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new approach for benchmarking execute scripts #191

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ gas_costs.txt

# Move Build Output
build/

Calibration.move
gen_smove_instr.sh
2 changes: 1 addition & 1 deletion doc/tech_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl pallet_move::Config for Test {
// Runtime event of this blockchain.
type RuntimeEvent = RuntimeEvent;
// Weight info for this pallet.
type WeightInfo = (); // or use pallet_move::weights::SubstrateWeights<Test>;
type WeightInfo = pallet_move::weights::SubstrateWeight<Test>;
}
```

Expand Down
2 changes: 2 additions & 0 deletions pallet/src/assets/move-projects/gas-costs/build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/sh
cd $(dirname $0)
ALICE=5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
sh ./gen_cal_scripts.sh
# Build the project
smove build
# Create all Script-Transactions
Expand All @@ -10,3 +11,4 @@ smove create-transaction --compiled-script-path build/gas-costs/bytecode_scripts
mv build/gas-costs/script_transactions/long_script.mvt build/gas-costs/script_transactions/long_cheap_script.mvt
smove create-transaction --compiled-script-path build/gas-costs/bytecode_scripts/long_script.mv --args signer:$ALICE bool:false
mv build/gas-costs/script_transactions/long_script.mvt build/gas-costs/script_transactions/long_expensive_script.mvt
sh ./gen_smove_instr.sh
41 changes: 41 additions & 0 deletions pallet/src/assets/move-projects/gas-costs/gen_cal_scripts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh
cd $(dirname $0)

MOVE_SRC="./sources/Calibration.move"
BASH_SH="./gen_smove_instr.sh"
ITERATIONS=25

function write_method() {
printf "script {\n" >> $MOVE_SRC
printf " fun cal_gas_cost_$1(v0: u8" >> $MOVE_SRC
if [ $1 -gt 0 ]
then
for i in $(seq 1 $1)
do
printf ", v$i: u8" >> $MOVE_SRC
done
fi
printf ") {\n" >> $MOVE_SRC
for i in $(seq 0 $1)
do
printf " assert!(v$i == $i, $i);\n" >> $MOVE_SRC
done
printf " }\n" >> $MOVE_SRC
printf "}\n" >> $MOVE_SRC
}

function write_smove_cmd() {
printf "\nsmove create-transaction -c build/gas-costs/bytecode_scripts/cal_gas_cost_$1.mv --args" >> $BASH_SH
for i in $(seq 0 $1)
do
printf " u8:$i" >> $BASH_SH
done
}

printf "" > $MOVE_SRC
printf "#!/bin/sh" > $BASH_SH
for i in $(seq 0 $(($ITERATIONS-1)))
do
write_method $i
write_smove_cmd $i
done
220 changes: 71 additions & 149 deletions pallet/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,144 +2,76 @@

use frame_benchmarking::v2::*;
use frame_system::{Config as SysConfig, RawOrigin};
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;

macro_rules! impl_gas_costs_cal_fns {
($name:tt) => {
pub fn $name() -> &'static [u8] {
core::include_bytes!(concat!(
"assets/move-projects/gas-costs/build/gas-costs/script_transactions/",
stringify!($name),
".mvt"
))
}
};
}

#[benchmarks(
where
T: Config + SysConfig + BalancesConfig,
T: Config + SysConfig,
T::AccountId: Ss58Codec,
T::Balance: From<u128>,
SourceOf<T>: From<T::AccountId>,
)]
mod benchmarks {
use super::*;

/// Because it is challenging to determine a reliable and fixed relation between gas costs and
/// Substrate weights, we created Move scripts with known gas costs and increasing steps of 20.
/// Twenty-five scripts with rising gas costs of about 20 for each iteration step were used as
/// input for this benchmark. Therefore, the original output was divided by 20 afterwards.
#[benchmark]
fn execute(n: Linear<0, 7>) {
let bob_32 = utils::account::<T>(utils::BOB_ADDR);
fn execute(n: Linear<0, 24>) {
Rqnsom marked this conversation as resolved.
Show resolved Hide resolved
let alice_32 = utils::account::<T>(utils::ALICE_ADDR);
let dave_32 = utils::account::<T>(utils::DAVE_ADDR);
let eve_32 = utils::account::<T>(utils::EVE_ADDR);

// Our benchmark plan (each is a test scenario with different parameters).
let script_bcs = [
car_wash_initial_coin_miniting().to_vec(),
car_wash_register_new_user().to_vec(),
car_wash_buy_coin().to_vec(),
car_wash_wash_car().to_vec(),
gas_costs_short_cheap_script().to_vec(),
gas_costs_long_cheap_script().to_vec(),
multiple_signers_init_module().to_vec(),
multiple_signers_rent_apartment().to_vec(),
];
// Sequence of account-IDs who will execute each extrinsic call.
let accounts = [
bob_32.clone(), // car-wash-example
alice_32.clone(),
alice_32.clone(),
alice_32.clone(),
alice_32.clone(), // gas-costs
alice_32.clone(),
bob_32.clone(), // multiple-signers
eve_32,
cal_gas_cost_0().to_vec(),
cal_gas_cost_1().to_vec(),
cal_gas_cost_2().to_vec(),
cal_gas_cost_3().to_vec(),
cal_gas_cost_4().to_vec(),
cal_gas_cost_5().to_vec(),
cal_gas_cost_6().to_vec(),
cal_gas_cost_7().to_vec(),
cal_gas_cost_8().to_vec(),
cal_gas_cost_9().to_vec(),
cal_gas_cost_10().to_vec(),
cal_gas_cost_11().to_vec(),
cal_gas_cost_12().to_vec(),
cal_gas_cost_13().to_vec(),
cal_gas_cost_14().to_vec(),
cal_gas_cost_15().to_vec(),
cal_gas_cost_16().to_vec(),
cal_gas_cost_17().to_vec(),
cal_gas_cost_18().to_vec(),
cal_gas_cost_19().to_vec(),
cal_gas_cost_20().to_vec(),
cal_gas_cost_21().to_vec(),
cal_gas_cost_22().to_vec(),
cal_gas_cost_23().to_vec(),
cal_gas_cost_24().to_vec(),
];
// Needed gas amounts for each script, estimated by smove.
let gas = [343, 197, 795, 425, 1, 8, 308, 1377];
// Balance limit to be used.
let regular = [LIMIT; 2];
let max = [u128::MAX; 2];
let limit = [regular, regular, max, regular].concat();

// Now we have to prepare each script execution with a proper setup.
// Publish both modules always.
Pallet::<T>::publish_module(
RawOrigin::Signed(bob_32.clone()).into(),
car_wash_example_module().to_vec(),
MAX_GAS_AMOUNT,
)
.unwrap();
Pallet::<T>::publish_module(
RawOrigin::Signed(bob_32.clone()).into(),
multiple_signers_module().to_vec(),
MAX_GAS_AMOUNT,
)
.unwrap();

// Now prepare individual situations for proper script sequences.
if n > 0 && n < 6 {
Pallet::<T>::execute(
RawOrigin::Signed(bob_32.clone()).into(),
car_wash_initial_coin_miniting().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
if n > 1 {
Pallet::<T>::execute(
RawOrigin::Signed(alice_32.clone()).into(),
car_wash_register_new_user().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
}
if n > 2 && n < 4 {
Pallet::<T>::execute(
RawOrigin::Signed(alice_32.clone()).into(),
car_wash_buy_coin().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
}
if n > 3 {
Balances::<T>::force_set_balance(
RawOrigin::Root.into(),
alice_32.clone().into(),
u128::MAX.into(),
)
.unwrap();
}
}
if n > 6 {
Pallet::<T>::execute(
RawOrigin::Signed(bob_32.clone()).into(),
multiple_signers_init_module().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
Pallet::<T>::execute(
RawOrigin::Signed(alice_32.clone()).into(),
multiple_signers_rent_apartment().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
Pallet::<T>::execute(
RawOrigin::Signed(dave_32).into(),
multiple_signers_rent_apartment().to_vec(),
MAX_GAS_AMOUNT,
LIMIT.into(),
)
.unwrap();
}

#[extrinsic_call]
execute(
RawOrigin::Signed(accounts[n as usize].clone()),
RawOrigin::Signed(alice_32),
script_bcs[n as usize].clone(),
gas[n as usize],
limit[n as usize].into(),
(n + 1) * 20,
0u128.into(),
)
}

Expand Down Expand Up @@ -243,26 +175,6 @@ mod benchmark_only {
)
}

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")
}

pub fn car_wash_register_new_user() -> &'static [u8] {
core::include_bytes!("assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/register_new_user.mvt")
}

pub fn car_wash_buy_coin() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/buy_coin.mvt"
)
}

pub fn car_wash_wash_car() -> &'static [u8] {
core::include_bytes!(
"assets/move-projects/car-wash-example/build/car-wash-example/script_transactions/wash_car.mvt"
)
}

// Multiple Signers Example
pub fn multiple_signers_module() -> &'static [u8] {
core::include_bytes!(
Expand All @@ -275,19 +187,29 @@ mod benchmark_only {
)
}

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

pub fn multiple_signers_rent_apartment() -> &'static [u8] {
core::include_bytes!("assets/move-projects/multiple-signers/build/multiple-signers/script_transactions/rent_apartment.mvt")
}

pub fn gas_costs_short_cheap_script() -> &'static [u8] {
core::include_bytes!("assets/move-projects/gas-costs/build/gas-costs/script_transactions/short_cheap_script.mvt")
}

pub fn gas_costs_long_cheap_script() -> &'static [u8] {
core::include_bytes!("assets/move-projects/gas-costs/build/gas-costs/script_transactions/long_cheap_script.mvt")
}
impl_gas_costs_cal_fns!(cal_gas_cost_0);
impl_gas_costs_cal_fns!(cal_gas_cost_1);
impl_gas_costs_cal_fns!(cal_gas_cost_2);
impl_gas_costs_cal_fns!(cal_gas_cost_3);
impl_gas_costs_cal_fns!(cal_gas_cost_4);
impl_gas_costs_cal_fns!(cal_gas_cost_5);
impl_gas_costs_cal_fns!(cal_gas_cost_6);
impl_gas_costs_cal_fns!(cal_gas_cost_7);
impl_gas_costs_cal_fns!(cal_gas_cost_8);
impl_gas_costs_cal_fns!(cal_gas_cost_9);
impl_gas_costs_cal_fns!(cal_gas_cost_10);
impl_gas_costs_cal_fns!(cal_gas_cost_11);
impl_gas_costs_cal_fns!(cal_gas_cost_12);
impl_gas_costs_cal_fns!(cal_gas_cost_13);
impl_gas_costs_cal_fns!(cal_gas_cost_14);
impl_gas_costs_cal_fns!(cal_gas_cost_15);
impl_gas_costs_cal_fns!(cal_gas_cost_16);
impl_gas_costs_cal_fns!(cal_gas_cost_17);
impl_gas_costs_cal_fns!(cal_gas_cost_18);
impl_gas_costs_cal_fns!(cal_gas_cost_19);
impl_gas_costs_cal_fns!(cal_gas_cost_20);
impl_gas_costs_cal_fns!(cal_gas_cost_21);
impl_gas_costs_cal_fns!(cal_gas_cost_22);
impl_gas_costs_cal_fns!(cal_gas_cost_23);
impl_gas_costs_cal_fns!(cal_gas_cost_24);
}
2 changes: 1 addition & 1 deletion pallet/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl pallet_move::Config for Test {
type MultisigReqExpireTime = MultisigReqExpireTime;
type MaxScriptSigners = MaxScriptSigners;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = crate::weights::SubstrateWeight<Test>;
type WeightInfo = pallet_move::weights::SubstrateWeight<Test>;
}

/// Test Externalities Builder for an easier test setup.
Expand Down
4 changes: 2 additions & 2 deletions pallet/src/mock_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ mod always_used {
// Reusable constants for test accounts.
pub const BOB_ADDR: &str = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty";
pub const ALICE_ADDR: &str = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY";
pub const DAVE_ADDR: &str = "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy";
pub const EVE_ADDR: &str = "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw";

/// Creates a native 32-byte address from a given ss58 string.
pub fn account<T: SysConfig + Config>(ss58addr: &str) -> T::AccountId
Expand Down Expand Up @@ -67,6 +65,8 @@ mod tests_only {
use crate::{Config, Pallet};

// Reusable constants for test accounts.
pub const DAVE_ADDR: &str = "5DAAnrj7VHTznn2AWBemMuyBwZWs6FNFjdyVXUeYum3PTXFy";
pub const EVE_ADDR: &str = "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw";
// equivalent to 0xCAFE
pub const CAFE_ADDR: &str = "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSv4fmh4G";
// equivalent to 0x1
Expand Down
Loading
Loading