diff --git a/runtime/common/src/weights.rs b/runtime/common/src/weights.rs index 06c965a102a..5110af19b17 100644 --- a/runtime/common/src/weights.rs +++ b/runtime/common/src/weights.rs @@ -1,7 +1,9 @@ +use gear_core::{costs::CostOf, pages::GearPagesAmount}; use gear_lazy_pages_common::LazyPagesCosts; -use pallet_gear::InstructionWeights; +use pallet_gear::{InstructionWeights, MemoryWeights, SyscallWeights}; const INSTRUCTIONS_SPREAD: u8 = 50; +const SYSCALL_SPREAD: u8 = 10; const PAGES_SPREAD: u8 = 10; #[track_caller] @@ -20,6 +22,11 @@ fn check_instruction_weight(weight: u32, expected: u32) { check_spreading(weight.into(), expected.into(), INSTRUCTIONS_SPREAD); } +#[track_caller] +fn check_syscall_weight(weight: u64, expected: u64) { + check_spreading(weight, expected, SYSCALL_SPREAD); +} + #[track_caller] fn check_pages_weight(weight: u64, expected: u64) { check_spreading(weight, expected, PAGES_SPREAD); @@ -123,6 +130,93 @@ pub fn check_instructions_weights( check_instruction_weight(weights.i32rotr, expected.i32rotr); } +/// Check that the weights of syscalls are within the expected range +pub fn check_syscall_weights( + weights: SyscallWeights, + expected: SyscallWeights, +) { + macro_rules! check { + ($inst_name:ident) => { + check_syscall_weight( + weights.$inst_name.ref_time(), + expected.$inst_name.ref_time(), + ); + }; + } + + check!(alloc); + check!(alloc_per_page); + check!(free); + check!(free_range); + check!(free_range_per_page); + check!(gr_reserve_gas); + check!(gr_unreserve_gas); + check!(gr_system_reserve_gas); + check!(gr_gas_available); + check!(gr_message_id); + check!(gr_program_id); + check!(gr_source); + check!(gr_value); + check!(gr_value_available); + check!(gr_size); + check!(gr_read); + check!(gr_read_per_byte); + check!(gr_env_vars); + check!(gr_block_height); + check!(gr_block_timestamp); + check!(gr_random); + check!(gr_reply_deposit); + check!(gr_send); + check!(gr_send_per_byte); + check!(gr_send_wgas); + check!(gr_send_wgas_per_byte); + check!(gr_send_init); + check!(gr_send_push); + check!(gr_send_push_per_byte); + check!(gr_send_commit); + check!(gr_send_commit_wgas); + check!(gr_reservation_send); + check!(gr_reservation_send_per_byte); + check!(gr_reservation_send_commit); + check!(gr_reply_commit); + check!(gr_reply_commit_wgas); + check!(gr_reservation_reply); + check!(gr_reservation_reply_per_byte); + check!(gr_reservation_reply_commit); + check!(gr_reply_push); + check!(gr_reply); + check!(gr_reply_per_byte); + check!(gr_reply_wgas); + check!(gr_reply_wgas_per_byte); + check!(gr_reply_push_per_byte); + check!(gr_reply_to); + check!(gr_signal_code); + check!(gr_signal_from); + check!(gr_reply_input); + check!(gr_reply_input_wgas); + check!(gr_reply_push_input); + check!(gr_reply_push_input_per_byte); + check!(gr_send_input); + check!(gr_send_input_wgas); + check!(gr_send_push_input); + check!(gr_send_push_input_per_byte); + check!(gr_debug); + check!(gr_debug_per_byte); + check!(gr_reply_code); + check!(gr_exit); + check!(gr_leave); + check!(gr_wait); + check!(gr_wait_for); + check!(gr_wait_up_to); + check!(gr_wake); + check!(gr_create_program); + check!(gr_create_program_payload_per_byte); + check!(gr_create_program_salt_per_byte); + check!(gr_create_program_wgas); + check!(gr_create_program_wgas_payload_per_byte); + check!(gr_create_program_wgas_salt_per_byte); +} + /// Check that the lazy-pages costs are within the expected range pub fn check_lazy_pages_costs( lazy_pages_costs: LazyPagesCosts, @@ -163,3 +257,52 @@ pub fn check_lazy_pages_costs( .cost_for_one(), ); } + +/// Memory pages access costs. +pub struct PagesCosts { + pub load_page_data: CostOf, + pub upload_page_data: CostOf, + pub static_page: CostOf, + pub mem_grow: CostOf, + pub parachain_read_heuristic: CostOf, +} + +impl From> for PagesCosts { + fn from(val: MemoryWeights) -> Self { + Self { + load_page_data: val.load_page_data.ref_time().into(), + upload_page_data: val.upload_page_data.ref_time().into(), + static_page: val.static_page.ref_time().into(), + mem_grow: val.mem_grow.ref_time().into(), + parachain_read_heuristic: val.parachain_read_heuristic.ref_time().into(), + } + } +} + +/// Check that the pages costs are within the expected range +pub fn check_pages_costs(page_costs: PagesCosts, expected_page_costs: PagesCosts) { + check_pages_weight( + page_costs.load_page_data.cost_for_one(), + expected_page_costs.load_page_data.cost_for_one(), + ); + + check_pages_weight( + page_costs.upload_page_data.cost_for_one(), + expected_page_costs.upload_page_data.cost_for_one(), + ); + + check_pages_weight( + page_costs.static_page.cost_for_one(), + expected_page_costs.static_page.cost_for_one(), + ); + + check_pages_weight( + page_costs.mem_grow.cost_for_one(), + expected_page_costs.mem_grow.cost_for_one(), + ); + + check_pages_weight( + page_costs.parachain_read_heuristic.cost_for_one(), + expected_page_costs.parachain_read_heuristic.cost_for_one(), + ); +} diff --git a/runtime/vara/src/tests.rs b/runtime/vara/src/tests.rs index 1d95ce6238d..c61cfb6bd15 100644 --- a/runtime/vara/src/tests.rs +++ b/runtime/vara/src/tests.rs @@ -19,8 +19,11 @@ use super::*; use crate::Runtime; use gear_lazy_pages_common::LazyPagesCosts; -use pallet_gear::{InstructionWeights, MemoryWeights}; -use runtime_common::weights::{check_instructions_weights, check_lazy_pages_costs}; +use pallet_gear::{InstructionWeights, MemoryWeights, SyscallWeights}; +use runtime_common::weights::{ + check_instructions_weights, check_lazy_pages_costs, check_pages_costs, check_syscall_weights, + PagesCosts, +}; #[test] fn instruction_weights_heuristics_test() { @@ -129,8 +132,105 @@ fn instruction_weights_heuristics_test() { check_instructions_weights(weights, expected_weights); } +#[test] +fn syscall_weights_test() { + let weights = SyscallWeights::::default(); + + let expected = SyscallWeights { + alloc: 8_000_000.into(), + alloc_per_page: 247_000.into(), + free: 628_000.into(), + free_range: 772_000.into(), + free_range_per_page: 63_000.into(), + gr_reserve_gas: 2_300_000.into(), + gr_unreserve_gas: 1_900_000.into(), + gr_system_reserve_gas: 1_000_000.into(), + gr_gas_available: 932_300.into(), + gr_message_id: 926_500.into(), + gr_program_id: 930_100.into(), + gr_source: 930_700.into(), + gr_value: 945_700.into(), + gr_value_available: 967_900.into(), + gr_size: 926_900.into(), + gr_read: 1_700_000.into(), + gr_read_per_byte: 157.into(), + gr_env_vars: 1_000_000.into(), + gr_block_height: 925_900.into(), + gr_block_timestamp: 933_000.into(), + gr_random: 1_900_000.into(), + gr_reply_deposit: 6_500_000.into(), + gr_send: 3_200_000.into(), + gr_send_per_byte: 373.into(), + gr_send_wgas: 3_300_000.into(), + gr_send_wgas_per_byte: 382.into(), + gr_send_init: 1_000_000.into(), + gr_send_push: 2_000_000.into(), + gr_send_push_per_byte: 379.into(), + gr_send_commit: 2_700_000.into(), + gr_send_commit_wgas: 2_700_000.into(), + gr_reservation_send: 3_400_000.into(), + gr_reservation_send_per_byte: 376.into(), + gr_reservation_send_commit: 2_900_000.into(), + gr_reply_commit: 21_300_000.into(), + gr_reply_commit_wgas: 19_200_000.into(), + gr_reservation_reply: 8_300_000.into(), + gr_reservation_reply_per_byte: 584_500.into(), + gr_reservation_reply_commit: 10_400_000.into(), + gr_reply_push: 1_700_000.into(), + gr_reply: 22_500_000.into(), + gr_reply_per_byte: 564.into(), + gr_reply_wgas: 21_400_000.into(), + gr_reply_wgas_per_byte: 575.into(), + gr_reply_push_per_byte: 640.into(), + gr_reply_to: 950_200.into(), + gr_signal_code: 962_500.into(), + gr_signal_from: 941_500.into(), + gr_reply_input: 25_900_000.into(), + gr_reply_input_wgas: 24_600_000.into(), + gr_reply_push_input: 1_200_000.into(), + gr_reply_push_input_per_byte: 146.into(), + gr_send_input: 3_100_000.into(), + gr_send_input_wgas: 3_100_000.into(), + gr_send_push_input: 1_500_000.into(), + gr_send_push_input_per_byte: 165.into(), + gr_debug: 1_200_000.into(), + gr_debug_per_byte: 316.into(), + gr_reply_code: 919_800.into(), + gr_exit: 24_100_000.into(), + gr_leave: 12_500_000.into(), + gr_wait: 11_400_000.into(), + gr_wait_for: 9_900_000.into(), + gr_wait_up_to: 11_600_000.into(), + gr_wake: 3_700_000.into(), + gr_create_program: 4_100_000.into(), + gr_create_program_payload_per_byte: 78.into(), + gr_create_program_salt_per_byte: 1_900.into(), + gr_create_program_wgas: 4_100_000.into(), + gr_create_program_wgas_payload_per_byte: 88.into(), + gr_create_program_wgas_salt_per_byte: 1_900.into(), + _phantom: Default::default(), + }; + + check_syscall_weights(weights, expected); +} + #[test] fn page_costs_heuristic_test() { + let page_costs: PagesCosts = MemoryWeights::::default().into(); + + let expected_page_costs = PagesCosts { + load_page_data: 10_000_000.into(), + upload_page_data: 105_000_000.into(), + static_page: 100.into(), + mem_grow: 1_100_000.into(), + parachain_read_heuristic: 0.into(), + }; + + check_pages_costs(page_costs, expected_page_costs); +} + +#[test] +fn lazy_page_costs_heuristic_test() { let lazy_pages_costs: LazyPagesCosts = MemoryWeights::::default().into(); let expected_lazy_pages_costs = LazyPagesCosts {