/__w/smoldot/smoldot/repo/lib/src/executor.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Smoldot |
2 | | // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. |
3 | | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 |
4 | | |
5 | | // This program is free software: you can redistribute it and/or modify |
6 | | // it under the terms of the GNU General Public License as published by |
7 | | // the Free Software Foundation, either version 3 of the License, or |
8 | | // (at your option) any later version. |
9 | | |
10 | | // This program is distributed in the hope that it will be useful, |
11 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | // GNU General Public License for more details. |
14 | | |
15 | | // You should have received a copy of the GNU General Public License |
16 | | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | |
18 | | //! WebAssembly runtime code execution. |
19 | | //! |
20 | | //! WebAssembly (often abbreviated *Wasm*) plays a big role in Substrate/Polkadot. The storage of |
21 | | //! each block in the chain has a special key named `:code` which contains the WebAssembly code |
22 | | //! of what we call *the runtime*. |
23 | | //! |
24 | | //! The runtime is a program (in WebAssembly) that decides, amongst other things, whether |
25 | | //! transactions are valid and how to apply them on the storage, and whether blocks themselves are |
26 | | //! valid. |
27 | | //! |
28 | | //! This module contains everything necessary to execute runtime code. The highest-level |
29 | | //! sub-module is [`runtime_call`]. |
30 | | |
31 | | mod allocator; // TODO: make public after refactoring |
32 | | pub mod host; |
33 | | pub mod runtime_call; |
34 | | pub mod storage_diff; |
35 | | pub mod trie_root_calculator; |
36 | | pub mod vm; |
37 | | |
38 | | pub use host::{CoreVersion, CoreVersionError, CoreVersionRef}; |
39 | | |
40 | | /// Default number of heap pages if the storage doesn't specify otherwise. |
41 | | /// |
42 | | /// # Context |
43 | | /// |
44 | | /// In order to initialize a [`host::HostVmPrototype`], one needs to pass a certain number of |
45 | | /// heap pages that are available to the runtime. |
46 | | /// |
47 | | /// This number is normally found in the storage, at the key `:heappages`. But if it is not |
48 | | /// specified, then the value of this constant must be used. |
49 | | pub const DEFAULT_HEAP_PAGES: vm::HeapPages = vm::HeapPages::new(2048); |
50 | | |
51 | | /// Converts a value of the key `:heappages` found in the storage to an actual number of heap |
52 | | /// pages. |
53 | 91 | pub fn storage_heap_pages_to_value( |
54 | 91 | storage_value: Option<&[u8]>, |
55 | 91 | ) -> Result<vm::HeapPages, InvalidHeapPagesError> { |
56 | 91 | if let Some(storage_value0 ) = storage_value { |
57 | 0 | let bytes = |
58 | 0 | <[u8; 8]>::try_from(storage_value).map_err(|_| InvalidHeapPagesError::WrongLen)?; Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot8executor27storage_heap_pages_to_value0B5_ Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot8executor27storage_heap_pages_to_value0B5_ |
59 | 0 | let num = u64::from_le_bytes(bytes); |
60 | 0 | let num = u32::try_from(num).map_err(|_| InvalidHeapPagesError::TooLarge)?; Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot8executor27storage_heap_pages_to_values_0B5_ Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot8executor27storage_heap_pages_to_values_0B5_ |
61 | 0 | Ok(vm::HeapPages::from(num)) |
62 | | } else { |
63 | 91 | Ok(DEFAULT_HEAP_PAGES) |
64 | | } |
65 | 91 | } _RNvNtCsN16ciHI6Qf_7smoldot8executor27storage_heap_pages_to_value Line | Count | Source | 53 | 5 | pub fn storage_heap_pages_to_value( | 54 | 5 | storage_value: Option<&[u8]>, | 55 | 5 | ) -> Result<vm::HeapPages, InvalidHeapPagesError> { | 56 | 5 | if let Some(storage_value0 ) = storage_value { | 57 | 0 | let bytes = | 58 | 0 | <[u8; 8]>::try_from(storage_value).map_err(|_| InvalidHeapPagesError::WrongLen)?; | 59 | 0 | let num = u64::from_le_bytes(bytes); | 60 | 0 | let num = u32::try_from(num).map_err(|_| InvalidHeapPagesError::TooLarge)?; | 61 | 0 | Ok(vm::HeapPages::from(num)) | 62 | | } else { | 63 | 5 | Ok(DEFAULT_HEAP_PAGES) | 64 | | } | 65 | 5 | } |
_RNvNtCseuYC0Zibziv_7smoldot8executor27storage_heap_pages_to_value Line | Count | Source | 53 | 86 | pub fn storage_heap_pages_to_value( | 54 | 86 | storage_value: Option<&[u8]>, | 55 | 86 | ) -> Result<vm::HeapPages, InvalidHeapPagesError> { | 56 | 86 | if let Some(storage_value0 ) = storage_value { | 57 | 0 | let bytes = | 58 | 0 | <[u8; 8]>::try_from(storage_value).map_err(|_| InvalidHeapPagesError::WrongLen)?; | 59 | 0 | let num = u64::from_le_bytes(bytes); | 60 | 0 | let num = u32::try_from(num).map_err(|_| InvalidHeapPagesError::TooLarge)?; | 61 | 0 | Ok(vm::HeapPages::from(num)) | 62 | | } else { | 63 | 86 | Ok(DEFAULT_HEAP_PAGES) | 64 | | } | 65 | 86 | } |
|
66 | | |
67 | | /// Error potentially returned by [`storage_heap_pages_to_value`]. |
68 | 0 | #[derive(Debug, derive_more::Display, Clone)] Unexecuted instantiation: _RNvXs_NtCsN16ciHI6Qf_7smoldot8executorNtB4_21InvalidHeapPagesErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt Unexecuted instantiation: _RNvXs_NtCseuYC0Zibziv_7smoldot8executorNtB4_21InvalidHeapPagesErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt |
69 | | pub enum InvalidHeapPagesError { |
70 | | /// Storage value has the wrong length. |
71 | | WrongLen, |
72 | | /// Number of heap pages is too large. |
73 | | TooLarge, |
74 | | } |