From e825e990d53d5afc22bb735a044b22e88c5ad85e Mon Sep 17 00:00:00 2001 From: Andrey Lazarko Date: Tue, 5 Nov 2024 16:49:25 +0100 Subject: [PATCH] post-review: code structure fix --- runtime/vara/src/tests/mod.rs | 376 ++++++++++++++++++ runtime/vara/src/{tests.rs => tests/utils.rs} | 372 +---------------- 2 files changed, 388 insertions(+), 360 deletions(-) create mode 100644 runtime/vara/src/tests/mod.rs rename runtime/vara/src/{tests.rs => tests/utils.rs} (56%) diff --git a/runtime/vara/src/tests/mod.rs b/runtime/vara/src/tests/mod.rs new file mode 100644 index 00000000000..49d5b5dea86 --- /dev/null +++ b/runtime/vara/src/tests/mod.rs @@ -0,0 +1,376 @@ +// This file is part of Gear. + +// Copyright (C) 2021-2024 Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Weight tests for the runtime. + +use super::*; +use crate::Runtime; + +use frame_support::dispatch::GetDispatchInfo; +use frame_system::limits::WeightsPerClass; +use gear_core::costs::LazyPagesCosts; +use pallet_gear::{InstructionWeights, MemoryWeights, SyscallWeights}; +use pallet_staking::WeightInfo as _; +use sp_runtime::AccountId32; + +#[cfg(feature = "dev")] +use frame_support::traits::StorageInstance; + +mod utils; +use utils::*; + +#[cfg(feature = "dev")] +#[test] +fn bridge_storages_have_correct_prefixes() { + // # SAFETY: Do not change storage prefixes without total bridge re-deploy. + const PALLET_PREFIX: &str = "GearEthBridge"; + + assert_eq!( + pallet_gear_eth_bridge::AuthoritySetHashPrefix::::pallet_prefix(), + PALLET_PREFIX + ); + assert_eq!( + pallet_gear_eth_bridge::QueueMerkleRootPrefix::::pallet_prefix(), + PALLET_PREFIX + ); + + assert_eq!( + pallet_gear_eth_bridge::AuthoritySetHashPrefix::::STORAGE_PREFIX, + "AuthoritySetHash" + ); + assert_eq!( + pallet_gear_eth_bridge::QueueMerkleRootPrefix::::STORAGE_PREFIX, + "QueueMerkleRoot" + ); +} + +#[cfg(feature = "dev")] +#[test] +fn bridge_session_timer_is_correct() { + assert_eq!( + ::SessionsPerEra::get(), + ::SessionsPerEra::get() + ); + + // # SAFETY: Do not change staking's SessionsPerEra parameter without + // making sure of correct integration with already running network. + // + // Change of the param will require migrating `pallet-gear-eth-bridge`'s + // `ClearTimer` (or any actual time- or epoch- dependent entity) and + // corresponding constant or even total bridge re-deploy. + assert_eq!( + ::SessionsPerEra::get(), + 6 + ); +} + +#[test] +fn payout_stakers_fits_in_block() { + let expected_weight = + ::WeightInfo::payout_stakers_alive_staked( + ::MaxExposurePageSize::get(), + ); + + let call: ::RuntimeCall = + RuntimeCall::Staking(pallet_staking::Call::payout_stakers { + validator_stash: AccountId32::new(Default::default()), + era: Default::default(), + }); + + let dispatch_info = call.get_dispatch_info(); + + assert_eq!(dispatch_info.class, DispatchClass::Normal); + assert_eq!(dispatch_info.weight, expected_weight); + + let block_weights = ::BlockWeights::get(); + + let normal_class_weights: WeightsPerClass = + block_weights.per_class.get(DispatchClass::Normal).clone(); + + let normal_ref_time = normal_class_weights + .max_extrinsic + .unwrap_or(Weight::MAX) + .ref_time(); + let base_weight = normal_class_weights.base_extrinsic.ref_time(); + + assert!(normal_ref_time - base_weight > expected_weight.ref_time()); +} + +#[test] +fn normal_dispatch_length_suits_minimal() { + const MB: u32 = 1024 * 1024; + + let block_length = ::BlockLength::get(); + + // Normal dispatch class is bigger than 2 MB. + assert!(*block_length.max.get(DispatchClass::Normal) > 2 * MB); + + // Others are on maximum. + assert_eq!(*block_length.max.get(DispatchClass::Operational), 5 * MB); + assert_eq!(*block_length.max.get(DispatchClass::Mandatory), 5 * MB); +} + +#[test] +fn instruction_weights_heuristics_test() { + let weights = InstructionWeights::::default(); + + let expected_weights = InstructionWeights { + version: 0, + _phantom: core::marker::PhantomData, + + i64const: 160, + i64load: 5_800, + i32load: 8_000, + i64store: 10_000, + i32store: 20_000, + select: 7_100, + r#if: 8_000, + br: 3_300, + br_if: 6_000, + br_table: 10_900, + br_table_per_entry: 150, + + call: 4_900, + call_per_local: 0, + call_indirect: 22_100, + call_indirect_per_param: 1_000, + + local_get: 900, + local_set: 1_900, + local_tee: 2_500, + global_get: 700, + global_set: 1_000, + memory_current: 14_200, + + i64clz: 400, + i32clz: 300, + i64ctz: 400, + i32ctz: 250, + i64popcnt: 450, + i32popcnt: 350, + i64eqz: 1_300, + i32eqz: 1_200, + i32extend8s: 200, + i32extend16s: 200, + i64extend8s: 400, + i64extend16s: 400, + i64extend32s: 400, + i64extendsi32: 200, + i64extendui32: 200, + i32wrapi64: 200, + i64eq: 1_800, + i32eq: 1_100, + i64ne: 1_700, + i32ne: 1_000, + + i64lts: 1_200, + i32lts: 1_000, + i64ltu: 1_200, + i32ltu: 1_000, + i64gts: 1_200, + i32gts: 1_000, + i64gtu: 1_900, + i32gtu: 1_000, + i64les: 1_900, + i32les: 1_000, + i64leu: 1_200, + i32leu: 1_000, + + i64ges: 1_300, + i32ges: 1_000, + i64geu: 1_300, + i32geu: 1_000, + i64add: 1_300, + i32add: 500, + i64sub: 1_300, + i32sub: 500, + i64mul: 2_000, + i32mul: 1_000, + i64divs: 3_500, + i32divs: 3_500, + + i64divu: 3_500, + i32divu: 3_500, + i64rems: 18_000, + i32rems: 15_000, + i64remu: 3_500, + i32remu: 3_500, + i64and: 1_000, + i32and: 500, + i64or: 1_000, + i32or: 500, + i64xor: 1_000, + i32xor: 500, + + i64shl: 1_000, + i32shl: 400, + i64shrs: 1_000, + i32shrs: 250, + i64shru: 1_000, + i32shru: 400, + i64rotl: 750, + i32rotl: 400, + i64rotr: 1_000, + i32rotr: 300, + }; + + let result = check_instructions_weights(weights, expected_weights); + + assert!(result.is_ok(), "{:#?}", result.err().unwrap()); + assert_eq!(result.unwrap(), expected_instructions_weights_count()); +} + +#[test] +fn syscall_weights_test() { + let weights = SyscallWeights::::default(); + + let expected = SyscallWeights { + alloc: 1_500_000.into(), + free: 900_000.into(), + free_range: 900_000.into(), + free_range_per_page: 40_000.into(), + gr_reserve_gas: 2_300_000.into(), + gr_unreserve_gas: 2_200_000.into(), + gr_system_reserve_gas: 1_200_000.into(), + gr_gas_available: 1_000_000.into(), + gr_message_id: 1_000_000.into(), + gr_program_id: 1_000_000.into(), + gr_source: 1_000_000.into(), + gr_value: 1_000_000.into(), + gr_value_available: 1_000_000.into(), + gr_size: 1_000_000.into(), + gr_read: 1_900_000.into(), + gr_read_per_byte: 200.into(), + gr_env_vars: 1_200_000.into(), + gr_block_height: 1_000_000.into(), + gr_block_timestamp: 1_000_000.into(), + gr_random: 1_900_000.into(), + gr_reply_deposit: 4_900_000.into(), + gr_send: 3_200_000.into(), + gr_send_per_byte: 500.into(), + gr_send_wgas: 3_300_000.into(), + gr_send_wgas_per_byte: 500.into(), + gr_send_init: 1_200_000.into(), + gr_send_push: 2_000_000.into(), + gr_send_push_per_byte: 500.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: 500.into(), + gr_reservation_send_commit: 2_900_000.into(), + gr_reply_commit: 12_000_000.into(), + gr_reply_commit_wgas: 12_000_000.into(), + gr_reservation_reply: 8_500_000.into(), + gr_reservation_reply_per_byte: 675_000.into(), + gr_reservation_reply_commit: 8_000_000.into(), + gr_reply_push: 1_700_000.into(), + gr_reply: 12_500_000.into(), + gr_reply_per_byte: 650.into(), + gr_reply_wgas: 12_500_000.into(), + gr_reply_wgas_per_byte: 650.into(), + gr_reply_push_per_byte: 640.into(), + gr_reply_to: 1_000_000.into(), + gr_signal_code: 1_000_000.into(), + gr_signal_from: 1_000_000.into(), + gr_reply_input: 20_000_000.into(), + gr_reply_input_wgas: 30_000_000.into(), + gr_reply_push_input: 1_200_000.into(), + gr_reply_push_input_per_byte: 110.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: 150.into(), + gr_debug: 1_200_000.into(), + gr_debug_per_byte: 500.into(), + gr_reply_code: 1_000_000.into(), + gr_exit: 18_000_000.into(), + gr_leave: 14_000_000.into(), + gr_wait: 14_000_000.into(), + gr_wait_for: 14_000_000.into(), + gr_wait_up_to: 14_500_000.into(), + gr_wake: 3_300_000.into(), + gr_create_program: 4_100_000.into(), + gr_create_program_payload_per_byte: 120.into(), + gr_create_program_salt_per_byte: 1_400.into(), + gr_create_program_wgas: 4_100_000.into(), + gr_create_program_wgas_payload_per_byte: 120.into(), + gr_create_program_wgas_salt_per_byte: 1_400.into(), + _phantom: Default::default(), + }; + + let result = check_syscall_weights(weights, expected); + + assert!(result.is_ok(), "{:#?}", result.err().unwrap()); + assert_eq!(result.unwrap(), expected_syscall_weights_count()); +} + +#[test] +fn page_costs_heuristic_test() { + let page_costs: LazyPagesCosts = MemoryWeights::::default().into(); + + let expected_page_costs = LazyPagesCosts { + load_page_data: 9_000_000.into(), + upload_page_data: 105_000_000.into(), + mem_grow: 800_000.into(), + mem_grow_per_page: 0.into(), + parachain_read_heuristic: 0.into(), + ..Default::default() + }; + + let result = check_pages_costs(page_costs, expected_page_costs); + + assert!(result.is_ok(), "{:#?}", result.err().unwrap()); + assert_eq!(result.unwrap(), expected_pages_costs_count()); +} + +#[test] +fn lazy_page_costs_heuristic_test() { + let lazy_pages_costs: LazyPagesCosts = MemoryWeights::::default().into(); + + let expected_lazy_pages_costs = LazyPagesCosts { + signal_read: 28_000_000.into(), + signal_write: 138_000_000.into(), + signal_write_after_read: 112_000_000.into(), + host_func_read: 29_000_000.into(), + host_func_write: 137_000_000.into(), + host_func_write_after_read: 112_000_000.into(), + load_page_storage_data: 9_000_000.into(), + ..Default::default() + }; + + let result = check_lazy_pages_costs(lazy_pages_costs, expected_lazy_pages_costs); + + assert!(result.is_ok(), "{:#?}", result.err().unwrap()); + assert_eq!(result.unwrap(), expected_lazy_pages_costs_count()); +} + +/// Check that it is not possible to write/change memory pages too cheaply, +/// because this may cause runtime heap memory overflow. +#[test] +fn write_is_not_too_cheap() { + let costs: LazyPagesCosts = MemoryWeights::::default().into(); + let cheapest_write = u64::MAX + .min(costs.signal_write.cost_for_one()) + .min(costs.signal_read.cost_for_one() + costs.signal_write_after_read.cost_for_one()) + .min(costs.host_func_write.cost_for_one()) + .min(costs.host_func_read.cost_for_one() + costs.host_func_write_after_read.cost_for_one()); + + let block_max_gas = 3 * 10 ^ 12; // 3 seconds + let runtime_heap_size_in_wasm_pages = 0x4000; // 1GB + assert!((block_max_gas / cheapest_write) < runtime_heap_size_in_wasm_pages); +} diff --git a/runtime/vara/src/tests.rs b/runtime/vara/src/tests/utils.rs similarity index 56% rename from runtime/vara/src/tests.rs rename to runtime/vara/src/tests/utils.rs index 13289b7bebf..b30b776438e 100644 --- a/runtime/vara/src/tests.rs +++ b/runtime/vara/src/tests/utils.rs @@ -19,22 +19,15 @@ use super::*; use crate::Runtime; -use frame_support::dispatch::GetDispatchInfo; -use frame_system::limits::WeightsPerClass; use gear_core::costs::LazyPagesCosts; use pallet_gear::{InstructionWeights, MemoryWeights, SyscallWeights}; -use pallet_staking::WeightInfo as _; -use sp_runtime::AccountId32; - -#[cfg(feature = "dev")] -use frame_support::traits::StorageInstance; const INSTRUCTIONS_SPREAD: u8 = 50; const SYSCALL_SPREAD: u8 = 10; const PAGES_SPREAD: u8 = 10; /// Structure to hold weight expectation -struct WeightExpectation { +pub(super) struct WeightExpectation { weight: u64, expected: u64, spread: u8, @@ -42,7 +35,7 @@ struct WeightExpectation { } impl WeightExpectation { - fn new(weight: u64, expected: u64, spread: u8, name: &'static str) -> Self { + pub(super) fn new(weight: u64, expected: u64, spread: u8, name: &'static str) -> Self { Self { weight, expected, @@ -51,7 +44,7 @@ impl WeightExpectation { } } - fn check(&self) -> Result<(), String> { + pub(super) fn check(&self) -> Result<(), String> { let left = self.expected - self.expected * self.spread as u64 / 100; let right = self.expected + self.expected * self.spread as u64 / 100; @@ -63,7 +56,7 @@ impl WeightExpectation { } } -fn check_expectations(expectations: &[WeightExpectation]) -> Result> { +pub(super) fn check_expectations(expectations: &[WeightExpectation]) -> Result> { let errors = expectations .iter() .filter_map(|expectation| { @@ -82,7 +75,7 @@ fn check_expectations(expectations: &[WeightExpectation]) -> Result usize { +pub(super) fn expected_instructions_weights_count() -> usize { let InstructionWeights { i64const: _, i64load: _, @@ -179,7 +172,7 @@ fn expected_instructions_weights_count() -> usize { 87 } -fn expected_syscall_weights_count() -> usize { +pub(super) fn expected_syscall_weights_count() -> usize { let SyscallWeights { alloc: _, free: _, @@ -258,7 +251,7 @@ fn expected_syscall_weights_count() -> usize { 70 } -fn expected_pages_costs_count() -> usize { +pub(super) fn expected_pages_costs_count() -> usize { let LazyPagesCosts { // Fields for lazy pages costs signal_read: _, @@ -280,7 +273,7 @@ fn expected_pages_costs_count() -> usize { 5 } -fn expected_lazy_pages_costs_count() -> usize { +pub(super) fn expected_lazy_pages_costs_count() -> usize { let LazyPagesCosts { // Fields for lazy pages costs signal_read: _, @@ -303,7 +296,7 @@ fn expected_lazy_pages_costs_count() -> usize { } /// Check that the weights of instructions are within the expected range -fn check_instructions_weights( +pub(super) fn check_instructions_weights( weights: InstructionWeights, expected: InstructionWeights, ) -> Result> { @@ -412,7 +405,7 @@ fn check_instructions_weights( } /// Check that the weights of syscalls are within the expected range -fn check_syscall_weights( +pub(super) fn check_syscall_weights( weights: SyscallWeights, expected: SyscallWeights, ) -> Result> { @@ -504,7 +497,7 @@ fn check_syscall_weights( } /// Check that the lazy-pages costs are within the expected range -fn check_lazy_pages_costs( +pub(super) fn check_lazy_pages_costs( lazy_pages_costs: LazyPagesCosts, expected_lazy_pages_costs: LazyPagesCosts, ) -> Result> { @@ -533,7 +526,7 @@ fn check_lazy_pages_costs( } /// Check that the pages costs are within the expected range -fn check_pages_costs( +pub(super) fn check_pages_costs( page_costs: LazyPagesCosts, expected_page_costs: LazyPagesCosts, ) -> Result> { @@ -558,344 +551,3 @@ fn check_pages_costs( check_expectations(&expectations) } - -#[cfg(feature = "dev")] -#[test] -fn bridge_storages_have_correct_prefixes() { - // # SAFETY: Do not change storage prefixes without total bridge re-deploy. - const PALLET_PREFIX: &str = "GearEthBridge"; - - assert_eq!( - pallet_gear_eth_bridge::AuthoritySetHashPrefix::::pallet_prefix(), - PALLET_PREFIX - ); - assert_eq!( - pallet_gear_eth_bridge::QueueMerkleRootPrefix::::pallet_prefix(), - PALLET_PREFIX - ); - - assert_eq!( - pallet_gear_eth_bridge::AuthoritySetHashPrefix::::STORAGE_PREFIX, - "AuthoritySetHash" - ); - assert_eq!( - pallet_gear_eth_bridge::QueueMerkleRootPrefix::::STORAGE_PREFIX, - "QueueMerkleRoot" - ); -} - -#[cfg(feature = "dev")] -#[test] -fn bridge_session_timer_is_correct() { - assert_eq!( - ::SessionsPerEra::get(), - ::SessionsPerEra::get() - ); - - // # SAFETY: Do not change staking's SessionsPerEra parameter without - // making sure of correct integration with already running network. - // - // Change of the param will require migrating `pallet-gear-eth-bridge`'s - // `ClearTimer` (or any actual time- or epoch- dependent entity) and - // corresponding constant or even total bridge re-deploy. - assert_eq!( - ::SessionsPerEra::get(), - 6 - ); -} - -#[test] -fn payout_stakers_fits_in_block() { - let expected_weight = - ::WeightInfo::payout_stakers_alive_staked( - ::MaxExposurePageSize::get(), - ); - - let call: ::RuntimeCall = - RuntimeCall::Staking(pallet_staking::Call::payout_stakers { - validator_stash: AccountId32::new(Default::default()), - era: Default::default(), - }); - - let dispatch_info = call.get_dispatch_info(); - - assert_eq!(dispatch_info.class, DispatchClass::Normal); - assert_eq!(dispatch_info.weight, expected_weight); - - let block_weights = ::BlockWeights::get(); - - let normal_class_weights: WeightsPerClass = - block_weights.per_class.get(DispatchClass::Normal).clone(); - - let normal_ref_time = normal_class_weights - .max_extrinsic - .unwrap_or(Weight::MAX) - .ref_time(); - let base_weight = normal_class_weights.base_extrinsic.ref_time(); - - assert!(normal_ref_time - base_weight > expected_weight.ref_time()); -} - -#[test] -fn normal_dispatch_length_suits_minimal() { - const MB: u32 = 1024 * 1024; - - let block_length = ::BlockLength::get(); - - // Normal dispatch class is bigger than 2 MB. - assert!(*block_length.max.get(DispatchClass::Normal) > 2 * MB); - - // Others are on maximum. - assert_eq!(*block_length.max.get(DispatchClass::Operational), 5 * MB); - assert_eq!(*block_length.max.get(DispatchClass::Mandatory), 5 * MB); -} - -#[test] -fn instruction_weights_heuristics_test() { - let weights = InstructionWeights::::default(); - - let expected_weights = InstructionWeights { - version: 0, - _phantom: core::marker::PhantomData, - - i64const: 160, - i64load: 5_800, - i32load: 8_000, - i64store: 10_000, - i32store: 20_000, - select: 7_100, - r#if: 8_000, - br: 3_300, - br_if: 6_000, - br_table: 10_900, - br_table_per_entry: 150, - - call: 4_900, - call_per_local: 0, - call_indirect: 22_100, - call_indirect_per_param: 1_000, - - local_get: 900, - local_set: 1_900, - local_tee: 2_500, - global_get: 700, - global_set: 1_000, - memory_current: 14_200, - - i64clz: 400, - i32clz: 300, - i64ctz: 400, - i32ctz: 250, - i64popcnt: 450, - i32popcnt: 350, - i64eqz: 1_300, - i32eqz: 1_200, - i32extend8s: 200, - i32extend16s: 200, - i64extend8s: 400, - i64extend16s: 400, - i64extend32s: 400, - i64extendsi32: 200, - i64extendui32: 200, - i32wrapi64: 200, - i64eq: 1_800, - i32eq: 1_100, - i64ne: 1_700, - i32ne: 1_000, - - i64lts: 1_200, - i32lts: 1_000, - i64ltu: 1_200, - i32ltu: 1_000, - i64gts: 1_200, - i32gts: 1_000, - i64gtu: 1_900, - i32gtu: 1_000, - i64les: 1_900, - i32les: 1_000, - i64leu: 1_200, - i32leu: 1_000, - - i64ges: 1_300, - i32ges: 1_000, - i64geu: 1_300, - i32geu: 1_000, - i64add: 1_300, - i32add: 500, - i64sub: 1_300, - i32sub: 500, - i64mul: 2_000, - i32mul: 1_000, - i64divs: 3_500, - i32divs: 3_500, - - i64divu: 3_500, - i32divu: 3_500, - i64rems: 18_000, - i32rems: 15_000, - i64remu: 3_500, - i32remu: 3_500, - i64and: 1_000, - i32and: 500, - i64or: 1_000, - i32or: 500, - i64xor: 1_000, - i32xor: 500, - - i64shl: 1_000, - i32shl: 400, - i64shrs: 1_000, - i32shrs: 250, - i64shru: 1_000, - i32shru: 400, - i64rotl: 750, - i32rotl: 400, - i64rotr: 1_000, - i32rotr: 300, - }; - - let result = check_instructions_weights(weights, expected_weights); - - assert!(result.is_ok(), "{:#?}", result.err().unwrap()); - assert_eq!(result.unwrap(), expected_instructions_weights_count()); -} - -#[test] -fn syscall_weights_test() { - let weights = SyscallWeights::::default(); - - let expected = SyscallWeights { - alloc: 1_500_000.into(), - free: 900_000.into(), - free_range: 900_000.into(), - free_range_per_page: 40_000.into(), - gr_reserve_gas: 2_300_000.into(), - gr_unreserve_gas: 2_200_000.into(), - gr_system_reserve_gas: 1_200_000.into(), - gr_gas_available: 1_000_000.into(), - gr_message_id: 1_000_000.into(), - gr_program_id: 1_000_000.into(), - gr_source: 1_000_000.into(), - gr_value: 1_000_000.into(), - gr_value_available: 1_000_000.into(), - gr_size: 1_000_000.into(), - gr_read: 1_900_000.into(), - gr_read_per_byte: 200.into(), - gr_env_vars: 1_200_000.into(), - gr_block_height: 1_000_000.into(), - gr_block_timestamp: 1_000_000.into(), - gr_random: 1_900_000.into(), - gr_reply_deposit: 4_900_000.into(), - gr_send: 3_200_000.into(), - gr_send_per_byte: 500.into(), - gr_send_wgas: 3_300_000.into(), - gr_send_wgas_per_byte: 500.into(), - gr_send_init: 1_200_000.into(), - gr_send_push: 2_000_000.into(), - gr_send_push_per_byte: 500.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: 500.into(), - gr_reservation_send_commit: 2_900_000.into(), - gr_reply_commit: 12_000_000.into(), - gr_reply_commit_wgas: 12_000_000.into(), - gr_reservation_reply: 8_500_000.into(), - gr_reservation_reply_per_byte: 675_000.into(), - gr_reservation_reply_commit: 8_000_000.into(), - gr_reply_push: 1_700_000.into(), - gr_reply: 12_500_000.into(), - gr_reply_per_byte: 650.into(), - gr_reply_wgas: 12_500_000.into(), - gr_reply_wgas_per_byte: 650.into(), - gr_reply_push_per_byte: 640.into(), - gr_reply_to: 1_000_000.into(), - gr_signal_code: 1_000_000.into(), - gr_signal_from: 1_000_000.into(), - gr_reply_input: 20_000_000.into(), - gr_reply_input_wgas: 30_000_000.into(), - gr_reply_push_input: 1_200_000.into(), - gr_reply_push_input_per_byte: 110.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: 150.into(), - gr_debug: 1_200_000.into(), - gr_debug_per_byte: 500.into(), - gr_reply_code: 1_000_000.into(), - gr_exit: 18_000_000.into(), - gr_leave: 14_000_000.into(), - gr_wait: 14_000_000.into(), - gr_wait_for: 14_000_000.into(), - gr_wait_up_to: 14_500_000.into(), - gr_wake: 3_300_000.into(), - gr_create_program: 4_100_000.into(), - gr_create_program_payload_per_byte: 120.into(), - gr_create_program_salt_per_byte: 1_400.into(), - gr_create_program_wgas: 4_100_000.into(), - gr_create_program_wgas_payload_per_byte: 120.into(), - gr_create_program_wgas_salt_per_byte: 1_400.into(), - _phantom: Default::default(), - }; - - let result = check_syscall_weights(weights, expected); - - assert!(result.is_ok(), "{:#?}", result.err().unwrap()); - assert_eq!(result.unwrap(), expected_syscall_weights_count()); -} - -#[test] -fn page_costs_heuristic_test() { - let page_costs: LazyPagesCosts = MemoryWeights::::default().into(); - - let expected_page_costs = LazyPagesCosts { - load_page_data: 9_000_000.into(), - upload_page_data: 105_000_000.into(), - mem_grow: 800_000.into(), - mem_grow_per_page: 0.into(), - parachain_read_heuristic: 0.into(), - ..Default::default() - }; - - let result = check_pages_costs(page_costs, expected_page_costs); - - assert!(result.is_ok(), "{:#?}", result.err().unwrap()); - assert_eq!(result.unwrap(), expected_pages_costs_count()); -} - -#[test] -fn lazy_page_costs_heuristic_test() { - let lazy_pages_costs: LazyPagesCosts = MemoryWeights::::default().into(); - - let expected_lazy_pages_costs = LazyPagesCosts { - signal_read: 28_000_000.into(), - signal_write: 138_000_000.into(), - signal_write_after_read: 112_000_000.into(), - host_func_read: 29_000_000.into(), - host_func_write: 137_000_000.into(), - host_func_write_after_read: 112_000_000.into(), - load_page_storage_data: 9_000_000.into(), - ..Default::default() - }; - - let result = check_lazy_pages_costs(lazy_pages_costs, expected_lazy_pages_costs); - - assert!(result.is_ok(), "{:#?}", result.err().unwrap()); - assert_eq!(result.unwrap(), expected_lazy_pages_costs_count()); -} - -/// Check that it is not possible to write/change memory pages too cheaply, -/// because this may cause runtime heap memory overflow. -#[test] -fn write_is_not_too_cheap() { - let costs: LazyPagesCosts = MemoryWeights::::default().into(); - let cheapest_write = u64::MAX - .min(costs.signal_write.cost_for_one()) - .min(costs.signal_read.cost_for_one() + costs.signal_write_after_read.cost_for_one()) - .min(costs.host_func_write.cost_for_one()) - .min(costs.host_func_read.cost_for_one() + costs.host_func_write_after_read.cost_for_one()); - - let block_max_gas = 3 * 10 ^ 12; // 3 seconds - let runtime_heap_size_in_wasm_pages = 0x4000; // 1GB - assert!((block_max_gas / cheapest_write) < runtime_heap_size_in_wasm_pages); -}