gear_core_processor/
configs.rs

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