1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
// This file is part of Gear.
// Copyright (C) 2021-2023 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 <https://www.gnu.org/licenses/>.
//! Configurations.
use alloc::{collections::BTreeSet, vec::Vec};
use gear_backend_common::lazy_pages::LazyPagesWeights;
use gear_core::{
costs::{CostPerPage, HostFnWeights},
pages::{GearPage, WasmPage},
};
use gear_wasm_instrument::syscalls::SysCallName;
use scale_info::scale::{self, Decode, Encode};
/// Number of max pages number to use it in tests.
pub const TESTS_MAX_PAGES_NUMBER: u16 = 512;
/// Contextual block information.
#[derive(Clone, Copy, Debug, Encode, Decode, Default)]
#[codec(crate = scale)]
pub struct BlockInfo {
/// Height.
pub height: u32,
/// Timestamp.
pub timestamp: u64,
}
/// Memory operations costs.
///
/// Each weight with `lazy_pages_` prefix contains weight for storage read,
/// because for each first page access we need at least check if page exists in storage.
/// But they do not include cost for loading page data from storage into program memory.
/// This weight is taken in account separately, when loading occurs.
///
/// Lazy-pages write accesses does not include cost for uploading page data to storage,
/// because uploading happens after execution, so benchmarks do not include this cost.
/// But they include cost for processing changed page data in runtime.
#[derive(Clone, Debug, Decode, Encode, Default)]
#[codec(crate = scale)]
pub struct PageCosts {
/// Cost per one [GearPage] signal `read` processing in lazy-pages.
pub lazy_pages_signal_read: CostPerPage<GearPage>,
/// Cost per one [GearPage] signal `write` processing in lazy-pages,
pub lazy_pages_signal_write: CostPerPage<GearPage>,
/// Cost per one [GearPage] signal `write after read` processing in lazy-pages.
pub lazy_pages_signal_write_after_read: CostPerPage<GearPage>,
/// Cost per one [GearPage] host func `read` access processing in lazy-pages.
pub lazy_pages_host_func_read: CostPerPage<GearPage>,
/// Cost per one [GearPage] host func `write` access processing in lazy-pages.
pub lazy_pages_host_func_write: CostPerPage<GearPage>,
/// Cost per one [GearPage] host func `write after read` access processing in lazy-pages,
pub lazy_pages_host_func_write_after_read: CostPerPage<GearPage>,
/// Cost per one [GearPage] data loading from storage and moving it in program memory.
/// Does not include cost for storage read, because it is taken in account separately.
pub load_page_data: CostPerPage<GearPage>,
/// Cost per one [GearPage] uploading data to storage.
/// Does not include cost for processing changed page data in runtime,
/// cause it is taken in account separately.
pub upload_page_data: CostPerPage<GearPage>,
/// Cost per one [WasmPage] static page. Static pages can have static data,
/// and executor must to move this data to static pages before execution.
pub static_page: CostPerPage<WasmPage>,
/// Cost per one [WasmPage] for memory growing.
pub mem_grow: CostPerPage<WasmPage>,
/// Cost per one [GearPage] storage read, when para-chain execution.
pub parachain_load_heuristic: CostPerPage<GearPage>,
}
impl PageCosts {
/// Calculates and returns weights for lazy-pages.
pub fn lazy_pages_weights(&self) -> LazyPagesWeights {
// Because page may have not data in storage, we do not include
// cost for loading page data from storage in weights. We provide
// this cost in `load_page_data` field, so lazy-pages can use it
// when page data is in storage and must be loaded.
// On other hand we include cost for uploading page data to storage
// in each `write` weight, because each write cause page uploading.
LazyPagesWeights {
signal_read: self.lazy_pages_signal_read,
signal_write: self
.lazy_pages_signal_write
.saturating_add(self.upload_page_data),
signal_write_after_read: self
.lazy_pages_signal_write_after_read
.saturating_add(self.upload_page_data),
host_func_read: self.lazy_pages_host_func_read,
host_func_write: self
.lazy_pages_host_func_write
.saturating_add(self.upload_page_data),
host_func_write_after_read: self
.lazy_pages_host_func_write_after_read
.saturating_add(self.upload_page_data),
load_page_storage_data: self
.load_page_data
.saturating_add(self.parachain_load_heuristic),
}
}
/// New one for tests usage.
pub fn new_for_tests() -> Self {
let a = 1000.into();
let b = 4000.into();
Self {
lazy_pages_signal_read: a,
lazy_pages_signal_write: a,
lazy_pages_signal_write_after_read: a,
lazy_pages_host_func_read: a,
lazy_pages_host_func_write: a,
lazy_pages_host_func_write_after_read: a,
load_page_data: a,
upload_page_data: a,
static_page: b,
mem_grow: b,
parachain_load_heuristic: a,
}
}
}
/// Execution settings for handling messages.
pub struct ExecutionSettings {
/// Contextual block information.
pub block_info: BlockInfo,
/// Max amount of pages in program memory during execution.
pub max_pages: WasmPage,
/// Pages costs.
pub page_costs: PageCosts,
/// Minimal amount of existence for account.
pub existential_deposit: u128,
/// Weights of host functions.
pub host_fn_weights: HostFnWeights,
/// Functions forbidden to be called.
pub forbidden_funcs: BTreeSet<SysCallName>,
/// Threshold for inserting into mailbox
pub mailbox_threshold: u64,
/// Cost for single block waitlist holding.
pub waitlist_cost: u64,
/// Cost of holding a message in dispatch stash.
pub dispatch_hold_cost: u64,
/// Reserve for parameter of scheduling.
pub reserve_for: u32,
/// Cost for reservation holding.
pub reservation: u64,
/// Most recently determined random seed, along with the time in the past since when it was determinable by chain observers.
// TODO: find a way to put a random seed inside block config.
pub random_data: (Vec<u8>, u32),
/// Rent cost per block.
pub rent_cost: u128,
}
/// Stable parameters for the whole block across processing runs.
#[derive(Clone)]
pub struct BlockConfig {
/// Block info.
pub block_info: BlockInfo,
/// Max allowed page numbers for wasm program.
pub max_pages: WasmPage,
/// Allocations config.
pub page_costs: PageCosts,
/// Existential deposit.
pub existential_deposit: u128,
/// Outgoing limit.
pub outgoing_limit: u32,
/// Host function weights.
pub host_fn_weights: HostFnWeights,
/// Forbidden functions.
pub forbidden_funcs: BTreeSet<SysCallName>,
/// Mailbox threshold.
pub mailbox_threshold: u64,
/// Cost for single block waitlist holding.
pub waitlist_cost: u64,
/// Cost of holding a message in dispatch stash.
pub dispatch_hold_cost: u64,
/// Reserve for parameter of scheduling.
pub reserve_for: u32,
/// Cost for reservation holding.
pub reservation: u64,
/// One-time db-read cost.
pub read_cost: u64,
/// One-time db-write cost.
pub write_cost: u64,
/// Per written byte cost.
pub write_per_byte_cost: u64,
/// Per loaded byte cost.
pub read_per_byte_cost: u64,
/// WASM module instantiation byte cost.
pub module_instantiation_byte_cost: u64,
/// Amount of reservations can exist for 1 program.
pub max_reservations: u64,
/// WASM code instrumentation base cost.
pub code_instrumentation_cost: u64,
/// WASM code instrumentation per-byte cost.
pub code_instrumentation_byte_cost: u64,
/// Rent cost per block.
pub rent_cost: u128,
}