Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/executor/host.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
//! Wasm virtual machine specific to the Substrate/Polkadot Runtime Environment.
19
//!
20
//! Contrary to [`VirtualMachine`](super::vm::VirtualMachine), this code is not just a generic
21
//! Wasm virtual machine, but is aware of the Substrate/Polkadot runtime environment. The host
22
//! functions that the Wasm code calls are automatically resolved and either handled or notified
23
//! to the user of this module.
24
//!
25
//! Any host function that requires pure CPU computations (for example building or verifying
26
//! a cryptographic signature) is directly handled by the code in this module. Other host
27
//! functions (for example accessing the state or printing a message) are instead handled by
28
//! interrupting the virtual machine and waiting for the user of this module to handle the call.
29
//!
30
//! > **Note**: The `ext_offchain_random_seed_version_1` and `ext_offchain_timestamp_version_1`
31
//! >           functions, which requires the host to respectively produce a random seed and
32
//! >           return the current time, must also be handled by the user. While these functions
33
//! >           could theoretically be handled directly by this module, it might be useful for
34
//! >           testing purposes to have the possibility to return a deterministic value.
35
//!
36
//! Contrary to most programs, runtime code doesn't have a singe `main` or `start` function.
37
//! Instead, it exposes several entry points. Which one to call indicates which action it has to
38
//! perform. Not all entry points are necessarily available on all runtimes.
39
//!
40
//! # Runtime requirements
41
//!
42
//! See the [documentation of the `vm` module](super::vm) for details about the requirements a
43
//! runtime must adhere to.
44
//!
45
//! In addition to the requirements described there, the WebAssembly runtime code can also be
46
//! zstandard-compressed and must also export a global symbol named `__heap_base`.
47
//! More details below.
48
//!
49
//! ## `Zstandard` compression
50
//!
51
//! The runtime code passed as parameter to [`HostVmPrototype::new`] can be compressed using the
52
//! [`zstd`](https://en.wikipedia.org/wiki/Zstandard) algorithm.
53
//!
54
//! If the code starts with the magic bytes `[82, 188, 83, 118, 70, 219, 142, 5]`, then it is
55
//! assumed that the rest of the data is a zstandard-compressed WebAssembly module.
56
//!
57
//! ## Runtime version
58
//!
59
//! Wasm files can contain so-called custom sections. A runtime can contain two custom sections
60
//! whose names are `"runtime_version"` and `"runtime_apis"`, in which case they must contain a
61
//! so-called runtime version.
62
//!
63
//! The runtime version contains important field that identifies a runtime.
64
//!
65
//! If no `"runtime_version"` and `"runtime_apis"` custom sections can be found, the
66
//! `Core_version` entry point is used as a fallback in order to obtain the runtime version. This
67
//! fallback mechanism is maintained for backwards compatibility purposes, but is considered
68
//! deprecated.
69
//!
70
//! ## Memory allocations
71
//!
72
//! One of the instructions available in WebAssembly code is
73
//! [the `memory.grow` instruction](https://webassembly.github.io/spec/core/bikeshed/#-hrefsyntax-instr-memorymathsfmemorygrow),
74
//! which allows increasing the size of the memory.
75
//!
76
//! WebAssembly code is normally intended to perform its own heap-management logic internally, and
77
//! use the `memory.grow` instruction if more memory is needed.
78
//!
79
//! In order to minimize the size of the runtime binary, and in order to accommodate for the API of
80
//! the host functions that return a buffer of variable length, the Substrate/Polkadot runtimes,
81
//! however, do not perform their heap management internally. Instead, they use the
82
//! `ext_allocator_malloc_version_1` and `ext_allocator_free_version_1` host functions for this
83
//! purpose. Calling `memory.grow` is forbidden.
84
//!
85
//! The runtime code must export a global symbol named `__heap_base` of type `i32`. Any memory
86
//! whose offset is below the value of `__heap_base` can be used at will by the program, while
87
//! any memory above `__heap_base` but below `__heap_base + heap_pages` (where `heap_pages` is
88
//! the value passed as parameter to [`HostVmPrototype::new`]) is available for use by the
89
//! implementation of `ext_allocator_malloc_version_1`.
90
//!
91
//! ## Entry points
92
//!
93
//! All entry points that can be called from the host (using, for example,
94
//! [`HostVmPrototype::run`]) have the same signature:
95
//!
96
//! ```ignore
97
//! (func $runtime_entry(param $data i32) (param $len i32) (result i64))
98
//! ```
99
//!
100
//! In order to call into the runtime, one must write a buffer of data containing the input
101
//! parameters into the Wasm virtual machine's memory, then pass a pointer and length of this
102
//! buffer as the parameters of the entry point.
103
//!
104
//! The function returns a 64 bits number. The 32 less significant bits represent a pointer to the
105
//! Wasm virtual machine's memory, and the 32 most significant bits a length. This pointer and
106
//! length designate a buffer containing the actual return value.
107
//!
108
//! ## Host functions
109
//!
110
//! The list of host functions available to the runtime is long and isn't documented here. See
111
//! the official specification for details.
112
//!
113
//! # Usage
114
//!
115
//! The first step is to create a [`HostVmPrototype`] object from the WebAssembly code. Creating
116
//! this object performs some initial steps, such as parsing and compiling the WebAssembly code.
117
//! You are encouraged to maintain a cache of [`HostVmPrototype`] objects (one instance per
118
//! WebAssembly byte code) in order to avoid performing these operations too often.
119
//!
120
//! To start calling the runtime, create a [`HostVm`] by calling [`HostVmPrototype::run`].
121
//!
122
//! While the Wasm runtime code has side-effects (such as storing values in the storage), the
123
//! [`HostVm`] itself is a pure state machine with no side effects.
124
//!
125
//! At any given point, you can examine the [`HostVm`] in order to know in which state the
126
//! execution currently is.
127
//! In case of a [`HostVm::ReadyToRun`] (which initially is the case when you create the
128
//! [`HostVm`]), you can execute the Wasm code by calling [`ReadyToRun::run`].
129
//! No background thread of any kind is used, and calling [`ReadyToRun::run`] directly performs
130
//! the execution of the Wasm code. If you need parallelism, you are encouraged to spawn a
131
//! background thread yourself and call this function from there.
132
//! [`ReadyToRun::run`] tries to make the execution progress as much as possible, and returns
133
//! the new state of the virtual machine once that is done.
134
//!
135
//! If the runtime has finished, or has crashed, or wants to perform an operation with side
136
//! effects, then the [`HostVm`] determines what to do next. For example, for
137
//! [`HostVm::ExternalStorageGet`], you must load a value from the storage and pass it back by
138
//! calling [`ExternalStorageGet::resume`].
139
//!
140
//! The Wasm execution is fully deterministic, and the outcome of the execution only depends on
141
//! the inputs. There is, for example, no implicit injection of randomness or of the current time.
142
//!
143
//! ## Example
144
//!
145
//! ```
146
//! use smoldot::executor::host::{
147
//!     Config, HeapPages, HostVm, HostVmPrototype, StorageProofSizeBehavior
148
//! };
149
//!
150
//! # let wasm_binary_code: &[u8] = return;
151
//!
152
//! // Start executing a function on the runtime.
153
//! let mut vm: HostVm = {
154
//!     let prototype = HostVmPrototype::new(Config {
155
//!         module: &wasm_binary_code,
156
//!         heap_pages: HeapPages::from(2048),
157
//!         exec_hint: smoldot::executor::vm::ExecHint::ValidateAndExecuteOnce,
158
//!         allow_unresolved_imports: false
159
//!     }).unwrap();
160
//!     prototype.run_no_param(
161
//!         "Core_version",
162
//!         StorageProofSizeBehavior::proof_recording_disabled()
163
//!     ).unwrap().into()
164
//! };
165
//!
166
//! // We need to answer the calls that the runtime might perform.
167
//! loop {
168
//!     match vm {
169
//!         // Calling `runner.run()` is what actually executes WebAssembly code and updates
170
//!         // the state.
171
//!         HostVm::ReadyToRun(runner) => vm = runner.run(),
172
//!
173
//!         HostVm::Finished(finished) => {
174
//!             // `finished.value()` here is an opaque blob of bytes returned by the runtime.
175
//!             // In the case of a call to `"Core_version"`, we know that it must be empty.
176
//!             assert!(finished.value().as_ref().is_empty());
177
//!             println!("Success!");
178
//!             break;
179
//!         },
180
//!
181
//!         // Errors can happen if the WebAssembly code panics or does something wrong.
182
//!         // In a real-life situation, the host should obviously not panic in these situations.
183
//!         HostVm::Error { .. } => {
184
//!             panic!("Error while executing code")
185
//!         },
186
//!
187
//!         // All the other variants correspond to function calls that the runtime might perform.
188
//!         // `ExternalStorageGet` is shown here as an example.
189
//!         HostVm::ExternalStorageGet(req) => {
190
//!             println!("Runtime requires the storage value at {:?}", req.key().as_ref());
191
//!             // Injects the value into the virtual machine and updates the state.
192
//!             vm = req.resume(None); // Just a stub
193
//!         }
194
//!         _ => unimplemented!()
195
//!     }
196
//! }
197
//! ```
198
199
use super::{allocator, vm};
200
use crate::{trie, util};
201
202
use alloc::{borrow::ToOwned as _, boxed::Box, string::String, sync::Arc, vec, vec::Vec};
203
use core::{fmt, hash::Hasher as _, iter, str};
204
use functions::HostFunction;
205
206
pub mod runtime_version;
207
208
pub use runtime_version::{
209
    CoreVersion, CoreVersionApisFromSliceErr, CoreVersionError, CoreVersionRef,
210
    FindEncodedEmbeddedRuntimeVersionApisError,
211
};
212
pub use trie::TrieEntryVersion;
213
pub use vm::HeapPages;
214
pub use zstd::Error as ModuleFormatError;
215
216
mod functions;
217
mod tests;
218
mod zstd;
219
220
/// Configuration for [`HostVmPrototype::new`].
221
pub struct Config<TModule> {
222
    /// Bytes of the WebAssembly module.
223
    ///
224
    /// The module can be either directly Wasm bytecode, or zstandard-compressed.
225
    pub module: TModule,
226
227
    /// Number of pages of heap available to the virtual machine.
228
    ///
229
    /// See the module-level documentation for an explanation.
230
    pub heap_pages: HeapPages,
231
232
    /// Hint used by the implementation to decide which kind of virtual machine to use.
233
    pub exec_hint: vm::ExecHint,
234
235
    /// If `true`, no [`vm::NewErr::UnresolvedFunctionImport`] error will be returned if the
236
    /// module trying to import functions that aren't recognized by the implementation. Instead,
237
    /// a [`Error::UnresolvedFunctionCalled`] error will be generated if the module tries to call
238
    /// an unresolved function.
239
    pub allow_unresolved_imports: bool,
240
}
241
242
/// Behavior if the `ext_storage_proof_size_storage_proof_size_version_1` host function is called.
243
///
244
/// When authoring a block or executing a block, this host function is expected to return the
245
/// current size of the proof. Smoldot unfortunately can't implement this due to the fact that
246
/// the proof generation algorithm is completely unspecified. For this reason, you should
247
/// use [`StorageProofSizeBehavior::Unimplemented`]. However, for testing purposes, using
248
/// `StorageProofSizeBehavior::ConstantReturnValue(0)` is acceptable.
249
///
250
/// In situations other than authoring or executing a block, use the value returned by
251
/// [`StorageProofSizeBehavior::proof_recording_disabled`].
252
///
253
#[derive(Debug, Clone, PartialEq, Eq)]
254
pub enum StorageProofSizeBehavior {
255
    /// The host function is unimplemented. An error is returned if it is called.
256
    Unimplemented,
257
    /// The host function returns the given value.
258
    ConstantReturnValue(u64),
259
}
260
261
impl StorageProofSizeBehavior {
262
    /// Returns the behavior to employ when proof recording is disabled, as defined in the
263
    /// specification.
264
171
    pub fn proof_recording_disabled() -> Self {
265
171
        StorageProofSizeBehavior::ConstantReturnValue(u64::MAX)
266
171
    }
_RNvMNtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB2_24StorageProofSizeBehavior24proof_recording_disabled
Line
Count
Source
264
44
    pub fn proof_recording_disabled() -> Self {
265
44
        StorageProofSizeBehavior::ConstantReturnValue(u64::MAX)
266
44
    }
_RNvMNtNtCseuYC0Zibziv_7smoldot8executor4hostNtB2_24StorageProofSizeBehavior24proof_recording_disabled
Line
Count
Source
264
127
    pub fn proof_recording_disabled() -> Self {
265
127
        StorageProofSizeBehavior::ConstantReturnValue(u64::MAX)
266
127
    }
267
}
268
269
/// Prototype for an [`HostVm`].
270
///
271
/// > **Note**: This struct implements `Clone`. Cloning a [`HostVmPrototype`] allocates memory
272
/// >           necessary for the clone to run.
273
#[derive(Clone)]
274
pub struct HostVmPrototype {
275
    /// Fields that are kept as is even during the execution.
276
    common: Box<VmCommon>,
277
278
    /// Inner virtual machine prototype.
279
    vm_proto: vm::VirtualMachinePrototype,
280
}
281
282
/// Fields that are kept as is even during the execution.
283
#[derive(Clone)]
284
struct VmCommon {
285
    /// Runtime version of this runtime.
286
    ///
287
    /// Always `Some`, except at initialization.
288
    runtime_version: Option<CoreVersion>,
289
290
    /// Initial value of the `__heap_base` global in the Wasm module. Used to initialize the memory
291
    /// allocator.
292
    heap_base: u32,
293
294
    /// List of functions that the Wasm code imports.
295
    ///
296
    /// The keys of this list (i.e. the `usize` indices) have been passed to the virtual machine
297
    /// executor. Whenever the Wasm code invokes a host function, we obtain its index, and look
298
    /// within this list to know what to do.
299
    registered_functions: Arc<[FunctionImport]>,
300
301
    /// Value of `heap_pages` passed to [`HostVmPrototype::new`].
302
    heap_pages: HeapPages,
303
304
    /// Total number of pages of Wasm memory. This is equal to `heap_base / 64k` (rounded up) plus
305
    /// `heap_pages`.
306
    memory_total_pages: HeapPages,
307
}
308
309
impl HostVmPrototype {
310
    /// Creates a new [`HostVmPrototype`]. Parses and potentially JITs the module.
311
154
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
154
        let 
module_bytes152
= zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
154
            .map_err(NewErr::BadFormat)
?2
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
152
        let 
runtime_version150
= match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
147
            Ok(Some(r)) => Some(r),
329
1
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
2
            ) => None,
333
2
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
2
                return Err(NewErr::RuntimeVersion(
335
2
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
2
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
144
        let (mut vm_proto, registered_functions) = {
355
150
            let mut registered_functions = Vec::new();
356
150
            let 
vm_proto144
= vm::VirtualMachinePrototype::new(vm::Config {
357
150
                module_bytes: &module_bytes[..],
358
150
                exec_hint: config.exec_hint,
359
150
                // This closure is called back for each function that the runtime imports.
360
2.95k
                symbols: &mut |mod_name, f_name, signature| {
361
2.95k
                    if mod_name != "env" {
362
0
                        return Err(());
363
2.95k
                    }
364
2.95k
365
2.95k
                    let id = registered_functions.len();
366
2.95k
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
2.94k
                        Some(
f2.93k
) if f.signature() == *signatur
e => FunctionImport::Resolved(f)2.93k
,
368
6
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
6
                            return Err(());
371
                        }
372
13
                        Some(_) | None => FunctionImport::Unresolved {
373
13
                            name: f_name.to_owned(),
374
13
                            module: mod_name.to_owned(),
375
13
                        },
376
                    });
377
2.94k
                    Ok(id)
378
2.95k
                },
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1R_11Interpreter11read_memory12AccessOffsetB1F_EEE0Bb_
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEE0Bb_
Line
Count
Source
360
46
                symbols: &mut |mod_name, f_name, signature| {
361
46
                    if mod_name != "env" {
362
0
                        return Err(());
363
46
                    }
364
46
365
46
                    let id = registered_functions.len();
366
46
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
46
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
46
                    Ok(id)
378
46
                },
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEE0Bb_
Line
Count
Source
360
170
                symbols: &mut |mod_name, f_name, signature| {
361
170
                    if mod_name != "env" {
362
0
                        return Err(());
363
170
                    }
364
170
365
170
                    let id = registered_functions.len();
366
170
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
162
                        Some(
f158
) if f.signature() == *signatur
e => FunctionImport::Resolved(f)158
,
368
6
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
6
                            return Err(());
371
                        }
372
6
                        Some(_) | None => FunctionImport::Unresolved {
373
6
                            name: f_name.to_owned(),
374
6
                            module: mod_name.to_owned(),
375
6
                        },
376
                    });
377
164
                    Ok(id)
378
170
                },
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6_E0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6b_E0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhjd_E0Bb_
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0Bb_
Line
Count
Source
360
149
                symbols: &mut |mod_name, f_name, signature| {
361
149
                    if mod_name != "env" {
362
0
                        return Err(());
363
149
                    }
364
149
365
149
                    let id = registered_functions.len();
366
149
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
142
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
7
                        Some(_) | None => FunctionImport::Unresolved {
373
7
                            name: f_name.to_owned(),
374
7
                            module: mod_name.to_owned(),
375
7
                        },
376
                    });
377
149
                    Ok(id)
378
149
                },
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShE0Bb_
Line
Count
Source
360
96
                symbols: &mut |mod_name, f_name, signature| {
361
96
                    if mod_name != "env" {
362
0
                        return Err(());
363
96
                    }
364
96
365
96
                    let id = registered_functions.len();
366
96
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
96
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
96
                    Ok(id)
378
96
                },
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEE0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1S_11Interpreter11read_memory12AccessOffsetB1G_EEE0Bb_
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEE0Bb_
Line
Count
Source
360
609
                symbols: &mut |mod_name, f_name, signature| {
361
609
                    if mod_name != "env" {
362
0
                        return Err(());
363
609
                    }
364
609
365
609
                    let id = registered_functions.len();
366
609
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
609
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
609
                    Ok(id)
378
609
                },
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0Bb_
Line
Count
Source
360
609
                symbols: &mut |mod_name, f_name, signature| {
361
609
                    if mod_name != "env" {
362
0
                        return Err(());
363
609
                    }
364
609
365
609
                    let id = registered_functions.len();
366
609
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
609
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
609
                    Ok(id)
378
609
                },
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEE0CsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
360
58
                symbols: &mut |mod_name, f_name, signature| {
361
58
                    if mod_name != "env" {
362
0
                        return Err(());
363
58
                    }
364
58
365
58
                    let id = registered_functions.len();
366
58
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
58
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
58
                    Ok(id)
378
58
                },
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEE0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0CsiLzmwikkc22_14json_rpc_basic
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShE0CsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
360
58
                symbols: &mut |mod_name, f_name, signature| {
361
58
                    if mod_name != "env" {
362
0
                        return Err(());
363
58
                    }
364
58
365
58
                    let id = registered_functions.len();
366
58
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
58
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
58
                    Ok(id)
378
58
                },
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEE0CsiUjFBJteJ7x_17smoldot_full_node
Line
Count
Source
360
58
                symbols: &mut |mod_name, f_name, signature| {
361
58
                    if mod_name != "env" {
362
0
                        return Err(());
363
58
                    }
364
58
365
58
                    let id = registered_functions.len();
366
58
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
58
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
58
                    Ok(id)
378
58
                },
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShE0CscDgN54JpMGG_6author
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEE0CsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
360
551
                symbols: &mut |mod_name, f_name, signature| {
361
551
                    if mod_name != "env" {
362
0
                        return Err(());
363
551
                    }
364
551
365
551
                    let id = registered_functions.len();
366
551
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
551
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
551
                    Ok(id)
378
551
                },
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEE0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShE0CsibGXYHQB8Ea_25json_rpc_general_requests
_RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShE0CsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
360
551
                symbols: &mut |mod_name, f_name, signature| {
361
551
                    if mod_name != "env" {
362
0
                        return Err(());
363
551
                    }
364
551
365
551
                    let id = registered_functions.len();
366
551
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
551
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
0
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
0
                            return Err(());
371
                        }
372
0
                        Some(_) | None => FunctionImport::Unresolved {
373
0
                            name: f_name.to_owned(),
374
0
                            module: mod_name.to_owned(),
375
0
                        },
376
                    });
377
551
                    Ok(id)
378
551
                },
379
150
            })
?6
;
380
144
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
144
        let 
heap_base142
= vm_proto
386
144
            .global_value("__heap_base")
387
144
            .map_err(|_| 
NewErr::HeapBaseNotFound2
)
?2
;
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1R_11Interpreter11read_memory12AccessOffsetB1F_EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0Bb_
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0Bb_
Line
Count
Source
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)?;
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6_Es_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6b_Es_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhjd_Es_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1S_11Interpreter11read_memory12AccessOffsetB1G_EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
388
389
142
        let memory_total_pages = if heap_base == 0 {
390
14
            config.heap_pages
391
        } else {
392
128
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
142
        if vm_proto
396
142
            .memory_max_pages()
397
142
            .map_or(false, |max| 
max < memory_total_pages2
)
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1R_11Interpreter11read_memory12AccessOffsetB1F_EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0Bb_
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0Bb_
Line
Count
Source
397
2
            .map_or(false, |max| max < memory_total_pages)
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6_Es0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhj6b_Es0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRAhjd_Es0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB9_2vm11interpreterNtB1S_11Interpreter11read_memory12AccessOffsetB1G_EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRRShEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype3newRShEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
398
        {
399
2
            return Err(NewErr::MemoryMaxSizeTooLow);
400
140
        }
401
140
402
140
        let mut host_vm_prototype = HostVmPrototype {
403
140
            vm_proto,
404
140
            common: Box::new(VmCommon {
405
140
                runtime_version,
406
140
                heap_base,
407
140
                registered_functions,
408
140
                heap_pages: config.heap_pages,
409
140
                memory_total_pages,
410
140
            }),
411
140
        };
412
140
413
140
        // Call `Core_version` if no runtime version is known yet.
414
140
        if host_vm_prototype.common.runtime_version.is_none() {
415
3
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
3
                "Core_version",
417
3
                StorageProofSizeBehavior::proof_recording_disabled(),
418
3
            ) {
419
3
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
10
            loop {
424
10
                match vm {
425
5
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
3
                    HostVm::Finished(finished) => {
427
3
                        let version =
428
3
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
3
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
3
                        host_vm_prototype = finished.into_prototype();
436
3
                        host_vm_prototype.common.runtime_version = Some(version);
437
3
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
2
                    HostVm::GetMaxLogLevel(resume) => {
442
2
                        vm = resume.resume(0); // Off
443
2
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
137
        }
456
457
        // Success!
458
140
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
140
        Ok(host_vm_prototype)
460
154
    }
Unexecuted instantiation: _RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB7_2vm11interpreterNtB1P_11Interpreter11read_memory12AccessOffsetB1D_EEEB9_
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEB9_
Line
Count
Source
311
1
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
1
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
1
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
1
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
1
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
1
        let (mut vm_proto, registered_functions) = {
355
1
            let mut registered_functions = Vec::new();
356
1
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
1
                module_bytes: &module_bytes[..],
358
1
                exec_hint: config.exec_hint,
359
1
                // This closure is called back for each function that the runtime imports.
360
1
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
1
                },
379
1
            })
?0
;
380
1
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
1
        let heap_base = vm_proto
386
1
            .global_value("__heap_base")
387
1
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
1
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
1
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
1
        if vm_proto
396
1
            .memory_max_pages()
397
1
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
1
        }
401
1
402
1
        let mut host_vm_prototype = HostVmPrototype {
403
1
            vm_proto,
404
1
            common: Box::new(VmCommon {
405
1
                runtime_version,
406
1
                heap_base,
407
1
                registered_functions,
408
1
                heap_pages: config.heap_pages,
409
1
                memory_total_pages,
410
1
            }),
411
1
        };
412
1
413
1
        // Call `Core_version` if no runtime version is known yet.
414
1
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
1
        }
456
457
        // Success!
458
1
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
1
        Ok(host_vm_prototype)
460
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEEB9_
Line
Count
Source
311
56
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
56
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
56
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
56
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
56
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
50
        let (mut vm_proto, registered_functions) = {
355
56
            let mut registered_functions = Vec::new();
356
56
            let 
vm_proto50
= vm::VirtualMachinePrototype::new(vm::Config {
357
56
                module_bytes: &module_bytes[..],
358
56
                exec_hint: config.exec_hint,
359
56
                // This closure is called back for each function that the runtime imports.
360
56
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
56
                },
379
56
            })
?6
;
380
50
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
50
        let 
heap_base48
= vm_proto
386
50
            .global_value("__heap_base")
387
50
            .map_err(|_| NewErr::HeapBaseNotFound)
?2
;
388
389
48
        let memory_total_pages = if heap_base == 0 {
390
12
            config.heap_pages
391
        } else {
392
36
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
48
        if vm_proto
396
48
            .memory_max_pages()
397
48
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
2
            return Err(NewErr::MemoryMaxSizeTooLow);
400
46
        }
401
46
402
46
        let mut host_vm_prototype = HostVmPrototype {
403
46
            vm_proto,
404
46
            common: Box::new(VmCommon {
405
46
                runtime_version,
406
46
                heap_base,
407
46
                registered_functions,
408
46
                heap_pages: config.heap_pages,
409
46
                memory_total_pages,
410
46
            }),
411
46
        };
412
46
413
46
        // Call `Core_version` if no runtime version is known yet.
414
46
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
46
        }
456
457
        // Success!
458
46
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
46
        Ok(host_vm_prototype)
460
56
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRAhj6_EB9_
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let 
runtime_version0
= match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
0
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
2
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
2
                return Err(NewErr::RuntimeVersion(
335
2
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
2
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
0
        let (mut vm_proto, registered_functions) = {
355
0
            let mut registered_functions = Vec::new();
356
0
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
0
                module_bytes: &module_bytes[..],
358
0
                exec_hint: config.exec_hint,
359
0
                // This closure is called back for each function that the runtime imports.
360
0
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
0
                },
379
0
            })?;
380
0
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
0
        let heap_base = vm_proto
386
0
            .global_value("__heap_base")
387
0
            .map_err(|_| NewErr::HeapBaseNotFound)?;
388
389
0
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
0
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
0
        if vm_proto
396
0
            .memory_max_pages()
397
0
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
0
        }
401
0
402
0
        let mut host_vm_prototype = HostVmPrototype {
403
0
            vm_proto,
404
0
            common: Box::new(VmCommon {
405
0
                runtime_version,
406
0
                heap_base,
407
0
                registered_functions,
408
0
                heap_pages: config.heap_pages,
409
0
                memory_total_pages,
410
0
            }),
411
0
        };
412
0
413
0
        // Call `Core_version` if no runtime version is known yet.
414
0
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
0
        }
456
457
        // Success!
458
0
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
0
        Ok(host_vm_prototype)
460
2
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRAhj6b_EB9_
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
2
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
2
        let (mut vm_proto, registered_functions) = {
355
2
            let mut registered_functions = Vec::new();
356
2
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
2
                module_bytes: &module_bytes[..],
358
2
                exec_hint: config.exec_hint,
359
2
                // This closure is called back for each function that the runtime imports.
360
2
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
2
                },
379
2
            })
?0
;
380
2
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
2
        let heap_base = vm_proto
386
2
            .global_value("__heap_base")
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
2
        let memory_total_pages = if heap_base == 0 {
390
2
            config.heap_pages
391
        } else {
392
0
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
2
        if vm_proto
396
2
            .memory_max_pages()
397
2
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
2
        }
401
2
402
2
        let mut host_vm_prototype = HostVmPrototype {
403
2
            vm_proto,
404
2
            common: Box::new(VmCommon {
405
2
                runtime_version,
406
2
                heap_base,
407
2
                registered_functions,
408
2
                heap_pages: config.heap_pages,
409
2
                memory_total_pages,
410
2
            }),
411
2
        };
412
2
413
2
        // Call `Core_version` if no runtime version is known yet.
414
2
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
2
        }
456
457
        // Success!
458
2
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
2
        Ok(host_vm_prototype)
460
2
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRAhjd_EB9_
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let 
module_bytes0
= zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)?;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
0
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
0
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
0
        let (mut vm_proto, registered_functions) = {
355
0
            let mut registered_functions = Vec::new();
356
0
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
0
                module_bytes: &module_bytes[..],
358
0
                exec_hint: config.exec_hint,
359
0
                // This closure is called back for each function that the runtime imports.
360
0
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
0
                },
379
0
            })?;
380
0
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
0
        let heap_base = vm_proto
386
0
            .global_value("__heap_base")
387
0
            .map_err(|_| NewErr::HeapBaseNotFound)?;
388
389
0
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
0
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
0
        if vm_proto
396
0
            .memory_max_pages()
397
0
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
0
        }
401
0
402
0
        let mut host_vm_prototype = HostVmPrototype {
403
0
            vm_proto,
404
0
            common: Box::new(VmCommon {
405
0
                runtime_version,
406
0
                heap_base,
407
0
                registered_functions,
408
0
                heap_pages: config.heap_pages,
409
0
                memory_total_pages,
410
0
            }),
411
0
        };
412
0
413
0
        // Call `Core_version` if no runtime version is known yet.
414
0
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
0
        }
456
457
        // Success!
458
0
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
0
        Ok(host_vm_prototype)
460
2
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShEB9_
Line
Count
Source
311
3
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
3
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
3
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
3
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
0
            Ok(Some(r)) => Some(r),
329
1
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
2
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
3
        let (mut vm_proto, registered_functions) = {
355
3
            let mut registered_functions = Vec::new();
356
3
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
3
                module_bytes: &module_bytes[..],
358
3
                exec_hint: config.exec_hint,
359
3
                // This closure is called back for each function that the runtime imports.
360
3
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
3
                },
379
3
            })
?0
;
380
3
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
3
        let heap_base = vm_proto
386
3
            .global_value("__heap_base")
387
3
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
3
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
3
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
3
        if vm_proto
396
3
            .memory_max_pages()
397
3
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
3
        }
401
3
402
3
        let mut host_vm_prototype = HostVmPrototype {
403
3
            vm_proto,
404
3
            common: Box::new(VmCommon {
405
3
                runtime_version,
406
3
                heap_base,
407
3
                registered_functions,
408
3
                heap_pages: config.heap_pages,
409
3
                memory_total_pages,
410
3
            }),
411
3
        };
412
3
413
3
        // Call `Core_version` if no runtime version is known yet.
414
3
        if host_vm_prototype.common.runtime_version.is_none() {
415
3
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
3
                "Core_version",
417
3
                StorageProofSizeBehavior::proof_recording_disabled(),
418
3
            ) {
419
3
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
10
            loop {
424
10
                match vm {
425
5
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
3
                    HostVm::Finished(finished) => {
427
3
                        let version =
428
3
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
3
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
3
                        host_vm_prototype = finished.into_prototype();
436
3
                        host_vm_prototype.common.runtime_version = Some(version);
437
3
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
2
                    HostVm::GetMaxLogLevel(resume) => {
442
2
                        vm = resume.resume(0); // Off
443
2
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
0
        }
456
457
        // Success!
458
3
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
3
        Ok(host_vm_prototype)
460
3
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype3newRShEB9_
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
2
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
2
        let (mut vm_proto, registered_functions) = {
355
2
            let mut registered_functions = Vec::new();
356
2
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
2
                module_bytes: &module_bytes[..],
358
2
                exec_hint: config.exec_hint,
359
2
                // This closure is called back for each function that the runtime imports.
360
2
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
2
                },
379
2
            })
?0
;
380
2
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
2
        let heap_base = vm_proto
386
2
            .global_value("__heap_base")
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
2
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
2
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
2
        if vm_proto
396
2
            .memory_max_pages()
397
2
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
2
        }
401
2
402
2
        let mut host_vm_prototype = HostVmPrototype {
403
2
            vm_proto,
404
2
            common: Box::new(VmCommon {
405
2
                runtime_version,
406
2
                heap_base,
407
2
                registered_functions,
408
2
                heap_pages: config.heap_pages,
409
2
                memory_total_pages,
410
2
            }),
411
2
        };
412
2
413
2
        // Call `Core_version` if no runtime version is known yet.
414
2
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
2
        }
456
457
        // Success!
458
2
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
2
        Ok(host_vm_prototype)
460
2
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtCs1qmLyiTSqYF_6either6EitherRShINtNvMs5_NtNtB7_2vm11interpreterNtB1Q_11Interpreter11read_memory12AccessOffsetB1E_EEEB9_
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEEB9_
Line
Count
Source
311
21
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
21
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
21
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
21
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
21
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
21
        let (mut vm_proto, registered_functions) = {
355
21
            let mut registered_functions = Vec::new();
356
21
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
21
                module_bytes: &module_bytes[..],
358
21
                exec_hint: config.exec_hint,
359
21
                // This closure is called back for each function that the runtime imports.
360
21
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
21
                },
379
21
            })
?0
;
380
21
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
21
        let heap_base = vm_proto
386
21
            .global_value("__heap_base")
387
21
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
21
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
21
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
21
        if vm_proto
396
21
            .memory_max_pages()
397
21
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
21
        }
401
21
402
21
        let mut host_vm_prototype = HostVmPrototype {
403
21
            vm_proto,
404
21
            common: Box::new(VmCommon {
405
21
                runtime_version,
406
21
                heap_base,
407
21
                registered_functions,
408
21
                heap_pages: config.heap_pages,
409
21
                memory_total_pages,
410
21
            }),
411
21
        };
412
21
413
21
        // Call `Core_version` if no runtime version is known yet.
414
21
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
21
        }
456
457
        // Success!
458
21
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
21
        Ok(host_vm_prototype)
460
21
    }
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShEB9_
Line
Count
Source
311
21
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
21
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
21
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
21
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
21
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
21
        let (mut vm_proto, registered_functions) = {
355
21
            let mut registered_functions = Vec::new();
356
21
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
21
                module_bytes: &module_bytes[..],
358
21
                exec_hint: config.exec_hint,
359
21
                // This closure is called back for each function that the runtime imports.
360
21
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
21
                },
379
21
            })
?0
;
380
21
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
21
        let heap_base = vm_proto
386
21
            .global_value("__heap_base")
387
21
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
21
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
21
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
21
        if vm_proto
396
21
            .memory_max_pages()
397
21
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
21
        }
401
21
402
21
        let mut host_vm_prototype = HostVmPrototype {
403
21
            vm_proto,
404
21
            common: Box::new(VmCommon {
405
21
                runtime_version,
406
21
                heap_base,
407
21
                registered_functions,
408
21
                heap_pages: config.heap_pages,
409
21
                memory_total_pages,
410
21
            }),
411
21
        };
412
21
413
21
        // Call `Core_version` if no runtime version is known yet.
414
21
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
21
        }
456
457
        // Success!
458
21
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
21
        Ok(host_vm_prototype)
460
21
    }
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
2
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
2
        let (mut vm_proto, registered_functions) = {
355
2
            let mut registered_functions = Vec::new();
356
2
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
2
                module_bytes: &module_bytes[..],
358
2
                exec_hint: config.exec_hint,
359
2
                // This closure is called back for each function that the runtime imports.
360
2
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
2
                },
379
2
            })
?0
;
380
2
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
2
        let heap_base = vm_proto
386
2
            .global_value("__heap_base")
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
2
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
2
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
2
        if vm_proto
396
2
            .memory_max_pages()
397
2
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
2
        }
401
2
402
2
        let mut host_vm_prototype = HostVmPrototype {
403
2
            vm_proto,
404
2
            common: Box::new(VmCommon {
405
2
                runtime_version,
406
2
                heap_base,
407
2
                registered_functions,
408
2
                heap_pages: config.heap_pages,
409
2
                memory_total_pages,
410
2
            }),
411
2
        };
412
2
413
2
        // Call `Core_version` if no runtime version is known yet.
414
2
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
2
        }
456
457
        // Success!
458
2
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
2
        Ok(host_vm_prototype)
460
2
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShECsiLzmwikkc22_14json_rpc_basic
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRShECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
2
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
2
        let (mut vm_proto, registered_functions) = {
355
2
            let mut registered_functions = Vec::new();
356
2
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
2
                module_bytes: &module_bytes[..],
358
2
                exec_hint: config.exec_hint,
359
2
                // This closure is called back for each function that the runtime imports.
360
2
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
2
                },
379
2
            })
?0
;
380
2
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
2
        let heap_base = vm_proto
386
2
            .global_value("__heap_base")
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
2
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
2
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
2
        if vm_proto
396
2
            .memory_max_pages()
397
2
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
2
        }
401
2
402
2
        let mut host_vm_prototype = HostVmPrototype {
403
2
            vm_proto,
404
2
            common: Box::new(VmCommon {
405
2
                runtime_version,
406
2
                heap_base,
407
2
                registered_functions,
408
2
                heap_pages: config.heap_pages,
409
2
                memory_total_pages,
410
2
            }),
411
2
        };
412
2
413
2
        // Call `Core_version` if no runtime version is known yet.
414
2
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
2
        }
456
457
        // Success!
458
2
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
2
        Ok(host_vm_prototype)
460
2
    }
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc3vec3VechEECsiUjFBJteJ7x_17smoldot_full_node
Line
Count
Source
311
2
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
2
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
2
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
2
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
2
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
2
        let (mut vm_proto, registered_functions) = {
355
2
            let mut registered_functions = Vec::new();
356
2
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
2
                module_bytes: &module_bytes[..],
358
2
                exec_hint: config.exec_hint,
359
2
                // This closure is called back for each function that the runtime imports.
360
2
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
2
                },
379
2
            })
?0
;
380
2
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
2
        let heap_base = vm_proto
386
2
            .global_value("__heap_base")
387
2
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
2
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
2
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
2
        if vm_proto
396
2
            .memory_max_pages()
397
2
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
2
        }
401
2
402
2
        let mut host_vm_prototype = HostVmPrototype {
403
2
            vm_proto,
404
2
            common: Box::new(VmCommon {
405
2
                runtime_version,
406
2
                heap_base,
407
2
                registered_functions,
408
2
                heap_pages: config.heap_pages,
409
2
                memory_total_pages,
410
2
            }),
411
2
        };
412
2
413
2
        // Call `Core_version` if no runtime version is known yet.
414
2
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
2
        }
456
457
        // Success!
458
2
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
2
        Ok(host_vm_prototype)
460
2
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRShECscDgN54JpMGG_6author
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newINtNtCsdZExvAaxgia_5alloc3vec3VechEECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
311
19
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
19
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
19
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
19
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
19
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
19
        let (mut vm_proto, registered_functions) = {
355
19
            let mut registered_functions = Vec::new();
356
19
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
19
                module_bytes: &module_bytes[..],
358
19
                exec_hint: config.exec_hint,
359
19
                // This closure is called back for each function that the runtime imports.
360
19
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
19
                },
379
19
            })
?0
;
380
19
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
19
        let heap_base = vm_proto
386
19
            .global_value("__heap_base")
387
19
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
19
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
19
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
19
        if vm_proto
396
19
            .memory_max_pages()
397
19
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
19
        }
401
19
402
19
        let mut host_vm_prototype = HostVmPrototype {
403
19
            vm_proto,
404
19
            common: Box::new(VmCommon {
405
19
                runtime_version,
406
19
                heap_base,
407
19
                registered_functions,
408
19
                heap_pages: config.heap_pages,
409
19
                memory_total_pages,
410
19
            }),
411
19
        };
412
19
413
19
        // Call `Core_version` if no runtime version is known yet.
414
19
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
19
        }
456
457
        // Success!
458
19
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
19
        Ok(host_vm_prototype)
460
19
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRINtNtCsdZExvAaxgia_5alloc6borrow3CowShEECsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRRShECsibGXYHQB8Ea_25json_rpc_general_requests
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype3newRShECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
311
19
    pub fn new(config: Config<impl AsRef<[u8]>>) -> Result<Self, NewErr> {
312
        // The maximum allowed size for the decompressed Wasm code needs to be the same amongst
313
        // all implementations.
314
        // See <https://github.com/paritytech/substrate/blob/f9d10fabe04d598d68f8b097cc4905adbb1ad630/primitives/maybe-compressed-blob/src/lib.rs#L37>.
315
        // Hopefully, this value doesn't get changed without the Substrate team informing everyone.
316
19
        let module_bytes = zstd::zstd_decode_if_necessary(config.module.as_ref(), 50 * 1024 * 1024)
317
19
            .map_err(NewErr::BadFormat)
?0
;
318
319
        // Try to find the runtime version as Wasm custom sections.
320
        // An error is returned if the sections have a wrong format, in which case we fail the
321
        // initialization. `Ok(None)` can also be returned, in which case the sections are
322
        // missing, and we will instead try to retrieve the version through a runtime call later
323
        // down this function.
324
        // In the case of `CustomSectionsPresenceMismatch`, indicating that one section is present
325
        // but not the other, we must ignore the custom sections. This is necessary due to some
326
        // historical accidents.
327
19
        let runtime_version = match runtime_version::find_embedded_runtime_version(&module_bytes) {
328
19
            Ok(Some(r)) => Some(r),
329
0
            Ok(None) => None,
330
            Err(
331
                runtime_version::FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch,
332
0
            ) => None,
333
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::FindSections(err)) => {
334
0
                return Err(NewErr::RuntimeVersion(
335
0
                    FindEmbeddedRuntimeVersionError::FindSections(err),
336
0
                ))
337
            }
338
0
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)) => {
339
0
                return Err(NewErr::RuntimeVersion(
340
0
                    FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err),
341
0
                ))
342
            }
343
            Err(runtime_version::FindEmbeddedRuntimeVersionError::RuntimeVersionDecode) => {
344
0
                return Err(NewErr::RuntimeVersion(
345
0
                    FindEmbeddedRuntimeVersionError::RuntimeVersionDecode,
346
0
                ))
347
            }
348
        };
349
350
        // Initialize the virtual machine.
351
        // Each symbol requested by the Wasm runtime will be put in `registered_functions`. Later,
352
        // when a function is invoked, the Wasm virtual machine will pass indices within that
353
        // array.
354
19
        let (mut vm_proto, registered_functions) = {
355
19
            let mut registered_functions = Vec::new();
356
19
            let vm_proto = vm::VirtualMachinePrototype::new(vm::Config {
357
19
                module_bytes: &module_bytes[..],
358
19
                exec_hint: config.exec_hint,
359
19
                // This closure is called back for each function that the runtime imports.
360
19
                symbols: &mut |mod_name, f_name, signature| {
361
                    if mod_name != "env" {
362
                        return Err(());
363
                    }
364
365
                    let id = registered_functions.len();
366
                    registered_functions.push(match HostFunction::by_name(f_name) {
367
                        Some(f) if f.signature() == *signature => FunctionImport::Resolved(f),
368
                        Some(_) | None if !config.allow_unresolved_imports => {
369
                            // TODO: return a better error if there is a signature mismatch
370
                            return Err(());
371
                        }
372
                        Some(_) | None => FunctionImport::Unresolved {
373
                            name: f_name.to_owned(),
374
                            module: mod_name.to_owned(),
375
                        },
376
                    });
377
                    Ok(id)
378
19
                },
379
19
            })
?0
;
380
19
            (vm_proto, registered_functions.into())
381
        };
382
383
        // In the runtime environment, Wasm blobs must export a global symbol named
384
        // `__heap_base` indicating where the memory allocator is allowed to allocate memory.
385
19
        let heap_base = vm_proto
386
19
            .global_value("__heap_base")
387
19
            .map_err(|_| NewErr::HeapBaseNotFound)
?0
;
388
389
19
        let memory_total_pages = if heap_base == 0 {
390
0
            config.heap_pages
391
        } else {
392
19
            HeapPages::new((heap_base - 1) / (64 * 1024)) + config.heap_pages + HeapPages::new(1)
393
        };
394
395
19
        if vm_proto
396
19
            .memory_max_pages()
397
19
            .map_or(false, |max| max < memory_total_pages)
398
        {
399
0
            return Err(NewErr::MemoryMaxSizeTooLow);
400
19
        }
401
19
402
19
        let mut host_vm_prototype = HostVmPrototype {
403
19
            vm_proto,
404
19
            common: Box::new(VmCommon {
405
19
                runtime_version,
406
19
                heap_base,
407
19
                registered_functions,
408
19
                heap_pages: config.heap_pages,
409
19
                memory_total_pages,
410
19
            }),
411
19
        };
412
19
413
19
        // Call `Core_version` if no runtime version is known yet.
414
19
        if host_vm_prototype.common.runtime_version.is_none() {
415
0
            let mut vm: HostVm = match host_vm_prototype.run_no_param(
416
0
                "Core_version",
417
0
                StorageProofSizeBehavior::proof_recording_disabled(),
418
0
            ) {
419
0
                Ok(vm) => vm.into(),
420
0
                Err((err, _)) => return Err(NewErr::CoreVersion(CoreVersionError::Start(err))),
421
            };
422
423
0
            loop {
424
0
                match vm {
425
0
                    HostVm::ReadyToRun(r) => vm = r.run(),
426
0
                    HostVm::Finished(finished) => {
427
0
                        let version =
428
0
                            match CoreVersion::from_slice(finished.value().as_ref().to_vec()) {
429
0
                                Ok(v) => v,
430
                                Err(_) => {
431
0
                                    return Err(NewErr::CoreVersion(CoreVersionError::Decode))
432
                                }
433
                            };
434
435
0
                        host_vm_prototype = finished.into_prototype();
436
0
                        host_vm_prototype.common.runtime_version = Some(version);
437
0
                        break;
438
                    }
439
440
                    // Emitted log lines are ignored.
441
0
                    HostVm::GetMaxLogLevel(resume) => {
442
0
                        vm = resume.resume(0); // Off
443
0
                    }
444
0
                    HostVm::LogEmit(log) => vm = log.resume(),
445
446
0
                    HostVm::Error { error, .. } => {
447
0
                        return Err(NewErr::CoreVersion(CoreVersionError::Run(error)))
448
                    }
449
450
                    // Getting the runtime version is a very core operation, and very few
451
                    // external calls are allowed.
452
0
                    _ => return Err(NewErr::CoreVersion(CoreVersionError::ForbiddenHostFunction)),
453
                }
454
            }
455
19
        }
456
457
        // Success!
458
19
        debug_assert!(host_vm_prototype.common.runtime_version.is_some());
459
19
        Ok(host_vm_prototype)
460
19
    }
461
462
    /// Returns the number of heap pages that were passed to [`HostVmPrototype::new`].
463
0
    pub fn heap_pages(&self) -> HeapPages {
464
0
        self.common.heap_pages
465
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB4_15HostVmPrototype10heap_pages
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB4_15HostVmPrototype10heap_pages
466
467
    /// Returns the runtime version found in the module.
468
229
    pub fn runtime_version(&self) -> &CoreVersion {
469
229
        self.common
470
229
            .runtime_version
471
229
            .as_ref()
472
229
            .unwrap_or_else(|| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_15HostVmPrototype15runtime_version0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_15HostVmPrototype15runtime_version0Ba_
473
229
    }
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB4_15HostVmPrototype15runtime_version
Line
Count
Source
468
17
    pub fn runtime_version(&self) -> &CoreVersion {
469
17
        self.common
470
17
            .runtime_version
471
17
            .as_ref()
472
17
            .unwrap_or_else(|| unreachable!())
473
17
    }
_RNvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB4_15HostVmPrototype15runtime_version
Line
Count
Source
468
212
    pub fn runtime_version(&self) -> &CoreVersion {
469
212
        self.common
470
212
            .runtime_version
471
212
            .as_ref()
472
212
            .unwrap_or_else(|| unreachable!())
473
212
    }
474
475
    /// Starts the VM, calling the function passed as parameter.
476
    ///
477
    /// See the documentation of [`StorageProofSizeBehavior`] for an explanation of
478
    /// the `storage_proof_size_behavior` parameter.
479
30
    pub fn run(
480
30
        self,
481
30
        function_to_call: &str,
482
30
        storage_proof_size_behavior: StorageProofSizeBehavior,
483
30
        data: &[u8],
484
30
    ) -> Result<ReadyToRun, (StartErr, Self)> {
485
30
        self.run_vectored(
486
30
            function_to_call,
487
30
            storage_proof_size_behavior,
488
30
            iter::once(data),
489
30
        )
490
30
    }
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB4_15HostVmPrototype3run
Line
Count
Source
479
30
    pub fn run(
480
30
        self,
481
30
        function_to_call: &str,
482
30
        storage_proof_size_behavior: StorageProofSizeBehavior,
483
30
        data: &[u8],
484
30
    ) -> Result<ReadyToRun, (StartErr, Self)> {
485
30
        self.run_vectored(
486
30
            function_to_call,
487
30
            storage_proof_size_behavior,
488
30
            iter::once(data),
489
30
        )
490
30
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB4_15HostVmPrototype3run
491
492
    /// Same as [`HostVmPrototype::run`], except that the function doesn't need any parameter.
493
    ///
494
    /// See the documentation of [`StorageProofSizeBehavior`] for an explanation of
495
    /// the `storage_proof_size_behavior` parameter.
496
9
    pub fn run_no_param(
497
9
        self,
498
9
        function_to_call: &str,
499
9
        storage_proof_size_behavior: StorageProofSizeBehavior,
500
9
    ) -> Result<ReadyToRun, (StartErr, Self)> {
501
9
        self.run_vectored(
502
9
            function_to_call,
503
9
            storage_proof_size_behavior,
504
9
            iter::empty::<Vec<u8>>(),
505
9
        )
506
9
    }
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB4_15HostVmPrototype12run_no_param
Line
Count
Source
496
9
    pub fn run_no_param(
497
9
        self,
498
9
        function_to_call: &str,
499
9
        storage_proof_size_behavior: StorageProofSizeBehavior,
500
9
    ) -> Result<ReadyToRun, (StartErr, Self)> {
501
9
        self.run_vectored(
502
9
            function_to_call,
503
9
            storage_proof_size_behavior,
504
9
            iter::empty::<Vec<u8>>(),
505
9
        )
506
9
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB4_15HostVmPrototype12run_no_param
507
508
    /// Same as [`HostVmPrototype::run`], except that the function parameter can be passed as
509
    /// a list of buffers. All the buffers will be concatenated in memory.
510
    ///
511
    /// See the documentation of [`StorageProofSizeBehavior`] for an explanation of
512
    /// the `storage_proof_size_behavior` parameter.
513
179
    pub fn run_vectored(
514
179
        mut self,
515
179
        function_to_call: &str,
516
179
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
179
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
179
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
179
        // Determine the total length of `data`.
520
179
        let mut data_len_u32: u32 = 0;
521
179
        for 
data66
in data.clone() {
522
66
            let len = match u32::try_from(data.as_ref().len()) {
523
66
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
66
            data_len_u32 = match data_len_u32.checked_add(len) {
527
66
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
179
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
179
537
179
        // Prepare the virtual machine for execution.
538
179
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
179
        let data_ptr = match allocator.allocate(
542
179
            &mut MemAccess {
543
179
                vm: MemAccessVm::Prepare(&mut vm),
544
179
                memory_total_pages: self.common.memory_total_pages,
545
179
            },
546
179
            data_len_u32,
547
179
        ) {
548
179
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
179
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
179
            .checked_sub(u32::from(vm.memory_size()))
559
179
        {
560
179
            // If the memory can't be grown, it indicates a bug in the allocator.
561
179
            vm.grow_memory(HeapPages::from(to_grow))
562
179
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1l_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1l_B1X_IB1l_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1U_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3N_3map3MapIB3J_IB3J_IB3J_INtNtNtB3P_7sources4once4OnceB1P_EB56_EB56_EB56_ENcNtB1k_4Left0EIB4B_IB3J_IB57_B2O_EINtNtB3N_7flatten7FlatMapNtNtBb_6header8LogsIterIB4B_INtNtNtB3R_5array4iter8IntoIterB2X_Kj2_ENcNtB2O_5Right0ENCNvMs2_B6T_NtB6T_9DigestRef14scale_encoding0EENcNtB1k_5Right0EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1l_Ahj8_IB1l_B1P_B2K_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3a_3map3MapINtNtNtB3c_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3Y_INtNtB3a_7flatten7FlatMapINtNtNtB3e_5array4iter8IntoIterTB2K_B2K_EKj1_EIB36_IB3Y_IB4f_B2K_ENcNtB2F_4Left0EIB3Y_IB36_IB3Y_B4e_NcNtB2P_4Left0EIB3Y_B6p_NcNtB2P_5Right0EENcNtB2F_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8b_18InherentExtrinsics25inject_raw_inherents_listB2K_B5v_E0ENcNtB1k_5Right0EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRAhj1_IB1l_RShRINtNtCsdZExvAaxgia_5alloc3vec3VechEEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB2G_INtNtB2K_3map3MapINtNtNtB2M_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3D_IB3D_IB3U_B23_ENcNtB1V_5Right0ENcNtB1k_5Right0EEIB3D_IB3D_IB3U_B20_ENcNtB1V_4Left0EB5g_EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRINtNtCsdZExvAaxgia_5alloc3vec3VechEIB1l_B1P_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB3r_INtNtNtB3x_7sources4once4OnceB1k_EB4n_EINtNtB3v_3map3MapINtNtNtB3z_5slice4iter4IterNtNtNtB9_12runtime_call5tests9HexStringENCNvB5K_s_14execute_blockss0_0EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1k_Kj2_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1m_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1m_B1Y_IB1m_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1V_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3O_3map3MapIB3K_IB3K_IB3K_INtNtNtB3Q_7sources4once4OnceB1Q_EB57_EB57_EB57_ENcNtB1l_4Left0EIB4C_IB3K_IB58_B2P_EINtNtB3O_7flatten7FlatMapNtNtBb_6header8LogsIterIB4C_INtNtNtB3S_5array4iter8IntoIterB2Y_Kj2_ENcNtB2P_5Right0ENCNvMs2_B6U_NtB6U_9DigestRef14scale_encoding0EENcNtB1l_5Right0EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1m_Ahj8_IB1m_B1Q_B2L_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3b_3map3MapINtNtNtB3d_7sources4once4OnceB1Q_ENcNtB1l_4Left0EIB3Z_INtNtB3b_7flatten7FlatMapINtNtNtB3f_5array4iter8IntoIterTB2L_B2L_EKj1_EIB37_IB3Z_IB4g_B2L_ENcNtB2G_4Left0EIB3Z_IB37_IB3Z_B4f_NcNtB2Q_4Left0EIB3Z_B6q_NcNtB2Q_5Right0EENcNtB2G_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8c_18InherentExtrinsics25inject_raw_inherents_listB2L_B5w_E0ENcNtB1l_5Right0EEE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EE0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EE0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EE0CsibGXYHQB8Ea_25json_rpc_general_requests
563
179
        }
0
564
565
        // Writing the input data into the VM.
566
179
        let mut data_ptr_iter = data_ptr;
567
245
        for 
data66
in data {
568
66
            let data = data.as_ref();
569
66
            vm.write_memory(data_ptr_iter, data)
570
66
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1l_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1l_B1X_IB1l_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1U_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3N_3map3MapIB3J_IB3J_IB3J_INtNtNtB3P_7sources4once4OnceB1P_EB56_EB56_EB56_ENcNtB1k_4Left0EIB4B_IB3J_IB57_B2O_EINtNtB3N_7flatten7FlatMapNtNtBb_6header8LogsIterIB4B_INtNtNtB3R_5array4iter8IntoIterB2X_Kj2_ENcNtB2O_5Right0ENCNvMs2_B6T_NtB6T_9DigestRef14scale_encoding0EENcNtB1k_5Right0EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1l_Ahj8_IB1l_B1P_B2K_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3a_3map3MapINtNtNtB3c_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3Y_INtNtB3a_7flatten7FlatMapINtNtNtB3e_5array4iter8IntoIterTB2K_B2K_EKj1_EIB36_IB3Y_IB4f_B2K_ENcNtB2F_4Left0EIB3Y_IB36_IB3Y_B4e_NcNtB2P_4Left0EIB3Y_B6p_NcNtB2P_5Right0EENcNtB2F_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8b_18InherentExtrinsics25inject_raw_inherents_listB2K_B5v_E0ENcNtB1k_5Right0EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRAhj1_IB1l_RShRINtNtCsdZExvAaxgia_5alloc3vec3VechEEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB2G_INtNtB2K_3map3MapINtNtNtB2M_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3D_IB3D_IB3U_B23_ENcNtB1V_5Right0ENcNtB1k_5Right0EEIB3D_IB3D_IB3U_B20_ENcNtB1V_4Left0EB5g_EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRINtNtCsdZExvAaxgia_5alloc3vec3VechEIB1l_B1P_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB3r_INtNtNtB3x_7sources4once4OnceB1k_EB4n_EINtNtB3v_3map3MapINtNtNtB3z_5slice4iter4IterNtNtNtB9_12runtime_call5tests9HexStringENCNvB5K_s_14execute_blockss0_0EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1k_Kj2_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1m_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1m_B1Y_IB1m_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1V_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3O_3map3MapIB3K_IB3K_IB3K_INtNtNtB3Q_7sources4once4OnceB1Q_EB57_EB57_EB57_ENcNtB1l_4Left0EIB4C_IB3K_IB58_B2P_EINtNtB3O_7flatten7FlatMapNtNtBb_6header8LogsIterIB4C_INtNtNtB3S_5array4iter8IntoIterB2Y_Kj2_ENcNtB2P_5Right0ENCNvMs2_B6U_NtB6U_9DigestRef14scale_encoding0EENcNtB1l_5Right0EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1m_Ahj8_IB1m_B1Q_B2L_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3b_3map3MapINtNtNtB3d_7sources4once4OnceB1Q_ENcNtB1l_4Left0EIB3Z_INtNtB3b_7flatten7FlatMapINtNtNtB3f_5array4iter8IntoIterTB2L_B2L_EKj1_EIB37_IB3Z_IB4g_B2L_ENcNtB2G_4Left0EIB3Z_IB37_IB3Z_B4f_NcNtB2Q_4Left0EIB3Z_B6q_NcNtB2Q_5Right0EENcNtB2G_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8c_18InherentExtrinsics25inject_raw_inherents_listB2L_B5w_E0ENcNtB1l_5Right0EEEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs_0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
571
66
            data_ptr_iter = data_ptr_iter
572
66
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| 
unreachable!()0
))
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1l_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1l_B1X_IB1l_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1U_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3N_3map3MapIB3J_IB3J_IB3J_INtNtNtB3P_7sources4once4OnceB1P_EB56_EB56_EB56_ENcNtB1k_4Left0EIB4B_IB3J_IB57_B2O_EINtNtB3N_7flatten7FlatMapNtNtBb_6header8LogsIterIB4B_INtNtNtB3R_5array4iter8IntoIterB2X_Kj2_ENcNtB2O_5Right0ENCNvMs2_B6T_NtB6T_9DigestRef14scale_encoding0EENcNtB1k_5Right0EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1l_Ahj8_IB1l_B1P_B2K_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3a_3map3MapINtNtNtB3c_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3Y_INtNtB3a_7flatten7FlatMapINtNtNtB3e_5array4iter8IntoIterTB2K_B2K_EKj1_EIB36_IB3Y_IB4f_B2K_ENcNtB2F_4Left0EIB3Y_IB36_IB3Y_B4e_NcNtB2P_4Left0EIB3Y_B6p_NcNtB2P_5Right0EENcNtB2F_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8b_18InherentExtrinsics25inject_raw_inherents_listB2K_B5v_E0ENcNtB1k_5Right0EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRAhj1_IB1l_RShRINtNtCsdZExvAaxgia_5alloc3vec3VechEEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB2G_INtNtB2K_3map3MapINtNtNtB2M_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3D_IB3D_IB3U_B23_ENcNtB1V_5Right0ENcNtB1k_5Right0EEIB3D_IB3D_IB3U_B20_ENcNtB1V_4Left0EB5g_EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRINtNtCsdZExvAaxgia_5alloc3vec3VechEIB1l_B1P_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB3r_INtNtNtB3x_7sources4once4OnceB1k_EB4n_EINtNtB3v_3map3MapINtNtNtB3z_5slice4iter4IterNtNtNtB9_12runtime_call5tests9HexStringENCNvB5K_s_14execute_blockss0_0EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1k_Kj2_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1m_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1m_B1Y_IB1m_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1V_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3O_3map3MapIB3K_IB3K_IB3K_INtNtNtB3Q_7sources4once4OnceB1Q_EB57_EB57_EB57_ENcNtB1l_4Left0EIB4C_IB3K_IB58_B2P_EINtNtB3O_7flatten7FlatMapNtNtBb_6header8LogsIterIB4C_INtNtNtB3S_5array4iter8IntoIterB2Y_Kj2_ENcNtB2P_5Right0ENCNvMs2_B6U_NtB6U_9DigestRef14scale_encoding0EENcNtB1l_5Right0EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1m_Ahj8_IB1m_B1Q_B2L_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3b_3map3MapINtNtNtB3d_7sources4once4OnceB1Q_ENcNtB1l_4Left0EIB3Z_INtNtB3b_7flatten7FlatMapINtNtNtB3f_5array4iter8IntoIterTB2L_B2L_EKj1_EIB37_IB3Z_IB4g_B2L_ENcNtB2G_4Left0EIB3Z_IB37_IB3Z_B4f_NcNtB2Q_4Left0EIB3Z_B6q_NcNtB2Q_5Right0EENcNtB2G_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8c_18InherentExtrinsics25inject_raw_inherents_listB2L_B5w_E0ENcNtB1l_5Right0EEEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs0_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs0_0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
573
66
                .unwrap_or_else(|| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1l_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1l_B1X_IB1l_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1U_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3N_3map3MapIB3J_IB3J_IB3J_INtNtNtB3P_7sources4once4OnceB1P_EB56_EB56_EB56_ENcNtB1k_4Left0EIB4B_IB3J_IB57_B2O_EINtNtB3N_7flatten7FlatMapNtNtBb_6header8LogsIterIB4B_INtNtNtB3R_5array4iter8IntoIterB2X_Kj2_ENcNtB2O_5Right0ENCNvMs2_B6T_NtB6T_9DigestRef14scale_encoding0EENcNtB1k_5Right0EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1l_Ahj8_IB1l_B1P_B2K_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3a_3map3MapINtNtNtB3c_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3Y_INtNtB3a_7flatten7FlatMapINtNtNtB3e_5array4iter8IntoIterTB2K_B2K_EKj1_EIB36_IB3Y_IB4f_B2K_ENcNtB2F_4Left0EIB3Y_IB36_IB3Y_B4e_NcNtB2P_4Left0EIB3Y_B6p_NcNtB2P_5Right0EENcNtB2F_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8b_18InherentExtrinsics25inject_raw_inherents_listB2K_B5v_E0ENcNtB1k_5Right0EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRAhj1_IB1l_RShRINtNtCsdZExvAaxgia_5alloc3vec3VechEEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB2G_INtNtB2K_3map3MapINtNtNtB2M_7sources4once4OnceB1P_ENcNtB1k_4Left0EIB3D_IB3D_IB3U_B23_ENcNtB1V_5Right0ENcNtB1k_5Right0EEIB3D_IB3D_IB3U_B20_ENcNtB1V_4Left0EB5g_EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRINtNtCsdZExvAaxgia_5alloc3vec3VechEIB1l_B1P_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB3r_INtNtNtB3x_7sources4once4OnceB1k_EB4n_EINtNtB3v_3map3MapINtNtNtB3z_5slice4iter4IterNtNtNtB9_12runtime_call5tests9HexStringENCNvB5K_s_14execute_blockss0_0EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1k_Kj2_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1k_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1k_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1m_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1m_B1Y_IB1m_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1V_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3O_3map3MapIB3K_IB3K_IB3K_INtNtNtB3Q_7sources4once4OnceB1Q_EB57_EB57_EB57_ENcNtB1l_4Left0EIB4C_IB3K_IB58_B2P_EINtNtB3O_7flatten7FlatMapNtNtBb_6header8LogsIterIB4C_INtNtNtB3S_5array4iter8IntoIterB2Y_Kj2_ENcNtB2P_5Right0ENCNvMs2_B6U_NtB6U_9DigestRef14scale_encoding0EENcNtB1l_5Right0EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1m_Ahj8_IB1m_B1Q_B2L_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3b_3map3MapINtNtNtB3d_7sources4once4OnceB1Q_ENcNtB1l_4Left0EIB3Z_INtNtB3b_7flatten7FlatMapINtNtNtB3f_5array4iter8IntoIterTB2L_B2L_EKj1_EIB37_IB3Z_IB4g_B2L_ENcNtB2G_4Left0EIB3Z_IB37_IB3Z_B4f_NcNtB2Q_4Left0EIB3Z_B6q_NcNtB2Q_5Right0EENcNtB2G_5Right0EENCINvMs_NtNtBb_6author7runtimeNtB8c_18InherentExtrinsics25inject_raw_inherents_listB2L_B5w_E0ENcNtB1l_5Right0EEEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs1_0Bb_
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1l_EEs1_0CsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1l_EEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests
574
66
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
179
        let 
vm175
= match vm.start(
579
179
            function_to_call,
580
179
            &[
581
179
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
179
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
179
            ],
584
179
        ) {
585
175
            Ok(vm) => vm,
586
4
            Err((error, vm_proto)) => {
587
4
                self.vm_proto = vm_proto;
588
4
                return Err((error.into(), self));
589
            }
590
        };
591
592
175
        Ok(ReadyToRun {
593
175
            resume_value: None,
594
175
            inner: Box::new(Inner {
595
175
                common: self.common,
596
175
                vm,
597
175
                storage_transaction_depth: 0,
598
175
                signatures_batch_verification: None,
599
175
                allocator,
600
175
                storage_proof_size_behavior,
601
175
            }),
602
175
        })
603
179
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1j_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1j_B1V_IB1j_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1S_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3L_3map3MapIB3H_IB3H_IB3H_INtNtNtB3N_7sources4once4OnceB1N_EB54_EB54_EB54_ENcNtB1i_4Left0EIB4z_IB3H_IB55_B2M_EINtNtB3L_7flatten7FlatMapNtNtB9_6header8LogsIterIB4z_INtNtNtB3P_5array4iter8IntoIterB2V_Kj2_ENcNtB2M_5Right0ENCNvMs2_B6R_NtB6R_9DigestRef14scale_encoding0EENcNtB1i_5Right0EEEB9_
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
7
        for data in 
data.clone()1
{
522
7
            let len = match u32::try_from(data.as_ref().len()) {
523
7
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
7
            data_len_u32 = match data_len_u32.checked_add(len) {
527
7
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
8
        for 
data7
in data {
568
7
            let data = data.as_ref();
569
7
            vm.write_memory(data_ptr_iter, data)
570
7
                .unwrap_or_else(|_| unreachable!());
571
7
            data_ptr_iter = data_ptr_iter
572
7
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
7
                .unwrap_or_else(|| unreachable!());
574
7
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1j_Ahj8_IB1j_B1N_B2I_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB38_3map3MapINtNtNtB3a_7sources4once4OnceB1N_ENcNtB1i_4Left0EIB3W_INtNtB38_7flatten7FlatMapINtNtNtB3c_5array4iter8IntoIterTB2I_B2I_EKj1_EIB34_IB3W_IB4d_B2I_ENcNtB2D_4Left0EIB3W_IB34_IB3W_B4c_NcNtB2N_4Left0EIB3W_B6n_NcNtB2N_5Right0EENcNtB2D_5Right0EENCINvMs_NtNtB9_6author7runtimeNtB89_18InherentExtrinsics25inject_raw_inherents_listB2I_B5t_E0ENcNtB1i_5Right0EEEB9_
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
4
        for data in 
data.clone()1
{
522
4
            let len = match u32::try_from(data.as_ref().len()) {
523
4
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
4
            data_len_u32 = match data_len_u32.checked_add(len) {
527
4
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
5
        for 
data4
in data {
568
4
            let data = data.as_ref();
569
4
            vm.write_memory(data_ptr_iter, data)
570
4
                .unwrap_or_else(|_| unreachable!());
571
4
            data_ptr_iter = data_ptr_iter
572
4
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
4
                .unwrap_or_else(|| unreachable!());
574
4
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRAhj1_IB1j_RShRINtNtCsdZExvAaxgia_5alloc3vec3VechEEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB2E_INtNtB2I_3map3MapINtNtNtB2K_7sources4once4OnceB1N_ENcNtB1i_4Left0EIB3B_IB3B_IB3S_B21_ENcNtB1T_5Right0ENcNtB1i_5Right0EEIB3B_IB3B_IB3S_B1Y_ENcNtB1T_4Left0EB5e_EEEB9_
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
3
        for data in 
data.clone()1
{
522
3
            let len = match u32::try_from(data.as_ref().len()) {
523
3
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
3
            data_len_u32 = match data_len_u32.checked_add(len) {
527
3
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
4
        for 
data3
in data {
568
3
            let data = data.as_ref();
569
3
            vm.write_memory(data_ptr_iter, data)
570
3
                .unwrap_or_else(|_| unreachable!());
571
3
            data_ptr_iter = data_ptr_iter
572
3
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
3
                .unwrap_or_else(|| unreachable!());
574
3
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherRINtNtCsdZExvAaxgia_5alloc3vec3VechEIB1j_B1N_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB3p_INtNtNtB3v_7sources4once4OnceB1i_EB4l_EINtNtB3t_3map3MapINtNtNtB3x_5slice4iter4IterNtNtNtB7_12runtime_call5tests9HexStringENCNvB5I_s_14execute_blockss0_0EEEB9_
Line
Count
Source
513
4
    pub fn run_vectored(
514
4
        mut self,
515
4
        function_to_call: &str,
516
4
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
4
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
4
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
4
        // Determine the total length of `data`.
520
4
        let mut data_len_u32: u32 = 0;
521
17
        for data in 
data.clone()4
{
522
17
            let len = match u32::try_from(data.as_ref().len()) {
523
17
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
17
            data_len_u32 = match data_len_u32.checked_add(len) {
527
17
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
4
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
4
537
4
        // Prepare the virtual machine for execution.
538
4
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
4
        let data_ptr = match allocator.allocate(
542
4
            &mut MemAccess {
543
4
                vm: MemAccessVm::Prepare(&mut vm),
544
4
                memory_total_pages: self.common.memory_total_pages,
545
4
            },
546
4
            data_len_u32,
547
4
        ) {
548
4
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
4
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
4
            .checked_sub(u32::from(vm.memory_size()))
559
4
        {
560
4
            // If the memory can't be grown, it indicates a bug in the allocator.
561
4
            vm.grow_memory(HeapPages::from(to_grow))
562
4
                .unwrap_or_else(|_| unreachable!());
563
4
        }
0
564
565
        // Writing the input data into the VM.
566
4
        let mut data_ptr_iter = data_ptr;
567
21
        for 
data17
in data {
568
17
            let data = data.as_ref();
569
17
            vm.write_memory(data_ptr_iter, data)
570
17
                .unwrap_or_else(|_| unreachable!());
571
17
            data_ptr_iter = data_ptr_iter
572
17
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
17
                .unwrap_or_else(|| unreachable!());
574
17
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
4
        let vm = match vm.start(
579
4
            function_to_call,
580
4
            &[
581
4
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
4
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
4
            ],
584
4
        ) {
585
4
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
4
        Ok(ReadyToRun {
593
4
            resume_value: None,
594
4
            inner: Box::new(Inner {
595
4
                common: self.common,
596
4
                vm,
597
4
                storage_transaction_depth: 0,
598
4
                signatures_batch_verification: None,
599
4
                allocator,
600
4
                storage_proof_size_behavior,
601
4
            }),
602
4
        })
603
4
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1i_EEB9_
Line
Count
Source
513
11
    pub fn run_vectored(
514
11
        mut self,
515
11
        function_to_call: &str,
516
11
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
11
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
11
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
11
        // Determine the total length of `data`.
520
11
        let mut data_len_u32: u32 = 0;
521
11
        for 
data0
in data.clone() {
522
0
            let len = match u32::try_from(data.as_ref().len()) {
523
0
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
0
            data_len_u32 = match data_len_u32.checked_add(len) {
527
0
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
11
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
11
537
11
        // Prepare the virtual machine for execution.
538
11
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
11
        let data_ptr = match allocator.allocate(
542
11
            &mut MemAccess {
543
11
                vm: MemAccessVm::Prepare(&mut vm),
544
11
                memory_total_pages: self.common.memory_total_pages,
545
11
            },
546
11
            data_len_u32,
547
11
        ) {
548
11
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
11
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
11
            .checked_sub(u32::from(vm.memory_size()))
559
11
        {
560
11
            // If the memory can't be grown, it indicates a bug in the allocator.
561
11
            vm.grow_memory(HeapPages::from(to_grow))
562
11
                .unwrap_or_else(|_| unreachable!());
563
11
        }
0
564
565
        // Writing the input data into the VM.
566
11
        let mut data_ptr_iter = data_ptr;
567
11
        for 
data0
in data {
568
0
            let data = data.as_ref();
569
0
            vm.write_memory(data_ptr_iter, data)
570
0
                .unwrap_or_else(|_| unreachable!());
571
0
            data_ptr_iter = data_ptr_iter
572
0
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
0
                .unwrap_or_else(|| unreachable!());
574
0
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
11
        let 
vm7
= match vm.start(
579
11
            function_to_call,
580
11
            &[
581
11
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
11
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
11
            ],
584
11
        ) {
585
7
            Ok(vm) => vm,
586
4
            Err((error, vm_proto)) => {
587
4
                self.vm_proto = vm_proto;
588
4
                return Err((error.into(), self));
589
            }
590
        };
591
592
7
        Ok(ReadyToRun {
593
7
            resume_value: None,
594
7
            inner: Box::new(Inner {
595
7
                common: self.common,
596
7
                vm,
597
7
                storage_transaction_depth: 0,
598
7
                signatures_batch_verification: None,
599
7
                allocator,
600
7
                storage_proof_size_behavior,
601
7
            }),
602
7
        })
603
11
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1i_EEB9_
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
1
        for data in data.clone() {
522
1
            let len = match u32::try_from(data.as_ref().len()) {
523
1
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
1
            data_len_u32 = match data_len_u32.checked_add(len) {
527
1
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
2
        for 
data1
in data {
568
1
            let data = data.as_ref();
569
1
            vm.write_memory(data_ptr_iter, data)
570
1
                .unwrap_or_else(|_| unreachable!());
571
1
            data_ptr_iter = data_ptr_iter
572
1
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
1
                .unwrap_or_else(|| unreachable!());
574
1
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1i_Kj2_EEB9_
Line
Count
Source
513
2
    pub fn run_vectored(
514
2
        mut self,
515
2
        function_to_call: &str,
516
2
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
2
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
2
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
2
        // Determine the total length of `data`.
520
2
        let mut data_len_u32: u32 = 0;
521
4
        for data in 
data.clone()2
{
522
4
            let len = match u32::try_from(data.as_ref().len()) {
523
4
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
4
            data_len_u32 = match data_len_u32.checked_add(len) {
527
4
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
2
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
2
537
2
        // Prepare the virtual machine for execution.
538
2
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
2
        let data_ptr = match allocator.allocate(
542
2
            &mut MemAccess {
543
2
                vm: MemAccessVm::Prepare(&mut vm),
544
2
                memory_total_pages: self.common.memory_total_pages,
545
2
            },
546
2
            data_len_u32,
547
2
        ) {
548
2
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
2
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
2
            .checked_sub(u32::from(vm.memory_size()))
559
2
        {
560
2
            // If the memory can't be grown, it indicates a bug in the allocator.
561
2
            vm.grow_memory(HeapPages::from(to_grow))
562
2
                .unwrap_or_else(|_| unreachable!());
563
2
        }
0
564
565
        // Writing the input data into the VM.
566
2
        let mut data_ptr_iter = data_ptr;
567
6
        for 
data4
in data {
568
4
            let data = data.as_ref();
569
4
            vm.write_memory(data_ptr_iter, data)
570
4
                .unwrap_or_else(|_| unreachable!());
571
4
            data_ptr_iter = data_ptr_iter
572
4
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
4
                .unwrap_or_else(|| unreachable!());
574
4
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
2
        let vm = match vm.start(
579
2
            function_to_call,
580
2
            &[
581
2
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
2
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
2
            ],
584
2
        ) {
585
2
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
2
        Ok(ReadyToRun {
593
2
            resume_value: None,
594
2
            inner: Box::new(Inner {
595
2
                common: self.common,
596
2
                vm,
597
2
                storage_transaction_depth: 0,
598
2
                signatures_batch_verification: None,
599
2
                allocator,
600
2
                storage_proof_size_behavior,
601
2
            }),
602
2
        })
603
2
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1i_EEB9_
Line
Count
Source
513
30
    pub fn run_vectored(
514
30
        mut self,
515
30
        function_to_call: &str,
516
30
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
30
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
30
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
30
        // Determine the total length of `data`.
520
30
        let mut data_len_u32: u32 = 0;
521
30
        for data in data.clone() {
522
30
            let len = match u32::try_from(data.as_ref().len()) {
523
30
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
30
            data_len_u32 = match data_len_u32.checked_add(len) {
527
30
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
30
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
30
537
30
        // Prepare the virtual machine for execution.
538
30
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
30
        let data_ptr = match allocator.allocate(
542
30
            &mut MemAccess {
543
30
                vm: MemAccessVm::Prepare(&mut vm),
544
30
                memory_total_pages: self.common.memory_total_pages,
545
30
            },
546
30
            data_len_u32,
547
30
        ) {
548
30
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
30
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
30
            .checked_sub(u32::from(vm.memory_size()))
559
30
        {
560
30
            // If the memory can't be grown, it indicates a bug in the allocator.
561
30
            vm.grow_memory(HeapPages::from(to_grow))
562
30
                .unwrap_or_else(|_| unreachable!());
563
30
        }
0
564
565
        // Writing the input data into the VM.
566
30
        let mut data_ptr_iter = data_ptr;
567
60
        for 
data30
in data {
568
30
            let data = data.as_ref();
569
30
            vm.write_memory(data_ptr_iter, data)
570
30
                .unwrap_or_else(|_| unreachable!());
571
30
            data_ptr_iter = data_ptr_iter
572
30
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
30
                .unwrap_or_else(|| unreachable!());
574
30
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
30
        let vm = match vm.start(
579
30
            function_to_call,
580
30
            &[
581
30
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
30
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
30
            ],
584
30
        ) {
585
30
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
30
        Ok(ReadyToRun {
593
30
            resume_value: None,
594
30
            inner: Box::new(Inner {
595
30
                common: self.common,
596
30
                vm,
597
30
                storage_transaction_depth: 0,
598
30
                signatures_batch_verification: None,
599
30
                allocator,
600
30
                storage_proof_size_behavior,
601
30
            }),
602
30
        })
603
30
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1i_EEB9_
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
1
        for 
data0
in data.clone() {
522
0
            let len = match u32::try_from(data.as_ref().len()) {
523
0
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
0
            data_len_u32 = match data_len_u32.checked_add(len) {
527
0
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
1
        for 
data0
in data {
568
0
            let data = data.as_ref();
569
0
            vm.write_memory(data_ptr_iter, data)
570
0
                .unwrap_or_else(|_| unreachable!());
571
0
            data_ptr_iter = data_ptr_iter
572
0
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
0
                .unwrap_or_else(|| unreachable!());
574
0
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1k_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1k_B1W_IB1k_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1T_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3M_3map3MapIB3I_IB3I_IB3I_INtNtNtB3O_7sources4once4OnceB1O_EB55_EB55_EB55_ENcNtB1j_4Left0EIB4A_IB3I_IB56_B2N_EINtNtB3M_7flatten7FlatMapNtNtB9_6header8LogsIterIB4A_INtNtNtB3Q_5array4iter8IntoIterB2W_Kj2_ENcNtB2N_5Right0ENCNvMs2_B6S_NtB6S_9DigestRef14scale_encoding0EENcNtB1j_5Right0EEEB9_
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtCs1qmLyiTSqYF_6either6EitherINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EIB1k_Ahj8_IB1k_B1O_B2J_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB39_3map3MapINtNtNtB3b_7sources4once4OnceB1O_ENcNtB1j_4Left0EIB3X_INtNtB39_7flatten7FlatMapINtNtNtB3d_5array4iter8IntoIterTB2J_B2J_EKj1_EIB35_IB3X_IB4e_B2J_ENcNtB2E_4Left0EIB3X_IB35_IB3X_B4d_NcNtB2O_4Left0EIB3X_B6o_NcNtB2O_5Right0EENcNtB2E_5Right0EENCINvMs_NtNtB9_6author7runtimeNtB8a_18InherentExtrinsics25inject_raw_inherents_listB2J_B5u_E0ENcNtB1j_5Right0EEEB9_
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1j_EEB9_
Line
Count
Source
513
126
    pub fn run_vectored(
514
126
        mut self,
515
126
        function_to_call: &str,
516
126
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
126
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
126
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
126
        // Determine the total length of `data`.
520
126
        let mut data_len_u32: u32 = 0;
521
126
        for 
data0
in data.clone() {
522
0
            let len = match u32::try_from(data.as_ref().len()) {
523
0
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
0
            data_len_u32 = match data_len_u32.checked_add(len) {
527
0
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
126
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
126
537
126
        // Prepare the virtual machine for execution.
538
126
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
126
        let data_ptr = match allocator.allocate(
542
126
            &mut MemAccess {
543
126
                vm: MemAccessVm::Prepare(&mut vm),
544
126
                memory_total_pages: self.common.memory_total_pages,
545
126
            },
546
126
            data_len_u32,
547
126
        ) {
548
126
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
126
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
126
            .checked_sub(u32::from(vm.memory_size()))
559
126
        {
560
126
            // If the memory can't be grown, it indicates a bug in the allocator.
561
126
            vm.grow_memory(HeapPages::from(to_grow))
562
126
                .unwrap_or_else(|_| unreachable!());
563
126
        }
0
564
565
        // Writing the input data into the VM.
566
126
        let mut data_ptr_iter = data_ptr;
567
126
        for 
data0
in data {
568
0
            let data = data.as_ref();
569
0
            vm.write_memory(data_ptr_iter, data)
570
0
                .unwrap_or_else(|_| unreachable!());
571
0
            data_ptr_iter = data_ptr_iter
572
0
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
0
                .unwrap_or_else(|| unreachable!());
574
0
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
126
        let vm = match vm.start(
579
126
            function_to_call,
580
126
            &[
581
126
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
126
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
126
            ],
584
126
        ) {
585
126
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
126
        Ok(ReadyToRun {
593
126
            resume_value: None,
594
126
            inner: Box::new(Inner {
595
126
                common: self.common,
596
126
                vm,
597
126
                storage_transaction_depth: 0,
598
126
                signatures_batch_verification: None,
599
126
                allocator,
600
126
                storage_proof_size_behavior,
601
126
            }),
602
126
        })
603
126
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EEB9_
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EEB9_
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1j_EEB9_
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EECsiLzmwikkc22_14json_rpc_basic
_RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyB1j_EECsiUjFBJteJ7x_17smoldot_full_node
Line
Count
Source
513
1
    pub fn run_vectored(
514
1
        mut self,
515
1
        function_to_call: &str,
516
1
        storage_proof_size_behavior: StorageProofSizeBehavior,
517
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
518
1
    ) -> Result<ReadyToRun, (StartErr, Self)> {
519
1
        // Determine the total length of `data`.
520
1
        let mut data_len_u32: u32 = 0;
521
1
        for 
data0
in data.clone() {
522
0
            let len = match u32::try_from(data.as_ref().len()) {
523
0
                Ok(v) => v,
524
0
                Err(_) => return Err((StartErr::DataSizeOverflow, self)),
525
            };
526
0
            data_len_u32 = match data_len_u32.checked_add(len) {
527
0
                Some(v) => v,
528
0
                None => return Err((StartErr::DataSizeOverflow, self)),
529
            };
530
        }
531
532
        // Initialize the state of the memory allocator. This is the allocator that is used in
533
        // order to allocate space for the input data, and also later used when the Wasm code
534
        // requests variable-length data.
535
1
        let mut allocator = allocator::FreeingBumpHeapAllocator::new(self.common.heap_base);
536
1
537
1
        // Prepare the virtual machine for execution.
538
1
        let mut vm = self.vm_proto.prepare();
539
540
        // Write the input data in the VM's memory using the allocator.
541
1
        let data_ptr = match allocator.allocate(
542
1
            &mut MemAccess {
543
1
                vm: MemAccessVm::Prepare(&mut vm),
544
1
                memory_total_pages: self.common.memory_total_pages,
545
1
            },
546
1
            data_len_u32,
547
1
        ) {
548
1
            Ok(p) => p,
549
            Err(_) => {
550
0
                self.vm_proto = vm.into_prototype();
551
0
                return Err((StartErr::DataSizeOverflow, self));
552
            }
553
        };
554
555
        // While the allocator has reserved memory, it might have reserved more memory than its
556
        // current size.
557
1
        if let Some(to_grow) = ((data_ptr + data_len_u32).saturating_sub(1) / (64 * 1024) + 1)
558
1
            .checked_sub(u32::from(vm.memory_size()))
559
1
        {
560
1
            // If the memory can't be grown, it indicates a bug in the allocator.
561
1
            vm.grow_memory(HeapPages::from(to_grow))
562
1
                .unwrap_or_else(|_| unreachable!());
563
1
        }
0
564
565
        // Writing the input data into the VM.
566
1
        let mut data_ptr_iter = data_ptr;
567
1
        for 
data0
in data {
568
0
            let data = data.as_ref();
569
0
            vm.write_memory(data_ptr_iter, data)
570
0
                .unwrap_or_else(|_| unreachable!());
571
0
            data_ptr_iter = data_ptr_iter
572
0
                .checked_add(u32::try_from(data.len()).unwrap_or_else(|_| unreachable!()))
573
0
                .unwrap_or_else(|| unreachable!());
574
0
        }
575
576
        // Now start executing the function. We pass as parameter the location and size of the
577
        // input data.
578
1
        let vm = match vm.start(
579
1
            function_to_call,
580
1
            &[
581
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_ptr.to_ne_bytes())),
582
1
                vm::WasmValue::I32(i32::from_ne_bytes(data_len_u32.to_ne_bytes())),
583
1
            ],
584
1
        ) {
585
1
            Ok(vm) => vm,
586
0
            Err((error, vm_proto)) => {
587
0
                self.vm_proto = vm_proto;
588
0
                return Err((error.into(), self));
589
            }
590
        };
591
592
1
        Ok(ReadyToRun {
593
1
            resume_value: None,
594
1
            inner: Box::new(Inner {
595
1
                common: self.common,
596
1
                vm,
597
1
                storage_transaction_depth: 0,
598
1
                signatures_batch_verification: None,
599
1
                allocator,
600
1
                storage_proof_size_behavior,
601
1
            }),
602
1
        })
603
1
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototype12run_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1j_EECsibGXYHQB8Ea_25json_rpc_general_requests
604
}
605
606
impl fmt::Debug for HostVmPrototype {
607
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608
0
        f.debug_tuple("HostVmPrototype").finish()
609
0
    }
Unexecuted instantiation: _RNvXs0_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_15HostVmPrototypeNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_15HostVmPrototypeNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
610
}
611
612
/// Running virtual machine.
613
#[must_use]
614
#[derive(derive_more::From, Debug)]
615
pub enum HostVm {
616
    /// Wasm virtual machine is ready to be run. Call [`ReadyToRun::run`] to make progress.
617
    #[from]
618
    ReadyToRun(ReadyToRun),
619
    /// Function execution has succeeded. Contains the return value of the call.
620
    ///
621
    /// The trie root hash of all the child tries must be recalculated and written to the main trie
622
    /// similar to when a [`ExternalStorageRoot`] with a `child_trie` of `None` is generated. See
623
    /// the documentation of [`ExternalStorageRoot`].
624
    #[from]
625
    Finished(Finished),
626
    /// The Wasm blob did something that doesn't conform to the runtime environment.
627
    Error {
628
        /// Virtual machine ready to be used again.
629
        prototype: HostVmPrototype,
630
        /// Error that happened.
631
        error: Error,
632
    },
633
    /// Must load an storage value.
634
    #[from]
635
    ExternalStorageGet(ExternalStorageGet),
636
    /// Must set an storage value.
637
    #[from]
638
    ExternalStorageSet(ExternalStorageSet),
639
    /// See documentation of [`ExternalStorageAppend`].
640
    #[from]
641
    ExternalStorageAppend(ExternalStorageAppend),
642
    /// Must remove all the storage values starting with a certain prefix.
643
    #[from]
644
    ExternalStorageClearPrefix(ExternalStorageClearPrefix),
645
    /// Must provide the trie root hash of the storage and write the trie root hash of child tries
646
    /// to the main trie.
647
    #[from]
648
    ExternalStorageRoot(ExternalStorageRoot),
649
    /// Need to provide the storage key that follows a specific one.
650
    #[from]
651
    ExternalStorageNextKey(ExternalStorageNextKey),
652
    /// Must set off-chain index value.
653
    #[from]
654
    ExternalOffchainIndexSet(ExternalOffchainIndexSet),
655
    /// Must load an offchain storage value.
656
    #[from]
657
    ExternalOffchainStorageGet(ExternalOffchainStorageGet),
658
    /// Must set value of an off-chain storage entry.
659
    #[from]
660
    ExternalOffchainStorageSet(ExternalOffchainStorageSet),
661
    /// Need to provide the current timestamp.
662
    #[from]
663
    OffchainTimestamp(OffchainTimestamp),
664
    /// Must return random seed.
665
    #[from]
666
    OffchainRandomSeed(OffchainRandomSeed),
667
    /// Submit a transaction from offchain worker.
668
    #[from]
669
    OffchainSubmitTransaction(OffchainSubmitTransaction),
670
    /// Need to verify whether a signature is valid.
671
    #[from]
672
    SignatureVerification(SignatureVerification),
673
    /// Need to call `Core_version` on the given Wasm code and return the raw output (i.e.
674
    /// still SCALE-encoded), or an error if the call has failed.
675
    #[from]
676
    CallRuntimeVersion(CallRuntimeVersion),
677
    /// Declares the start of a storage transaction. See [`HostVm::EndStorageTransaction`].
678
    #[from]
679
    StartStorageTransaction(StartStorageTransaction),
680
    /// Ends a storage transaction. All changes made to the storage (e.g. through a
681
    /// [`HostVm::ExternalStorageSet`]) since the previous
682
    /// [`HostVm::StartStorageTransaction`] must be rolled back if `rollback` is true.
683
    ///
684
    /// Guaranteed by the code in this module to never happen if no transaction is in progress.
685
    /// If the runtime attempts to end a non-existing transaction, an [`HostVm::Error`] is
686
    /// generated instead.
687
    EndStorageTransaction {
688
        /// Object used to resume execution.
689
        resume: EndStorageTransaction,
690
        /// If true, changes must be rolled back.
691
        rollback: bool,
692
    },
693
    /// Need to provide the maximum log level.
694
    #[from]
695
    GetMaxLogLevel(GetMaxLogLevel),
696
    /// Runtime has emitted a log entry.
697
    #[from]
698
    LogEmit(LogEmit),
699
}
700
701
impl HostVm {
702
    /// Cancels execution of the virtual machine and returns back the prototype.
703
0
    pub fn into_prototype(self) -> HostVmPrototype {
704
0
        match self {
705
0
            HostVm::ReadyToRun(inner) => inner.inner.into_prototype(),
706
0
            HostVm::Finished(inner) => inner.inner.into_prototype(),
707
0
            HostVm::Error { prototype, .. } => prototype,
708
0
            HostVm::ExternalStorageGet(inner) => inner.inner.into_prototype(),
709
0
            HostVm::ExternalStorageSet(inner) => inner.inner.into_prototype(),
710
0
            HostVm::ExternalStorageAppend(inner) => inner.inner.into_prototype(),
711
0
            HostVm::ExternalStorageClearPrefix(inner) => inner.inner.into_prototype(),
712
0
            HostVm::ExternalStorageRoot(inner) => inner.inner.into_prototype(),
713
0
            HostVm::ExternalStorageNextKey(inner) => inner.inner.into_prototype(),
714
0
            HostVm::ExternalOffchainIndexSet(inner) => inner.inner.into_prototype(),
715
0
            HostVm::ExternalOffchainStorageGet(inner) => inner.inner.into_prototype(),
716
0
            HostVm::ExternalOffchainStorageSet(inner) => inner.inner.into_prototype(),
717
0
            HostVm::OffchainTimestamp(inner) => inner.inner.into_prototype(),
718
0
            HostVm::OffchainRandomSeed(inner) => inner.inner.into_prototype(),
719
0
            HostVm::OffchainSubmitTransaction(inner) => inner.inner.into_prototype(),
720
0
            HostVm::SignatureVerification(inner) => inner.inner.into_prototype(),
721
0
            HostVm::CallRuntimeVersion(inner) => inner.inner.into_prototype(),
722
0
            HostVm::StartStorageTransaction(inner) => inner.inner.into_prototype(),
723
0
            HostVm::EndStorageTransaction { resume, .. } => resume.inner.into_prototype(),
724
0
            HostVm::GetMaxLogLevel(inner) => inner.inner.into_prototype(),
725
0
            HostVm::LogEmit(inner) => inner.inner.into_prototype(),
726
        }
727
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_6HostVm14into_prototype
Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_6HostVm14into_prototype
728
}
729
730
/// Virtual machine is ready to run.
731
pub struct ReadyToRun {
732
    inner: Box<Inner>,
733
    resume_value: Option<vm::WasmValue>,
734
}
735
736
impl ReadyToRun {
737
    /// Runs the virtual machine until something important happens.
738
    ///
739
    /// > **Note**: This is when the actual CPU-heavy computation happens.
740
1.49k
    pub fn run(mut self) -> HostVm {
741
34.4k
        loop {
742
34.4k
            match self.run_once() {
743
32.9k
                HostVm::ReadyToRun(r) => self = r,
744
1.49k
                other => return other,
745
1.49k
            }
746
1.49k
        }
747
1.49k
    }
_RNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_10ReadyToRun3run
Line
Count
Source
740
1.15k
    pub fn run(mut self) -> HostVm {
741
29.2k
        loop {
742
29.2k
            match self.run_once() {
743
28.0k
                HostVm::ReadyToRun(r) => self = r,
744
1.15k
                other => return other,
745
1.15k
            }
746
1.15k
        }
747
1.15k
    }
_RNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_10ReadyToRun3run
Line
Count
Source
740
338
    pub fn run(mut self) -> HostVm {
741
5.20k
        loop {
742
5.20k
            match self.run_once() {
743
4.86k
                HostVm::ReadyToRun(r) => self = r,
744
338
                other => return other,
745
338
            }
746
338
        }
747
338
    }
748
749
34.4k
    fn run_once(mut self) -> HostVm {
750
        // `vm::ExecOutcome::Interrupted` is by far the variant that requires the most
751
        // handling code. As such, special-case all other variants before.
752
34.4k
        let (
id, params34.2k
) = match self.inner.vm.run(self.resume_value) {
753
34.2k
            Ok(vm::ExecOutcome::Interrupted { id, params }) => (id, params),
754
755
            Ok(vm::ExecOutcome::Finished {
756
169
                return_value: Ok(Some(vm::WasmValue::I64(ret))),
757
169
            }) => {
758
169
                // Wasm virtual machine has successfully returned.
759
169
760
169
                if self.inner.storage_transaction_depth > 0 {
761
0
                    return HostVm::Error {
762
0
                        prototype: self.inner.into_prototype(),
763
0
                        error: Error::FinishedWithPendingTransaction,
764
0
                    };
765
169
                }
766
169
767
169
                // Turn the `i64` into a `u64`, not changing any bit.
768
169
                let ret = u64::from_ne_bytes(ret.to_ne_bytes());
769
169
770
169
                // According to the runtime environment specification, the return value is two
771
169
                // consecutive I32s representing the length and size of the SCALE-encoded
772
169
                // return value.
773
169
                let value_size = u32::try_from(ret >> 32).unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_once0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_once0Bb_
774
169
                let value_ptr = u32::try_from(ret & 0xffff_ffff).unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces_0Bb_
775
169
776
169
                if value_size.saturating_add(value_ptr)
777
169
                    <= u32::from(self.inner.vm.memory_size()) * 64 * 1024
778
                {
779
165
                    return HostVm::Finished(Finished {
780
165
                        inner: self.inner,
781
165
                        value_ptr,
782
165
                        value_size,
783
165
                    });
784
4
                }
785
4
                let error = Error::ReturnedPtrOutOfRange {
786
4
                    pointer: value_ptr,
787
4
                    size: value_size,
788
4
                    memory_size: u32::from(self.inner.vm.memory_size()) * 64 * 1024,
789
4
                };
790
4
791
4
                return HostVm::Error {
792
4
                    prototype: self.inner.into_prototype(),
793
4
                    error,
794
4
                };
795
            }
796
797
            Ok(vm::ExecOutcome::Finished {
798
2
                return_value: Ok(return_value),
799
2
            }) => {
800
2
                // The Wasm function has successfully returned, but the specs require that it
801
2
                // returns a `i64`.
802
2
                return HostVm::Error {
803
2
                    prototype: self.inner.into_prototype(),
804
2
                    error: Error::BadReturnValue {
805
2
                        actual: return_value.map(|v| v.ty()),
_RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces0_0Bb_
Line
Count
Source
805
2
                        actual: return_value.map(|v| v.ty()),
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces0_0Bb_
806
2
                    },
807
2
                };
808
            }
809
810
            Ok(vm::ExecOutcome::Finished {
811
2
                return_value: Err(err),
812
2
            }) => {
813
2
                return HostVm::Error {
814
2
                    error: Error::Trap(err),
815
2
                    prototype: self.inner.into_prototype(),
816
2
                }
817
            }
818
819
            Err(vm::RunErr::BadValueTy { .. }) => {
820
                // Tried to inject back the value returned by a host function, but it doesn't
821
                // match what the Wasm code expects. Given that we check the host function
822
                // signatures at initialization, this indicates a bug in this implementation.
823
0
                unreachable!()
824
            }
825
826
            Err(vm::RunErr::Poisoned) => {
827
                // Can only happen if there's a bug somewhere.
828
0
                unreachable!()
829
            }
830
        };
831
832
        // The Wasm code has called an host_fn. The `id` is a value that we passed
833
        // at initialization, and corresponds to an index in `registered_functions`.
834
34.2k
        let 
host_fn34.2k
= match self.inner.common.registered_functions.get(id) {
835
34.2k
            Some(FunctionImport::Resolved(f)) => *f,
836
2
            Some(FunctionImport::Unresolved { name, module }) => {
837
2
                return HostVm::Error {
838
2
                    error: Error::UnresolvedFunctionCalled {
839
2
                        function: name.clone(),
840
2
                        module_name: module.clone(),
841
2
                    },
842
2
                    prototype: self.inner.into_prototype(),
843
2
                };
844
            }
845
0
            None => unreachable!(),
846
        };
847
848
        // Passed a parameter index. Produces an `impl AsRef<[u8]>`.
849
        macro_rules! expect_pointer_size {
850
            ($num:expr) => {{
851
                let val = match &params[$num] {
852
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
853
                    // The signatures are checked at initialization and the Wasm VM ensures that
854
                    // the proper parameter types are provided.
855
                    _ => unreachable!(),
856
                };
857
858
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
859
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
860
861
                let result = self.inner.vm.read_memory(ptr, len);
862
                match result {
863
                    Ok(v) => v,
864
                    Err(vm::OutOfBoundsError) => {
865
                        drop(result);
866
                        return HostVm::Error {
867
                            error: Error::ParamOutOfRange {
868
                                function: host_fn.name(),
869
                                param_num: $num,
870
                                pointer: ptr,
871
                                length: len,
872
                            },
873
                            prototype: self.inner.into_prototype(),
874
                        };
875
                    }
876
                }
877
            }};
878
        }
879
880
        macro_rules! expect_pointer_size_raw {
881
            ($num:expr) => {{
882
                let val = match &params[$num] {
883
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
884
                    // The signatures are checked at initialization and the Wasm VM ensures that
885
                    // the proper parameter types are provided.
886
                    _ => unreachable!(),
887
                };
888
889
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
890
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
891
892
                if len.saturating_add(ptr) > u32::from(self.inner.vm.memory_size()) * 64 * 1024 {
893
                    return HostVm::Error {
894
                        error: Error::ParamOutOfRange {
895
                            function: host_fn.name(),
896
                            param_num: $num,
897
                            pointer: ptr,
898
                            length: len,
899
                        },
900
                        prototype: self.inner.into_prototype(),
901
                    };
902
                }
903
904
                (ptr, len)
905
            }};
906
        }
907
908
        macro_rules! expect_pointer_constant_size {
909
            ($num:expr, $size:expr) => {{
910
                let ptr = match params[$num] {
911
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
912
                    // The signatures are checked at initialization and the Wasm VM ensures that
913
                    // the proper parameter types are provided.
914
                    _ => unreachable!(),
915
                };
916
917
                let result = self.inner.vm.read_memory(ptr, $size);
918
                match result {
919
                    Ok(v) => {
920
                        *<&[u8; $size]>::try_from(v.as_ref()).unwrap_or_else(|_| unreachable!())
921
                    }
922
                    Err(vm::OutOfBoundsError) => {
923
                        drop(result);
924
                        return HostVm::Error {
925
                            error: Error::ParamOutOfRange {
926
                                function: host_fn.name(),
927
                                param_num: $num,
928
                                pointer: ptr,
929
                                length: $size,
930
                            },
931
                            prototype: self.inner.into_prototype(),
932
                        };
933
                    }
934
                }
935
            }};
936
        }
937
938
        macro_rules! expect_pointer_constant_size_raw {
939
            ($num:expr, $size:expr) => {{
940
                let ptr = match params[$num] {
941
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
942
                    // The signatures are checked at initialization and the Wasm VM ensures that
943
                    // the proper parameter types are provided.
944
                    _ => unreachable!(),
945
                };
946
947
                if u32::saturating_add($size, ptr)
948
                    > u32::from(self.inner.vm.memory_size()) * 64 * 1024
949
                {
950
                    return HostVm::Error {
951
                        error: Error::ParamOutOfRange {
952
                            function: host_fn.name(),
953
                            param_num: $num,
954
                            pointer: ptr,
955
                            length: $size,
956
                        },
957
                        prototype: self.inner.into_prototype(),
958
                    };
959
                }
960
961
                ptr
962
            }};
963
        }
964
965
        macro_rules! expect_u32 {
966
            ($num:expr) => {{
967
                match &params[$num] {
968
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
969
                    // The signatures are checked at initialization and the Wasm VM ensures that
970
                    // the proper parameter types are provided.
971
                    _ => unreachable!(),
972
                }
973
            }};
974
        }
975
976
        macro_rules! expect_offchain_storage_kind {
977
            ($num:expr) => {{
978
                match &params[$num] {
979
                    // `0` indicates `StorageKind::PERSISTENT`, the only kind of offchain
980
                    // storage that is available.
981
                    vm::WasmValue::I32(0) => true,
982
                    // `1` indicates `StorageKind::LOCAL`, which is valid but has never been
983
                    // implemented in Substrate.
984
                    vm::WasmValue::I32(1) => false,
985
                    vm::WasmValue::I32(_) => {
986
                        return HostVm::Error {
987
                            error: Error::ParamDecodeError,
988
                            prototype: self.inner.into_prototype(),
989
                        }
990
                    }
991
                    // The signatures are checked at initialization and the Wasm VM ensures that
992
                    // the proper parameter types are provided.
993
                    _ => unreachable!(),
994
                }
995
            }};
996
        }
997
998
        macro_rules! expect_state_version {
999
            ($num:expr) => {{
1000
                match &params[$num] {
1001
                    vm::WasmValue::I32(0) => TrieEntryVersion::V0,
1002
                    vm::WasmValue::I32(1) => TrieEntryVersion::V1,
1003
                    vm::WasmValue::I32(_) => {
1004
                        return HostVm::Error {
1005
                            error: Error::ParamDecodeError,
1006
                            prototype: self.inner.into_prototype(),
1007
                        }
1008
                    }
1009
                    // The signatures are checked at initialization and the Wasm VM ensures that
1010
                    // the proper parameter types are provided.
1011
                    _ => unreachable!(),
1012
                }
1013
            }};
1014
        }
1015
1016
        // TODO: implement all functions and remove this macro
1017
        macro_rules! host_fn_not_implemented {
1018
            () => {{
1019
                return HostVm::Error {
1020
                    error: Error::HostFunctionNotImplemented {
1021
                        function: host_fn.name(),
1022
                    },
1023
                    prototype: self.inner.into_prototype(),
1024
                };
1025
            }};
1026
        }
1027
1028
        // Handle the function calls.
1029
        // Some of these enum variants simply change the state of `self`, while most of them
1030
        // instead return an `ExternalVm` to the user.
1031
34.2k
        match host_fn {
1032
            HostFunction::ext_storage_set_version_1 => {
1033
300
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesl_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesk_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesl_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesk_0Bb_
1034
300
                let (value_ptr, value_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesn_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesm_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesn_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesm_0Bb_
1035
300
                HostVm::ExternalStorageSet(ExternalStorageSet {
1036
300
                    key_ptr,
1037
300
                    key_size,
1038
300
                    child_trie_ptr_size: None,
1039
300
                    value: Some((value_ptr, value_size)),
1040
300
                    inner: self.inner,
1041
300
                })
1042
            }
1043
            HostFunction::ext_storage_get_version_1 => {
1044
655
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesp_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onceso_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesp_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onceso_0Bb_
1045
655
                HostVm::ExternalStorageGet(ExternalStorageGet {
1046
655
                    key_ptr,
1047
655
                    key_size,
1048
655
                    child_trie_ptr_size: None,
1049
655
                    calling: id,
1050
655
                    value_out_ptr: None,
1051
655
                    offset: 0,
1052
655
                    max_size: u32::MAX,
1053
655
                    inner: self.inner,
1054
655
                })
1055
            }
1056
            HostFunction::ext_storage_read_version_1 => {
1057
10
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesr_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesq_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesr_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesq_0Bb_
1058
10
                let (value_out_ptr, value_out_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncest_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncess_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncest_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncess_0Bb_
1059
10
                let offset = expect_u32!(2);
1060
10
                HostVm::ExternalStorageGet(ExternalStorageGet {
1061
10
                    key_ptr,
1062
10
                    key_size,
1063
10
                    child_trie_ptr_size: None,
1064
10
                    calling: id,
1065
10
                    value_out_ptr: Some(value_out_ptr),
1066
10
                    offset,
1067
10
                    max_size: value_out_size,
1068
10
                    inner: self.inner,
1069
10
                })
1070
            }
1071
            HostFunction::ext_storage_clear_version_1 => {
1072
71
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesv_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesu_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesv_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesu_0Bb_
1073
71
                HostVm::ExternalStorageSet(ExternalStorageSet {
1074
71
                    key_ptr,
1075
71
                    key_size,
1076
71
                    child_trie_ptr_size: None,
1077
71
                    value: None,
1078
71
                    inner: self.inner,
1079
71
                })
1080
            }
1081
            HostFunction::ext_storage_exists_version_1 => {
1082
16
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesx_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesw_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesx_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesw_0Bb_
1083
16
                HostVm::ExternalStorageGet(ExternalStorageGet {
1084
16
                    key_ptr,
1085
16
                    key_size,
1086
16
                    child_trie_ptr_size: None,
1087
16
                    calling: id,
1088
16
                    value_out_ptr: None,
1089
16
                    offset: 0,
1090
16
                    max_size: 0,
1091
16
                    inner: self.inner,
1092
16
                })
1093
            }
1094
            HostFunction::ext_storage_clear_prefix_version_1 => {
1095
1
                let (prefix_ptr, prefix_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesz_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesy_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesz_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesy_0Bb_
1096
1
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1097
1
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1098
1
                    child_trie_ptr_size: None,
1099
1
                    inner: self.inner,
1100
1
                    max_keys_to_remove: None,
1101
1
                    calling: id,
1102
1
                })
1103
            }
1104
            HostFunction::ext_storage_clear_prefix_version_2 => {
1105
4
                let (prefix_ptr, prefix_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesB_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesA_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesB_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesA_0Bb_
1106
1107
4
                let max_keys_to_remove = {
1108
4
                    let input = 
expect_pointer_size!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesD_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesC_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesD_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesC_0Bb_
1109
4
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1110
4
                        nom::combinator::all_consuming(util::nom_option_decode(
1111
4
                            nom::number::streaming::le_u32,
1112
4
                        ))(input.as_ref())
1113
4
                        .map(|(_, parse_result)| parse_result);
_RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1_0Bb_
Line
Count
Source
1113
4
                        .map(|(_, parse_result)| parse_result);
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1_0Bb_
1114
4
1115
4
                    match parsing_result {
1116
4
                        Ok(val) => Ok(val),
1117
0
                        Err(_) => Err(()),
1118
                    }
1119
                };
1120
1121
4
                let max_keys_to_remove = match max_keys_to_remove {
1122
4
                    Ok(l) => l,
1123
                    Err(()) => {
1124
0
                        return HostVm::Error {
1125
0
                            error: Error::ParamDecodeError,
1126
0
                            prototype: self.inner.into_prototype(),
1127
0
                        };
1128
                    }
1129
                };
1130
1131
4
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1132
4
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1133
4
                    child_trie_ptr_size: None,
1134
4
                    inner: self.inner,
1135
4
                    max_keys_to_remove,
1136
4
                    calling: id,
1137
4
                })
1138
            }
1139
            HostFunction::ext_storage_root_version_1 => {
1140
1
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1141
1
                    inner: self.inner,
1142
1
                    calling: id,
1143
1
                    child_trie_ptr_size: None,
1144
1
                })
1145
            }
1146
            HostFunction::ext_storage_root_version_2 => {
1147
                // The `ext_storage_root_version_2` host function gets passed as parameter the
1148
                // state version of the runtime. This is in fact completely unnecessary as the
1149
                // same information is found in the runtime specification, and this parameter
1150
                // should be considered as a historical accident. We verify that the version
1151
                // provided as parameter is the same as the one in the specification.
1152
4
                let version_param = expect_state_version!(0);
1153
4
                let version_spec = self
1154
4
                    .inner
1155
4
                    .common
1156
4
                    .runtime_version
1157
4
                    .as_ref()
1158
4
                    .unwrap_or_else(|| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2_0Bb_
1159
4
                    .decode()
1160
4
                    .state_version
1161
4
                    .unwrap_or(TrieEntryVersion::V0);
1162
4
1163
4
                if version_param != version_spec {
1164
0
                    return HostVm::Error {
1165
0
                        error: Error::StateVersionMismatch {
1166
0
                            parameter: version_param,
1167
0
                            specification: version_spec,
1168
0
                        },
1169
0
                        prototype: self.inner.into_prototype(),
1170
0
                    };
1171
4
                }
1172
4
1173
4
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1174
4
                    inner: self.inner,
1175
4
                    calling: id,
1176
4
                    child_trie_ptr_size: None,
1177
4
                })
1178
            }
1179
            HostFunction::ext_storage_changes_root_version_1 => {
1180
                // The changes trie is an obsolete attempt at having a second trie containing, for
1181
                // each storage item, the latest block height where this item has been modified.
1182
                // When this function returns `None`, it indicates that the changes trie is
1183
                // disabled. While this function used to be called by the runtimes of
1184
                // Westend/Polkadot/Kusama (and maybe others), it has never returned anything else
1185
                // but `None`. The entire changes trie mechanism was ultimately removed in
1186
                // October 2021.
1187
                // This function is no longer called by recent runtimes, but must be preserved for
1188
                // backwards compatibility.
1189
1
                self.inner.alloc_write_and_return_pointer_size(
1190
1
                    HostFunction::ext_storage_changes_root_version_1.name(),
1191
1
                    iter::once(&[0][..]),
1192
1
                )
1193
            }
1194
            HostFunction::ext_storage_next_key_version_1 => {
1195
1
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesF_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesE_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesF_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesE_0Bb_
1196
1
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1197
1
                    key_ptr,
1198
1
                    key_size,
1199
1
                    child_trie_ptr_size: None,
1200
1
                    inner: self.inner,
1201
1
                })
1202
            }
1203
            HostFunction::ext_storage_append_version_1 => {
1204
71
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesH_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesG_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesH_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesG_0Bb_
1205
71
                let (value_ptr, value_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesJ_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesI_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesJ_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesI_0Bb_
1206
71
                HostVm::ExternalStorageAppend(ExternalStorageAppend {
1207
71
                    key_ptr,
1208
71
                    key_size,
1209
71
                    value_ptr,
1210
71
                    value_size,
1211
71
                    inner: self.inner,
1212
71
                })
1213
            }
1214
            HostFunction::ext_storage_start_transaction_version_1 => {
1215
                // TODO: a maximum depth is important in order to prevent a malicious runtime from crashing the client, but the depth needs to be the same as in Substrate; figure out
1216
14
                self.inner.storage_transaction_depth += 1;
1217
14
                HostVm::StartStorageTransaction(StartStorageTransaction { inner: self.inner })
1218
            }
1219
            HostFunction::ext_storage_rollback_transaction_version_1 => {
1220
0
                if self.inner.storage_transaction_depth == 0 {
1221
0
                    return HostVm::Error {
1222
0
                        error: Error::NoActiveTransaction,
1223
0
                        prototype: self.inner.into_prototype(),
1224
0
                    };
1225
0
                }
1226
0
1227
0
                self.inner.storage_transaction_depth -= 1;
1228
0
                HostVm::EndStorageTransaction {
1229
0
                    resume: EndStorageTransaction { inner: self.inner },
1230
0
                    rollback: true,
1231
0
                }
1232
            }
1233
            HostFunction::ext_storage_commit_transaction_version_1 => {
1234
14
                if self.inner.storage_transaction_depth == 0 {
1235
0
                    return HostVm::Error {
1236
0
                        error: Error::NoActiveTransaction,
1237
0
                        prototype: self.inner.into_prototype(),
1238
0
                    };
1239
14
                }
1240
14
1241
14
                self.inner.storage_transaction_depth -= 1;
1242
14
                HostVm::EndStorageTransaction {
1243
14
                    resume: EndStorageTransaction { inner: self.inner },
1244
14
                    rollback: false,
1245
14
                }
1246
            }
1247
            HostFunction::ext_storage_proof_size_storage_proof_size_version_1 => {
1248
0
                match self.inner.storage_proof_size_behavior {
1249
0
                    StorageProofSizeBehavior::ConstantReturnValue(value) => {
1250
0
                        HostVm::ReadyToRun(ReadyToRun {
1251
0
                            inner: self.inner,
1252
0
                            resume_value: Some(vm::WasmValue::I64(i64::from_ne_bytes(
1253
0
                                value.to_ne_bytes(),
1254
0
                            ))),
1255
0
                        })
1256
                    }
1257
0
                    StorageProofSizeBehavior::Unimplemented => HostVm::Error {
1258
0
                        error: Error::HostFunctionNotImplemented {
1259
0
                            function: host_fn.name(),
1260
0
                        },
1261
0
                        prototype: self.inner.into_prototype(),
1262
0
                    },
1263
                }
1264
            }
1265
            HostFunction::ext_default_child_storage_get_version_1 => {
1266
2
                let (child_trie_ptr, child_trie_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesL_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesK_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesL_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesK_0Bb_
1267
2
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesN_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesM_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesN_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesM_0Bb_
1268
2
                HostVm::ExternalStorageGet(ExternalStorageGet {
1269
2
                    key_ptr,
1270
2
                    key_size,
1271
2
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1272
2
                    calling: id,
1273
2
                    value_out_ptr: None,
1274
2
                    offset: 0,
1275
2
                    max_size: u32::MAX,
1276
2
                    inner: self.inner,
1277
2
                })
1278
            }
1279
            HostFunction::ext_default_child_storage_read_version_1 => {
1280
4
                let (child_trie_ptr, child_trie_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesP_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesO_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesP_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesO_0Bb_
1281
4
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesR_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesQ_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesR_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesQ_0Bb_
1282
4
                let (value_out_ptr, value_out_size) = 
expect_pointer_size_raw!(2)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesT_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesS_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesT_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesS_0Bb_
1283
4
                let offset = expect_u32!(3);
1284
4
                HostVm::ExternalStorageGet(ExternalStorageGet {
1285
4
                    key_ptr,
1286
4
                    key_size,
1287
4
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1288
4
                    calling: id,
1289
4
                    value_out_ptr: Some(value_out_ptr),
1290
4
                    offset,
1291
4
                    max_size: value_out_size,
1292
4
                    inner: self.inner,
1293
4
                })
1294
            }
1295
            HostFunction::ext_default_child_storage_storage_kill_version_1 => {
1296
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesV_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesU_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesV_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesU_0Bb_
1297
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1298
0
                    prefix_ptr_size: None,
1299
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1300
0
                    inner: self.inner,
1301
0
                    max_keys_to_remove: None,
1302
0
                    calling: id,
1303
0
                })
1304
            }
1305
            HostFunction::ext_default_child_storage_storage_kill_version_2
1306
            | HostFunction::ext_default_child_storage_storage_kill_version_3 => {
1307
1
                let (child_trie_ptr, child_trie_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesX_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesW_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesX_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesW_0Bb_
1308
1309
1
                let max_keys_to_remove = {
1310
1
                    let input = 
expect_pointer_size!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesZ_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesY_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesZ_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesY_0Bb_
1311
1
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1312
1
                        nom::combinator::all_consuming(util::nom_option_decode(
1313
1
                            nom::number::streaming::le_u32,
1314
1
                        ))(input.as_ref())
1315
1
                        .map(|(_, parse_result)| parse_result);
_RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces3_0Bb_
Line
Count
Source
1315
1
                        .map(|(_, parse_result)| parse_result);
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces3_0Bb_
1316
1
1317
1
                    match parsing_result {
1318
1
                        Ok(val) => Ok(val),
1319
0
                        Err(_) => Err(()),
1320
                    }
1321
                };
1322
1323
1
                let max_keys_to_remove = match max_keys_to_remove {
1324
1
                    Ok(l) => l,
1325
                    Err(()) => {
1326
0
                        return HostVm::Error {
1327
0
                            error: Error::ParamDecodeError,
1328
0
                            prototype: self.inner.into_prototype(),
1329
0
                        };
1330
                    }
1331
                };
1332
1333
1
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1334
1
                    prefix_ptr_size: None,
1335
1
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1336
1
                    inner: self.inner,
1337
1
                    max_keys_to_remove,
1338
1
                    calling: id,
1339
1
                })
1340
            }
1341
            HostFunction::ext_default_child_storage_clear_prefix_version_1 => {
1342
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces11_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces10_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces11_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces10_0Bb_
1343
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces13_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces12_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces13_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces12_0Bb_
1344
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1345
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1346
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1347
0
                    inner: self.inner,
1348
0
                    max_keys_to_remove: None,
1349
0
                    calling: id,
1350
0
                })
1351
            }
1352
            HostFunction::ext_default_child_storage_clear_prefix_version_2 => {
1353
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces15_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces14_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces15_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces14_0Bb_
1354
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces17_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces16_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces17_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces16_0Bb_
1355
1356
0
                let max_keys_to_remove = {
1357
0
                    let input = expect_pointer_size!(2);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces19_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces18_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces19_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces18_0Bb_
1358
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1359
0
                        nom::combinator::all_consuming(util::nom_option_decode(
1360
0
                            nom::number::streaming::le_u32,
1361
0
                        ))(input.as_ref())
1362
0
                        .map(|(_, parse_result)| parse_result);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces4_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces4_0Bb_
1363
0
1364
0
                    match parsing_result {
1365
0
                        Ok(val) => Ok(val),
1366
0
                        Err(_) => Err(()),
1367
                    }
1368
                };
1369
1370
0
                let max_keys_to_remove = match max_keys_to_remove {
1371
0
                    Ok(l) => l,
1372
                    Err(()) => {
1373
0
                        return HostVm::Error {
1374
0
                            error: Error::ParamDecodeError,
1375
0
                            prototype: self.inner.into_prototype(),
1376
0
                        };
1377
                    }
1378
                };
1379
1380
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1381
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1382
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1383
0
                    inner: self.inner,
1384
0
                    max_keys_to_remove,
1385
0
                    calling: id,
1386
0
                })
1387
            }
1388
            HostFunction::ext_default_child_storage_set_version_1 => {
1389
4
                let (child_trie_ptr, child_trie_size) = 
expect_pointer_size_raw!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1b_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1a_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1b_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1a_0Bb_
1390
4
                let (key_ptr, key_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1d_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1c_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1d_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1c_0Bb_
1391
4
                let (value_ptr, value_size) = 
expect_pointer_size_raw!(2)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1f_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1e_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1f_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1e_0Bb_
1392
4
                HostVm::ExternalStorageSet(ExternalStorageSet {
1393
4
                    key_ptr,
1394
4
                    key_size,
1395
4
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1396
4
                    value: Some((value_ptr, value_size)),
1397
4
                    inner: self.inner,
1398
4
                })
1399
            }
1400
            HostFunction::ext_default_child_storage_clear_version_1 => {
1401
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1h_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1g_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1h_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1g_0Bb_
1402
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1j_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1i_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1j_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1i_0Bb_
1403
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1404
0
                    key_ptr,
1405
0
                    key_size,
1406
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1407
0
                    value: None,
1408
0
                    inner: self.inner,
1409
0
                })
1410
            }
1411
            HostFunction::ext_default_child_storage_exists_version_1 => {
1412
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1l_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1k_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1l_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1k_0Bb_
1413
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1n_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1m_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1n_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1m_0Bb_
1414
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1415
0
                    key_ptr,
1416
0
                    key_size,
1417
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1418
0
                    calling: id,
1419
0
                    value_out_ptr: None,
1420
0
                    offset: 0,
1421
0
                    max_size: 0,
1422
0
                    inner: self.inner,
1423
0
                })
1424
            }
1425
            HostFunction::ext_default_child_storage_next_key_version_1 => {
1426
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1p_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1o_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1p_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1o_0Bb_
1427
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1r_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1q_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1r_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1q_0Bb_
1428
0
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1429
0
                    key_ptr,
1430
0
                    key_size,
1431
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1432
0
                    inner: self.inner,
1433
0
                })
1434
            }
1435
            HostFunction::ext_default_child_storage_root_version_1 => {
1436
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1t_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1s_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1t_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1s_0Bb_
1437
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1438
0
                    inner: self.inner,
1439
0
                    calling: id,
1440
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1441
0
                })
1442
            }
1443
            HostFunction::ext_default_child_storage_root_version_2 => {
1444
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1v_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1u_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1v_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1u_0Bb_
1445
1446
                // The `ext_default_child_storage_root_version_2` host function gets passed as
1447
                // parameter the state version of the runtime. This is in fact completely
1448
                // unnecessary as the same information is found in the runtime specification, and
1449
                // this parameter should be considered as a historical accident. We verify that the
1450
                // version provided as parameter is the same as the one in the specification.
1451
0
                let version_param = expect_state_version!(1);
1452
0
                let version_spec = self
1453
0
                    .inner
1454
0
                    .common
1455
0
                    .runtime_version
1456
0
                    .as_ref()
1457
0
                    .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces5_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces5_0Bb_
1458
0
                    .decode()
1459
0
                    .state_version
1460
0
                    .unwrap_or(TrieEntryVersion::V0);
1461
0
1462
0
                if version_param != version_spec {
1463
0
                    return HostVm::Error {
1464
0
                        error: Error::StateVersionMismatch {
1465
0
                            parameter: version_param,
1466
0
                            specification: version_spec,
1467
0
                        },
1468
0
                        prototype: self.inner.into_prototype(),
1469
0
                    };
1470
0
                }
1471
0
1472
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1473
0
                    inner: self.inner,
1474
0
                    calling: id,
1475
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1476
0
                })
1477
            }
1478
0
            HostFunction::ext_crypto_ed25519_public_keys_version_1 => host_fn_not_implemented!(),
1479
0
            HostFunction::ext_crypto_ed25519_generate_version_1 => host_fn_not_implemented!(),
1480
0
            HostFunction::ext_crypto_ed25519_sign_version_1 => host_fn_not_implemented!(),
1481
            HostFunction::ext_crypto_ed25519_verify_version_1
1482
            | HostFunction::ext_crypto_ed25519_batch_verify_version_1 => {
1483
0
                let is_batch_verification = matches!(
1484
0
                    host_fn,
1485
                    HostFunction::ext_crypto_ed25519_batch_verify_version_1
1486
                );
1487
1488
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1489
0
                    return HostVm::Error {
1490
0
                        error: Error::BatchVerifyWithoutStarting,
1491
0
                        prototype: self.inner.into_prototype(),
1492
0
                    };
1493
0
                }
1494
1495
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1x_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1w_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1x_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1w_0Bb_
1496
                HostVm::SignatureVerification(SignatureVerification {
1497
0
                    algorithm: SignatureVerificationAlgorithm::Ed25519,
1498
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1499
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1500
0
                    message_ptr,
1501
0
                    message_size,
1502
0
                    inner: self.inner,
1503
0
                    is_batch_verification,
1504
                })
1505
            }
1506
0
            HostFunction::ext_crypto_sr25519_public_keys_version_1 => host_fn_not_implemented!(),
1507
0
            HostFunction::ext_crypto_sr25519_generate_version_1 => host_fn_not_implemented!(),
1508
0
            HostFunction::ext_crypto_sr25519_sign_version_1 => host_fn_not_implemented!(),
1509
            HostFunction::ext_crypto_sr25519_verify_version_1
1510
            | HostFunction::ext_crypto_sr25519_batch_verify_version_1 => {
1511
0
                let is_batch_verification = matches!(
1512
0
                    host_fn,
1513
                    HostFunction::ext_crypto_sr25519_batch_verify_version_1
1514
                );
1515
1516
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1517
0
                    return HostVm::Error {
1518
0
                        error: Error::BatchVerifyWithoutStarting,
1519
0
                        prototype: self.inner.into_prototype(),
1520
0
                    };
1521
0
                }
1522
1523
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1z_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1y_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1z_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1y_0Bb_
1524
                HostVm::SignatureVerification(SignatureVerification {
1525
0
                    algorithm: SignatureVerificationAlgorithm::Sr25519V1,
1526
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1527
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1528
0
                    message_ptr,
1529
0
                    message_size,
1530
0
                    inner: self.inner,
1531
0
                    is_batch_verification,
1532
                })
1533
            }
1534
            HostFunction::ext_crypto_sr25519_verify_version_2 => {
1535
6
                let (message_ptr, message_size) = 
expect_pointer_size_raw!(1)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1B_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1A_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1B_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1A_0Bb_
1536
                HostVm::SignatureVerification(SignatureVerification {
1537
6
                    algorithm: SignatureVerificationAlgorithm::Sr25519V2,
1538
6
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1539
6
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1540
6
                    message_ptr,
1541
6
                    message_size,
1542
6
                    inner: self.inner,
1543
                    is_batch_verification: false,
1544
                })
1545
            }
1546
0
            HostFunction::ext_crypto_ecdsa_generate_version_1 => host_fn_not_implemented!(),
1547
            HostFunction::ext_crypto_ecdsa_sign_version_1 => {
1548
                // NOTE: safe to unwrap here because we supply the nn to blake2b fn
1549
0
                let data = <[u8; 32]>::try_from(
1550
0
                    blake2_rfc::blake2b::blake2b(32, &[], expect_pointer_size!(0).as_ref())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1D_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1C_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1D_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1C_0Bb_
1551
0
                        .as_bytes(),
1552
0
                )
1553
0
                .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces6_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces6_0Bb_
1554
0
                let message = libsecp256k1::Message::parse(&data);
1555
1556
0
                if let Ok(sc) =
1557
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1E_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1E_0Bb_
1558
                {
1559
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1560
0
1561
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1562
0
                    self.inner.alloc_write_and_return_pointer(
1563
0
                        host_fn.name(),
1564
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1565
0
                    )
1566
                } else {
1567
0
                    HostVm::Error {
1568
0
                        error: Error::ParamDecodeError,
1569
0
                        prototype: self.inner.into_prototype(),
1570
0
                    }
1571
                }
1572
            }
1573
0
            HostFunction::ext_crypto_ecdsa_public_keys_version_1 => host_fn_not_implemented!(),
1574
            HostFunction::ext_crypto_ecdsa_verify_version_1
1575
            | HostFunction::ext_crypto_ecdsa_batch_verify_version_1 => {
1576
0
                let is_batch_verification = matches!(
1577
0
                    host_fn,
1578
                    HostFunction::ext_crypto_ecdsa_batch_verify_version_1
1579
                );
1580
1581
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1582
0
                    return HostVm::Error {
1583
0
                        error: Error::BatchVerifyWithoutStarting,
1584
0
                        prototype: self.inner.into_prototype(),
1585
0
                    };
1586
0
                }
1587
1588
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1G_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1F_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1G_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1F_0Bb_
1589
                HostVm::SignatureVerification(SignatureVerification {
1590
0
                    algorithm: SignatureVerificationAlgorithm::Ecdsa,
1591
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1592
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1593
0
                    message_ptr,
1594
0
                    message_size,
1595
0
                    inner: self.inner,
1596
0
                    is_batch_verification,
1597
                })
1598
            }
1599
0
            HostFunction::ext_crypto_ecdsa_verify_version_2 => host_fn_not_implemented!(),
1600
            HostFunction::ext_crypto_ecdsa_sign_prehashed_version_1 => {
1601
                // TODO: seems misimplemented, see https://spec.polkadot.network/#id-ext_crypto_ecdsa_sign_prehashed
1602
0
                let message = libsecp256k1::Message::parse(&expect_pointer_constant_size!(0, 32));
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1H_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1H_0Bb_
1603
1604
0
                if let Ok(sc) =
1605
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1I_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1I_0Bb_
1606
                {
1607
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1608
0
1609
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1610
0
                    self.inner.alloc_write_and_return_pointer(
1611
0
                        host_fn.name(),
1612
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1613
0
                    )
1614
                } else {
1615
0
                    HostVm::Error {
1616
0
                        error: Error::ParamDecodeError,
1617
0
                        prototype: self.inner.into_prototype(),
1618
0
                    }
1619
                }
1620
            }
1621
            HostFunction::ext_crypto_ecdsa_verify_prehashed_version_1 => {
1622
                HostVm::SignatureVerification(SignatureVerification {
1623
0
                    algorithm: SignatureVerificationAlgorithm::EcdsaPrehashed,
1624
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1625
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1626
0
                    message_ptr: expect_pointer_constant_size_raw!(1, 32),
1627
                    message_size: 32,
1628
0
                    inner: self.inner,
1629
                    is_batch_verification: false,
1630
                })
1631
            }
1632
1633
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_1
1634
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2 => {
1635
0
                let sig = expect_pointer_constant_size!(0, 65);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1J_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1J_0Bb_
1636
0
                let msg = expect_pointer_constant_size!(1, 32);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1K_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1K_0Bb_
1637
0
                let is_v2 = matches!(
1638
0
                    host_fn,
1639
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2
1640
                );
1641
1642
0
                let result = {
1643
0
                    let rs = if is_v2 {
1644
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1645
                    } else {
1646
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1647
                    };
1648
1649
0
                    if let Ok(rs) = rs {
1650
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1651
0
                            sig[64] - 27
1652
                        } else {
1653
0
                            sig[64]
1654
                        });
1655
1656
0
                        if let Ok(v) = v {
1657
0
                            let pubkey = libsecp256k1::recover(
1658
0
                                &libsecp256k1::Message::parse_slice(&msg)
1659
0
                                    .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces7_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces7_0Bb_
1660
0
                                &rs,
1661
0
                                &v,
1662
0
                            );
1663
1664
0
                            if let Ok(pubkey) = pubkey {
1665
0
                                let mut res = Vec::with_capacity(65);
1666
0
                                res.push(0);
1667
0
                                res.extend_from_slice(&pubkey.serialize()[1..65]);
1668
0
                                res
1669
                            } else {
1670
0
                                vec![1, 2]
1671
                            }
1672
                        } else {
1673
0
                            vec![1, 1]
1674
                        }
1675
                    } else {
1676
0
                        vec![1, 0]
1677
                    }
1678
                };
1679
1680
0
                self.inner
1681
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1682
            }
1683
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_1
1684
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2 => {
1685
0
                let sig = expect_pointer_constant_size!(0, 65);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1L_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1L_0Bb_
1686
0
                let msg = expect_pointer_constant_size!(1, 32);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1M_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1M_0Bb_
1687
0
                let is_v2 = matches!(
1688
0
                    host_fn,
1689
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2
1690
                );
1691
1692
0
                let result = {
1693
0
                    let rs = if is_v2 {
1694
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1695
                    } else {
1696
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1697
                    };
1698
1699
0
                    if let Ok(rs) = rs {
1700
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1701
0
                            sig[64] - 27
1702
                        } else {
1703
0
                            sig[64]
1704
                        });
1705
1706
0
                        if let Ok(v) = v {
1707
0
                            let pubkey = libsecp256k1::recover(
1708
0
                                &libsecp256k1::Message::parse_slice(&msg)
1709
0
                                    .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces8_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces8_0Bb_
1710
0
                                &rs,
1711
0
                                &v,
1712
0
                            );
1713
1714
0
                            if let Ok(pubkey) = pubkey {
1715
0
                                let mut res = Vec::with_capacity(34);
1716
0
                                res.push(0);
1717
0
                                res.extend_from_slice(&pubkey.serialize_compressed());
1718
0
                                res
1719
                            } else {
1720
0
                                vec![1, 2]
1721
                            }
1722
                        } else {
1723
0
                            vec![1, 1]
1724
                        }
1725
                    } else {
1726
0
                        vec![1, 0]
1727
                    }
1728
                };
1729
1730
0
                self.inner
1731
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1732
            }
1733
            HostFunction::ext_crypto_start_batch_verify_version_1 => {
1734
4
                if self.inner.signatures_batch_verification.is_some() {
1735
0
                    return HostVm::Error {
1736
0
                        error: Error::AlreadyBatchVerify,
1737
0
                        prototype: self.inner.into_prototype(),
1738
0
                    };
1739
4
                }
1740
4
1741
4
                self.inner.signatures_batch_verification = Some(true);
1742
4
1743
4
                HostVm::ReadyToRun(ReadyToRun {
1744
4
                    resume_value: None,
1745
4
                    inner: self.inner,
1746
4
                })
1747
            }
1748
            HostFunction::ext_crypto_finish_batch_verify_version_1 => {
1749
4
                let Some(outcome) = self.inner.signatures_batch_verification.take() else {
1750
0
                    return HostVm::Error {
1751
0
                        error: Error::NoBatchVerify,
1752
0
                        prototype: self.inner.into_prototype(),
1753
0
                    };
1754
                };
1755
1756
                HostVm::ReadyToRun(ReadyToRun {
1757
4
                    resume_value: Some(vm::WasmValue::I32(if outcome { 1 } else { 
00
})),
1758
4
                    inner: self.inner,
1759
                })
1760
            }
1761
            HostFunction::ext_hashing_keccak_256_version_1 => {
1762
2
                let hash =
1763
2
                    <sha3::Keccak256 as sha3::Digest>::digest(
expect_pointer_size!(0)0
.as_ref());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1O_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1N_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1O_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1N_0Bb_
1764
2
                self.inner
1765
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1766
            }
1767
            HostFunction::ext_hashing_keccak_512_version_1 => {
1768
2
                let hash =
1769
2
                    <sha3::Keccak512 as sha3::Digest>::digest(
expect_pointer_size!(0)0
.as_ref());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Q_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1P_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Q_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1P_0Bb_
1770
2
                self.inner
1771
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1772
            }
1773
            HostFunction::ext_hashing_sha2_256_version_1 => {
1774
2
                let hash = <sha2::Sha256 as sha2::Digest>::digest(
expect_pointer_size!(0)0
.as_ref());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1S_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1R_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1S_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1R_0Bb_
1775
2
                self.inner
1776
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1777
            }
1778
            HostFunction::ext_hashing_blake2_128_version_1 => {
1779
148
                let out = {
1780
148
                    let data = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1U_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1T_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1U_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1T_0Bb_
1781
148
                    blake2_rfc::blake2b::blake2b(16, &[], data.as_ref())
1782
148
                };
1783
148
1784
148
                self.inner
1785
148
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1786
            }
1787
            HostFunction::ext_hashing_blake2_256_version_1 => {
1788
30
                let out = {
1789
30
                    let data = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1W_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1V_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1W_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1V_0Bb_
1790
30
                    blake2_rfc::blake2b::blake2b(32, &[], data.as_ref())
1791
30
                };
1792
30
1793
30
                self.inner
1794
30
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1795
            }
1796
            HostFunction::ext_hashing_twox_64_version_1 => {
1797
67
                let mut h0 = twox_hash::XxHash::with_seed(0);
1798
67
                {
1799
67
                    let data = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Y_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1X_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Y_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1X_0Bb_
1800
67
                    h0.write(data.as_ref());
1801
67
                }
1802
67
                let r0 = h0.finish();
1803
67
1804
67
                self.inner
1805
67
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&r0.to_le_bytes()))
1806
            }
1807
            HostFunction::ext_hashing_twox_128_version_1 => {
1808
1.81k
                let mut h0 = twox_hash::XxHash::with_seed(0);
1809
1.81k
                let mut h1 = twox_hash::XxHash::with_seed(1);
1810
1.81k
                {
1811
1.81k
                    let data = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces20_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Z_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces20_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces1Z_0Bb_
1812
1.81k
                    let data = data.as_ref();
1813
1.81k
                    h0.write(data);
1814
1.81k
                    h1.write(data);
1815
1.81k
                }
1816
1.81k
                let r0 = h0.finish();
1817
1.81k
                let r1 = h1.finish();
1818
1.81k
1819
1.81k
                self.inner.alloc_write_and_return_pointer(
1820
1.81k
                    host_fn.name(),
1821
1.81k
                    iter::once(&r0.to_le_bytes()).chain(iter::once(&r1.to_le_bytes())),
1822
1.81k
                )
1823
            }
1824
            HostFunction::ext_hashing_twox_256_version_1 => {
1825
2
                let mut h0 = twox_hash::XxHash::with_seed(0);
1826
2
                let mut h1 = twox_hash::XxHash::with_seed(1);
1827
2
                let mut h2 = twox_hash::XxHash::with_seed(2);
1828
2
                let mut h3 = twox_hash::XxHash::with_seed(3);
1829
2
                {
1830
2
                    let data = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces22_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces21_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces22_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces21_0Bb_
1831
2
                    let data = data.as_ref();
1832
2
                    h0.write(data);
1833
2
                    h1.write(data);
1834
2
                    h2.write(data);
1835
2
                    h3.write(data);
1836
2
                }
1837
2
                let r0 = h0.finish();
1838
2
                let r1 = h1.finish();
1839
2
                let r2 = h2.finish();
1840
2
                let r3 = h3.finish();
1841
2
1842
2
                self.inner.alloc_write_and_return_pointer(
1843
2
                    host_fn.name(),
1844
2
                    iter::once(&r0.to_le_bytes())
1845
2
                        .chain(iter::once(&r1.to_le_bytes()))
1846
2
                        .chain(iter::once(&r2.to_le_bytes()))
1847
2
                        .chain(iter::once(&r3.to_le_bytes())),
1848
2
                )
1849
            }
1850
            HostFunction::ext_offchain_index_set_version_1 => {
1851
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces24_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces23_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces24_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces23_0Bb_
1852
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces26_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces25_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces26_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces25_0Bb_
1853
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1854
0
                    key_ptr,
1855
0
                    key_size,
1856
0
                    value: Some((value_ptr, value_size)),
1857
0
                    inner: self.inner,
1858
0
                })
1859
            }
1860
            HostFunction::ext_offchain_index_clear_version_1 => {
1861
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces28_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces27_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces28_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces27_0Bb_
1862
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1863
0
                    key_ptr,
1864
0
                    key_size,
1865
0
                    value: None,
1866
0
                    inner: self.inner,
1867
0
                })
1868
            }
1869
0
            HostFunction::ext_offchain_is_validator_version_1 => HostVm::ReadyToRun(ReadyToRun {
1870
0
                inner: self.inner,
1871
0
                resume_value: Some(vm::WasmValue::I32(1)), // TODO: ask the API user
1872
0
            }),
1873
            HostFunction::ext_offchain_submit_transaction_version_1 => {
1874
0
                let (tx_ptr, tx_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2a_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces29_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2a_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces29_0Bb_
1875
0
                HostVm::OffchainSubmitTransaction(OffchainSubmitTransaction {
1876
0
                    inner: self.inner,
1877
0
                    calling: id,
1878
0
                    tx_ptr,
1879
0
                    tx_size,
1880
0
                })
1881
            }
1882
            HostFunction::ext_offchain_network_state_version_1 => {
1883
0
                host_fn_not_implemented!()
1884
            }
1885
            HostFunction::ext_offchain_timestamp_version_1 => {
1886
0
                HostVm::OffchainTimestamp(OffchainTimestamp { inner: self.inner })
1887
            }
1888
            HostFunction::ext_offchain_sleep_until_version_1 => {
1889
0
                host_fn_not_implemented!()
1890
            }
1891
            HostFunction::ext_offchain_random_seed_version_1 => {
1892
0
                HostVm::OffchainRandomSeed(OffchainRandomSeed {
1893
0
                    inner: self.inner,
1894
0
                    calling: id,
1895
0
                })
1896
            }
1897
            HostFunction::ext_offchain_local_storage_set_version_1 => {
1898
0
                if expect_offchain_storage_kind!(0) {
1899
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2c_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2b_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2c_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2b_0Bb_
1900
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(2);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2e_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2d_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2e_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2d_0Bb_
1901
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1902
0
                        key_ptr,
1903
0
                        key_size,
1904
0
                        value: Some((value_ptr, value_size)),
1905
0
                        old_value: None,
1906
0
                        inner: self.inner,
1907
0
                    })
1908
                } else {
1909
0
                    HostVm::ReadyToRun(ReadyToRun {
1910
0
                        inner: self.inner,
1911
0
                        resume_value: None,
1912
0
                    })
1913
                }
1914
            }
1915
            HostFunction::ext_offchain_local_storage_compare_and_set_version_1 => {
1916
0
                if expect_offchain_storage_kind!(0) {
1917
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2g_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2f_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2g_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2f_0Bb_
1918
0
                    let (old_value_ptr, old_value_size) = expect_pointer_size_raw!(2);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2i_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2h_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2i_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2h_0Bb_
1919
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(3);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2k_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2j_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2k_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2j_0Bb_
1920
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1921
0
                        key_ptr,
1922
0
                        key_size,
1923
0
                        value: Some((value_ptr, value_size)),
1924
0
                        old_value: Some((old_value_ptr, old_value_size)),
1925
0
                        inner: self.inner,
1926
0
                    })
1927
                } else {
1928
0
                    HostVm::ReadyToRun(ReadyToRun {
1929
0
                        inner: self.inner,
1930
0
                        resume_value: Some(vm::WasmValue::I32(0)),
1931
0
                    })
1932
                }
1933
            }
1934
            HostFunction::ext_offchain_local_storage_get_version_1 => {
1935
0
                if expect_offchain_storage_kind!(0) {
1936
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2m_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2l_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2m_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2l_0Bb_
1937
0
                    HostVm::ExternalOffchainStorageGet(ExternalOffchainStorageGet {
1938
0
                        key_ptr,
1939
0
                        key_size,
1940
0
                        calling: id,
1941
0
                        inner: self.inner,
1942
0
                    })
1943
                } else {
1944
                    // Write a SCALE-encoded `None`.
1945
0
                    self.inner
1946
0
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
1947
                }
1948
            }
1949
            HostFunction::ext_offchain_local_storage_clear_version_1 => {
1950
0
                if expect_offchain_storage_kind!(0) {
1951
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2o_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2n_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2o_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2n_0Bb_
1952
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1953
0
                        key_ptr,
1954
0
                        key_size,
1955
0
                        value: None,
1956
0
                        old_value: None,
1957
0
                        inner: self.inner,
1958
0
                    })
1959
                } else {
1960
0
                    HostVm::ReadyToRun(ReadyToRun {
1961
0
                        inner: self.inner,
1962
0
                        resume_value: None,
1963
0
                    })
1964
                }
1965
            }
1966
0
            HostFunction::ext_offchain_http_request_start_version_1 => host_fn_not_implemented!(),
1967
            HostFunction::ext_offchain_http_request_add_header_version_1 => {
1968
0
                host_fn_not_implemented!()
1969
            }
1970
            HostFunction::ext_offchain_http_request_write_body_version_1 => {
1971
0
                host_fn_not_implemented!()
1972
            }
1973
0
            HostFunction::ext_offchain_http_response_wait_version_1 => host_fn_not_implemented!(),
1974
            HostFunction::ext_offchain_http_response_headers_version_1 => {
1975
0
                host_fn_not_implemented!()
1976
            }
1977
            HostFunction::ext_offchain_http_response_read_body_version_1 => {
1978
0
                host_fn_not_implemented!()
1979
            }
1980
            HostFunction::ext_trie_blake2_256_root_version_1
1981
            | HostFunction::ext_trie_blake2_256_root_version_2
1982
            | HostFunction::ext_trie_keccak_256_root_version_1
1983
            | HostFunction::ext_trie_keccak_256_root_version_2 => {
1984
0
                let state_version = if matches!(
1985
0
                    host_fn,
1986
                    HostFunction::ext_trie_blake2_256_root_version_2
1987
                        | HostFunction::ext_trie_keccak_256_root_version_2
1988
                ) {
1989
0
                    expect_state_version!(1)
1990
                } else {
1991
0
                    TrieEntryVersion::V0
1992
                };
1993
1994
0
                let result = {
1995
0
                    let input = expect_pointer_size!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2q_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2p_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2q_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2p_0Bb_
1996
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1997
0
                        nom::combinator::all_consuming(nom::combinator::flat_map(
1998
0
                            crate::util::nom_scale_compact_usize,
1999
0
                            |num_elems| {
2000
0
                                nom::multi::many_m_n(
2001
0
                                    num_elems,
2002
0
                                    num_elems,
2003
0
                                    nom::sequence::tuple((
2004
0
                                        nom::combinator::flat_map(
2005
0
                                            crate::util::nom_scale_compact_usize,
2006
0
                                            nom::bytes::streaming::take,
2007
0
                                        ),
2008
0
                                        nom::combinator::flat_map(
2009
0
                                            crate::util::nom_scale_compact_usize,
2010
0
                                            nom::bytes::streaming::take,
2011
0
                                        ),
2012
0
                                    )),
2013
0
                                )
2014
0
                            },
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces9_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces9_0Bb_
2015
0
                        ))(input.as_ref())
2016
0
                        .map(|(_, parse_result)| parse_result);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesa_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesa_0Bb_
2017
0
2018
0
                    match parsing_result {
2019
0
                        Ok(elements) => Ok(trie::trie_root(
2020
0
                            state_version,
2021
0
                            if matches!(
2022
0
                                host_fn,
2023
                                HostFunction::ext_trie_blake2_256_root_version_1
2024
                                    | HostFunction::ext_trie_blake2_256_root_version_2
2025
                            ) {
2026
0
                                trie::HashFunction::Blake2
2027
                            } else {
2028
0
                                trie::HashFunction::Keccak256
2029
                            },
2030
0
                            &elements[..],
2031
                        )),
2032
0
                        Err(_) => Err(()),
2033
                    }
2034
                };
2035
2036
0
                match result {
2037
0
                    Ok(out) => self
2038
0
                        .inner
2039
0
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2040
0
                    Err(()) => HostVm::Error {
2041
0
                        error: Error::ParamDecodeError,
2042
0
                        prototype: self.inner.into_prototype(),
2043
0
                    },
2044
                }
2045
            }
2046
            HostFunction::ext_trie_blake2_256_ordered_root_version_1
2047
            | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2048
            | HostFunction::ext_trie_keccak_256_ordered_root_version_1
2049
            | HostFunction::ext_trie_keccak_256_ordered_root_version_2 => {
2050
5
                let state_version = if 
matches!1
(
2051
5
                    host_fn,
2052
                    HostFunction::ext_trie_blake2_256_ordered_root_version_2
2053
                        | HostFunction::ext_trie_keccak_256_ordered_root_version_2
2054
                ) {
2055
4
                    expect_state_version!(1)
2056
                } else {
2057
1
                    TrieEntryVersion::V0
2058
                };
2059
2060
5
                let result = {
2061
5
                    let input = 
expect_pointer_size!(0)0
;
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2s_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2r_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2s_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2r_0Bb_
2062
5
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
2063
5
                        nom::combinator::all_consuming(nom::combinator::flat_map(
2064
5
                            crate::util::nom_scale_compact_usize,
2065
5
                            |num_elems| {
2066
5
                                nom::multi::many_m_n(
2067
5
                                    num_elems,
2068
5
                                    num_elems,
2069
5
                                    nom::combinator::flat_map(
2070
5
                                        crate::util::nom_scale_compact_usize,
2071
5
                                        nom::bytes::streaming::take,
2072
5
                                    ),
2073
5
                                )
2074
5
                            },
_RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesb_0Bb_
Line
Count
Source
2065
5
                            |num_elems| {
2066
5
                                nom::multi::many_m_n(
2067
5
                                    num_elems,
2068
5
                                    num_elems,
2069
5
                                    nom::combinator::flat_map(
2070
5
                                        crate::util::nom_scale_compact_usize,
2071
5
                                        nom::bytes::streaming::take,
2072
5
                                    ),
2073
5
                                )
2074
5
                            },
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesb_0Bb_
2075
5
                        ))(input.as_ref())
2076
5
                        .map(|(_, parse_result)| parse_result);
_RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesc_0Bb_
Line
Count
Source
2076
5
                        .map(|(_, parse_result)| parse_result);
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesc_0Bb_
2077
5
2078
5
                    match parsing_result {
2079
5
                        Ok(elements) => Ok(trie::ordered_root(
2080
5
                            state_version,
2081
0
                            if matches!(
2082
5
                                host_fn,
2083
                                HostFunction::ext_trie_blake2_256_ordered_root_version_1
2084
                                    | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2085
                            ) {
2086
5
                                trie::HashFunction::Blake2
2087
                            } else {
2088
0
                                trie::HashFunction::Keccak256
2089
                            },
2090
5
                            &elements[..],
2091
                        )),
2092
0
                        Err(_) => Err(()),
2093
                    }
2094
                };
2095
2096
5
                match result {
2097
5
                    Ok(out) => self
2098
5
                        .inner
2099
5
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2100
0
                    Err(()) => HostVm::Error {
2101
0
                        error: Error::ParamDecodeError,
2102
0
                        prototype: self.inner.into_prototype(),
2103
0
                    },
2104
                }
2105
            }
2106
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_1 => host_fn_not_implemented!(),
2107
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_2 => host_fn_not_implemented!(),
2108
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_1 => host_fn_not_implemented!(),
2109
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_2 => host_fn_not_implemented!(),
2110
            HostFunction::ext_misc_print_num_version_1 => {
2111
0
                let num = match params[0] {
2112
0
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
2113
                    // The signatures are checked at initialization and the Wasm VM ensures that
2114
                    // the proper parameter types are provided.
2115
0
                    _ => unreachable!(),
2116
                };
2117
2118
0
                HostVm::LogEmit(LogEmit {
2119
0
                    inner: self.inner,
2120
0
                    log_entry: LogEmitInner::Num(num),
2121
0
                })
2122
            }
2123
            HostFunction::ext_misc_print_utf8_version_1 => {
2124
0
                let (str_ptr, str_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2u_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2t_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2u_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2t_0Bb_
2125
2126
0
                let utf8_check = str::from_utf8(
2127
0
                    self.inner
2128
0
                        .vm
2129
0
                        .read_memory(str_ptr, str_size)
2130
0
                        .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesd_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesd_0Bb_
2131
0
                        .as_ref(),
2132
0
                )
2133
0
                .map(|_| ());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncese_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncese_0Bb_
2134
0
                if let Err(error) = utf8_check {
2135
0
                    return HostVm::Error {
2136
0
                        error: Error::Utf8Error {
2137
0
                            function: host_fn.name(),
2138
0
                            param_num: 2,
2139
0
                            error,
2140
0
                        },
2141
0
                        prototype: self.inner.into_prototype(),
2142
0
                    };
2143
0
                }
2144
0
2145
0
                HostVm::LogEmit(LogEmit {
2146
0
                    inner: self.inner,
2147
0
                    log_entry: LogEmitInner::Utf8 { str_ptr, str_size },
2148
0
                })
2149
            }
2150
            HostFunction::ext_misc_print_hex_version_1 => {
2151
0
                let (data_ptr, data_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2w_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2v_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2w_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2v_0Bb_
2152
0
                HostVm::LogEmit(LogEmit {
2153
0
                    inner: self.inner,
2154
0
                    log_entry: LogEmitInner::Hex {
2155
0
                        data_ptr,
2156
0
                        data_size,
2157
0
                    },
2158
0
                })
2159
            }
2160
            HostFunction::ext_misc_runtime_version_version_1 => {
2161
0
                let (wasm_blob_ptr, wasm_blob_size) = expect_pointer_size_raw!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2y_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2x_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2y_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2x_0Bb_
2162
0
                HostVm::CallRuntimeVersion(CallRuntimeVersion {
2163
0
                    inner: self.inner,
2164
0
                    wasm_blob_ptr,
2165
0
                    wasm_blob_size,
2166
0
                })
2167
            }
2168
            HostFunction::ext_allocator_malloc_version_1 => {
2169
14.1k
                let size = expect_u32!(0);
2170
2171
14.1k
                let ptr = match self.inner.alloc(host_fn.name(), size) {
2172
14.1k
                    Ok(p) => p,
2173
0
                    Err(error) => {
2174
0
                        return HostVm::Error {
2175
0
                            error,
2176
0
                            prototype: self.inner.into_prototype(),
2177
0
                        }
2178
                    }
2179
                };
2180
2181
14.1k
                let ptr_i32 = i32::from_ne_bytes(ptr.to_ne_bytes());
2182
14.1k
                HostVm::ReadyToRun(ReadyToRun {
2183
14.1k
                    resume_value: Some(vm::WasmValue::I32(ptr_i32)),
2184
14.1k
                    inner: self.inner,
2185
14.1k
                })
2186
            }
2187
            HostFunction::ext_allocator_free_version_1 => {
2188
16.7k
                let pointer = expect_u32!(0);
2189
16.7k
                match self.inner.allocator.deallocate(
2190
16.7k
                    &mut MemAccess {
2191
16.7k
                        vm: MemAccessVm::Running(&mut self.inner.vm),
2192
16.7k
                        memory_total_pages: self.inner.common.memory_total_pages,
2193
16.7k
                    },
2194
16.7k
                    pointer,
2195
16.7k
                ) {
2196
16.7k
                    Ok(()) => {}
2197
                    Err(_) => {
2198
0
                        return HostVm::Error {
2199
0
                            error: Error::FreeError { pointer },
2200
0
                            prototype: self.inner.into_prototype(),
2201
0
                        }
2202
                    }
2203
                };
2204
2205
16.7k
                HostVm::ReadyToRun(ReadyToRun {
2206
16.7k
                    resume_value: None,
2207
16.7k
                    inner: self.inner,
2208
16.7k
                })
2209
            }
2210
            HostFunction::ext_logging_log_version_1 => {
2211
0
                let log_level = expect_u32!(0);
2212
2213
0
                let (target_str_ptr, target_str_size) = expect_pointer_size_raw!(1);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2A_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2z_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2A_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2z_0Bb_
2214
0
                let target_utf8_check = str::from_utf8(
2215
0
                    self.inner
2216
0
                        .vm
2217
0
                        .read_memory(target_str_ptr, target_str_size)
2218
0
                        .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesf_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesf_0Bb_
2219
0
                        .as_ref(),
2220
0
                )
2221
0
                .map(|_| ());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesg_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesg_0Bb_
2222
0
                if let Err(error) = target_utf8_check {
2223
0
                    return HostVm::Error {
2224
0
                        error: Error::Utf8Error {
2225
0
                            function: host_fn.name(),
2226
0
                            param_num: 1,
2227
0
                            error,
2228
0
                        },
2229
0
                        prototype: self.inner.into_prototype(),
2230
0
                    };
2231
0
                }
2232
2233
0
                let (msg_str_ptr, msg_str_size) = expect_pointer_size_raw!(2);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2C_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2B_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2C_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2B_0Bb_
2234
0
                let msg_utf8_check = str::from_utf8(
2235
0
                    self.inner
2236
0
                        .vm
2237
0
                        .read_memory(msg_str_ptr, msg_str_size)
2238
0
                        .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesh_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesh_0Bb_
2239
0
                        .as_ref(),
2240
0
                )
2241
0
                .map(|_| ());
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesi_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesi_0Bb_
2242
0
                if let Err(error) = msg_utf8_check {
2243
0
                    return HostVm::Error {
2244
0
                        error: Error::Utf8Error {
2245
0
                            function: host_fn.name(),
2246
0
                            param_num: 2,
2247
0
                            error,
2248
0
                        },
2249
0
                        prototype: self.inner.into_prototype(),
2250
0
                    };
2251
0
                }
2252
0
2253
0
                HostVm::LogEmit(LogEmit {
2254
0
                    inner: self.inner,
2255
0
                    log_entry: LogEmitInner::Log {
2256
0
                        log_level,
2257
0
                        target_str_ptr,
2258
0
                        target_str_size,
2259
0
                        msg_str_ptr,
2260
0
                        msg_str_size,
2261
0
                    },
2262
0
                })
2263
            }
2264
            HostFunction::ext_logging_max_level_version_1 => {
2265
136
                HostVm::GetMaxLogLevel(GetMaxLogLevel { inner: self.inner })
2266
            }
2267
            HostFunction::ext_panic_handler_abort_on_panic_version_1 => {
2268
0
                let message = {
2269
0
                    let message_bytes = expect_pointer_size!(0);
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2E_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2D_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2E_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_onces2D_0Bb_
2270
0
                    str::from_utf8(message_bytes.as_ref()).map(|msg| msg.to_owned())
Unexecuted instantiation: _RNCNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesj_0Bb_
Unexecuted instantiation: _RNCNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_10ReadyToRun8run_oncesj_0Bb_
2271
0
                };
2272
0
2273
0
                match message {
2274
0
                    Ok(message) => HostVm::Error {
2275
0
                        error: Error::AbortOnPanic { message },
2276
0
                        prototype: self.inner.into_prototype(),
2277
0
                    },
2278
0
                    Err(error) => HostVm::Error {
2279
0
                        error: Error::Utf8Error {
2280
0
                            function: host_fn.name(),
2281
0
                            param_num: 0,
2282
0
                            error,
2283
0
                        },
2284
0
                        prototype: self.inner.into_prototype(),
2285
0
                    },
2286
                }
2287
            }
2288
        }
2289
34.4k
    }
_RNvMs2_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_10ReadyToRun8run_once
Line
Count
Source
749
29.2k
    fn run_once(mut self) -> HostVm {
750
        // `vm::ExecOutcome::Interrupted` is by far the variant that requires the most
751
        // handling code. As such, special-case all other variants before.
752
29.2k
        let (
id, params29.1k
) = match self.inner.vm.run(self.resume_value) {
753
29.1k
            Ok(vm::ExecOutcome::Interrupted { id, params }) => (id, params),
754
755
            Ok(vm::ExecOutcome::Finished {
756
42
                return_value: Ok(Some(vm::WasmValue::I64(ret))),
757
42
            }) => {
758
42
                // Wasm virtual machine has successfully returned.
759
42
760
42
                if self.inner.storage_transaction_depth > 0 {
761
0
                    return HostVm::Error {
762
0
                        prototype: self.inner.into_prototype(),
763
0
                        error: Error::FinishedWithPendingTransaction,
764
0
                    };
765
42
                }
766
42
767
42
                // Turn the `i64` into a `u64`, not changing any bit.
768
42
                let ret = u64::from_ne_bytes(ret.to_ne_bytes());
769
42
770
42
                // According to the runtime environment specification, the return value is two
771
42
                // consecutive I32s representing the length and size of the SCALE-encoded
772
42
                // return value.
773
42
                let value_size = u32::try_from(ret >> 32).unwrap_or_else(|_| unreachable!());
774
42
                let value_ptr = u32::try_from(ret & 0xffff_ffff).unwrap_or_else(|_| unreachable!());
775
42
776
42
                if value_size.saturating_add(value_ptr)
777
42
                    <= u32::from(self.inner.vm.memory_size()) * 64 * 1024
778
                {
779
38
                    return HostVm::Finished(Finished {
780
38
                        inner: self.inner,
781
38
                        value_ptr,
782
38
                        value_size,
783
38
                    });
784
4
                }
785
4
                let error = Error::ReturnedPtrOutOfRange {
786
4
                    pointer: value_ptr,
787
4
                    size: value_size,
788
4
                    memory_size: u32::from(self.inner.vm.memory_size()) * 64 * 1024,
789
4
                };
790
4
791
4
                return HostVm::Error {
792
4
                    prototype: self.inner.into_prototype(),
793
4
                    error,
794
4
                };
795
            }
796
797
            Ok(vm::ExecOutcome::Finished {
798
2
                return_value: Ok(return_value),
799
2
            }) => {
800
2
                // The Wasm function has successfully returned, but the specs require that it
801
2
                // returns a `i64`.
802
2
                return HostVm::Error {
803
2
                    prototype: self.inner.into_prototype(),
804
2
                    error: Error::BadReturnValue {
805
2
                        actual: return_value.map(|v| v.ty()),
806
2
                    },
807
2
                };
808
            }
809
810
            Ok(vm::ExecOutcome::Finished {
811
2
                return_value: Err(err),
812
2
            }) => {
813
2
                return HostVm::Error {
814
2
                    error: Error::Trap(err),
815
2
                    prototype: self.inner.into_prototype(),
816
2
                }
817
            }
818
819
            Err(vm::RunErr::BadValueTy { .. }) => {
820
                // Tried to inject back the value returned by a host function, but it doesn't
821
                // match what the Wasm code expects. Given that we check the host function
822
                // signatures at initialization, this indicates a bug in this implementation.
823
0
                unreachable!()
824
            }
825
826
            Err(vm::RunErr::Poisoned) => {
827
                // Can only happen if there's a bug somewhere.
828
0
                unreachable!()
829
            }
830
        };
831
832
        // The Wasm code has called an host_fn. The `id` is a value that we passed
833
        // at initialization, and corresponds to an index in `registered_functions`.
834
29.1k
        let 
host_fn29.1k
= match self.inner.common.registered_functions.get(id) {
835
29.1k
            Some(FunctionImport::Resolved(f)) => *f,
836
2
            Some(FunctionImport::Unresolved { name, module }) => {
837
2
                return HostVm::Error {
838
2
                    error: Error::UnresolvedFunctionCalled {
839
2
                        function: name.clone(),
840
2
                        module_name: module.clone(),
841
2
                    },
842
2
                    prototype: self.inner.into_prototype(),
843
2
                };
844
            }
845
0
            None => unreachable!(),
846
        };
847
848
        // Passed a parameter index. Produces an `impl AsRef<[u8]>`.
849
        macro_rules! expect_pointer_size {
850
            ($num:expr) => {{
851
                let val = match &params[$num] {
852
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
853
                    // The signatures are checked at initialization and the Wasm VM ensures that
854
                    // the proper parameter types are provided.
855
                    _ => unreachable!(),
856
                };
857
858
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
859
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
860
861
                let result = self.inner.vm.read_memory(ptr, len);
862
                match result {
863
                    Ok(v) => v,
864
                    Err(vm::OutOfBoundsError) => {
865
                        drop(result);
866
                        return HostVm::Error {
867
                            error: Error::ParamOutOfRange {
868
                                function: host_fn.name(),
869
                                param_num: $num,
870
                                pointer: ptr,
871
                                length: len,
872
                            },
873
                            prototype: self.inner.into_prototype(),
874
                        };
875
                    }
876
                }
877
            }};
878
        }
879
880
        macro_rules! expect_pointer_size_raw {
881
            ($num:expr) => {{
882
                let val = match &params[$num] {
883
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
884
                    // The signatures are checked at initialization and the Wasm VM ensures that
885
                    // the proper parameter types are provided.
886
                    _ => unreachable!(),
887
                };
888
889
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
890
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
891
892
                if len.saturating_add(ptr) > u32::from(self.inner.vm.memory_size()) * 64 * 1024 {
893
                    return HostVm::Error {
894
                        error: Error::ParamOutOfRange {
895
                            function: host_fn.name(),
896
                            param_num: $num,
897
                            pointer: ptr,
898
                            length: len,
899
                        },
900
                        prototype: self.inner.into_prototype(),
901
                    };
902
                }
903
904
                (ptr, len)
905
            }};
906
        }
907
908
        macro_rules! expect_pointer_constant_size {
909
            ($num:expr, $size:expr) => {{
910
                let ptr = match params[$num] {
911
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
912
                    // The signatures are checked at initialization and the Wasm VM ensures that
913
                    // the proper parameter types are provided.
914
                    _ => unreachable!(),
915
                };
916
917
                let result = self.inner.vm.read_memory(ptr, $size);
918
                match result {
919
                    Ok(v) => {
920
                        *<&[u8; $size]>::try_from(v.as_ref()).unwrap_or_else(|_| unreachable!())
921
                    }
922
                    Err(vm::OutOfBoundsError) => {
923
                        drop(result);
924
                        return HostVm::Error {
925
                            error: Error::ParamOutOfRange {
926
                                function: host_fn.name(),
927
                                param_num: $num,
928
                                pointer: ptr,
929
                                length: $size,
930
                            },
931
                            prototype: self.inner.into_prototype(),
932
                        };
933
                    }
934
                }
935
            }};
936
        }
937
938
        macro_rules! expect_pointer_constant_size_raw {
939
            ($num:expr, $size:expr) => {{
940
                let ptr = match params[$num] {
941
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
942
                    // The signatures are checked at initialization and the Wasm VM ensures that
943
                    // the proper parameter types are provided.
944
                    _ => unreachable!(),
945
                };
946
947
                if u32::saturating_add($size, ptr)
948
                    > u32::from(self.inner.vm.memory_size()) * 64 * 1024
949
                {
950
                    return HostVm::Error {
951
                        error: Error::ParamOutOfRange {
952
                            function: host_fn.name(),
953
                            param_num: $num,
954
                            pointer: ptr,
955
                            length: $size,
956
                        },
957
                        prototype: self.inner.into_prototype(),
958
                    };
959
                }
960
961
                ptr
962
            }};
963
        }
964
965
        macro_rules! expect_u32 {
966
            ($num:expr) => {{
967
                match &params[$num] {
968
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
969
                    // The signatures are checked at initialization and the Wasm VM ensures that
970
                    // the proper parameter types are provided.
971
                    _ => unreachable!(),
972
                }
973
            }};
974
        }
975
976
        macro_rules! expect_offchain_storage_kind {
977
            ($num:expr) => {{
978
                match &params[$num] {
979
                    // `0` indicates `StorageKind::PERSISTENT`, the only kind of offchain
980
                    // storage that is available.
981
                    vm::WasmValue::I32(0) => true,
982
                    // `1` indicates `StorageKind::LOCAL`, which is valid but has never been
983
                    // implemented in Substrate.
984
                    vm::WasmValue::I32(1) => false,
985
                    vm::WasmValue::I32(_) => {
986
                        return HostVm::Error {
987
                            error: Error::ParamDecodeError,
988
                            prototype: self.inner.into_prototype(),
989
                        }
990
                    }
991
                    // The signatures are checked at initialization and the Wasm VM ensures that
992
                    // the proper parameter types are provided.
993
                    _ => unreachable!(),
994
                }
995
            }};
996
        }
997
998
        macro_rules! expect_state_version {
999
            ($num:expr) => {{
1000
                match &params[$num] {
1001
                    vm::WasmValue::I32(0) => TrieEntryVersion::V0,
1002
                    vm::WasmValue::I32(1) => TrieEntryVersion::V1,
1003
                    vm::WasmValue::I32(_) => {
1004
                        return HostVm::Error {
1005
                            error: Error::ParamDecodeError,
1006
                            prototype: self.inner.into_prototype(),
1007
                        }
1008
                    }
1009
                    // The signatures are checked at initialization and the Wasm VM ensures that
1010
                    // the proper parameter types are provided.
1011
                    _ => unreachable!(),
1012
                }
1013
            }};
1014
        }
1015
1016
        // TODO: implement all functions and remove this macro
1017
        macro_rules! host_fn_not_implemented {
1018
            () => {{
1019
                return HostVm::Error {
1020
                    error: Error::HostFunctionNotImplemented {
1021
                        function: host_fn.name(),
1022
                    },
1023
                    prototype: self.inner.into_prototype(),
1024
                };
1025
            }};
1026
        }
1027
1028
        // Handle the function calls.
1029
        // Some of these enum variants simply change the state of `self`, while most of them
1030
        // instead return an `ExternalVm` to the user.
1031
29.1k
        match host_fn {
1032
            HostFunction::ext_storage_set_version_1 => {
1033
300
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1034
300
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1035
300
                HostVm::ExternalStorageSet(ExternalStorageSet {
1036
300
                    key_ptr,
1037
300
                    key_size,
1038
300
                    child_trie_ptr_size: None,
1039
300
                    value: Some((value_ptr, value_size)),
1040
300
                    inner: self.inner,
1041
300
                })
1042
            }
1043
            HostFunction::ext_storage_get_version_1 => {
1044
571
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1045
571
                HostVm::ExternalStorageGet(ExternalStorageGet {
1046
571
                    key_ptr,
1047
571
                    key_size,
1048
571
                    child_trie_ptr_size: None,
1049
571
                    calling: id,
1050
571
                    value_out_ptr: None,
1051
571
                    offset: 0,
1052
571
                    max_size: u32::MAX,
1053
571
                    inner: self.inner,
1054
571
                })
1055
            }
1056
            HostFunction::ext_storage_read_version_1 => {
1057
10
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1058
10
                let (value_out_ptr, value_out_size) = expect_pointer_size_raw!(1);
1059
10
                let offset = expect_u32!(2);
1060
10
                HostVm::ExternalStorageGet(ExternalStorageGet {
1061
10
                    key_ptr,
1062
10
                    key_size,
1063
10
                    child_trie_ptr_size: None,
1064
10
                    calling: id,
1065
10
                    value_out_ptr: Some(value_out_ptr),
1066
10
                    offset,
1067
10
                    max_size: value_out_size,
1068
10
                    inner: self.inner,
1069
10
                })
1070
            }
1071
            HostFunction::ext_storage_clear_version_1 => {
1072
71
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1073
71
                HostVm::ExternalStorageSet(ExternalStorageSet {
1074
71
                    key_ptr,
1075
71
                    key_size,
1076
71
                    child_trie_ptr_size: None,
1077
71
                    value: None,
1078
71
                    inner: self.inner,
1079
71
                })
1080
            }
1081
            HostFunction::ext_storage_exists_version_1 => {
1082
16
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1083
16
                HostVm::ExternalStorageGet(ExternalStorageGet {
1084
16
                    key_ptr,
1085
16
                    key_size,
1086
16
                    child_trie_ptr_size: None,
1087
16
                    calling: id,
1088
16
                    value_out_ptr: None,
1089
16
                    offset: 0,
1090
16
                    max_size: 0,
1091
16
                    inner: self.inner,
1092
16
                })
1093
            }
1094
            HostFunction::ext_storage_clear_prefix_version_1 => {
1095
1
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(0);
1096
1
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1097
1
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1098
1
                    child_trie_ptr_size: None,
1099
1
                    inner: self.inner,
1100
1
                    max_keys_to_remove: None,
1101
1
                    calling: id,
1102
1
                })
1103
            }
1104
            HostFunction::ext_storage_clear_prefix_version_2 => {
1105
4
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(0);
1106
1107
4
                let max_keys_to_remove = {
1108
4
                    let input = expect_pointer_size!(1);
1109
4
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1110
4
                        nom::combinator::all_consuming(util::nom_option_decode(
1111
4
                            nom::number::streaming::le_u32,
1112
4
                        ))(input.as_ref())
1113
4
                        .map(|(_, parse_result)| parse_result);
1114
4
1115
4
                    match parsing_result {
1116
4
                        Ok(val) => Ok(val),
1117
0
                        Err(_) => Err(()),
1118
                    }
1119
                };
1120
1121
4
                let max_keys_to_remove = match max_keys_to_remove {
1122
4
                    Ok(l) => l,
1123
                    Err(()) => {
1124
0
                        return HostVm::Error {
1125
0
                            error: Error::ParamDecodeError,
1126
0
                            prototype: self.inner.into_prototype(),
1127
0
                        };
1128
                    }
1129
                };
1130
1131
4
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1132
4
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1133
4
                    child_trie_ptr_size: None,
1134
4
                    inner: self.inner,
1135
4
                    max_keys_to_remove,
1136
4
                    calling: id,
1137
4
                })
1138
            }
1139
            HostFunction::ext_storage_root_version_1 => {
1140
1
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1141
1
                    inner: self.inner,
1142
1
                    calling: id,
1143
1
                    child_trie_ptr_size: None,
1144
1
                })
1145
            }
1146
            HostFunction::ext_storage_root_version_2 => {
1147
                // The `ext_storage_root_version_2` host function gets passed as parameter the
1148
                // state version of the runtime. This is in fact completely unnecessary as the
1149
                // same information is found in the runtime specification, and this parameter
1150
                // should be considered as a historical accident. We verify that the version
1151
                // provided as parameter is the same as the one in the specification.
1152
4
                let version_param = expect_state_version!(0);
1153
4
                let version_spec = self
1154
4
                    .inner
1155
4
                    .common
1156
4
                    .runtime_version
1157
4
                    .as_ref()
1158
4
                    .unwrap_or_else(|| unreachable!())
1159
4
                    .decode()
1160
4
                    .state_version
1161
4
                    .unwrap_or(TrieEntryVersion::V0);
1162
4
1163
4
                if version_param != version_spec {
1164
0
                    return HostVm::Error {
1165
0
                        error: Error::StateVersionMismatch {
1166
0
                            parameter: version_param,
1167
0
                            specification: version_spec,
1168
0
                        },
1169
0
                        prototype: self.inner.into_prototype(),
1170
0
                    };
1171
4
                }
1172
4
1173
4
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1174
4
                    inner: self.inner,
1175
4
                    calling: id,
1176
4
                    child_trie_ptr_size: None,
1177
4
                })
1178
            }
1179
            HostFunction::ext_storage_changes_root_version_1 => {
1180
                // The changes trie is an obsolete attempt at having a second trie containing, for
1181
                // each storage item, the latest block height where this item has been modified.
1182
                // When this function returns `None`, it indicates that the changes trie is
1183
                // disabled. While this function used to be called by the runtimes of
1184
                // Westend/Polkadot/Kusama (and maybe others), it has never returned anything else
1185
                // but `None`. The entire changes trie mechanism was ultimately removed in
1186
                // October 2021.
1187
                // This function is no longer called by recent runtimes, but must be preserved for
1188
                // backwards compatibility.
1189
1
                self.inner.alloc_write_and_return_pointer_size(
1190
1
                    HostFunction::ext_storage_changes_root_version_1.name(),
1191
1
                    iter::once(&[0][..]),
1192
1
                )
1193
            }
1194
            HostFunction::ext_storage_next_key_version_1 => {
1195
1
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1196
1
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1197
1
                    key_ptr,
1198
1
                    key_size,
1199
1
                    child_trie_ptr_size: None,
1200
1
                    inner: self.inner,
1201
1
                })
1202
            }
1203
            HostFunction::ext_storage_append_version_1 => {
1204
71
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1205
71
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1206
71
                HostVm::ExternalStorageAppend(ExternalStorageAppend {
1207
71
                    key_ptr,
1208
71
                    key_size,
1209
71
                    value_ptr,
1210
71
                    value_size,
1211
71
                    inner: self.inner,
1212
71
                })
1213
            }
1214
            HostFunction::ext_storage_start_transaction_version_1 => {
1215
                // TODO: a maximum depth is important in order to prevent a malicious runtime from crashing the client, but the depth needs to be the same as in Substrate; figure out
1216
14
                self.inner.storage_transaction_depth += 1;
1217
14
                HostVm::StartStorageTransaction(StartStorageTransaction { inner: self.inner })
1218
            }
1219
            HostFunction::ext_storage_rollback_transaction_version_1 => {
1220
0
                if self.inner.storage_transaction_depth == 0 {
1221
0
                    return HostVm::Error {
1222
0
                        error: Error::NoActiveTransaction,
1223
0
                        prototype: self.inner.into_prototype(),
1224
0
                    };
1225
0
                }
1226
0
1227
0
                self.inner.storage_transaction_depth -= 1;
1228
0
                HostVm::EndStorageTransaction {
1229
0
                    resume: EndStorageTransaction { inner: self.inner },
1230
0
                    rollback: true,
1231
0
                }
1232
            }
1233
            HostFunction::ext_storage_commit_transaction_version_1 => {
1234
14
                if self.inner.storage_transaction_depth == 0 {
1235
0
                    return HostVm::Error {
1236
0
                        error: Error::NoActiveTransaction,
1237
0
                        prototype: self.inner.into_prototype(),
1238
0
                    };
1239
14
                }
1240
14
1241
14
                self.inner.storage_transaction_depth -= 1;
1242
14
                HostVm::EndStorageTransaction {
1243
14
                    resume: EndStorageTransaction { inner: self.inner },
1244
14
                    rollback: false,
1245
14
                }
1246
            }
1247
            HostFunction::ext_storage_proof_size_storage_proof_size_version_1 => {
1248
0
                match self.inner.storage_proof_size_behavior {
1249
0
                    StorageProofSizeBehavior::ConstantReturnValue(value) => {
1250
0
                        HostVm::ReadyToRun(ReadyToRun {
1251
0
                            inner: self.inner,
1252
0
                            resume_value: Some(vm::WasmValue::I64(i64::from_ne_bytes(
1253
0
                                value.to_ne_bytes(),
1254
0
                            ))),
1255
0
                        })
1256
                    }
1257
0
                    StorageProofSizeBehavior::Unimplemented => HostVm::Error {
1258
0
                        error: Error::HostFunctionNotImplemented {
1259
0
                            function: host_fn.name(),
1260
0
                        },
1261
0
                        prototype: self.inner.into_prototype(),
1262
0
                    },
1263
                }
1264
            }
1265
            HostFunction::ext_default_child_storage_get_version_1 => {
1266
2
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1267
2
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1268
2
                HostVm::ExternalStorageGet(ExternalStorageGet {
1269
2
                    key_ptr,
1270
2
                    key_size,
1271
2
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1272
2
                    calling: id,
1273
2
                    value_out_ptr: None,
1274
2
                    offset: 0,
1275
2
                    max_size: u32::MAX,
1276
2
                    inner: self.inner,
1277
2
                })
1278
            }
1279
            HostFunction::ext_default_child_storage_read_version_1 => {
1280
4
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1281
4
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1282
4
                let (value_out_ptr, value_out_size) = expect_pointer_size_raw!(2);
1283
4
                let offset = expect_u32!(3);
1284
4
                HostVm::ExternalStorageGet(ExternalStorageGet {
1285
4
                    key_ptr,
1286
4
                    key_size,
1287
4
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1288
4
                    calling: id,
1289
4
                    value_out_ptr: Some(value_out_ptr),
1290
4
                    offset,
1291
4
                    max_size: value_out_size,
1292
4
                    inner: self.inner,
1293
4
                })
1294
            }
1295
            HostFunction::ext_default_child_storage_storage_kill_version_1 => {
1296
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1297
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1298
0
                    prefix_ptr_size: None,
1299
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1300
0
                    inner: self.inner,
1301
0
                    max_keys_to_remove: None,
1302
0
                    calling: id,
1303
0
                })
1304
            }
1305
            HostFunction::ext_default_child_storage_storage_kill_version_2
1306
            | HostFunction::ext_default_child_storage_storage_kill_version_3 => {
1307
1
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1308
1309
1
                let max_keys_to_remove = {
1310
1
                    let input = expect_pointer_size!(1);
1311
1
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1312
1
                        nom::combinator::all_consuming(util::nom_option_decode(
1313
1
                            nom::number::streaming::le_u32,
1314
1
                        ))(input.as_ref())
1315
1
                        .map(|(_, parse_result)| parse_result);
1316
1
1317
1
                    match parsing_result {
1318
1
                        Ok(val) => Ok(val),
1319
0
                        Err(_) => Err(()),
1320
                    }
1321
                };
1322
1323
1
                let max_keys_to_remove = match max_keys_to_remove {
1324
1
                    Ok(l) => l,
1325
                    Err(()) => {
1326
0
                        return HostVm::Error {
1327
0
                            error: Error::ParamDecodeError,
1328
0
                            prototype: self.inner.into_prototype(),
1329
0
                        };
1330
                    }
1331
                };
1332
1333
1
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1334
1
                    prefix_ptr_size: None,
1335
1
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1336
1
                    inner: self.inner,
1337
1
                    max_keys_to_remove,
1338
1
                    calling: id,
1339
1
                })
1340
            }
1341
            HostFunction::ext_default_child_storage_clear_prefix_version_1 => {
1342
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1343
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
1344
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1345
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1346
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1347
0
                    inner: self.inner,
1348
0
                    max_keys_to_remove: None,
1349
0
                    calling: id,
1350
0
                })
1351
            }
1352
            HostFunction::ext_default_child_storage_clear_prefix_version_2 => {
1353
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1354
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
1355
1356
0
                let max_keys_to_remove = {
1357
0
                    let input = expect_pointer_size!(2);
1358
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1359
0
                        nom::combinator::all_consuming(util::nom_option_decode(
1360
0
                            nom::number::streaming::le_u32,
1361
0
                        ))(input.as_ref())
1362
0
                        .map(|(_, parse_result)| parse_result);
1363
0
1364
0
                    match parsing_result {
1365
0
                        Ok(val) => Ok(val),
1366
0
                        Err(_) => Err(()),
1367
                    }
1368
                };
1369
1370
0
                let max_keys_to_remove = match max_keys_to_remove {
1371
0
                    Ok(l) => l,
1372
                    Err(()) => {
1373
0
                        return HostVm::Error {
1374
0
                            error: Error::ParamDecodeError,
1375
0
                            prototype: self.inner.into_prototype(),
1376
0
                        };
1377
                    }
1378
                };
1379
1380
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1381
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1382
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1383
0
                    inner: self.inner,
1384
0
                    max_keys_to_remove,
1385
0
                    calling: id,
1386
0
                })
1387
            }
1388
            HostFunction::ext_default_child_storage_set_version_1 => {
1389
4
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1390
4
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1391
4
                let (value_ptr, value_size) = expect_pointer_size_raw!(2);
1392
4
                HostVm::ExternalStorageSet(ExternalStorageSet {
1393
4
                    key_ptr,
1394
4
                    key_size,
1395
4
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1396
4
                    value: Some((value_ptr, value_size)),
1397
4
                    inner: self.inner,
1398
4
                })
1399
            }
1400
            HostFunction::ext_default_child_storage_clear_version_1 => {
1401
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1402
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1403
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1404
0
                    key_ptr,
1405
0
                    key_size,
1406
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1407
0
                    value: None,
1408
0
                    inner: self.inner,
1409
0
                })
1410
            }
1411
            HostFunction::ext_default_child_storage_exists_version_1 => {
1412
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1413
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1414
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1415
0
                    key_ptr,
1416
0
                    key_size,
1417
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1418
0
                    calling: id,
1419
0
                    value_out_ptr: None,
1420
0
                    offset: 0,
1421
0
                    max_size: 0,
1422
0
                    inner: self.inner,
1423
0
                })
1424
            }
1425
            HostFunction::ext_default_child_storage_next_key_version_1 => {
1426
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1427
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1428
0
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1429
0
                    key_ptr,
1430
0
                    key_size,
1431
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1432
0
                    inner: self.inner,
1433
0
                })
1434
            }
1435
            HostFunction::ext_default_child_storage_root_version_1 => {
1436
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1437
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1438
0
                    inner: self.inner,
1439
0
                    calling: id,
1440
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1441
0
                })
1442
            }
1443
            HostFunction::ext_default_child_storage_root_version_2 => {
1444
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1445
1446
                // The `ext_default_child_storage_root_version_2` host function gets passed as
1447
                // parameter the state version of the runtime. This is in fact completely
1448
                // unnecessary as the same information is found in the runtime specification, and
1449
                // this parameter should be considered as a historical accident. We verify that the
1450
                // version provided as parameter is the same as the one in the specification.
1451
0
                let version_param = expect_state_version!(1);
1452
0
                let version_spec = self
1453
0
                    .inner
1454
0
                    .common
1455
0
                    .runtime_version
1456
0
                    .as_ref()
1457
0
                    .unwrap_or_else(|| unreachable!())
1458
0
                    .decode()
1459
0
                    .state_version
1460
0
                    .unwrap_or(TrieEntryVersion::V0);
1461
0
1462
0
                if version_param != version_spec {
1463
0
                    return HostVm::Error {
1464
0
                        error: Error::StateVersionMismatch {
1465
0
                            parameter: version_param,
1466
0
                            specification: version_spec,
1467
0
                        },
1468
0
                        prototype: self.inner.into_prototype(),
1469
0
                    };
1470
0
                }
1471
0
1472
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1473
0
                    inner: self.inner,
1474
0
                    calling: id,
1475
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1476
0
                })
1477
            }
1478
0
            HostFunction::ext_crypto_ed25519_public_keys_version_1 => host_fn_not_implemented!(),
1479
0
            HostFunction::ext_crypto_ed25519_generate_version_1 => host_fn_not_implemented!(),
1480
0
            HostFunction::ext_crypto_ed25519_sign_version_1 => host_fn_not_implemented!(),
1481
            HostFunction::ext_crypto_ed25519_verify_version_1
1482
            | HostFunction::ext_crypto_ed25519_batch_verify_version_1 => {
1483
0
                let is_batch_verification = matches!(
1484
0
                    host_fn,
1485
                    HostFunction::ext_crypto_ed25519_batch_verify_version_1
1486
                );
1487
1488
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1489
0
                    return HostVm::Error {
1490
0
                        error: Error::BatchVerifyWithoutStarting,
1491
0
                        prototype: self.inner.into_prototype(),
1492
0
                    };
1493
0
                }
1494
1495
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1496
                HostVm::SignatureVerification(SignatureVerification {
1497
0
                    algorithm: SignatureVerificationAlgorithm::Ed25519,
1498
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1499
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1500
0
                    message_ptr,
1501
0
                    message_size,
1502
0
                    inner: self.inner,
1503
0
                    is_batch_verification,
1504
                })
1505
            }
1506
0
            HostFunction::ext_crypto_sr25519_public_keys_version_1 => host_fn_not_implemented!(),
1507
0
            HostFunction::ext_crypto_sr25519_generate_version_1 => host_fn_not_implemented!(),
1508
0
            HostFunction::ext_crypto_sr25519_sign_version_1 => host_fn_not_implemented!(),
1509
            HostFunction::ext_crypto_sr25519_verify_version_1
1510
            | HostFunction::ext_crypto_sr25519_batch_verify_version_1 => {
1511
0
                let is_batch_verification = matches!(
1512
0
                    host_fn,
1513
                    HostFunction::ext_crypto_sr25519_batch_verify_version_1
1514
                );
1515
1516
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1517
0
                    return HostVm::Error {
1518
0
                        error: Error::BatchVerifyWithoutStarting,
1519
0
                        prototype: self.inner.into_prototype(),
1520
0
                    };
1521
0
                }
1522
1523
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1524
                HostVm::SignatureVerification(SignatureVerification {
1525
0
                    algorithm: SignatureVerificationAlgorithm::Sr25519V1,
1526
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1527
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1528
0
                    message_ptr,
1529
0
                    message_size,
1530
0
                    inner: self.inner,
1531
0
                    is_batch_verification,
1532
                })
1533
            }
1534
            HostFunction::ext_crypto_sr25519_verify_version_2 => {
1535
6
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1536
                HostVm::SignatureVerification(SignatureVerification {
1537
6
                    algorithm: SignatureVerificationAlgorithm::Sr25519V2,
1538
6
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1539
6
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1540
6
                    message_ptr,
1541
6
                    message_size,
1542
6
                    inner: self.inner,
1543
                    is_batch_verification: false,
1544
                })
1545
            }
1546
0
            HostFunction::ext_crypto_ecdsa_generate_version_1 => host_fn_not_implemented!(),
1547
            HostFunction::ext_crypto_ecdsa_sign_version_1 => {
1548
                // NOTE: safe to unwrap here because we supply the nn to blake2b fn
1549
0
                let data = <[u8; 32]>::try_from(
1550
0
                    blake2_rfc::blake2b::blake2b(32, &[], expect_pointer_size!(0).as_ref())
1551
0
                        .as_bytes(),
1552
0
                )
1553
0
                .unwrap_or_else(|_| unreachable!());
1554
0
                let message = libsecp256k1::Message::parse(&data);
1555
1556
0
                if let Ok(sc) =
1557
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
1558
                {
1559
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1560
0
1561
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1562
0
                    self.inner.alloc_write_and_return_pointer(
1563
0
                        host_fn.name(),
1564
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1565
0
                    )
1566
                } else {
1567
0
                    HostVm::Error {
1568
0
                        error: Error::ParamDecodeError,
1569
0
                        prototype: self.inner.into_prototype(),
1570
0
                    }
1571
                }
1572
            }
1573
0
            HostFunction::ext_crypto_ecdsa_public_keys_version_1 => host_fn_not_implemented!(),
1574
            HostFunction::ext_crypto_ecdsa_verify_version_1
1575
            | HostFunction::ext_crypto_ecdsa_batch_verify_version_1 => {
1576
0
                let is_batch_verification = matches!(
1577
0
                    host_fn,
1578
                    HostFunction::ext_crypto_ecdsa_batch_verify_version_1
1579
                );
1580
1581
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1582
0
                    return HostVm::Error {
1583
0
                        error: Error::BatchVerifyWithoutStarting,
1584
0
                        prototype: self.inner.into_prototype(),
1585
0
                    };
1586
0
                }
1587
1588
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1589
                HostVm::SignatureVerification(SignatureVerification {
1590
0
                    algorithm: SignatureVerificationAlgorithm::Ecdsa,
1591
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1592
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1593
0
                    message_ptr,
1594
0
                    message_size,
1595
0
                    inner: self.inner,
1596
0
                    is_batch_verification,
1597
                })
1598
            }
1599
0
            HostFunction::ext_crypto_ecdsa_verify_version_2 => host_fn_not_implemented!(),
1600
            HostFunction::ext_crypto_ecdsa_sign_prehashed_version_1 => {
1601
                // TODO: seems misimplemented, see https://spec.polkadot.network/#id-ext_crypto_ecdsa_sign_prehashed
1602
0
                let message = libsecp256k1::Message::parse(&expect_pointer_constant_size!(0, 32));
1603
1604
0
                if let Ok(sc) =
1605
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
1606
                {
1607
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1608
0
1609
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1610
0
                    self.inner.alloc_write_and_return_pointer(
1611
0
                        host_fn.name(),
1612
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1613
0
                    )
1614
                } else {
1615
0
                    HostVm::Error {
1616
0
                        error: Error::ParamDecodeError,
1617
0
                        prototype: self.inner.into_prototype(),
1618
0
                    }
1619
                }
1620
            }
1621
            HostFunction::ext_crypto_ecdsa_verify_prehashed_version_1 => {
1622
                HostVm::SignatureVerification(SignatureVerification {
1623
0
                    algorithm: SignatureVerificationAlgorithm::EcdsaPrehashed,
1624
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1625
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1626
0
                    message_ptr: expect_pointer_constant_size_raw!(1, 32),
1627
                    message_size: 32,
1628
0
                    inner: self.inner,
1629
                    is_batch_verification: false,
1630
                })
1631
            }
1632
1633
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_1
1634
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2 => {
1635
0
                let sig = expect_pointer_constant_size!(0, 65);
1636
0
                let msg = expect_pointer_constant_size!(1, 32);
1637
0
                let is_v2 = matches!(
1638
0
                    host_fn,
1639
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2
1640
                );
1641
1642
0
                let result = {
1643
0
                    let rs = if is_v2 {
1644
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1645
                    } else {
1646
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1647
                    };
1648
1649
0
                    if let Ok(rs) = rs {
1650
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1651
0
                            sig[64] - 27
1652
                        } else {
1653
0
                            sig[64]
1654
                        });
1655
1656
0
                        if let Ok(v) = v {
1657
0
                            let pubkey = libsecp256k1::recover(
1658
0
                                &libsecp256k1::Message::parse_slice(&msg)
1659
0
                                    .unwrap_or_else(|_| unreachable!()),
1660
0
                                &rs,
1661
0
                                &v,
1662
0
                            );
1663
1664
0
                            if let Ok(pubkey) = pubkey {
1665
0
                                let mut res = Vec::with_capacity(65);
1666
0
                                res.push(0);
1667
0
                                res.extend_from_slice(&pubkey.serialize()[1..65]);
1668
0
                                res
1669
                            } else {
1670
0
                                vec![1, 2]
1671
                            }
1672
                        } else {
1673
0
                            vec![1, 1]
1674
                        }
1675
                    } else {
1676
0
                        vec![1, 0]
1677
                    }
1678
                };
1679
1680
0
                self.inner
1681
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1682
            }
1683
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_1
1684
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2 => {
1685
0
                let sig = expect_pointer_constant_size!(0, 65);
1686
0
                let msg = expect_pointer_constant_size!(1, 32);
1687
0
                let is_v2 = matches!(
1688
0
                    host_fn,
1689
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2
1690
                );
1691
1692
0
                let result = {
1693
0
                    let rs = if is_v2 {
1694
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1695
                    } else {
1696
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1697
                    };
1698
1699
0
                    if let Ok(rs) = rs {
1700
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1701
0
                            sig[64] - 27
1702
                        } else {
1703
0
                            sig[64]
1704
                        });
1705
1706
0
                        if let Ok(v) = v {
1707
0
                            let pubkey = libsecp256k1::recover(
1708
0
                                &libsecp256k1::Message::parse_slice(&msg)
1709
0
                                    .unwrap_or_else(|_| unreachable!()),
1710
0
                                &rs,
1711
0
                                &v,
1712
0
                            );
1713
1714
0
                            if let Ok(pubkey) = pubkey {
1715
0
                                let mut res = Vec::with_capacity(34);
1716
0
                                res.push(0);
1717
0
                                res.extend_from_slice(&pubkey.serialize_compressed());
1718
0
                                res
1719
                            } else {
1720
0
                                vec![1, 2]
1721
                            }
1722
                        } else {
1723
0
                            vec![1, 1]
1724
                        }
1725
                    } else {
1726
0
                        vec![1, 0]
1727
                    }
1728
                };
1729
1730
0
                self.inner
1731
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1732
            }
1733
            HostFunction::ext_crypto_start_batch_verify_version_1 => {
1734
4
                if self.inner.signatures_batch_verification.is_some() {
1735
0
                    return HostVm::Error {
1736
0
                        error: Error::AlreadyBatchVerify,
1737
0
                        prototype: self.inner.into_prototype(),
1738
0
                    };
1739
4
                }
1740
4
1741
4
                self.inner.signatures_batch_verification = Some(true);
1742
4
1743
4
                HostVm::ReadyToRun(ReadyToRun {
1744
4
                    resume_value: None,
1745
4
                    inner: self.inner,
1746
4
                })
1747
            }
1748
            HostFunction::ext_crypto_finish_batch_verify_version_1 => {
1749
4
                let Some(outcome) = self.inner.signatures_batch_verification.take() else {
1750
0
                    return HostVm::Error {
1751
0
                        error: Error::NoBatchVerify,
1752
0
                        prototype: self.inner.into_prototype(),
1753
0
                    };
1754
                };
1755
1756
                HostVm::ReadyToRun(ReadyToRun {
1757
4
                    resume_value: Some(vm::WasmValue::I32(if outcome { 1 } else { 
00
})),
1758
4
                    inner: self.inner,
1759
                })
1760
            }
1761
            HostFunction::ext_hashing_keccak_256_version_1 => {
1762
2
                let hash =
1763
2
                    <sha3::Keccak256 as sha3::Digest>::digest(expect_pointer_size!(0).as_ref());
1764
2
                self.inner
1765
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1766
            }
1767
            HostFunction::ext_hashing_keccak_512_version_1 => {
1768
2
                let hash =
1769
2
                    <sha3::Keccak512 as sha3::Digest>::digest(expect_pointer_size!(0).as_ref());
1770
2
                self.inner
1771
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1772
            }
1773
            HostFunction::ext_hashing_sha2_256_version_1 => {
1774
2
                let hash = <sha2::Sha256 as sha2::Digest>::digest(expect_pointer_size!(0).as_ref());
1775
2
                self.inner
1776
2
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1777
            }
1778
            HostFunction::ext_hashing_blake2_128_version_1 => {
1779
148
                let out = {
1780
148
                    let data = expect_pointer_size!(0);
1781
148
                    blake2_rfc::blake2b::blake2b(16, &[], data.as_ref())
1782
148
                };
1783
148
1784
148
                self.inner
1785
148
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1786
            }
1787
            HostFunction::ext_hashing_blake2_256_version_1 => {
1788
30
                let out = {
1789
30
                    let data = expect_pointer_size!(0);
1790
30
                    blake2_rfc::blake2b::blake2b(32, &[], data.as_ref())
1791
30
                };
1792
30
1793
30
                self.inner
1794
30
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1795
            }
1796
            HostFunction::ext_hashing_twox_64_version_1 => {
1797
67
                let mut h0 = twox_hash::XxHash::with_seed(0);
1798
67
                {
1799
67
                    let data = expect_pointer_size!(0);
1800
67
                    h0.write(data.as_ref());
1801
67
                }
1802
67
                let r0 = h0.finish();
1803
67
1804
67
                self.inner
1805
67
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&r0.to_le_bytes()))
1806
            }
1807
            HostFunction::ext_hashing_twox_128_version_1 => {
1808
1.73k
                let mut h0 = twox_hash::XxHash::with_seed(0);
1809
1.73k
                let mut h1 = twox_hash::XxHash::with_seed(1);
1810
1.73k
                {
1811
1.73k
                    let data = expect_pointer_size!(0);
1812
1.73k
                    let data = data.as_ref();
1813
1.73k
                    h0.write(data);
1814
1.73k
                    h1.write(data);
1815
1.73k
                }
1816
1.73k
                let r0 = h0.finish();
1817
1.73k
                let r1 = h1.finish();
1818
1.73k
1819
1.73k
                self.inner.alloc_write_and_return_pointer(
1820
1.73k
                    host_fn.name(),
1821
1.73k
                    iter::once(&r0.to_le_bytes()).chain(iter::once(&r1.to_le_bytes())),
1822
1.73k
                )
1823
            }
1824
            HostFunction::ext_hashing_twox_256_version_1 => {
1825
2
                let mut h0 = twox_hash::XxHash::with_seed(0);
1826
2
                let mut h1 = twox_hash::XxHash::with_seed(1);
1827
2
                let mut h2 = twox_hash::XxHash::with_seed(2);
1828
2
                let mut h3 = twox_hash::XxHash::with_seed(3);
1829
2
                {
1830
2
                    let data = expect_pointer_size!(0);
1831
2
                    let data = data.as_ref();
1832
2
                    h0.write(data);
1833
2
                    h1.write(data);
1834
2
                    h2.write(data);
1835
2
                    h3.write(data);
1836
2
                }
1837
2
                let r0 = h0.finish();
1838
2
                let r1 = h1.finish();
1839
2
                let r2 = h2.finish();
1840
2
                let r3 = h3.finish();
1841
2
1842
2
                self.inner.alloc_write_and_return_pointer(
1843
2
                    host_fn.name(),
1844
2
                    iter::once(&r0.to_le_bytes())
1845
2
                        .chain(iter::once(&r1.to_le_bytes()))
1846
2
                        .chain(iter::once(&r2.to_le_bytes()))
1847
2
                        .chain(iter::once(&r3.to_le_bytes())),
1848
2
                )
1849
            }
1850
            HostFunction::ext_offchain_index_set_version_1 => {
1851
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1852
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1853
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1854
0
                    key_ptr,
1855
0
                    key_size,
1856
0
                    value: Some((value_ptr, value_size)),
1857
0
                    inner: self.inner,
1858
0
                })
1859
            }
1860
            HostFunction::ext_offchain_index_clear_version_1 => {
1861
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1862
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1863
0
                    key_ptr,
1864
0
                    key_size,
1865
0
                    value: None,
1866
0
                    inner: self.inner,
1867
0
                })
1868
            }
1869
0
            HostFunction::ext_offchain_is_validator_version_1 => HostVm::ReadyToRun(ReadyToRun {
1870
0
                inner: self.inner,
1871
0
                resume_value: Some(vm::WasmValue::I32(1)), // TODO: ask the API user
1872
0
            }),
1873
            HostFunction::ext_offchain_submit_transaction_version_1 => {
1874
0
                let (tx_ptr, tx_size) = expect_pointer_size_raw!(0);
1875
0
                HostVm::OffchainSubmitTransaction(OffchainSubmitTransaction {
1876
0
                    inner: self.inner,
1877
0
                    calling: id,
1878
0
                    tx_ptr,
1879
0
                    tx_size,
1880
0
                })
1881
            }
1882
            HostFunction::ext_offchain_network_state_version_1 => {
1883
0
                host_fn_not_implemented!()
1884
            }
1885
            HostFunction::ext_offchain_timestamp_version_1 => {
1886
0
                HostVm::OffchainTimestamp(OffchainTimestamp { inner: self.inner })
1887
            }
1888
            HostFunction::ext_offchain_sleep_until_version_1 => {
1889
0
                host_fn_not_implemented!()
1890
            }
1891
            HostFunction::ext_offchain_random_seed_version_1 => {
1892
0
                HostVm::OffchainRandomSeed(OffchainRandomSeed {
1893
0
                    inner: self.inner,
1894
0
                    calling: id,
1895
0
                })
1896
            }
1897
            HostFunction::ext_offchain_local_storage_set_version_1 => {
1898
0
                if expect_offchain_storage_kind!(0) {
1899
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1900
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(2);
1901
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1902
0
                        key_ptr,
1903
0
                        key_size,
1904
0
                        value: Some((value_ptr, value_size)),
1905
0
                        old_value: None,
1906
0
                        inner: self.inner,
1907
0
                    })
1908
                } else {
1909
0
                    HostVm::ReadyToRun(ReadyToRun {
1910
0
                        inner: self.inner,
1911
0
                        resume_value: None,
1912
0
                    })
1913
                }
1914
            }
1915
            HostFunction::ext_offchain_local_storage_compare_and_set_version_1 => {
1916
0
                if expect_offchain_storage_kind!(0) {
1917
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1918
0
                    let (old_value_ptr, old_value_size) = expect_pointer_size_raw!(2);
1919
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(3);
1920
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1921
0
                        key_ptr,
1922
0
                        key_size,
1923
0
                        value: Some((value_ptr, value_size)),
1924
0
                        old_value: Some((old_value_ptr, old_value_size)),
1925
0
                        inner: self.inner,
1926
0
                    })
1927
                } else {
1928
0
                    HostVm::ReadyToRun(ReadyToRun {
1929
0
                        inner: self.inner,
1930
0
                        resume_value: Some(vm::WasmValue::I32(0)),
1931
0
                    })
1932
                }
1933
            }
1934
            HostFunction::ext_offchain_local_storage_get_version_1 => {
1935
0
                if expect_offchain_storage_kind!(0) {
1936
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1937
0
                    HostVm::ExternalOffchainStorageGet(ExternalOffchainStorageGet {
1938
0
                        key_ptr,
1939
0
                        key_size,
1940
0
                        calling: id,
1941
0
                        inner: self.inner,
1942
0
                    })
1943
                } else {
1944
                    // Write a SCALE-encoded `None`.
1945
0
                    self.inner
1946
0
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
1947
                }
1948
            }
1949
            HostFunction::ext_offchain_local_storage_clear_version_1 => {
1950
0
                if expect_offchain_storage_kind!(0) {
1951
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1952
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1953
0
                        key_ptr,
1954
0
                        key_size,
1955
0
                        value: None,
1956
0
                        old_value: None,
1957
0
                        inner: self.inner,
1958
0
                    })
1959
                } else {
1960
0
                    HostVm::ReadyToRun(ReadyToRun {
1961
0
                        inner: self.inner,
1962
0
                        resume_value: None,
1963
0
                    })
1964
                }
1965
            }
1966
0
            HostFunction::ext_offchain_http_request_start_version_1 => host_fn_not_implemented!(),
1967
            HostFunction::ext_offchain_http_request_add_header_version_1 => {
1968
0
                host_fn_not_implemented!()
1969
            }
1970
            HostFunction::ext_offchain_http_request_write_body_version_1 => {
1971
0
                host_fn_not_implemented!()
1972
            }
1973
0
            HostFunction::ext_offchain_http_response_wait_version_1 => host_fn_not_implemented!(),
1974
            HostFunction::ext_offchain_http_response_headers_version_1 => {
1975
0
                host_fn_not_implemented!()
1976
            }
1977
            HostFunction::ext_offchain_http_response_read_body_version_1 => {
1978
0
                host_fn_not_implemented!()
1979
            }
1980
            HostFunction::ext_trie_blake2_256_root_version_1
1981
            | HostFunction::ext_trie_blake2_256_root_version_2
1982
            | HostFunction::ext_trie_keccak_256_root_version_1
1983
            | HostFunction::ext_trie_keccak_256_root_version_2 => {
1984
0
                let state_version = if matches!(
1985
0
                    host_fn,
1986
                    HostFunction::ext_trie_blake2_256_root_version_2
1987
                        | HostFunction::ext_trie_keccak_256_root_version_2
1988
                ) {
1989
0
                    expect_state_version!(1)
1990
                } else {
1991
0
                    TrieEntryVersion::V0
1992
                };
1993
1994
0
                let result = {
1995
0
                    let input = expect_pointer_size!(0);
1996
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1997
0
                        nom::combinator::all_consuming(nom::combinator::flat_map(
1998
0
                            crate::util::nom_scale_compact_usize,
1999
0
                            |num_elems| {
2000
                                nom::multi::many_m_n(
2001
                                    num_elems,
2002
                                    num_elems,
2003
                                    nom::sequence::tuple((
2004
                                        nom::combinator::flat_map(
2005
                                            crate::util::nom_scale_compact_usize,
2006
                                            nom::bytes::streaming::take,
2007
                                        ),
2008
                                        nom::combinator::flat_map(
2009
                                            crate::util::nom_scale_compact_usize,
2010
                                            nom::bytes::streaming::take,
2011
                                        ),
2012
                                    )),
2013
                                )
2014
0
                            },
2015
0
                        ))(input.as_ref())
2016
0
                        .map(|(_, parse_result)| parse_result);
2017
0
2018
0
                    match parsing_result {
2019
0
                        Ok(elements) => Ok(trie::trie_root(
2020
0
                            state_version,
2021
0
                            if matches!(
2022
0
                                host_fn,
2023
                                HostFunction::ext_trie_blake2_256_root_version_1
2024
                                    | HostFunction::ext_trie_blake2_256_root_version_2
2025
                            ) {
2026
0
                                trie::HashFunction::Blake2
2027
                            } else {
2028
0
                                trie::HashFunction::Keccak256
2029
                            },
2030
0
                            &elements[..],
2031
                        )),
2032
0
                        Err(_) => Err(()),
2033
                    }
2034
                };
2035
2036
0
                match result {
2037
0
                    Ok(out) => self
2038
0
                        .inner
2039
0
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2040
0
                    Err(()) => HostVm::Error {
2041
0
                        error: Error::ParamDecodeError,
2042
0
                        prototype: self.inner.into_prototype(),
2043
0
                    },
2044
                }
2045
            }
2046
            HostFunction::ext_trie_blake2_256_ordered_root_version_1
2047
            | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2048
            | HostFunction::ext_trie_keccak_256_ordered_root_version_1
2049
            | HostFunction::ext_trie_keccak_256_ordered_root_version_2 => {
2050
5
                let state_version = if 
matches!1
(
2051
5
                    host_fn,
2052
                    HostFunction::ext_trie_blake2_256_ordered_root_version_2
2053
                        | HostFunction::ext_trie_keccak_256_ordered_root_version_2
2054
                ) {
2055
4
                    expect_state_version!(1)
2056
                } else {
2057
1
                    TrieEntryVersion::V0
2058
                };
2059
2060
5
                let result = {
2061
5
                    let input = expect_pointer_size!(0);
2062
5
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
2063
5
                        nom::combinator::all_consuming(nom::combinator::flat_map(
2064
5
                            crate::util::nom_scale_compact_usize,
2065
5
                            |num_elems| {
2066
                                nom::multi::many_m_n(
2067
                                    num_elems,
2068
                                    num_elems,
2069
                                    nom::combinator::flat_map(
2070
                                        crate::util::nom_scale_compact_usize,
2071
                                        nom::bytes::streaming::take,
2072
                                    ),
2073
                                )
2074
5
                            },
2075
5
                        ))(input.as_ref())
2076
5
                        .map(|(_, parse_result)| parse_result);
2077
5
2078
5
                    match parsing_result {
2079
5
                        Ok(elements) => Ok(trie::ordered_root(
2080
5
                            state_version,
2081
0
                            if matches!(
2082
5
                                host_fn,
2083
                                HostFunction::ext_trie_blake2_256_ordered_root_version_1
2084
                                    | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2085
                            ) {
2086
5
                                trie::HashFunction::Blake2
2087
                            } else {
2088
0
                                trie::HashFunction::Keccak256
2089
                            },
2090
5
                            &elements[..],
2091
                        )),
2092
0
                        Err(_) => Err(()),
2093
                    }
2094
                };
2095
2096
5
                match result {
2097
5
                    Ok(out) => self
2098
5
                        .inner
2099
5
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2100
0
                    Err(()) => HostVm::Error {
2101
0
                        error: Error::ParamDecodeError,
2102
0
                        prototype: self.inner.into_prototype(),
2103
0
                    },
2104
                }
2105
            }
2106
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_1 => host_fn_not_implemented!(),
2107
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_2 => host_fn_not_implemented!(),
2108
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_1 => host_fn_not_implemented!(),
2109
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_2 => host_fn_not_implemented!(),
2110
            HostFunction::ext_misc_print_num_version_1 => {
2111
0
                let num = match params[0] {
2112
0
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
2113
                    // The signatures are checked at initialization and the Wasm VM ensures that
2114
                    // the proper parameter types are provided.
2115
0
                    _ => unreachable!(),
2116
                };
2117
2118
0
                HostVm::LogEmit(LogEmit {
2119
0
                    inner: self.inner,
2120
0
                    log_entry: LogEmitInner::Num(num),
2121
0
                })
2122
            }
2123
            HostFunction::ext_misc_print_utf8_version_1 => {
2124
0
                let (str_ptr, str_size) = expect_pointer_size_raw!(0);
2125
2126
0
                let utf8_check = str::from_utf8(
2127
0
                    self.inner
2128
0
                        .vm
2129
0
                        .read_memory(str_ptr, str_size)
2130
0
                        .unwrap_or_else(|_| unreachable!())
2131
0
                        .as_ref(),
2132
0
                )
2133
0
                .map(|_| ());
2134
0
                if let Err(error) = utf8_check {
2135
0
                    return HostVm::Error {
2136
0
                        error: Error::Utf8Error {
2137
0
                            function: host_fn.name(),
2138
0
                            param_num: 2,
2139
0
                            error,
2140
0
                        },
2141
0
                        prototype: self.inner.into_prototype(),
2142
0
                    };
2143
0
                }
2144
0
2145
0
                HostVm::LogEmit(LogEmit {
2146
0
                    inner: self.inner,
2147
0
                    log_entry: LogEmitInner::Utf8 { str_ptr, str_size },
2148
0
                })
2149
            }
2150
            HostFunction::ext_misc_print_hex_version_1 => {
2151
0
                let (data_ptr, data_size) = expect_pointer_size_raw!(0);
2152
0
                HostVm::LogEmit(LogEmit {
2153
0
                    inner: self.inner,
2154
0
                    log_entry: LogEmitInner::Hex {
2155
0
                        data_ptr,
2156
0
                        data_size,
2157
0
                    },
2158
0
                })
2159
            }
2160
            HostFunction::ext_misc_runtime_version_version_1 => {
2161
0
                let (wasm_blob_ptr, wasm_blob_size) = expect_pointer_size_raw!(0);
2162
0
                HostVm::CallRuntimeVersion(CallRuntimeVersion {
2163
0
                    inner: self.inner,
2164
0
                    wasm_blob_ptr,
2165
0
                    wasm_blob_size,
2166
0
                })
2167
            }
2168
            HostFunction::ext_allocator_malloc_version_1 => {
2169
11.7k
                let size = expect_u32!(0);
2170
2171
11.7k
                let ptr = match self.inner.alloc(host_fn.name(), size) {
2172
11.7k
                    Ok(p) => p,
2173
0
                    Err(error) => {
2174
0
                        return HostVm::Error {
2175
0
                            error,
2176
0
                            prototype: self.inner.into_prototype(),
2177
0
                        }
2178
                    }
2179
                };
2180
2181
11.7k
                let ptr_i32 = i32::from_ne_bytes(ptr.to_ne_bytes());
2182
11.7k
                HostVm::ReadyToRun(ReadyToRun {
2183
11.7k
                    resume_value: Some(vm::WasmValue::I32(ptr_i32)),
2184
11.7k
                    inner: self.inner,
2185
11.7k
                })
2186
            }
2187
            HostFunction::ext_allocator_free_version_1 => {
2188
14.3k
                let pointer = expect_u32!(0);
2189
14.3k
                match self.inner.allocator.deallocate(
2190
14.3k
                    &mut MemAccess {
2191
14.3k
                        vm: MemAccessVm::Running(&mut self.inner.vm),
2192
14.3k
                        memory_total_pages: self.inner.common.memory_total_pages,
2193
14.3k
                    },
2194
14.3k
                    pointer,
2195
14.3k
                ) {
2196
14.3k
                    Ok(()) => {}
2197
                    Err(_) => {
2198
0
                        return HostVm::Error {
2199
0
                            error: Error::FreeError { pointer },
2200
0
                            prototype: self.inner.into_prototype(),
2201
0
                        }
2202
                    }
2203
                };
2204
2205
14.3k
                HostVm::ReadyToRun(ReadyToRun {
2206
14.3k
                    resume_value: None,
2207
14.3k
                    inner: self.inner,
2208
14.3k
                })
2209
            }
2210
            HostFunction::ext_logging_log_version_1 => {
2211
0
                let log_level = expect_u32!(0);
2212
2213
0
                let (target_str_ptr, target_str_size) = expect_pointer_size_raw!(1);
2214
0
                let target_utf8_check = str::from_utf8(
2215
0
                    self.inner
2216
0
                        .vm
2217
0
                        .read_memory(target_str_ptr, target_str_size)
2218
0
                        .unwrap_or_else(|_| unreachable!())
2219
0
                        .as_ref(),
2220
0
                )
2221
0
                .map(|_| ());
2222
0
                if let Err(error) = target_utf8_check {
2223
0
                    return HostVm::Error {
2224
0
                        error: Error::Utf8Error {
2225
0
                            function: host_fn.name(),
2226
0
                            param_num: 1,
2227
0
                            error,
2228
0
                        },
2229
0
                        prototype: self.inner.into_prototype(),
2230
0
                    };
2231
0
                }
2232
2233
0
                let (msg_str_ptr, msg_str_size) = expect_pointer_size_raw!(2);
2234
0
                let msg_utf8_check = str::from_utf8(
2235
0
                    self.inner
2236
0
                        .vm
2237
0
                        .read_memory(msg_str_ptr, msg_str_size)
2238
0
                        .unwrap_or_else(|_| unreachable!())
2239
0
                        .as_ref(),
2240
0
                )
2241
0
                .map(|_| ());
2242
0
                if let Err(error) = msg_utf8_check {
2243
0
                    return HostVm::Error {
2244
0
                        error: Error::Utf8Error {
2245
0
                            function: host_fn.name(),
2246
0
                            param_num: 2,
2247
0
                            error,
2248
0
                        },
2249
0
                        prototype: self.inner.into_prototype(),
2250
0
                    };
2251
0
                }
2252
0
2253
0
                HostVm::LogEmit(LogEmit {
2254
0
                    inner: self.inner,
2255
0
                    log_entry: LogEmitInner::Log {
2256
0
                        log_level,
2257
0
                        target_str_ptr,
2258
0
                        target_str_size,
2259
0
                        msg_str_ptr,
2260
0
                        msg_str_size,
2261
0
                    },
2262
0
                })
2263
            }
2264
            HostFunction::ext_logging_max_level_version_1 => {
2265
9
                HostVm::GetMaxLogLevel(GetMaxLogLevel { inner: self.inner })
2266
            }
2267
            HostFunction::ext_panic_handler_abort_on_panic_version_1 => {
2268
0
                let message = {
2269
0
                    let message_bytes = expect_pointer_size!(0);
2270
0
                    str::from_utf8(message_bytes.as_ref()).map(|msg| msg.to_owned())
2271
0
                };
2272
0
2273
0
                match message {
2274
0
                    Ok(message) => HostVm::Error {
2275
0
                        error: Error::AbortOnPanic { message },
2276
0
                        prototype: self.inner.into_prototype(),
2277
0
                    },
2278
0
                    Err(error) => HostVm::Error {
2279
0
                        error: Error::Utf8Error {
2280
0
                            function: host_fn.name(),
2281
0
                            param_num: 0,
2282
0
                            error,
2283
0
                        },
2284
0
                        prototype: self.inner.into_prototype(),
2285
0
                    },
2286
                }
2287
            }
2288
        }
2289
29.2k
    }
_RNvMs2_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_10ReadyToRun8run_once
Line
Count
Source
749
5.20k
    fn run_once(mut self) -> HostVm {
750
        // `vm::ExecOutcome::Interrupted` is by far the variant that requires the most
751
        // handling code. As such, special-case all other variants before.
752
5.20k
        let (
id, params5.07k
) = match self.inner.vm.run(self.resume_value) {
753
5.07k
            Ok(vm::ExecOutcome::Interrupted { id, params }) => (id, params),
754
755
            Ok(vm::ExecOutcome::Finished {
756
127
                return_value: Ok(Some(vm::WasmValue::I64(ret))),
757
127
            }) => {
758
127
                // Wasm virtual machine has successfully returned.
759
127
760
127
                if self.inner.storage_transaction_depth > 0 {
761
0
                    return HostVm::Error {
762
0
                        prototype: self.inner.into_prototype(),
763
0
                        error: Error::FinishedWithPendingTransaction,
764
0
                    };
765
127
                }
766
127
767
127
                // Turn the `i64` into a `u64`, not changing any bit.
768
127
                let ret = u64::from_ne_bytes(ret.to_ne_bytes());
769
127
770
127
                // According to the runtime environment specification, the return value is two
771
127
                // consecutive I32s representing the length and size of the SCALE-encoded
772
127
                // return value.
773
127
                let value_size = u32::try_from(ret >> 32).unwrap_or_else(|_| unreachable!());
774
127
                let value_ptr = u32::try_from(ret & 0xffff_ffff).unwrap_or_else(|_| unreachable!());
775
127
776
127
                if value_size.saturating_add(value_ptr)
777
127
                    <= u32::from(self.inner.vm.memory_size()) * 64 * 1024
778
                {
779
127
                    return HostVm::Finished(Finished {
780
127
                        inner: self.inner,
781
127
                        value_ptr,
782
127
                        value_size,
783
127
                    });
784
0
                }
785
0
                let error = Error::ReturnedPtrOutOfRange {
786
0
                    pointer: value_ptr,
787
0
                    size: value_size,
788
0
                    memory_size: u32::from(self.inner.vm.memory_size()) * 64 * 1024,
789
0
                };
790
0
791
0
                return HostVm::Error {
792
0
                    prototype: self.inner.into_prototype(),
793
0
                    error,
794
0
                };
795
            }
796
797
            Ok(vm::ExecOutcome::Finished {
798
0
                return_value: Ok(return_value),
799
0
            }) => {
800
0
                // The Wasm function has successfully returned, but the specs require that it
801
0
                // returns a `i64`.
802
0
                return HostVm::Error {
803
0
                    prototype: self.inner.into_prototype(),
804
0
                    error: Error::BadReturnValue {
805
0
                        actual: return_value.map(|v| v.ty()),
806
0
                    },
807
0
                };
808
            }
809
810
            Ok(vm::ExecOutcome::Finished {
811
0
                return_value: Err(err),
812
0
            }) => {
813
0
                return HostVm::Error {
814
0
                    error: Error::Trap(err),
815
0
                    prototype: self.inner.into_prototype(),
816
0
                }
817
            }
818
819
            Err(vm::RunErr::BadValueTy { .. }) => {
820
                // Tried to inject back the value returned by a host function, but it doesn't
821
                // match what the Wasm code expects. Given that we check the host function
822
                // signatures at initialization, this indicates a bug in this implementation.
823
0
                unreachable!()
824
            }
825
826
            Err(vm::RunErr::Poisoned) => {
827
                // Can only happen if there's a bug somewhere.
828
0
                unreachable!()
829
            }
830
        };
831
832
        // The Wasm code has called an host_fn. The `id` is a value that we passed
833
        // at initialization, and corresponds to an index in `registered_functions`.
834
5.07k
        let host_fn = match self.inner.common.registered_functions.get(id) {
835
5.07k
            Some(FunctionImport::Resolved(f)) => *f,
836
0
            Some(FunctionImport::Unresolved { name, module }) => {
837
0
                return HostVm::Error {
838
0
                    error: Error::UnresolvedFunctionCalled {
839
0
                        function: name.clone(),
840
0
                        module_name: module.clone(),
841
0
                    },
842
0
                    prototype: self.inner.into_prototype(),
843
0
                };
844
            }
845
0
            None => unreachable!(),
846
        };
847
848
        // Passed a parameter index. Produces an `impl AsRef<[u8]>`.
849
        macro_rules! expect_pointer_size {
850
            ($num:expr) => {{
851
                let val = match &params[$num] {
852
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
853
                    // The signatures are checked at initialization and the Wasm VM ensures that
854
                    // the proper parameter types are provided.
855
                    _ => unreachable!(),
856
                };
857
858
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
859
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
860
861
                let result = self.inner.vm.read_memory(ptr, len);
862
                match result {
863
                    Ok(v) => v,
864
                    Err(vm::OutOfBoundsError) => {
865
                        drop(result);
866
                        return HostVm::Error {
867
                            error: Error::ParamOutOfRange {
868
                                function: host_fn.name(),
869
                                param_num: $num,
870
                                pointer: ptr,
871
                                length: len,
872
                            },
873
                            prototype: self.inner.into_prototype(),
874
                        };
875
                    }
876
                }
877
            }};
878
        }
879
880
        macro_rules! expect_pointer_size_raw {
881
            ($num:expr) => {{
882
                let val = match &params[$num] {
883
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
884
                    // The signatures are checked at initialization and the Wasm VM ensures that
885
                    // the proper parameter types are provided.
886
                    _ => unreachable!(),
887
                };
888
889
                let len = u32::try_from(val >> 32).unwrap_or_else(|_| unreachable!());
890
                let ptr = u32::try_from(val & 0xffffffff).unwrap_or_else(|_| unreachable!());
891
892
                if len.saturating_add(ptr) > u32::from(self.inner.vm.memory_size()) * 64 * 1024 {
893
                    return HostVm::Error {
894
                        error: Error::ParamOutOfRange {
895
                            function: host_fn.name(),
896
                            param_num: $num,
897
                            pointer: ptr,
898
                            length: len,
899
                        },
900
                        prototype: self.inner.into_prototype(),
901
                    };
902
                }
903
904
                (ptr, len)
905
            }};
906
        }
907
908
        macro_rules! expect_pointer_constant_size {
909
            ($num:expr, $size:expr) => {{
910
                let ptr = match params[$num] {
911
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
912
                    // The signatures are checked at initialization and the Wasm VM ensures that
913
                    // the proper parameter types are provided.
914
                    _ => unreachable!(),
915
                };
916
917
                let result = self.inner.vm.read_memory(ptr, $size);
918
                match result {
919
                    Ok(v) => {
920
                        *<&[u8; $size]>::try_from(v.as_ref()).unwrap_or_else(|_| unreachable!())
921
                    }
922
                    Err(vm::OutOfBoundsError) => {
923
                        drop(result);
924
                        return HostVm::Error {
925
                            error: Error::ParamOutOfRange {
926
                                function: host_fn.name(),
927
                                param_num: $num,
928
                                pointer: ptr,
929
                                length: $size,
930
                            },
931
                            prototype: self.inner.into_prototype(),
932
                        };
933
                    }
934
                }
935
            }};
936
        }
937
938
        macro_rules! expect_pointer_constant_size_raw {
939
            ($num:expr, $size:expr) => {{
940
                let ptr = match params[$num] {
941
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
942
                    // The signatures are checked at initialization and the Wasm VM ensures that
943
                    // the proper parameter types are provided.
944
                    _ => unreachable!(),
945
                };
946
947
                if u32::saturating_add($size, ptr)
948
                    > u32::from(self.inner.vm.memory_size()) * 64 * 1024
949
                {
950
                    return HostVm::Error {
951
                        error: Error::ParamOutOfRange {
952
                            function: host_fn.name(),
953
                            param_num: $num,
954
                            pointer: ptr,
955
                            length: $size,
956
                        },
957
                        prototype: self.inner.into_prototype(),
958
                    };
959
                }
960
961
                ptr
962
            }};
963
        }
964
965
        macro_rules! expect_u32 {
966
            ($num:expr) => {{
967
                match &params[$num] {
968
                    vm::WasmValue::I32(v) => u32::from_ne_bytes(v.to_ne_bytes()),
969
                    // The signatures are checked at initialization and the Wasm VM ensures that
970
                    // the proper parameter types are provided.
971
                    _ => unreachable!(),
972
                }
973
            }};
974
        }
975
976
        macro_rules! expect_offchain_storage_kind {
977
            ($num:expr) => {{
978
                match &params[$num] {
979
                    // `0` indicates `StorageKind::PERSISTENT`, the only kind of offchain
980
                    // storage that is available.
981
                    vm::WasmValue::I32(0) => true,
982
                    // `1` indicates `StorageKind::LOCAL`, which is valid but has never been
983
                    // implemented in Substrate.
984
                    vm::WasmValue::I32(1) => false,
985
                    vm::WasmValue::I32(_) => {
986
                        return HostVm::Error {
987
                            error: Error::ParamDecodeError,
988
                            prototype: self.inner.into_prototype(),
989
                        }
990
                    }
991
                    // The signatures are checked at initialization and the Wasm VM ensures that
992
                    // the proper parameter types are provided.
993
                    _ => unreachable!(),
994
                }
995
            }};
996
        }
997
998
        macro_rules! expect_state_version {
999
            ($num:expr) => {{
1000
                match &params[$num] {
1001
                    vm::WasmValue::I32(0) => TrieEntryVersion::V0,
1002
                    vm::WasmValue::I32(1) => TrieEntryVersion::V1,
1003
                    vm::WasmValue::I32(_) => {
1004
                        return HostVm::Error {
1005
                            error: Error::ParamDecodeError,
1006
                            prototype: self.inner.into_prototype(),
1007
                        }
1008
                    }
1009
                    // The signatures are checked at initialization and the Wasm VM ensures that
1010
                    // the proper parameter types are provided.
1011
                    _ => unreachable!(),
1012
                }
1013
            }};
1014
        }
1015
1016
        // TODO: implement all functions and remove this macro
1017
        macro_rules! host_fn_not_implemented {
1018
            () => {{
1019
                return HostVm::Error {
1020
                    error: Error::HostFunctionNotImplemented {
1021
                        function: host_fn.name(),
1022
                    },
1023
                    prototype: self.inner.into_prototype(),
1024
                };
1025
            }};
1026
        }
1027
1028
        // Handle the function calls.
1029
        // Some of these enum variants simply change the state of `self`, while most of them
1030
        // instead return an `ExternalVm` to the user.
1031
5.07k
        match host_fn {
1032
            HostFunction::ext_storage_set_version_1 => {
1033
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1034
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1035
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1036
0
                    key_ptr,
1037
0
                    key_size,
1038
0
                    child_trie_ptr_size: None,
1039
0
                    value: Some((value_ptr, value_size)),
1040
0
                    inner: self.inner,
1041
0
                })
1042
            }
1043
            HostFunction::ext_storage_get_version_1 => {
1044
84
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1045
84
                HostVm::ExternalStorageGet(ExternalStorageGet {
1046
84
                    key_ptr,
1047
84
                    key_size,
1048
84
                    child_trie_ptr_size: None,
1049
84
                    calling: id,
1050
84
                    value_out_ptr: None,
1051
84
                    offset: 0,
1052
84
                    max_size: u32::MAX,
1053
84
                    inner: self.inner,
1054
84
                })
1055
            }
1056
            HostFunction::ext_storage_read_version_1 => {
1057
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1058
0
                let (value_out_ptr, value_out_size) = expect_pointer_size_raw!(1);
1059
0
                let offset = expect_u32!(2);
1060
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1061
0
                    key_ptr,
1062
0
                    key_size,
1063
0
                    child_trie_ptr_size: None,
1064
0
                    calling: id,
1065
0
                    value_out_ptr: Some(value_out_ptr),
1066
0
                    offset,
1067
0
                    max_size: value_out_size,
1068
0
                    inner: self.inner,
1069
0
                })
1070
            }
1071
            HostFunction::ext_storage_clear_version_1 => {
1072
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1073
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1074
0
                    key_ptr,
1075
0
                    key_size,
1076
0
                    child_trie_ptr_size: None,
1077
0
                    value: None,
1078
0
                    inner: self.inner,
1079
0
                })
1080
            }
1081
            HostFunction::ext_storage_exists_version_1 => {
1082
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1083
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1084
0
                    key_ptr,
1085
0
                    key_size,
1086
0
                    child_trie_ptr_size: None,
1087
0
                    calling: id,
1088
0
                    value_out_ptr: None,
1089
0
                    offset: 0,
1090
0
                    max_size: 0,
1091
0
                    inner: self.inner,
1092
0
                })
1093
            }
1094
            HostFunction::ext_storage_clear_prefix_version_1 => {
1095
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(0);
1096
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1097
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1098
0
                    child_trie_ptr_size: None,
1099
0
                    inner: self.inner,
1100
0
                    max_keys_to_remove: None,
1101
0
                    calling: id,
1102
0
                })
1103
            }
1104
            HostFunction::ext_storage_clear_prefix_version_2 => {
1105
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(0);
1106
1107
0
                let max_keys_to_remove = {
1108
0
                    let input = expect_pointer_size!(1);
1109
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1110
0
                        nom::combinator::all_consuming(util::nom_option_decode(
1111
0
                            nom::number::streaming::le_u32,
1112
0
                        ))(input.as_ref())
1113
0
                        .map(|(_, parse_result)| parse_result);
1114
0
1115
0
                    match parsing_result {
1116
0
                        Ok(val) => Ok(val),
1117
0
                        Err(_) => Err(()),
1118
                    }
1119
                };
1120
1121
0
                let max_keys_to_remove = match max_keys_to_remove {
1122
0
                    Ok(l) => l,
1123
                    Err(()) => {
1124
0
                        return HostVm::Error {
1125
0
                            error: Error::ParamDecodeError,
1126
0
                            prototype: self.inner.into_prototype(),
1127
0
                        };
1128
                    }
1129
                };
1130
1131
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1132
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1133
0
                    child_trie_ptr_size: None,
1134
0
                    inner: self.inner,
1135
0
                    max_keys_to_remove,
1136
0
                    calling: id,
1137
0
                })
1138
            }
1139
            HostFunction::ext_storage_root_version_1 => {
1140
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1141
0
                    inner: self.inner,
1142
0
                    calling: id,
1143
0
                    child_trie_ptr_size: None,
1144
0
                })
1145
            }
1146
            HostFunction::ext_storage_root_version_2 => {
1147
                // The `ext_storage_root_version_2` host function gets passed as parameter the
1148
                // state version of the runtime. This is in fact completely unnecessary as the
1149
                // same information is found in the runtime specification, and this parameter
1150
                // should be considered as a historical accident. We verify that the version
1151
                // provided as parameter is the same as the one in the specification.
1152
0
                let version_param = expect_state_version!(0);
1153
0
                let version_spec = self
1154
0
                    .inner
1155
0
                    .common
1156
0
                    .runtime_version
1157
0
                    .as_ref()
1158
0
                    .unwrap_or_else(|| unreachable!())
1159
0
                    .decode()
1160
0
                    .state_version
1161
0
                    .unwrap_or(TrieEntryVersion::V0);
1162
0
1163
0
                if version_param != version_spec {
1164
0
                    return HostVm::Error {
1165
0
                        error: Error::StateVersionMismatch {
1166
0
                            parameter: version_param,
1167
0
                            specification: version_spec,
1168
0
                        },
1169
0
                        prototype: self.inner.into_prototype(),
1170
0
                    };
1171
0
                }
1172
0
1173
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1174
0
                    inner: self.inner,
1175
0
                    calling: id,
1176
0
                    child_trie_ptr_size: None,
1177
0
                })
1178
            }
1179
            HostFunction::ext_storage_changes_root_version_1 => {
1180
                // The changes trie is an obsolete attempt at having a second trie containing, for
1181
                // each storage item, the latest block height where this item has been modified.
1182
                // When this function returns `None`, it indicates that the changes trie is
1183
                // disabled. While this function used to be called by the runtimes of
1184
                // Westend/Polkadot/Kusama (and maybe others), it has never returned anything else
1185
                // but `None`. The entire changes trie mechanism was ultimately removed in
1186
                // October 2021.
1187
                // This function is no longer called by recent runtimes, but must be preserved for
1188
                // backwards compatibility.
1189
0
                self.inner.alloc_write_and_return_pointer_size(
1190
0
                    HostFunction::ext_storage_changes_root_version_1.name(),
1191
0
                    iter::once(&[0][..]),
1192
0
                )
1193
            }
1194
            HostFunction::ext_storage_next_key_version_1 => {
1195
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1196
0
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1197
0
                    key_ptr,
1198
0
                    key_size,
1199
0
                    child_trie_ptr_size: None,
1200
0
                    inner: self.inner,
1201
0
                })
1202
            }
1203
            HostFunction::ext_storage_append_version_1 => {
1204
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1205
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1206
0
                HostVm::ExternalStorageAppend(ExternalStorageAppend {
1207
0
                    key_ptr,
1208
0
                    key_size,
1209
0
                    value_ptr,
1210
0
                    value_size,
1211
0
                    inner: self.inner,
1212
0
                })
1213
            }
1214
            HostFunction::ext_storage_start_transaction_version_1 => {
1215
                // TODO: a maximum depth is important in order to prevent a malicious runtime from crashing the client, but the depth needs to be the same as in Substrate; figure out
1216
0
                self.inner.storage_transaction_depth += 1;
1217
0
                HostVm::StartStorageTransaction(StartStorageTransaction { inner: self.inner })
1218
            }
1219
            HostFunction::ext_storage_rollback_transaction_version_1 => {
1220
0
                if self.inner.storage_transaction_depth == 0 {
1221
0
                    return HostVm::Error {
1222
0
                        error: Error::NoActiveTransaction,
1223
0
                        prototype: self.inner.into_prototype(),
1224
0
                    };
1225
0
                }
1226
0
1227
0
                self.inner.storage_transaction_depth -= 1;
1228
0
                HostVm::EndStorageTransaction {
1229
0
                    resume: EndStorageTransaction { inner: self.inner },
1230
0
                    rollback: true,
1231
0
                }
1232
            }
1233
            HostFunction::ext_storage_commit_transaction_version_1 => {
1234
0
                if self.inner.storage_transaction_depth == 0 {
1235
0
                    return HostVm::Error {
1236
0
                        error: Error::NoActiveTransaction,
1237
0
                        prototype: self.inner.into_prototype(),
1238
0
                    };
1239
0
                }
1240
0
1241
0
                self.inner.storage_transaction_depth -= 1;
1242
0
                HostVm::EndStorageTransaction {
1243
0
                    resume: EndStorageTransaction { inner: self.inner },
1244
0
                    rollback: false,
1245
0
                }
1246
            }
1247
            HostFunction::ext_storage_proof_size_storage_proof_size_version_1 => {
1248
0
                match self.inner.storage_proof_size_behavior {
1249
0
                    StorageProofSizeBehavior::ConstantReturnValue(value) => {
1250
0
                        HostVm::ReadyToRun(ReadyToRun {
1251
0
                            inner: self.inner,
1252
0
                            resume_value: Some(vm::WasmValue::I64(i64::from_ne_bytes(
1253
0
                                value.to_ne_bytes(),
1254
0
                            ))),
1255
0
                        })
1256
                    }
1257
0
                    StorageProofSizeBehavior::Unimplemented => HostVm::Error {
1258
0
                        error: Error::HostFunctionNotImplemented {
1259
0
                            function: host_fn.name(),
1260
0
                        },
1261
0
                        prototype: self.inner.into_prototype(),
1262
0
                    },
1263
                }
1264
            }
1265
            HostFunction::ext_default_child_storage_get_version_1 => {
1266
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1267
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1268
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1269
0
                    key_ptr,
1270
0
                    key_size,
1271
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1272
0
                    calling: id,
1273
0
                    value_out_ptr: None,
1274
0
                    offset: 0,
1275
0
                    max_size: u32::MAX,
1276
0
                    inner: self.inner,
1277
0
                })
1278
            }
1279
            HostFunction::ext_default_child_storage_read_version_1 => {
1280
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1281
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1282
0
                let (value_out_ptr, value_out_size) = expect_pointer_size_raw!(2);
1283
0
                let offset = expect_u32!(3);
1284
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1285
0
                    key_ptr,
1286
0
                    key_size,
1287
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1288
0
                    calling: id,
1289
0
                    value_out_ptr: Some(value_out_ptr),
1290
0
                    offset,
1291
0
                    max_size: value_out_size,
1292
0
                    inner: self.inner,
1293
0
                })
1294
            }
1295
            HostFunction::ext_default_child_storage_storage_kill_version_1 => {
1296
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1297
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1298
0
                    prefix_ptr_size: None,
1299
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1300
0
                    inner: self.inner,
1301
0
                    max_keys_to_remove: None,
1302
0
                    calling: id,
1303
0
                })
1304
            }
1305
            HostFunction::ext_default_child_storage_storage_kill_version_2
1306
            | HostFunction::ext_default_child_storage_storage_kill_version_3 => {
1307
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1308
1309
0
                let max_keys_to_remove = {
1310
0
                    let input = expect_pointer_size!(1);
1311
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1312
0
                        nom::combinator::all_consuming(util::nom_option_decode(
1313
0
                            nom::number::streaming::le_u32,
1314
0
                        ))(input.as_ref())
1315
0
                        .map(|(_, parse_result)| parse_result);
1316
0
1317
0
                    match parsing_result {
1318
0
                        Ok(val) => Ok(val),
1319
0
                        Err(_) => Err(()),
1320
                    }
1321
                };
1322
1323
0
                let max_keys_to_remove = match max_keys_to_remove {
1324
0
                    Ok(l) => l,
1325
                    Err(()) => {
1326
0
                        return HostVm::Error {
1327
0
                            error: Error::ParamDecodeError,
1328
0
                            prototype: self.inner.into_prototype(),
1329
0
                        };
1330
                    }
1331
                };
1332
1333
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1334
0
                    prefix_ptr_size: None,
1335
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1336
0
                    inner: self.inner,
1337
0
                    max_keys_to_remove,
1338
0
                    calling: id,
1339
0
                })
1340
            }
1341
            HostFunction::ext_default_child_storage_clear_prefix_version_1 => {
1342
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1343
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
1344
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1345
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1346
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1347
0
                    inner: self.inner,
1348
0
                    max_keys_to_remove: None,
1349
0
                    calling: id,
1350
0
                })
1351
            }
1352
            HostFunction::ext_default_child_storage_clear_prefix_version_2 => {
1353
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1354
0
                let (prefix_ptr, prefix_size) = expect_pointer_size_raw!(1);
1355
1356
0
                let max_keys_to_remove = {
1357
0
                    let input = expect_pointer_size!(2);
1358
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1359
0
                        nom::combinator::all_consuming(util::nom_option_decode(
1360
0
                            nom::number::streaming::le_u32,
1361
0
                        ))(input.as_ref())
1362
0
                        .map(|(_, parse_result)| parse_result);
1363
0
1364
0
                    match parsing_result {
1365
0
                        Ok(val) => Ok(val),
1366
0
                        Err(_) => Err(()),
1367
                    }
1368
                };
1369
1370
0
                let max_keys_to_remove = match max_keys_to_remove {
1371
0
                    Ok(l) => l,
1372
                    Err(()) => {
1373
0
                        return HostVm::Error {
1374
0
                            error: Error::ParamDecodeError,
1375
0
                            prototype: self.inner.into_prototype(),
1376
0
                        };
1377
                    }
1378
                };
1379
1380
0
                HostVm::ExternalStorageClearPrefix(ExternalStorageClearPrefix {
1381
0
                    prefix_ptr_size: Some((prefix_ptr, prefix_size)),
1382
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1383
0
                    inner: self.inner,
1384
0
                    max_keys_to_remove,
1385
0
                    calling: id,
1386
0
                })
1387
            }
1388
            HostFunction::ext_default_child_storage_set_version_1 => {
1389
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1390
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1391
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(2);
1392
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1393
0
                    key_ptr,
1394
0
                    key_size,
1395
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1396
0
                    value: Some((value_ptr, value_size)),
1397
0
                    inner: self.inner,
1398
0
                })
1399
            }
1400
            HostFunction::ext_default_child_storage_clear_version_1 => {
1401
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1402
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1403
0
                HostVm::ExternalStorageSet(ExternalStorageSet {
1404
0
                    key_ptr,
1405
0
                    key_size,
1406
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1407
0
                    value: None,
1408
0
                    inner: self.inner,
1409
0
                })
1410
            }
1411
            HostFunction::ext_default_child_storage_exists_version_1 => {
1412
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1413
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1414
0
                HostVm::ExternalStorageGet(ExternalStorageGet {
1415
0
                    key_ptr,
1416
0
                    key_size,
1417
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1418
0
                    calling: id,
1419
0
                    value_out_ptr: None,
1420
0
                    offset: 0,
1421
0
                    max_size: 0,
1422
0
                    inner: self.inner,
1423
0
                })
1424
            }
1425
            HostFunction::ext_default_child_storage_next_key_version_1 => {
1426
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1427
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1428
0
                HostVm::ExternalStorageNextKey(ExternalStorageNextKey {
1429
0
                    key_ptr,
1430
0
                    key_size,
1431
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1432
0
                    inner: self.inner,
1433
0
                })
1434
            }
1435
            HostFunction::ext_default_child_storage_root_version_1 => {
1436
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1437
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1438
0
                    inner: self.inner,
1439
0
                    calling: id,
1440
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1441
0
                })
1442
            }
1443
            HostFunction::ext_default_child_storage_root_version_2 => {
1444
0
                let (child_trie_ptr, child_trie_size) = expect_pointer_size_raw!(0);
1445
1446
                // The `ext_default_child_storage_root_version_2` host function gets passed as
1447
                // parameter the state version of the runtime. This is in fact completely
1448
                // unnecessary as the same information is found in the runtime specification, and
1449
                // this parameter should be considered as a historical accident. We verify that the
1450
                // version provided as parameter is the same as the one in the specification.
1451
0
                let version_param = expect_state_version!(1);
1452
0
                let version_spec = self
1453
0
                    .inner
1454
0
                    .common
1455
0
                    .runtime_version
1456
0
                    .as_ref()
1457
0
                    .unwrap_or_else(|| unreachable!())
1458
0
                    .decode()
1459
0
                    .state_version
1460
0
                    .unwrap_or(TrieEntryVersion::V0);
1461
0
1462
0
                if version_param != version_spec {
1463
0
                    return HostVm::Error {
1464
0
                        error: Error::StateVersionMismatch {
1465
0
                            parameter: version_param,
1466
0
                            specification: version_spec,
1467
0
                        },
1468
0
                        prototype: self.inner.into_prototype(),
1469
0
                    };
1470
0
                }
1471
0
1472
0
                HostVm::ExternalStorageRoot(ExternalStorageRoot {
1473
0
                    inner: self.inner,
1474
0
                    calling: id,
1475
0
                    child_trie_ptr_size: Some((child_trie_ptr, child_trie_size)),
1476
0
                })
1477
            }
1478
0
            HostFunction::ext_crypto_ed25519_public_keys_version_1 => host_fn_not_implemented!(),
1479
0
            HostFunction::ext_crypto_ed25519_generate_version_1 => host_fn_not_implemented!(),
1480
0
            HostFunction::ext_crypto_ed25519_sign_version_1 => host_fn_not_implemented!(),
1481
            HostFunction::ext_crypto_ed25519_verify_version_1
1482
            | HostFunction::ext_crypto_ed25519_batch_verify_version_1 => {
1483
0
                let is_batch_verification = matches!(
1484
0
                    host_fn,
1485
                    HostFunction::ext_crypto_ed25519_batch_verify_version_1
1486
                );
1487
1488
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1489
0
                    return HostVm::Error {
1490
0
                        error: Error::BatchVerifyWithoutStarting,
1491
0
                        prototype: self.inner.into_prototype(),
1492
0
                    };
1493
0
                }
1494
1495
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1496
                HostVm::SignatureVerification(SignatureVerification {
1497
0
                    algorithm: SignatureVerificationAlgorithm::Ed25519,
1498
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1499
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1500
0
                    message_ptr,
1501
0
                    message_size,
1502
0
                    inner: self.inner,
1503
0
                    is_batch_verification,
1504
                })
1505
            }
1506
0
            HostFunction::ext_crypto_sr25519_public_keys_version_1 => host_fn_not_implemented!(),
1507
0
            HostFunction::ext_crypto_sr25519_generate_version_1 => host_fn_not_implemented!(),
1508
0
            HostFunction::ext_crypto_sr25519_sign_version_1 => host_fn_not_implemented!(),
1509
            HostFunction::ext_crypto_sr25519_verify_version_1
1510
            | HostFunction::ext_crypto_sr25519_batch_verify_version_1 => {
1511
0
                let is_batch_verification = matches!(
1512
0
                    host_fn,
1513
                    HostFunction::ext_crypto_sr25519_batch_verify_version_1
1514
                );
1515
1516
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1517
0
                    return HostVm::Error {
1518
0
                        error: Error::BatchVerifyWithoutStarting,
1519
0
                        prototype: self.inner.into_prototype(),
1520
0
                    };
1521
0
                }
1522
1523
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1524
                HostVm::SignatureVerification(SignatureVerification {
1525
0
                    algorithm: SignatureVerificationAlgorithm::Sr25519V1,
1526
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1527
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1528
0
                    message_ptr,
1529
0
                    message_size,
1530
0
                    inner: self.inner,
1531
0
                    is_batch_verification,
1532
                })
1533
            }
1534
            HostFunction::ext_crypto_sr25519_verify_version_2 => {
1535
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1536
                HostVm::SignatureVerification(SignatureVerification {
1537
0
                    algorithm: SignatureVerificationAlgorithm::Sr25519V2,
1538
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 64),
1539
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 32),
1540
0
                    message_ptr,
1541
0
                    message_size,
1542
0
                    inner: self.inner,
1543
                    is_batch_verification: false,
1544
                })
1545
            }
1546
0
            HostFunction::ext_crypto_ecdsa_generate_version_1 => host_fn_not_implemented!(),
1547
            HostFunction::ext_crypto_ecdsa_sign_version_1 => {
1548
                // NOTE: safe to unwrap here because we supply the nn to blake2b fn
1549
0
                let data = <[u8; 32]>::try_from(
1550
0
                    blake2_rfc::blake2b::blake2b(32, &[], expect_pointer_size!(0).as_ref())
1551
0
                        .as_bytes(),
1552
0
                )
1553
0
                .unwrap_or_else(|_| unreachable!());
1554
0
                let message = libsecp256k1::Message::parse(&data);
1555
1556
0
                if let Ok(sc) =
1557
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
1558
                {
1559
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1560
0
1561
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1562
0
                    self.inner.alloc_write_and_return_pointer(
1563
0
                        host_fn.name(),
1564
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1565
0
                    )
1566
                } else {
1567
0
                    HostVm::Error {
1568
0
                        error: Error::ParamDecodeError,
1569
0
                        prototype: self.inner.into_prototype(),
1570
0
                    }
1571
                }
1572
            }
1573
0
            HostFunction::ext_crypto_ecdsa_public_keys_version_1 => host_fn_not_implemented!(),
1574
            HostFunction::ext_crypto_ecdsa_verify_version_1
1575
            | HostFunction::ext_crypto_ecdsa_batch_verify_version_1 => {
1576
0
                let is_batch_verification = matches!(
1577
0
                    host_fn,
1578
                    HostFunction::ext_crypto_ecdsa_batch_verify_version_1
1579
                );
1580
1581
0
                if is_batch_verification && self.inner.signatures_batch_verification.is_none() {
1582
0
                    return HostVm::Error {
1583
0
                        error: Error::BatchVerifyWithoutStarting,
1584
0
                        prototype: self.inner.into_prototype(),
1585
0
                    };
1586
0
                }
1587
1588
0
                let (message_ptr, message_size) = expect_pointer_size_raw!(1);
1589
                HostVm::SignatureVerification(SignatureVerification {
1590
0
                    algorithm: SignatureVerificationAlgorithm::Ecdsa,
1591
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1592
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1593
0
                    message_ptr,
1594
0
                    message_size,
1595
0
                    inner: self.inner,
1596
0
                    is_batch_verification,
1597
                })
1598
            }
1599
0
            HostFunction::ext_crypto_ecdsa_verify_version_2 => host_fn_not_implemented!(),
1600
            HostFunction::ext_crypto_ecdsa_sign_prehashed_version_1 => {
1601
                // TODO: seems misimplemented, see https://spec.polkadot.network/#id-ext_crypto_ecdsa_sign_prehashed
1602
0
                let message = libsecp256k1::Message::parse(&expect_pointer_constant_size!(0, 32));
1603
1604
0
                if let Ok(sc) =
1605
0
                    libsecp256k1::SecretKey::parse(&expect_pointer_constant_size!(1, 32))
1606
                {
1607
0
                    let (sig, ri) = libsecp256k1::sign(&message, &sc);
1608
0
1609
0
                    // NOTE: the function returns 2 slices: signature (64 bytes) and recovery ID (1 byte; AS A SLICE)
1610
0
                    self.inner.alloc_write_and_return_pointer(
1611
0
                        host_fn.name(),
1612
0
                        [&sig.serialize()[..], &[ri.serialize()]].into_iter(),
1613
0
                    )
1614
                } else {
1615
0
                    HostVm::Error {
1616
0
                        error: Error::ParamDecodeError,
1617
0
                        prototype: self.inner.into_prototype(),
1618
0
                    }
1619
                }
1620
            }
1621
            HostFunction::ext_crypto_ecdsa_verify_prehashed_version_1 => {
1622
                HostVm::SignatureVerification(SignatureVerification {
1623
0
                    algorithm: SignatureVerificationAlgorithm::EcdsaPrehashed,
1624
0
                    signature_ptr: expect_pointer_constant_size_raw!(0, 65),
1625
0
                    public_key_ptr: expect_pointer_constant_size_raw!(2, 33),
1626
0
                    message_ptr: expect_pointer_constant_size_raw!(1, 32),
1627
                    message_size: 32,
1628
0
                    inner: self.inner,
1629
                    is_batch_verification: false,
1630
                })
1631
            }
1632
1633
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_1
1634
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2 => {
1635
0
                let sig = expect_pointer_constant_size!(0, 65);
1636
0
                let msg = expect_pointer_constant_size!(1, 32);
1637
0
                let is_v2 = matches!(
1638
0
                    host_fn,
1639
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_version_2
1640
                );
1641
1642
0
                let result = {
1643
0
                    let rs = if is_v2 {
1644
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1645
                    } else {
1646
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1647
                    };
1648
1649
0
                    if let Ok(rs) = rs {
1650
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1651
0
                            sig[64] - 27
1652
                        } else {
1653
0
                            sig[64]
1654
                        });
1655
1656
0
                        if let Ok(v) = v {
1657
0
                            let pubkey = libsecp256k1::recover(
1658
0
                                &libsecp256k1::Message::parse_slice(&msg)
1659
0
                                    .unwrap_or_else(|_| unreachable!()),
1660
0
                                &rs,
1661
0
                                &v,
1662
0
                            );
1663
1664
0
                            if let Ok(pubkey) = pubkey {
1665
0
                                let mut res = Vec::with_capacity(65);
1666
0
                                res.push(0);
1667
0
                                res.extend_from_slice(&pubkey.serialize()[1..65]);
1668
0
                                res
1669
                            } else {
1670
0
                                vec![1, 2]
1671
                            }
1672
                        } else {
1673
0
                            vec![1, 1]
1674
                        }
1675
                    } else {
1676
0
                        vec![1, 0]
1677
                    }
1678
                };
1679
1680
0
                self.inner
1681
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1682
            }
1683
            HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_1
1684
            | HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2 => {
1685
0
                let sig = expect_pointer_constant_size!(0, 65);
1686
0
                let msg = expect_pointer_constant_size!(1, 32);
1687
0
                let is_v2 = matches!(
1688
0
                    host_fn,
1689
                    HostFunction::ext_crypto_secp256k1_ecdsa_recover_compressed_version_2
1690
                );
1691
1692
0
                let result = {
1693
0
                    let rs = if is_v2 {
1694
0
                        libsecp256k1::Signature::parse_standard_slice(&sig[0..64])
1695
                    } else {
1696
0
                        libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1697
                    };
1698
1699
0
                    if let Ok(rs) = rs {
1700
0
                        let v = libsecp256k1::RecoveryId::parse(if sig[64] > 26 {
1701
0
                            sig[64] - 27
1702
                        } else {
1703
0
                            sig[64]
1704
                        });
1705
1706
0
                        if let Ok(v) = v {
1707
0
                            let pubkey = libsecp256k1::recover(
1708
0
                                &libsecp256k1::Message::parse_slice(&msg)
1709
0
                                    .unwrap_or_else(|_| unreachable!()),
1710
0
                                &rs,
1711
0
                                &v,
1712
0
                            );
1713
1714
0
                            if let Ok(pubkey) = pubkey {
1715
0
                                let mut res = Vec::with_capacity(34);
1716
0
                                res.push(0);
1717
0
                                res.extend_from_slice(&pubkey.serialize_compressed());
1718
0
                                res
1719
                            } else {
1720
0
                                vec![1, 2]
1721
                            }
1722
                        } else {
1723
0
                            vec![1, 1]
1724
                        }
1725
                    } else {
1726
0
                        vec![1, 0]
1727
                    }
1728
                };
1729
1730
0
                self.inner
1731
0
                    .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&result))
1732
            }
1733
            HostFunction::ext_crypto_start_batch_verify_version_1 => {
1734
0
                if self.inner.signatures_batch_verification.is_some() {
1735
0
                    return HostVm::Error {
1736
0
                        error: Error::AlreadyBatchVerify,
1737
0
                        prototype: self.inner.into_prototype(),
1738
0
                    };
1739
0
                }
1740
0
1741
0
                self.inner.signatures_batch_verification = Some(true);
1742
0
1743
0
                HostVm::ReadyToRun(ReadyToRun {
1744
0
                    resume_value: None,
1745
0
                    inner: self.inner,
1746
0
                })
1747
            }
1748
            HostFunction::ext_crypto_finish_batch_verify_version_1 => {
1749
0
                let Some(outcome) = self.inner.signatures_batch_verification.take() else {
1750
0
                    return HostVm::Error {
1751
0
                        error: Error::NoBatchVerify,
1752
0
                        prototype: self.inner.into_prototype(),
1753
0
                    };
1754
                };
1755
1756
                HostVm::ReadyToRun(ReadyToRun {
1757
0
                    resume_value: Some(vm::WasmValue::I32(if outcome { 1 } else { 0 })),
1758
0
                    inner: self.inner,
1759
                })
1760
            }
1761
            HostFunction::ext_hashing_keccak_256_version_1 => {
1762
0
                let hash =
1763
0
                    <sha3::Keccak256 as sha3::Digest>::digest(expect_pointer_size!(0).as_ref());
1764
0
                self.inner
1765
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1766
            }
1767
            HostFunction::ext_hashing_keccak_512_version_1 => {
1768
0
                let hash =
1769
0
                    <sha3::Keccak512 as sha3::Digest>::digest(expect_pointer_size!(0).as_ref());
1770
0
                self.inner
1771
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1772
            }
1773
            HostFunction::ext_hashing_sha2_256_version_1 => {
1774
0
                let hash = <sha2::Sha256 as sha2::Digest>::digest(expect_pointer_size!(0).as_ref());
1775
0
                self.inner
1776
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&hash))
1777
            }
1778
            HostFunction::ext_hashing_blake2_128_version_1 => {
1779
0
                let out = {
1780
0
                    let data = expect_pointer_size!(0);
1781
0
                    blake2_rfc::blake2b::blake2b(16, &[], data.as_ref())
1782
0
                };
1783
0
1784
0
                self.inner
1785
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1786
            }
1787
            HostFunction::ext_hashing_blake2_256_version_1 => {
1788
0
                let out = {
1789
0
                    let data = expect_pointer_size!(0);
1790
0
                    blake2_rfc::blake2b::blake2b(32, &[], data.as_ref())
1791
0
                };
1792
0
1793
0
                self.inner
1794
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(out.as_bytes()))
1795
            }
1796
            HostFunction::ext_hashing_twox_64_version_1 => {
1797
0
                let mut h0 = twox_hash::XxHash::with_seed(0);
1798
0
                {
1799
0
                    let data = expect_pointer_size!(0);
1800
0
                    h0.write(data.as_ref());
1801
0
                }
1802
0
                let r0 = h0.finish();
1803
0
1804
0
                self.inner
1805
0
                    .alloc_write_and_return_pointer(host_fn.name(), iter::once(&r0.to_le_bytes()))
1806
            }
1807
            HostFunction::ext_hashing_twox_128_version_1 => {
1808
84
                let mut h0 = twox_hash::XxHash::with_seed(0);
1809
84
                let mut h1 = twox_hash::XxHash::with_seed(1);
1810
84
                {
1811
84
                    let data = expect_pointer_size!(0);
1812
84
                    let data = data.as_ref();
1813
84
                    h0.write(data);
1814
84
                    h1.write(data);
1815
84
                }
1816
84
                let r0 = h0.finish();
1817
84
                let r1 = h1.finish();
1818
84
1819
84
                self.inner.alloc_write_and_return_pointer(
1820
84
                    host_fn.name(),
1821
84
                    iter::once(&r0.to_le_bytes()).chain(iter::once(&r1.to_le_bytes())),
1822
84
                )
1823
            }
1824
            HostFunction::ext_hashing_twox_256_version_1 => {
1825
0
                let mut h0 = twox_hash::XxHash::with_seed(0);
1826
0
                let mut h1 = twox_hash::XxHash::with_seed(1);
1827
0
                let mut h2 = twox_hash::XxHash::with_seed(2);
1828
0
                let mut h3 = twox_hash::XxHash::with_seed(3);
1829
0
                {
1830
0
                    let data = expect_pointer_size!(0);
1831
0
                    let data = data.as_ref();
1832
0
                    h0.write(data);
1833
0
                    h1.write(data);
1834
0
                    h2.write(data);
1835
0
                    h3.write(data);
1836
0
                }
1837
0
                let r0 = h0.finish();
1838
0
                let r1 = h1.finish();
1839
0
                let r2 = h2.finish();
1840
0
                let r3 = h3.finish();
1841
0
1842
0
                self.inner.alloc_write_and_return_pointer(
1843
0
                    host_fn.name(),
1844
0
                    iter::once(&r0.to_le_bytes())
1845
0
                        .chain(iter::once(&r1.to_le_bytes()))
1846
0
                        .chain(iter::once(&r2.to_le_bytes()))
1847
0
                        .chain(iter::once(&r3.to_le_bytes())),
1848
0
                )
1849
            }
1850
            HostFunction::ext_offchain_index_set_version_1 => {
1851
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1852
0
                let (value_ptr, value_size) = expect_pointer_size_raw!(1);
1853
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1854
0
                    key_ptr,
1855
0
                    key_size,
1856
0
                    value: Some((value_ptr, value_size)),
1857
0
                    inner: self.inner,
1858
0
                })
1859
            }
1860
            HostFunction::ext_offchain_index_clear_version_1 => {
1861
0
                let (key_ptr, key_size) = expect_pointer_size_raw!(0);
1862
0
                HostVm::ExternalOffchainIndexSet(ExternalOffchainIndexSet {
1863
0
                    key_ptr,
1864
0
                    key_size,
1865
0
                    value: None,
1866
0
                    inner: self.inner,
1867
0
                })
1868
            }
1869
0
            HostFunction::ext_offchain_is_validator_version_1 => HostVm::ReadyToRun(ReadyToRun {
1870
0
                inner: self.inner,
1871
0
                resume_value: Some(vm::WasmValue::I32(1)), // TODO: ask the API user
1872
0
            }),
1873
            HostFunction::ext_offchain_submit_transaction_version_1 => {
1874
0
                let (tx_ptr, tx_size) = expect_pointer_size_raw!(0);
1875
0
                HostVm::OffchainSubmitTransaction(OffchainSubmitTransaction {
1876
0
                    inner: self.inner,
1877
0
                    calling: id,
1878
0
                    tx_ptr,
1879
0
                    tx_size,
1880
0
                })
1881
            }
1882
            HostFunction::ext_offchain_network_state_version_1 => {
1883
0
                host_fn_not_implemented!()
1884
            }
1885
            HostFunction::ext_offchain_timestamp_version_1 => {
1886
0
                HostVm::OffchainTimestamp(OffchainTimestamp { inner: self.inner })
1887
            }
1888
            HostFunction::ext_offchain_sleep_until_version_1 => {
1889
0
                host_fn_not_implemented!()
1890
            }
1891
            HostFunction::ext_offchain_random_seed_version_1 => {
1892
0
                HostVm::OffchainRandomSeed(OffchainRandomSeed {
1893
0
                    inner: self.inner,
1894
0
                    calling: id,
1895
0
                })
1896
            }
1897
            HostFunction::ext_offchain_local_storage_set_version_1 => {
1898
0
                if expect_offchain_storage_kind!(0) {
1899
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1900
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(2);
1901
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1902
0
                        key_ptr,
1903
0
                        key_size,
1904
0
                        value: Some((value_ptr, value_size)),
1905
0
                        old_value: None,
1906
0
                        inner: self.inner,
1907
0
                    })
1908
                } else {
1909
0
                    HostVm::ReadyToRun(ReadyToRun {
1910
0
                        inner: self.inner,
1911
0
                        resume_value: None,
1912
0
                    })
1913
                }
1914
            }
1915
            HostFunction::ext_offchain_local_storage_compare_and_set_version_1 => {
1916
0
                if expect_offchain_storage_kind!(0) {
1917
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1918
0
                    let (old_value_ptr, old_value_size) = expect_pointer_size_raw!(2);
1919
0
                    let (value_ptr, value_size) = expect_pointer_size_raw!(3);
1920
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1921
0
                        key_ptr,
1922
0
                        key_size,
1923
0
                        value: Some((value_ptr, value_size)),
1924
0
                        old_value: Some((old_value_ptr, old_value_size)),
1925
0
                        inner: self.inner,
1926
0
                    })
1927
                } else {
1928
0
                    HostVm::ReadyToRun(ReadyToRun {
1929
0
                        inner: self.inner,
1930
0
                        resume_value: Some(vm::WasmValue::I32(0)),
1931
0
                    })
1932
                }
1933
            }
1934
            HostFunction::ext_offchain_local_storage_get_version_1 => {
1935
0
                if expect_offchain_storage_kind!(0) {
1936
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1937
0
                    HostVm::ExternalOffchainStorageGet(ExternalOffchainStorageGet {
1938
0
                        key_ptr,
1939
0
                        key_size,
1940
0
                        calling: id,
1941
0
                        inner: self.inner,
1942
0
                    })
1943
                } else {
1944
                    // Write a SCALE-encoded `None`.
1945
0
                    self.inner
1946
0
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
1947
                }
1948
            }
1949
            HostFunction::ext_offchain_local_storage_clear_version_1 => {
1950
0
                if expect_offchain_storage_kind!(0) {
1951
0
                    let (key_ptr, key_size) = expect_pointer_size_raw!(1);
1952
0
                    HostVm::ExternalOffchainStorageSet(ExternalOffchainStorageSet {
1953
0
                        key_ptr,
1954
0
                        key_size,
1955
0
                        value: None,
1956
0
                        old_value: None,
1957
0
                        inner: self.inner,
1958
0
                    })
1959
                } else {
1960
0
                    HostVm::ReadyToRun(ReadyToRun {
1961
0
                        inner: self.inner,
1962
0
                        resume_value: None,
1963
0
                    })
1964
                }
1965
            }
1966
0
            HostFunction::ext_offchain_http_request_start_version_1 => host_fn_not_implemented!(),
1967
            HostFunction::ext_offchain_http_request_add_header_version_1 => {
1968
0
                host_fn_not_implemented!()
1969
            }
1970
            HostFunction::ext_offchain_http_request_write_body_version_1 => {
1971
0
                host_fn_not_implemented!()
1972
            }
1973
0
            HostFunction::ext_offchain_http_response_wait_version_1 => host_fn_not_implemented!(),
1974
            HostFunction::ext_offchain_http_response_headers_version_1 => {
1975
0
                host_fn_not_implemented!()
1976
            }
1977
            HostFunction::ext_offchain_http_response_read_body_version_1 => {
1978
0
                host_fn_not_implemented!()
1979
            }
1980
            HostFunction::ext_trie_blake2_256_root_version_1
1981
            | HostFunction::ext_trie_blake2_256_root_version_2
1982
            | HostFunction::ext_trie_keccak_256_root_version_1
1983
            | HostFunction::ext_trie_keccak_256_root_version_2 => {
1984
0
                let state_version = if matches!(
1985
0
                    host_fn,
1986
                    HostFunction::ext_trie_blake2_256_root_version_2
1987
                        | HostFunction::ext_trie_keccak_256_root_version_2
1988
                ) {
1989
0
                    expect_state_version!(1)
1990
                } else {
1991
0
                    TrieEntryVersion::V0
1992
                };
1993
1994
0
                let result = {
1995
0
                    let input = expect_pointer_size!(0);
1996
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
1997
0
                        nom::combinator::all_consuming(nom::combinator::flat_map(
1998
0
                            crate::util::nom_scale_compact_usize,
1999
0
                            |num_elems| {
2000
                                nom::multi::many_m_n(
2001
                                    num_elems,
2002
                                    num_elems,
2003
                                    nom::sequence::tuple((
2004
                                        nom::combinator::flat_map(
2005
                                            crate::util::nom_scale_compact_usize,
2006
                                            nom::bytes::streaming::take,
2007
                                        ),
2008
                                        nom::combinator::flat_map(
2009
                                            crate::util::nom_scale_compact_usize,
2010
                                            nom::bytes::streaming::take,
2011
                                        ),
2012
                                    )),
2013
                                )
2014
0
                            },
2015
0
                        ))(input.as_ref())
2016
0
                        .map(|(_, parse_result)| parse_result);
2017
0
2018
0
                    match parsing_result {
2019
0
                        Ok(elements) => Ok(trie::trie_root(
2020
0
                            state_version,
2021
0
                            if matches!(
2022
0
                                host_fn,
2023
                                HostFunction::ext_trie_blake2_256_root_version_1
2024
                                    | HostFunction::ext_trie_blake2_256_root_version_2
2025
                            ) {
2026
0
                                trie::HashFunction::Blake2
2027
                            } else {
2028
0
                                trie::HashFunction::Keccak256
2029
                            },
2030
0
                            &elements[..],
2031
                        )),
2032
0
                        Err(_) => Err(()),
2033
                    }
2034
                };
2035
2036
0
                match result {
2037
0
                    Ok(out) => self
2038
0
                        .inner
2039
0
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2040
0
                    Err(()) => HostVm::Error {
2041
0
                        error: Error::ParamDecodeError,
2042
0
                        prototype: self.inner.into_prototype(),
2043
0
                    },
2044
                }
2045
            }
2046
            HostFunction::ext_trie_blake2_256_ordered_root_version_1
2047
            | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2048
            | HostFunction::ext_trie_keccak_256_ordered_root_version_1
2049
            | HostFunction::ext_trie_keccak_256_ordered_root_version_2 => {
2050
0
                let state_version = if matches!(
2051
0
                    host_fn,
2052
                    HostFunction::ext_trie_blake2_256_ordered_root_version_2
2053
                        | HostFunction::ext_trie_keccak_256_ordered_root_version_2
2054
                ) {
2055
0
                    expect_state_version!(1)
2056
                } else {
2057
0
                    TrieEntryVersion::V0
2058
                };
2059
2060
0
                let result = {
2061
0
                    let input = expect_pointer_size!(0);
2062
0
                    let parsing_result: Result<_, nom::Err<(&[u8], nom::error::ErrorKind)>> =
2063
0
                        nom::combinator::all_consuming(nom::combinator::flat_map(
2064
0
                            crate::util::nom_scale_compact_usize,
2065
0
                            |num_elems| {
2066
                                nom::multi::many_m_n(
2067
                                    num_elems,
2068
                                    num_elems,
2069
                                    nom::combinator::flat_map(
2070
                                        crate::util::nom_scale_compact_usize,
2071
                                        nom::bytes::streaming::take,
2072
                                    ),
2073
                                )
2074
0
                            },
2075
0
                        ))(input.as_ref())
2076
0
                        .map(|(_, parse_result)| parse_result);
2077
0
2078
0
                    match parsing_result {
2079
0
                        Ok(elements) => Ok(trie::ordered_root(
2080
0
                            state_version,
2081
0
                            if matches!(
2082
0
                                host_fn,
2083
                                HostFunction::ext_trie_blake2_256_ordered_root_version_1
2084
                                    | HostFunction::ext_trie_blake2_256_ordered_root_version_2
2085
                            ) {
2086
0
                                trie::HashFunction::Blake2
2087
                            } else {
2088
0
                                trie::HashFunction::Keccak256
2089
                            },
2090
0
                            &elements[..],
2091
                        )),
2092
0
                        Err(_) => Err(()),
2093
                    }
2094
                };
2095
2096
0
                match result {
2097
0
                    Ok(out) => self
2098
0
                        .inner
2099
0
                        .alloc_write_and_return_pointer(host_fn.name(), iter::once(&out)),
2100
0
                    Err(()) => HostVm::Error {
2101
0
                        error: Error::ParamDecodeError,
2102
0
                        prototype: self.inner.into_prototype(),
2103
0
                    },
2104
                }
2105
            }
2106
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_1 => host_fn_not_implemented!(),
2107
0
            HostFunction::ext_trie_blake2_256_verify_proof_version_2 => host_fn_not_implemented!(),
2108
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_1 => host_fn_not_implemented!(),
2109
0
            HostFunction::ext_trie_keccak_256_verify_proof_version_2 => host_fn_not_implemented!(),
2110
            HostFunction::ext_misc_print_num_version_1 => {
2111
0
                let num = match params[0] {
2112
0
                    vm::WasmValue::I64(v) => u64::from_ne_bytes(v.to_ne_bytes()),
2113
                    // The signatures are checked at initialization and the Wasm VM ensures that
2114
                    // the proper parameter types are provided.
2115
0
                    _ => unreachable!(),
2116
                };
2117
2118
0
                HostVm::LogEmit(LogEmit {
2119
0
                    inner: self.inner,
2120
0
                    log_entry: LogEmitInner::Num(num),
2121
0
                })
2122
            }
2123
            HostFunction::ext_misc_print_utf8_version_1 => {
2124
0
                let (str_ptr, str_size) = expect_pointer_size_raw!(0);
2125
2126
0
                let utf8_check = str::from_utf8(
2127
0
                    self.inner
2128
0
                        .vm
2129
0
                        .read_memory(str_ptr, str_size)
2130
0
                        .unwrap_or_else(|_| unreachable!())
2131
0
                        .as_ref(),
2132
0
                )
2133
0
                .map(|_| ());
2134
0
                if let Err(error) = utf8_check {
2135
0
                    return HostVm::Error {
2136
0
                        error: Error::Utf8Error {
2137
0
                            function: host_fn.name(),
2138
0
                            param_num: 2,
2139
0
                            error,
2140
0
                        },
2141
0
                        prototype: self.inner.into_prototype(),
2142
0
                    };
2143
0
                }
2144
0
2145
0
                HostVm::LogEmit(LogEmit {
2146
0
                    inner: self.inner,
2147
0
                    log_entry: LogEmitInner::Utf8 { str_ptr, str_size },
2148
0
                })
2149
            }
2150
            HostFunction::ext_misc_print_hex_version_1 => {
2151
0
                let (data_ptr, data_size) = expect_pointer_size_raw!(0);
2152
0
                HostVm::LogEmit(LogEmit {
2153
0
                    inner: self.inner,
2154
0
                    log_entry: LogEmitInner::Hex {
2155
0
                        data_ptr,
2156
0
                        data_size,
2157
0
                    },
2158
0
                })
2159
            }
2160
            HostFunction::ext_misc_runtime_version_version_1 => {
2161
0
                let (wasm_blob_ptr, wasm_blob_size) = expect_pointer_size_raw!(0);
2162
0
                HostVm::CallRuntimeVersion(CallRuntimeVersion {
2163
0
                    inner: self.inner,
2164
0
                    wasm_blob_ptr,
2165
0
                    wasm_blob_size,
2166
0
                })
2167
            }
2168
            HostFunction::ext_allocator_malloc_version_1 => {
2169
2.37k
                let size = expect_u32!(0);
2170
2171
2.37k
                let ptr = match self.inner.alloc(host_fn.name(), size) {
2172
2.37k
                    Ok(p) => p,
2173
0
                    Err(error) => {
2174
0
                        return HostVm::Error {
2175
0
                            error,
2176
0
                            prototype: self.inner.into_prototype(),
2177
0
                        }
2178
                    }
2179
                };
2180
2181
2.37k
                let ptr_i32 = i32::from_ne_bytes(ptr.to_ne_bytes());
2182
2.37k
                HostVm::ReadyToRun(ReadyToRun {
2183
2.37k
                    resume_value: Some(vm::WasmValue::I32(ptr_i32)),
2184
2.37k
                    inner: self.inner,
2185
2.37k
                })
2186
            }
2187
            HostFunction::ext_allocator_free_version_1 => {
2188
2.41k
                let pointer = expect_u32!(0);
2189
2.41k
                match self.inner.allocator.deallocate(
2190
2.41k
                    &mut MemAccess {
2191
2.41k
                        vm: MemAccessVm::Running(&mut self.inner.vm),
2192
2.41k
                        memory_total_pages: self.inner.common.memory_total_pages,
2193
2.41k
                    },
2194
2.41k
                    pointer,
2195
2.41k
                ) {
2196
2.41k
                    Ok(()) => {}
2197
                    Err(_) => {
2198
0
                        return HostVm::Error {
2199
0
                            error: Error::FreeError { pointer },
2200
0
                            prototype: self.inner.into_prototype(),
2201
0
                        }
2202
                    }
2203
                };
2204
2205
2.41k
                HostVm::ReadyToRun(ReadyToRun {
2206
2.41k
                    resume_value: None,
2207
2.41k
                    inner: self.inner,
2208
2.41k
                })
2209
            }
2210
            HostFunction::ext_logging_log_version_1 => {
2211
0
                let log_level = expect_u32!(0);
2212
2213
0
                let (target_str_ptr, target_str_size) = expect_pointer_size_raw!(1);
2214
0
                let target_utf8_check = str::from_utf8(
2215
0
                    self.inner
2216
0
                        .vm
2217
0
                        .read_memory(target_str_ptr, target_str_size)
2218
0
                        .unwrap_or_else(|_| unreachable!())
2219
0
                        .as_ref(),
2220
0
                )
2221
0
                .map(|_| ());
2222
0
                if let Err(error) = target_utf8_check {
2223
0
                    return HostVm::Error {
2224
0
                        error: Error::Utf8Error {
2225
0
                            function: host_fn.name(),
2226
0
                            param_num: 1,
2227
0
                            error,
2228
0
                        },
2229
0
                        prototype: self.inner.into_prototype(),
2230
0
                    };
2231
0
                }
2232
2233
0
                let (msg_str_ptr, msg_str_size) = expect_pointer_size_raw!(2);
2234
0
                let msg_utf8_check = str::from_utf8(
2235
0
                    self.inner
2236
0
                        .vm
2237
0
                        .read_memory(msg_str_ptr, msg_str_size)
2238
0
                        .unwrap_or_else(|_| unreachable!())
2239
0
                        .as_ref(),
2240
0
                )
2241
0
                .map(|_| ());
2242
0
                if let Err(error) = msg_utf8_check {
2243
0
                    return HostVm::Error {
2244
0
                        error: Error::Utf8Error {
2245
0
                            function: host_fn.name(),
2246
0
                            param_num: 2,
2247
0
                            error,
2248
0
                        },
2249
0
                        prototype: self.inner.into_prototype(),
2250
0
                    };
2251
0
                }
2252
0
2253
0
                HostVm::LogEmit(LogEmit {
2254
0
                    inner: self.inner,
2255
0
                    log_entry: LogEmitInner::Log {
2256
0
                        log_level,
2257
0
                        target_str_ptr,
2258
0
                        target_str_size,
2259
0
                        msg_str_ptr,
2260
0
                        msg_str_size,
2261
0
                    },
2262
0
                })
2263
            }
2264
            HostFunction::ext_logging_max_level_version_1 => {
2265
127
                HostVm::GetMaxLogLevel(GetMaxLogLevel { inner: self.inner })
2266
            }
2267
            HostFunction::ext_panic_handler_abort_on_panic_version_1 => {
2268
0
                let message = {
2269
0
                    let message_bytes = expect_pointer_size!(0);
2270
0
                    str::from_utf8(message_bytes.as_ref()).map(|msg| msg.to_owned())
2271
0
                };
2272
0
2273
0
                match message {
2274
0
                    Ok(message) => HostVm::Error {
2275
0
                        error: Error::AbortOnPanic { message },
2276
0
                        prototype: self.inner.into_prototype(),
2277
0
                    },
2278
0
                    Err(error) => HostVm::Error {
2279
0
                        error: Error::Utf8Error {
2280
0
                            function: host_fn.name(),
2281
0
                            param_num: 0,
2282
0
                            error,
2283
0
                        },
2284
0
                        prototype: self.inner.into_prototype(),
2285
0
                    },
2286
                }
2287
            }
2288
        }
2289
5.20k
    }
2290
}
2291
2292
impl fmt::Debug for ReadyToRun {
2293
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2294
0
        f.debug_tuple("ReadyToRun").finish()
2295
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_10ReadyToRunNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_10ReadyToRunNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2296
}
2297
2298
/// Function execution has succeeded. Contains the return value of the call.
2299
///
2300
/// The trie root hash of all the child tries must be recalculated and written to the main trie
2301
/// similar to when a [`ExternalStorageRoot`] with a `child_trie` of `None` is generated. See the
2302
/// documentation of [`ExternalStorageRoot`].
2303
pub struct Finished {
2304
    inner: Box<Inner>,
2305
2306
    /// Pointer to the value returned by the VM. Guaranteed to be in range.
2307
    value_ptr: u32,
2308
    /// Size of the value returned by the VM. Guaranteed to be in range.
2309
    value_size: u32,
2310
}
2311
2312
impl Finished {
2313
    /// Returns the value the called function has returned.
2314
158
    pub fn value(&'_ self) -> impl AsRef<[u8]> + '_ {
2315
158
        self.inner
2316
158
            .vm
2317
158
            .read_memory(self.value_ptr, self.value_size)
2318
158
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs4_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_8Finished5value0Bb_
Unexecuted instantiation: _RNCNvMs4_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_8Finished5value0Bb_
2319
158
    }
_RNvMs4_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_8Finished5value
Line
Count
Source
2314
31
    pub fn value(&'_ self) -> impl AsRef<[u8]> + '_ {
2315
31
        self.inner
2316
31
            .vm
2317
31
            .read_memory(self.value_ptr, self.value_size)
2318
31
            .unwrap_or_else(|_| unreachable!())
2319
31
    }
_RNvMs4_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_8Finished5value
Line
Count
Source
2314
127
    pub fn value(&'_ self) -> impl AsRef<[u8]> + '_ {
2315
127
        self.inner
2316
127
            .vm
2317
127
            .read_memory(self.value_ptr, self.value_size)
2318
127
            .unwrap_or_else(|_| unreachable!())
2319
127
    }
2320
2321
    /// Turns the virtual machine back into a prototype.
2322
135
    pub fn into_prototype(self) -> HostVmPrototype {
2323
135
        self.inner.into_prototype()
2324
135
    }
_RNvMs4_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_8Finished14into_prototype
Line
Count
Source
2322
9
    pub fn into_prototype(self) -> HostVmPrototype {
2323
9
        self.inner.into_prototype()
2324
9
    }
_RNvMs4_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_8Finished14into_prototype
Line
Count
Source
2322
126
    pub fn into_prototype(self) -> HostVmPrototype {
2323
126
        self.inner.into_prototype()
2324
126
    }
2325
}
2326
2327
impl fmt::Debug for Finished {
2328
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2329
0
        f.debug_tuple("Finished").finish()
2330
0
    }
Unexecuted instantiation: _RNvXs5_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_8FinishedNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_8FinishedNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2331
}
2332
2333
/// Must provide the value of a storage entry.
2334
pub struct ExternalStorageGet {
2335
    inner: Box<Inner>,
2336
2337
    /// Function currently being called by the Wasm code. Refers to an index within
2338
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
2339
    calling: usize,
2340
2341
    /// Used only for the `ext_storage_read_version_1` function. Stores the pointer where the
2342
    /// output should be stored.
2343
    value_out_ptr: Option<u32>,
2344
2345
    /// Pointer to the key whose value must be loaded. Guaranteed to be in range.
2346
    key_ptr: u32,
2347
    /// Size of the key whose value must be loaded. Guaranteed to be in range.
2348
    key_size: u32,
2349
    /// Pointer and size to the default child trie. `None` if main trie. Guaranteed to be in range.
2350
    child_trie_ptr_size: Option<(u32, u32)>,
2351
    /// Offset within the value that the Wasm VM requires.
2352
    offset: u32,
2353
    /// Maximum size that the Wasm VM would accept.
2354
    max_size: u32,
2355
}
2356
2357
impl ExternalStorageGet {
2358
    /// Returns the key whose value must be provided back with [`ExternalStorageGet::resume`].
2359
2.90k
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2360
2.90k
        self.inner
2361
2.90k
            .vm
2362
2.90k
            .read_memory(self.key_ptr, self.key_size)
2363
2.90k
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet3key0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet3key0Bb_
2364
2.90k
    }
_RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet3key
Line
Count
Source
2359
2.73k
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2360
2.73k
        self.inner
2361
2.73k
            .vm
2362
2.73k
            .read_memory(self.key_ptr, self.key_size)
2363
2.73k
            .unwrap_or_else(|_| unreachable!())
2364
2.73k
    }
_RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet3key
Line
Count
Source
2359
168
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2360
168
        self.inner
2361
168
            .vm
2362
168
            .read_memory(self.key_ptr, self.key_size)
2363
168
            .unwrap_or_else(|_| unreachable!())
2364
168
    }
2365
2366
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
2367
811
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2368
811
        if let Some((
child_trie_ptr, child_trie_size12
)) = self.child_trie_ptr_size {
2369
12
            let child_trie = self
2370
12
                .inner
2371
12
                .vm
2372
12
                .read_memory(child_trie_ptr, child_trie_size)
2373
12
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet10child_trie0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet10child_trie0Bb_
2374
12
            Some(child_trie)
2375
        } else {
2376
799
            None
2377
        }
2378
811
    }
_RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet10child_trie
Line
Count
Source
2367
727
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2368
727
        if let Some((
child_trie_ptr, child_trie_size12
)) = self.child_trie_ptr_size {
2369
12
            let child_trie = self
2370
12
                .inner
2371
12
                .vm
2372
12
                .read_memory(child_trie_ptr, child_trie_size)
2373
12
                .unwrap_or_else(|_| unreachable!());
2374
12
            Some(child_trie)
2375
        } else {
2376
715
            None
2377
        }
2378
727
    }
_RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet10child_trie
Line
Count
Source
2367
84
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2368
84
        if let Some((
child_trie_ptr, child_trie_size0
)) = self.child_trie_ptr_size {
2369
0
            let child_trie = self
2370
0
                .inner
2371
0
                .vm
2372
0
                .read_memory(child_trie_ptr, child_trie_size)
2373
0
                .unwrap_or_else(|_| unreachable!());
2374
0
            Some(child_trie)
2375
        } else {
2376
84
            None
2377
        }
2378
84
    }
2379
2380
    /// Offset within the value that is requested.
2381
0
    pub fn offset(&self) -> u32 {
2382
0
        self.offset
2383
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet6offset
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet6offset
2384
2385
    /// Maximum size of the value to pass back.
2386
    ///
2387
    /// > **Note**: This can be 0 if we only want to know whether a value exists.
2388
0
    pub fn max_size(&self) -> u32 {
2389
0
        self.max_size
2390
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet8max_size
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet8max_size
2391
2392
    /// Same as [`ExternalStorageGet::resume`], but passes the full value, without taking the
2393
    /// offset and maximum size into account.
2394
    ///
2395
    /// This is a convenient function that automatically applies the offset and maximum size, to
2396
    /// use when the full storage value is already present in memory.
2397
687
    pub fn resume_full_value(self, value: Option<&[u8]>) -> HostVm {
2398
687
        if let Some(
value598
) = value {
2399
598
            if usize::try_from(self.offset).unwrap_or_else(|_| 
unreachable!()0
) < value.len() {
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_value0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_value0Bb_
2400
598
                let value_slice =
2401
598
                    &value[usize::try_from(self.offset).unwrap_or_else(|_| 
unreachable!()0
)..];
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values_0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values_0Bb_
2402
598
                if usize::try_from(self.max_size).unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values0_0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values0_0Bb_
2403
598
                    < value_slice.len()
2404
                {
2405
10
                    let value_slice = &value_slice
2406
10
                        [..usize::try_from(self.max_size).unwrap_or_else(|_| 
unreachable!()0
)];
Unexecuted instantiation: _RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values1_0Bb_
Unexecuted instantiation: _RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet17resume_full_values1_0Bb_
2407
10
                    self.resume(Some((value_slice, value.len())))
2408
                } else {
2409
588
                    self.resume(Some((value_slice, value.len())))
2410
                }
2411
            } else {
2412
0
                self.resume(Some((&[], value.len())))
2413
            }
2414
        } else {
2415
89
            self.resume(None)
2416
        }
2417
687
    }
_RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet17resume_full_value
Line
Count
Source
2397
603
    pub fn resume_full_value(self, value: Option<&[u8]>) -> HostVm {
2398
603
        if let Some(
value514
) = value {
2399
514
            if usize::try_from(self.offset).unwrap_or_else(|_| unreachable!()) < value.len() {
2400
514
                let value_slice =
2401
514
                    &value[usize::try_from(self.offset).unwrap_or_else(|_| unreachable!())..];
2402
514
                if usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!())
2403
514
                    < value_slice.len()
2404
                {
2405
10
                    let value_slice = &value_slice
2406
10
                        [..usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!())];
2407
10
                    self.resume(Some((value_slice, value.len())))
2408
                } else {
2409
504
                    self.resume(Some((value_slice, value.len())))
2410
                }
2411
            } else {
2412
0
                self.resume(Some((&[], value.len())))
2413
            }
2414
        } else {
2415
89
            self.resume(None)
2416
        }
2417
603
    }
_RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet17resume_full_value
Line
Count
Source
2397
84
    pub fn resume_full_value(self, value: Option<&[u8]>) -> HostVm {
2398
84
        if let Some(value) = value {
2399
84
            if usize::try_from(self.offset).unwrap_or_else(|_| unreachable!()) < value.len() {
2400
84
                let value_slice =
2401
84
                    &value[usize::try_from(self.offset).unwrap_or_else(|_| unreachable!())..];
2402
84
                if usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!())
2403
84
                    < value_slice.len()
2404
                {
2405
0
                    let value_slice = &value_slice
2406
0
                        [..usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!())];
2407
0
                    self.resume(Some((value_slice, value.len())))
2408
                } else {
2409
84
                    self.resume(Some((value_slice, value.len())))
2410
                }
2411
            } else {
2412
0
                self.resume(Some((&[], value.len())))
2413
            }
2414
        } else {
2415
0
            self.resume(None)
2416
        }
2417
84
    }
2418
2419
    /// Writes the storage value in the Wasm VM's memory and prepares the virtual machine to
2420
    /// resume execution.
2421
    ///
2422
    /// The value to provide must be the value of that key starting at the offset returned by
2423
    /// [`ExternalStorageGet::offset`]. If the offset is out of range, an empty slice must be
2424
    /// passed.
2425
    ///
2426
    /// If `Some`, the total size of the value, without taking [`ExternalStorageGet::offset`] or
2427
    /// [`ExternalStorageGet::max_size`] into account, must additionally be provided.
2428
    ///
2429
    /// If [`ExternalStorageGet::child_trie`] returns `Some` but the child trie doesn't exist,
2430
    /// then `None` must be provided.
2431
    ///
2432
    /// The value must not be longer than what [`ExternalStorageGet::max_size`] returns.
2433
    ///
2434
    /// # Panic
2435
    ///
2436
    /// Panics if the value is longer than what [`ExternalStorageGet::max_size`] returns.
2437
    ///
2438
687
    pub fn resume(self, value: Option<(&[u8], usize)>) -> HostVm {
2439
687
        self.resume_vectored(
2440
687
            value
2441
687
                .as_ref()
2442
687
                .map(|(value, size)| 
(iter::once(&value[..]), *size)598
),
_RNCNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageGet6resume0Bb_
Line
Count
Source
2442
514
                .map(|(value, size)| (iter::once(&value[..]), *size)),
_RNCNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageGet6resume0Bb_
Line
Count
Source
2442
84
                .map(|(value, size)| (iter::once(&value[..]), *size)),
2443
687
        )
2444
687
    }
_RNvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGet6resume
Line
Count
Source
2438
603
    pub fn resume(self, value: Option<(&[u8], usize)>) -> HostVm {
2439
603
        self.resume_vectored(
2440
603
            value
2441
603
                .as_ref()
2442
603
                .map(|(value, size)| (iter::once(&value[..]), *size)),
2443
603
        )
2444
603
    }
_RNvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGet6resume
Line
Count
Source
2438
84
    pub fn resume(self, value: Option<(&[u8], usize)>) -> HostVm {
2439
84
        self.resume_vectored(
2440
84
            value
2441
84
                .as_ref()
2442
84
                .map(|(value, size)| (iter::once(&value[..]), *size)),
2443
84
        )
2444
84
    }
2445
2446
    /// Similar to [`ExternalStorageGet::resume`], but allows passing the value as a list of
2447
    /// buffers whose concatenation forms the actual value.
2448
    ///
2449
    /// If `Some`, the total size of the value, without taking [`ExternalStorageGet::offset`] or
2450
    /// [`ExternalStorageGet::max_size`] into account, must additionally be provided.
2451
    ///
2452
    /// # Panic
2453
    ///
2454
    /// See [`ExternalStorageGet::resume`].
2455
    ///
2456
687
    pub fn resume_vectored(
2457
687
        mut self,
2458
687
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>> + Clone, usize)>,
2459
687
    ) -> HostVm {
2460
687
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2461
687
            FunctionImport::Resolved(f) => f,
2462
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2463
        };
2464
2465
687
        match host_fn {
2466
            HostFunction::ext_storage_get_version_1
2467
            | HostFunction::ext_default_child_storage_get_version_1 => {
2468
657
                if let Some((
value, value_total_len588
)) = value {
2469
                    // Writing `Some(value)`.
2470
588
                    debug_assert_eq!(
2471
588
                        value.clone().fold(0, |a, b| a + b.as_ref().len()),
_RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEs3_0Bc_
Line
Count
Source
2471
504
                        value.clone().fold(0, |a, b| a + b.as_ref().len()),
_RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EEs3_0Bc_
Line
Count
Source
2471
84
                        value.clone().fold(0, |a, b| a + b.as_ref().len()),
2472
                        value_total_len
2473
                    );
2474
588
                    let value_len_enc = util::encode_scale_compact_usize(value_total_len);
2475
588
                    self.inner.alloc_write_and_return_pointer_size(
2476
588
                        host_fn.name(),
2477
588
                        iter::once(&[1][..])
2478
588
                            .chain(iter::once(value_len_enc.as_ref()))
2479
588
                            .map(either::Left)
2480
588
                            .chain(value.map(either::Right)),
2481
588
                    )
2482
                } else {
2483
                    // Write a SCALE-encoded `None`.
2484
69
                    self.inner
2485
69
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
2486
                }
2487
            }
2488
            HostFunction::ext_storage_read_version_1
2489
            | HostFunction::ext_default_child_storage_read_version_1 => {
2490
14
                let outcome = if let Some((
value, value_total_len2
)) = value {
2491
2
                    let mut remaining_max_allowed =
2492
2
                        usize::try_from(self.max_size).unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredppE0Bc_
Unexecuted instantiation: _RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredppE0Bc_
2493
2
                    let mut offset = self.value_out_ptr.unwrap_or_else(|| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEs_0Bc_
Unexecuted instantiation: _RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EEs_0Bc_
2494
4
                    for 
value2
in value {
2495
2
                        let value = value.as_ref();
2496
2
                        assert!(value.len() <= remaining_max_allowed);
2497
2
                        remaining_max_allowed -= value.len();
2498
2
                        self.inner
2499
2
                            .vm
2500
2
                            .write_memory(offset, value)
2501
2
                            .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEs0_0Bc_
Unexecuted instantiation: _RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EEs0_0Bc_
2502
2
                        offset += u32::try_from(value.len()).unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEs1_0Bc_
Unexecuted instantiation: _RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EEs1_0Bc_
2503
                    }
2504
2505
                    // Note: the https://github.com/paritytech/substrate/pull/7084 PR has changed
2506
                    // the meaning of this return value.
2507
2
                    Some(
2508
2
                        u32::try_from(value_total_len).unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEs2_0Bc_
Unexecuted instantiation: _RNCINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EEs2_0Bc_
2509
2
                            - self.offset,
2510
2
                    )
2511
                } else {
2512
12
                    None
2513
                };
2514
2515
14
                return self.inner.alloc_write_and_return_pointer_size(
2516
14
                    host_fn.name(),
2517
14
                    if let Some(
outcome2
) = outcome {
2518
2
                        either::Left(
2519
2
                            iter::once(either::Left([1u8]))
2520
2
                                .chain(iter::once(either::Right(outcome.to_le_bytes()))),
2521
2
                        )
2522
                    } else {
2523
12
                        either::Right(iter::once(either::Left([0u8])))
2524
                    },
2525
                );
2526
            }
2527
            HostFunction::ext_storage_exists_version_1
2528
            | HostFunction::ext_default_child_storage_exists_version_1 => {
2529
                HostVm::ReadyToRun(ReadyToRun {
2530
16
                    inner: self.inner,
2531
16
                    resume_value: Some(if value.is_some() {
2532
8
                        vm::WasmValue::I32(1)
2533
                    } else {
2534
8
                        vm::WasmValue::I32(0)
2535
                    }),
2536
                })
2537
            }
2538
0
            _ => unreachable!(),
2539
        }
2540
687
    }
_RINvMs6_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1p_EEBa_
Line
Count
Source
2456
603
    pub fn resume_vectored(
2457
603
        mut self,
2458
603
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>> + Clone, usize)>,
2459
603
    ) -> HostVm {
2460
603
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2461
603
            FunctionImport::Resolved(f) => f,
2462
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2463
        };
2464
2465
603
        match host_fn {
2466
            HostFunction::ext_storage_get_version_1
2467
            | HostFunction::ext_default_child_storage_get_version_1 => {
2468
573
                if let Some((
value, value_total_len504
)) = value {
2469
                    // Writing `Some(value)`.
2470
504
                    debug_assert_eq!(
2471
504
                        value.clone().fold(0, |a, b| a + b.as_ref().len()),
2472
                        value_total_len
2473
                    );
2474
504
                    let value_len_enc = util::encode_scale_compact_usize(value_total_len);
2475
504
                    self.inner.alloc_write_and_return_pointer_size(
2476
504
                        host_fn.name(),
2477
504
                        iter::once(&[1][..])
2478
504
                            .chain(iter::once(value_len_enc.as_ref()))
2479
504
                            .map(either::Left)
2480
504
                            .chain(value.map(either::Right)),
2481
504
                    )
2482
                } else {
2483
                    // Write a SCALE-encoded `None`.
2484
69
                    self.inner
2485
69
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
2486
                }
2487
            }
2488
            HostFunction::ext_storage_read_version_1
2489
            | HostFunction::ext_default_child_storage_read_version_1 => {
2490
14
                let outcome = if let Some((
value, value_total_len2
)) = value {
2491
2
                    let mut remaining_max_allowed =
2492
2
                        usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!());
2493
2
                    let mut offset = self.value_out_ptr.unwrap_or_else(|| unreachable!());
2494
4
                    for 
value2
in value {
2495
2
                        let value = value.as_ref();
2496
2
                        assert!(value.len() <= remaining_max_allowed);
2497
2
                        remaining_max_allowed -= value.len();
2498
2
                        self.inner
2499
2
                            .vm
2500
2
                            .write_memory(offset, value)
2501
2
                            .unwrap_or_else(|_| unreachable!());
2502
2
                        offset += u32::try_from(value.len()).unwrap_or_else(|_| unreachable!());
2503
                    }
2504
2505
                    // Note: the https://github.com/paritytech/substrate/pull/7084 PR has changed
2506
                    // the meaning of this return value.
2507
2
                    Some(
2508
2
                        u32::try_from(value_total_len).unwrap_or_else(|_| unreachable!())
2509
2
                            - self.offset,
2510
2
                    )
2511
                } else {
2512
12
                    None
2513
                };
2514
2515
14
                return self.inner.alloc_write_and_return_pointer_size(
2516
14
                    host_fn.name(),
2517
14
                    if let Some(
outcome2
) = outcome {
2518
2
                        either::Left(
2519
2
                            iter::once(either::Left([1u8]))
2520
2
                                .chain(iter::once(either::Right(outcome.to_le_bytes()))),
2521
2
                        )
2522
                    } else {
2523
12
                        either::Right(iter::once(either::Left([0u8])))
2524
                    },
2525
                );
2526
            }
2527
            HostFunction::ext_storage_exists_version_1
2528
            | HostFunction::ext_default_child_storage_exists_version_1 => {
2529
                HostVm::ReadyToRun(ReadyToRun {
2530
16
                    inner: self.inner,
2531
16
                    resume_value: Some(if value.is_some() {
2532
8
                        vm::WasmValue::I32(1)
2533
                    } else {
2534
8
                        vm::WasmValue::I32(0)
2535
                    }),
2536
                })
2537
            }
2538
0
            _ => unreachable!(),
2539
        }
2540
603
    }
_RINvMs6_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_18ExternalStorageGet15resume_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
2456
84
    pub fn resume_vectored(
2457
84
        mut self,
2458
84
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>> + Clone, usize)>,
2459
84
    ) -> HostVm {
2460
84
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2461
84
            FunctionImport::Resolved(f) => f,
2462
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2463
        };
2464
2465
84
        match host_fn {
2466
            HostFunction::ext_storage_get_version_1
2467
            | HostFunction::ext_default_child_storage_get_version_1 => {
2468
84
                if let Some((value, value_total_len)) = value {
2469
                    // Writing `Some(value)`.
2470
84
                    debug_assert_eq!(
2471
84
                        value.clone().fold(0, |a, b| a + b.as_ref().len()),
2472
                        value_total_len
2473
                    );
2474
84
                    let value_len_enc = util::encode_scale_compact_usize(value_total_len);
2475
84
                    self.inner.alloc_write_and_return_pointer_size(
2476
84
                        host_fn.name(),
2477
84
                        iter::once(&[1][..])
2478
84
                            .chain(iter::once(value_len_enc.as_ref()))
2479
84
                            .map(either::Left)
2480
84
                            .chain(value.map(either::Right)),
2481
84
                    )
2482
                } else {
2483
                    // Write a SCALE-encoded `None`.
2484
0
                    self.inner
2485
0
                        .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
2486
                }
2487
            }
2488
            HostFunction::ext_storage_read_version_1
2489
            | HostFunction::ext_default_child_storage_read_version_1 => {
2490
0
                let outcome = if let Some((value, value_total_len)) = value {
2491
0
                    let mut remaining_max_allowed =
2492
0
                        usize::try_from(self.max_size).unwrap_or_else(|_| unreachable!());
2493
0
                    let mut offset = self.value_out_ptr.unwrap_or_else(|| unreachable!());
2494
0
                    for value in value {
2495
0
                        let value = value.as_ref();
2496
0
                        assert!(value.len() <= remaining_max_allowed);
2497
0
                        remaining_max_allowed -= value.len();
2498
0
                        self.inner
2499
0
                            .vm
2500
0
                            .write_memory(offset, value)
2501
0
                            .unwrap_or_else(|_| unreachable!());
2502
0
                        offset += u32::try_from(value.len()).unwrap_or_else(|_| unreachable!());
2503
                    }
2504
2505
                    // Note: the https://github.com/paritytech/substrate/pull/7084 PR has changed
2506
                    // the meaning of this return value.
2507
0
                    Some(
2508
0
                        u32::try_from(value_total_len).unwrap_or_else(|_| unreachable!())
2509
0
                            - self.offset,
2510
0
                    )
2511
                } else {
2512
0
                    None
2513
                };
2514
2515
0
                return self.inner.alloc_write_and_return_pointer_size(
2516
0
                    host_fn.name(),
2517
0
                    if let Some(outcome) = outcome {
2518
0
                        either::Left(
2519
0
                            iter::once(either::Left([1u8]))
2520
0
                                .chain(iter::once(either::Right(outcome.to_le_bytes()))),
2521
0
                        )
2522
                    } else {
2523
0
                        either::Right(iter::once(either::Left([0u8])))
2524
                    },
2525
                );
2526
            }
2527
            HostFunction::ext_storage_exists_version_1
2528
            | HostFunction::ext_default_child_storage_exists_version_1 => {
2529
                HostVm::ReadyToRun(ReadyToRun {
2530
0
                    inner: self.inner,
2531
0
                    resume_value: Some(if value.is_some() {
2532
0
                        vm::WasmValue::I32(1)
2533
                    } else {
2534
0
                        vm::WasmValue::I32(0)
2535
                    }),
2536
                })
2537
            }
2538
0
            _ => unreachable!(),
2539
        }
2540
84
    }
2541
}
2542
2543
impl fmt::Debug for ExternalStorageGet {
2544
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2545
0
        f.debug_tuple("ExternalStorageGet").finish()
2546
0
    }
Unexecuted instantiation: _RNvXs7_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageGetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs7_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageGetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2547
}
2548
2549
/// Must set the value of a storage entry.
2550
///
2551
/// If [`ExternalStorageSet::child_trie`] return `None` and [`ExternalStorageSet::key`]
2552
/// returns a key that starts with `:child_storage:`, then the write must be silently ignored.
2553
///
2554
/// If [`ExternalStorageSet::child_trie`] and [`ExternalStorageSet::value`] return `Some` and the
2555
/// child trie doesn't exist, it must implicitly be created.
2556
/// If [`ExternalStorageSet::child_trie`] returns `Some` and [`ExternalStorageSet::value`]
2557
/// returns `None` and this is the last entry in the child trie, it must implicitly be destroyed.
2558
pub struct ExternalStorageSet {
2559
    inner: Box<Inner>,
2560
2561
    /// Pointer to the key whose value must be set. Guaranteed to be in range.
2562
    key_ptr: u32,
2563
    /// Size of the key whose value must be set. Guaranteed to be in range.
2564
    key_size: u32,
2565
    /// Pointer and size to the default child trie key. `None` if main trie. Guaranteed to be
2566
    /// in range.
2567
    child_trie_ptr_size: Option<(u32, u32)>,
2568
2569
    /// Pointer and size of the value to set. `None` for clearing. Guaranteed to be in range.
2570
    value: Option<(u32, u32)>,
2571
}
2572
2573
impl ExternalStorageSet {
2574
    /// Returns the key whose value must be set.
2575
746
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2576
746
        self.inner
2577
746
            .vm
2578
746
            .read_memory(self.key_ptr, self.key_size)
2579
746
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageSet3key0Bb_
Unexecuted instantiation: _RNCNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageSet3key0Bb_
2580
746
    }
_RNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSet3key
Line
Count
Source
2575
746
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2576
746
        self.inner
2577
746
            .vm
2578
746
            .read_memory(self.key_ptr, self.key_size)
2579
746
            .unwrap_or_else(|_| unreachable!())
2580
746
    }
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSet3key
2581
2582
    /// If `Some`, write to the given child trie. If `None`, write to the main trie.
2583
    ///
2584
    /// If [`ExternalStorageSet::value`] returns `Some` and the child trie doesn't exist, it must
2585
    /// implicitly be created.
2586
    /// If [`ExternalStorageSet::value`] returns `None` and this is the last entry in the child
2587
    /// trie, it must implicitly be destroyed.
2588
1.12k
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2589
1.12k
        match &self.child_trie_ptr_size {
2590
12
            Some((ptr, size)) => {
2591
12
                let child_trie = self
2592
12
                    .inner
2593
12
                    .vm
2594
12
                    .read_memory(*ptr, *size)
2595
12
                    .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageSet10child_trie0Bb_
Unexecuted instantiation: _RNCNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageSet10child_trie0Bb_
2596
12
                Some(child_trie)
2597
            }
2598
1.11k
            None => None,
2599
        }
2600
1.12k
    }
_RNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSet10child_trie
Line
Count
Source
2588
1.12k
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2589
1.12k
        match &self.child_trie_ptr_size {
2590
12
            Some((ptr, size)) => {
2591
12
                let child_trie = self
2592
12
                    .inner
2593
12
                    .vm
2594
12
                    .read_memory(*ptr, *size)
2595
12
                    .unwrap_or_else(|_| unreachable!());
2596
12
                Some(child_trie)
2597
            }
2598
1.11k
            None => None,
2599
        }
2600
1.12k
    }
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSet10child_trie
2601
2602
    /// Returns the value to set.
2603
    ///
2604
    /// If `None` is returned, the key should be removed from the storage entirely.
2605
375
    pub fn value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2606
375
        self.value.map(|(ptr, size)| {
2607
304
            self.inner
2608
304
                .vm
2609
304
                .read_memory(ptr, size)
2610
304
                .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNCNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB9_18ExternalStorageSet5value00Bd_
Unexecuted instantiation: _RNCNCNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB9_18ExternalStorageSet5value00Bd_
2611
375
        })
_RNCNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageSet5value0Bb_
Line
Count
Source
2606
304
        self.value.map(|(ptr, size)| {
2607
304
            self.inner
2608
304
                .vm
2609
304
                .read_memory(ptr, size)
2610
304
                .unwrap_or_else(|_| unreachable!())
2611
304
        })
Unexecuted instantiation: _RNCNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageSet5value0Bb_
2612
375
    }
_RNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSet5value
Line
Count
Source
2605
375
    pub fn value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2606
375
        self.value.map(|(ptr, size)| {
2607
            self.inner
2608
                .vm
2609
                .read_memory(ptr, size)
2610
                .unwrap_or_else(|_| unreachable!())
2611
375
        })
2612
375
    }
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSet5value
2613
2614
    /// Returns the state trie version indicated by the runtime.
2615
    ///
2616
    /// This information should be stored alongside with the storage value and is necessary in
2617
    /// order to properly build the trie and thus the trie root node hash.
2618
0
    pub fn state_trie_version(&self) -> TrieEntryVersion {
2619
0
        self.inner
2620
0
            .common
2621
0
            .runtime_version
2622
0
            .as_ref()
2623
0
            .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18ExternalStorageSet18state_trie_version0Bb_
Unexecuted instantiation: _RNCNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18ExternalStorageSet18state_trie_version0Bb_
2624
0
            .decode()
2625
0
            .state_version
2626
0
            .unwrap_or(TrieEntryVersion::V0)
2627
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSet18state_trie_version
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSet18state_trie_version
2628
2629
    /// Resumes execution after having set the value.
2630
375
    pub fn resume(self) -> HostVm {
2631
375
        HostVm::ReadyToRun(ReadyToRun {
2632
375
            inner: self.inner,
2633
375
            resume_value: None,
2634
375
        })
2635
375
    }
_RNvMs8_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSet6resume
Line
Count
Source
2630
375
    pub fn resume(self) -> HostVm {
2631
375
        HostVm::ReadyToRun(ReadyToRun {
2632
375
            inner: self.inner,
2633
375
            resume_value: None,
2634
375
        })
2635
375
    }
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSet6resume
2636
}
2637
2638
impl fmt::Debug for ExternalStorageSet {
2639
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2640
0
        f.debug_tuple("ExternalStorageSet").finish()
2641
0
    }
Unexecuted instantiation: _RNvXs9_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18ExternalStorageSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18ExternalStorageSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2642
}
2643
2644
/// Must load a storage value, treat it as if it was a SCALE-encoded container, and put `value`
2645
/// at the end of the container, increasing the number of elements.
2646
///
2647
/// If [`ExternalStorageAppend::child_trie`] return `Some` and the child trie doesn't exist, it
2648
/// must implicitly be created.
2649
///
2650
/// If [`ExternalStorageAppend::child_trie`] return `None` and [`ExternalStorageAppend::key`]
2651
/// returns a key that starts with `:child_storage:`, then the write must be silently ignored.
2652
///
2653
/// If there isn't any existing value of if the existing value isn't actually a SCALE-encoded
2654
/// container, store a 1-size container with the `value`.
2655
///
2656
/// # Details
2657
///
2658
/// The SCALE encoding encodes containers as a SCALE-compact-encoded length followed with the
2659
/// SCALE-encoded items one after the other. For example, a container of two elements is stored
2660
/// as the number `2` followed with the two items.
2661
///
2662
/// This change consists in taking an existing value and assuming that it is a SCALE-encoded
2663
/// container. This can be done as decoding a SCALE-compact-encoded number at the start of
2664
/// the existing encoded value. One most then increments that number and puts `value` at the
2665
/// end of the encoded value.
2666
///
2667
/// It is not necessary to decode `value` as is assumed that is already encoded in the same
2668
/// way as the other items in the container.
2669
pub struct ExternalStorageAppend {
2670
    inner: Box<Inner>,
2671
2672
    /// Pointer to the key whose value must be set. Guaranteed to be in range.
2673
    key_ptr: u32,
2674
    /// Size of the key whose value must be set. Guaranteed to be in range.
2675
    key_size: u32,
2676
2677
    /// Pointer to the value to append. Guaranteed to be in range.
2678
    value_ptr: u32,
2679
    /// Size of the value to append. Guaranteed to be in range.
2680
    value_size: u32,
2681
}
2682
2683
impl ExternalStorageAppend {
2684
    /// Returns the key whose value must be set.
2685
221
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2686
221
        self.inner
2687
221
            .vm
2688
221
            .read_memory(self.key_ptr, self.key_size)
2689
221
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21ExternalStorageAppend3key0Bb_
Unexecuted instantiation: _RNCNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21ExternalStorageAppend3key0Bb_
2690
221
    }
_RNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21ExternalStorageAppend3key
Line
Count
Source
2685
221
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2686
221
        self.inner
2687
221
            .vm
2688
221
            .read_memory(self.key_ptr, self.key_size)
2689
221
            .unwrap_or_else(|_| unreachable!())
2690
221
    }
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21ExternalStorageAppend3key
2691
2692
    /// If `Some`, write to the given child trie. If `None`, write to the main trie.
2693
    ///
2694
    /// If this returns `Some` and the child trie doesn't exist, it must implicitly be created.
2695
    ///
2696
    /// > **Note**: At the moment, this function always returns None, as there is no host function
2697
    /// >           that appends to a child trie storage.
2698
228
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2699
228
        // Note that there is no equivalent of this host function for child tries.
2700
228
        None::<&'static [u8]>
2701
228
    }
_RNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21ExternalStorageAppend10child_trie
Line
Count
Source
2698
228
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2699
228
        // Note that there is no equivalent of this host function for child tries.
2700
228
        None::<&'static [u8]>
2701
228
    }
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21ExternalStorageAppend10child_trie
2702
2703
    /// Returns the value to append.
2704
71
    pub fn value(&'_ self) -> impl AsRef<[u8]> + '_ {
2705
71
        self.inner
2706
71
            .vm
2707
71
            .read_memory(self.value_ptr, self.value_size)
2708
71
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21ExternalStorageAppend5value0Bb_
Unexecuted instantiation: _RNCNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21ExternalStorageAppend5value0Bb_
2709
71
    }
_RNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21ExternalStorageAppend5value
Line
Count
Source
2704
71
    pub fn value(&'_ self) -> impl AsRef<[u8]> + '_ {
2705
71
        self.inner
2706
71
            .vm
2707
71
            .read_memory(self.value_ptr, self.value_size)
2708
71
            .unwrap_or_else(|_| unreachable!())
2709
71
    }
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21ExternalStorageAppend5value
2710
2711
    /// Resumes execution after having set the value.
2712
71
    pub fn resume(self) -> HostVm {
2713
71
        HostVm::ReadyToRun(ReadyToRun {
2714
71
            inner: self.inner,
2715
71
            resume_value: None,
2716
71
        })
2717
71
    }
_RNvMsa_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21ExternalStorageAppend6resume
Line
Count
Source
2712
71
    pub fn resume(self) -> HostVm {
2713
71
        HostVm::ReadyToRun(ReadyToRun {
2714
71
            inner: self.inner,
2715
71
            resume_value: None,
2716
71
        })
2717
71
    }
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21ExternalStorageAppend6resume
2718
}
2719
2720
impl fmt::Debug for ExternalStorageAppend {
2721
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2722
0
        f.debug_tuple("ExternalStorageAppend").finish()
2723
0
    }
Unexecuted instantiation: _RNvXsb_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21ExternalStorageAppendNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsb_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21ExternalStorageAppendNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2724
}
2725
2726
/// Must remove from the storage keys which start with a certain prefix. Use
2727
/// [`ExternalStorageClearPrefix::max_keys_to_remove`] to determine the maximum number of keys
2728
/// to remove.
2729
///
2730
/// If [`ExternalStorageClearPrefix::child_trie`] returns `Some` and all the entries of the child
2731
/// trie are removed, the child trie must implicitly be destroyed.
2732
///
2733
/// If [`ExternalStorageClearPrefix::child_trie`] return `None` and the prefix returned by
2734
/// [`ExternalStorageClearPrefix::prefix`] intersects with `:child_storage:`, then the clearing
2735
/// must be silently ignored.
2736
pub struct ExternalStorageClearPrefix {
2737
    inner: Box<Inner>,
2738
    /// Function currently being called by the Wasm code. Refers to an index within
2739
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
2740
    calling: usize,
2741
2742
    /// Pointer and size to the prefix. `None` if `&[]`. Guaranteed to be in range.
2743
    prefix_ptr_size: Option<(u32, u32)>,
2744
    /// Pointer and size to the default child trie. `None` if main trie. Guaranteed to be in range.
2745
    child_trie_ptr_size: Option<(u32, u32)>,
2746
2747
    /// Maximum number of keys to remove.
2748
    max_keys_to_remove: Option<u32>,
2749
}
2750
2751
impl ExternalStorageClearPrefix {
2752
    /// Returns the prefix whose keys must be removed.
2753
35
    pub fn prefix(&'_ self) -> impl AsRef<[u8]> + '_ {
2754
35
        if let Some((
prefix_ptr, prefix_size31
)) = self.prefix_ptr_size {
2755
31
            either::Left(
2756
31
                self.inner
2757
31
                    .vm
2758
31
                    .read_memory(prefix_ptr, prefix_size)
2759
31
                    .unwrap_or_else(|_| 
unreachable!()0
),
Unexecuted instantiation: _RNCNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalStorageClearPrefix6prefix0Bb_
Unexecuted instantiation: _RNCNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalStorageClearPrefix6prefix0Bb_
2760
31
            )
2761
        } else {
2762
4
            either::Right(&[][..])
2763
        }
2764
35
    }
_RNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix6prefix
Line
Count
Source
2753
35
    pub fn prefix(&'_ self) -> impl AsRef<[u8]> + '_ {
2754
35
        if let Some((
prefix_ptr, prefix_size31
)) = self.prefix_ptr_size {
2755
31
            either::Left(
2756
31
                self.inner
2757
31
                    .vm
2758
31
                    .read_memory(prefix_ptr, prefix_size)
2759
31
                    .unwrap_or_else(|_| unreachable!()),
2760
31
            )
2761
        } else {
2762
4
            either::Right(&[][..])
2763
        }
2764
35
    }
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix6prefix
2765
2766
    /// If `Some`, write to the given child trie. If `None`, write to the main trie.
2767
    ///
2768
    /// If [`ExternalStorageClearPrefix::child_trie`] returns `Some` and all the entries of the
2769
    /// child trie are removed, the child trie must implicitly be destroyed.
2770
49
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2771
49
        if let Some((
child_trie_ptr, child_trie_size7
)) = self.child_trie_ptr_size {
2772
7
            let child_trie = self
2773
7
                .inner
2774
7
                .vm
2775
7
                .read_memory(child_trie_ptr, child_trie_size)
2776
7
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalStorageClearPrefix10child_trie0Bb_
Unexecuted instantiation: _RNCNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalStorageClearPrefix10child_trie0Bb_
2777
7
            Some(child_trie)
2778
        } else {
2779
42
            None
2780
        }
2781
49
    }
_RNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix10child_trie
Line
Count
Source
2770
49
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2771
49
        if let Some((
child_trie_ptr, child_trie_size7
)) = self.child_trie_ptr_size {
2772
7
            let child_trie = self
2773
7
                .inner
2774
7
                .vm
2775
7
                .read_memory(child_trie_ptr, child_trie_size)
2776
7
                .unwrap_or_else(|_| unreachable!());
2777
7
            Some(child_trie)
2778
        } else {
2779
42
            None
2780
        }
2781
49
    }
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix10child_trie
2782
2783
    /// Returns the maximum number of keys to remove. `None` means "infinity".
2784
9
    pub fn max_keys_to_remove(&self) -> Option<u32> {
2785
9
        self.max_keys_to_remove
2786
9
    }
_RNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix18max_keys_to_remove
Line
Count
Source
2784
9
    pub fn max_keys_to_remove(&self) -> Option<u32> {
2785
9
        self.max_keys_to_remove
2786
9
    }
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix18max_keys_to_remove
2787
2788
    /// Resumes execution after having cleared the values.
2789
    ///
2790
    /// Must be passed how many keys have been cleared, and whether some keys remaining to be
2791
    /// cleared.
2792
6
    pub fn resume(self, num_cleared: u32, some_keys_remain: bool) -> HostVm {
2793
6
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2794
6
            FunctionImport::Resolved(f) => f,
2795
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2796
        };
2797
2798
6
        match host_fn {
2799
            HostFunction::ext_storage_clear_prefix_version_1
2800
            | HostFunction::ext_default_child_storage_clear_prefix_version_1
2801
            | HostFunction::ext_default_child_storage_storage_kill_version_1 => {
2802
1
                HostVm::ReadyToRun(ReadyToRun {
2803
1
                    inner: self.inner,
2804
1
                    resume_value: None,
2805
1
                })
2806
            }
2807
            HostFunction::ext_default_child_storage_storage_kill_version_2 => {
2808
                HostVm::ReadyToRun(ReadyToRun {
2809
0
                    inner: self.inner,
2810
0
                    resume_value: Some(vm::WasmValue::I32(if some_keys_remain { 0 } else { 1 })),
2811
                })
2812
            }
2813
            HostFunction::ext_storage_clear_prefix_version_2
2814
            | HostFunction::ext_default_child_storage_clear_prefix_version_2
2815
            | HostFunction::ext_default_child_storage_storage_kill_version_3 => {
2816
5
                self.inner.alloc_write_and_return_pointer_size(
2817
5
                    host_fn.name(),
2818
5
                    [
2819
5
                        either::Left(if some_keys_remain { 
[1u8]0
} else { [0u8] }),
2820
5
                        either::Right(num_cleared.to_le_bytes()),
2821
5
                    ]
2822
5
                    .into_iter(),
2823
                )
2824
            }
2825
0
            _ => unreachable!(),
2826
        }
2827
6
    }
_RNvMsc_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix6resume
Line
Count
Source
2792
6
    pub fn resume(self, num_cleared: u32, some_keys_remain: bool) -> HostVm {
2793
6
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2794
6
            FunctionImport::Resolved(f) => f,
2795
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2796
        };
2797
2798
6
        match host_fn {
2799
            HostFunction::ext_storage_clear_prefix_version_1
2800
            | HostFunction::ext_default_child_storage_clear_prefix_version_1
2801
            | HostFunction::ext_default_child_storage_storage_kill_version_1 => {
2802
1
                HostVm::ReadyToRun(ReadyToRun {
2803
1
                    inner: self.inner,
2804
1
                    resume_value: None,
2805
1
                })
2806
            }
2807
            HostFunction::ext_default_child_storage_storage_kill_version_2 => {
2808
                HostVm::ReadyToRun(ReadyToRun {
2809
0
                    inner: self.inner,
2810
0
                    resume_value: Some(vm::WasmValue::I32(if some_keys_remain { 0 } else { 1 })),
2811
                })
2812
            }
2813
            HostFunction::ext_storage_clear_prefix_version_2
2814
            | HostFunction::ext_default_child_storage_clear_prefix_version_2
2815
            | HostFunction::ext_default_child_storage_storage_kill_version_3 => {
2816
5
                self.inner.alloc_write_and_return_pointer_size(
2817
5
                    host_fn.name(),
2818
5
                    [
2819
5
                        either::Left(if some_keys_remain { 
[1u8]0
} else { [0u8] }),
2820
5
                        either::Right(num_cleared.to_le_bytes()),
2821
5
                    ]
2822
5
                    .into_iter(),
2823
                )
2824
            }
2825
0
            _ => unreachable!(),
2826
        }
2827
6
    }
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefix6resume
2828
}
2829
2830
impl fmt::Debug for ExternalStorageClearPrefix {
2831
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2832
0
        f.debug_tuple("ExternalStorageClearPrefix").finish()
2833
0
    }
Unexecuted instantiation: _RNvXsd_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefixNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsd_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalStorageClearPrefixNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2834
}
2835
2836
/// Must provide the trie root hash of the storage and write the trie root hash of child tries
2837
/// to the main trie.
2838
///
2839
/// If [`ExternalStorageRoot::child_trie`] returns `Some` and the child trie is non-empty, the
2840
/// trie root hash of the child trie must also be written to the main trie at the key
2841
/// `concat(":child_storage:default:", child_trie)`.
2842
/// If [`ExternalStorageRoot::child_trie`] returns `Some` and the child trie is empty, the entry
2843
/// in the main trie at the key `concat(":child_storage:default:", child_trie)` must be removed.
2844
///
2845
/// If [`ExternalStorageRoot::child_trie`] returns `None`, the same operation as above must be
2846
/// done for every single child trie that has been modified in one way or the other during the
2847
/// runtime call.
2848
pub struct ExternalStorageRoot {
2849
    inner: Box<Inner>,
2850
2851
    /// Function currently being called by the Wasm code. Refers to an index within
2852
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
2853
    calling: usize,
2854
2855
    /// Pointer and size of the child trie, if any. Guaranteed to be in range.
2856
    child_trie_ptr_size: Option<(u32, u32)>,
2857
}
2858
2859
impl ExternalStorageRoot {
2860
    /// Returns the child trie whose root hash must be provided. `None` for the main trie.
2861
20
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2862
20
        if let Some((
ptr, size0
)) = self.child_trie_ptr_size {
2863
0
            let child_trie = self
2864
0
                .inner
2865
0
                .vm
2866
0
                .read_memory(ptr, size)
2867
0
                .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvMse_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_19ExternalStorageRoot10child_trie0Bb_
Unexecuted instantiation: _RNCNvMse_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_19ExternalStorageRoot10child_trie0Bb_
2868
0
            Some(child_trie)
2869
        } else {
2870
20
            None
2871
        }
2872
20
    }
_RNvMse_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_19ExternalStorageRoot10child_trie
Line
Count
Source
2861
20
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2862
20
        if let Some((
ptr, size0
)) = self.child_trie_ptr_size {
2863
0
            let child_trie = self
2864
0
                .inner
2865
0
                .vm
2866
0
                .read_memory(ptr, size)
2867
0
                .unwrap_or_else(|_| unreachable!());
2868
0
            Some(child_trie)
2869
        } else {
2870
20
            None
2871
        }
2872
20
    }
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_19ExternalStorageRoot10child_trie
2873
2874
    /// Writes the trie root hash to the Wasm VM and prepares it for resume.
2875
    ///
2876
    /// If [`ExternalStorageRoot::child_trie`] returns `Some` but the child trie doesn't exist,
2877
    /// the root hash of an empty trie must be provided.
2878
5
    pub fn resume(self, hash: &[u8; 32]) -> HostVm {
2879
5
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2880
5
            FunctionImport::Resolved(f) => f,
2881
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2882
        };
2883
2884
5
        self.inner
2885
5
            .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(hash))
2886
5
    }
_RNvMse_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_19ExternalStorageRoot6resume
Line
Count
Source
2878
5
    pub fn resume(self, hash: &[u8; 32]) -> HostVm {
2879
5
        let host_fn = match self.inner.common.registered_functions[self.calling] {
2880
5
            FunctionImport::Resolved(f) => f,
2881
0
            FunctionImport::Unresolved { .. } => unreachable!(),
2882
        };
2883
2884
5
        self.inner
2885
5
            .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(hash))
2886
5
    }
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_19ExternalStorageRoot6resume
2887
}
2888
2889
impl fmt::Debug for ExternalStorageRoot {
2890
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2891
0
        f.debug_tuple("ExternalStorageRoot").finish()
2892
0
    }
Unexecuted instantiation: _RNvXsf_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_19ExternalStorageRootNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsf_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_19ExternalStorageRootNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2893
}
2894
2895
/// Must provide the storage key that follows, in lexicographic order, a specific one.
2896
pub struct ExternalStorageNextKey {
2897
    inner: Box<Inner>,
2898
2899
    /// Pointer to the key whose follow-up must be found. Guaranteed to be in range.
2900
    key_ptr: u32,
2901
    /// Size of the key whose follow-up must be found. Guaranteed to be in range.
2902
    key_size: u32,
2903
    /// Pointer and size of the child trie, if any. Guaranteed to be in range.
2904
    child_trie_ptr_size: Option<(u32, u32)>,
2905
}
2906
2907
impl ExternalStorageNextKey {
2908
    /// Returns the key whose following key must be returned.
2909
2
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2910
2
        self.inner
2911
2
            .vm
2912
2
            .read_memory(self.key_ptr, self.key_size)
2913
2
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_22ExternalStorageNextKey3key0Bb_
Unexecuted instantiation: _RNCNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_22ExternalStorageNextKey3key0Bb_
2914
2
    }
_RNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_22ExternalStorageNextKey3key
Line
Count
Source
2909
2
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
2910
2
        self.inner
2911
2
            .vm
2912
2
            .read_memory(self.key_ptr, self.key_size)
2913
2
            .unwrap_or_else(|_| unreachable!())
2914
2
    }
Unexecuted instantiation: _RNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_22ExternalStorageNextKey3key
2915
2916
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
2917
3
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2918
3
        if let Some((
child_trie_ptr, child_trie_size0
)) = self.child_trie_ptr_size {
2919
0
            let child_trie = self
2920
0
                .inner
2921
0
                .vm
2922
0
                .read_memory(child_trie_ptr, child_trie_size)
2923
0
                .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_22ExternalStorageNextKey10child_trie0Bb_
Unexecuted instantiation: _RNCNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_22ExternalStorageNextKey10child_trie0Bb_
2924
0
            Some(child_trie)
2925
        } else {
2926
3
            None
2927
        }
2928
3
    }
_RNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_22ExternalStorageNextKey10child_trie
Line
Count
Source
2917
3
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
2918
3
        if let Some((
child_trie_ptr, child_trie_size0
)) = self.child_trie_ptr_size {
2919
0
            let child_trie = self
2920
0
                .inner
2921
0
                .vm
2922
0
                .read_memory(child_trie_ptr, child_trie_size)
2923
0
                .unwrap_or_else(|_| unreachable!());
2924
0
            Some(child_trie)
2925
        } else {
2926
3
            None
2927
        }
2928
3
    }
Unexecuted instantiation: _RNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_22ExternalStorageNextKey10child_trie
2929
2930
    /// Writes the follow-up key in the Wasm VM memory and prepares it for execution.
2931
    ///
2932
    /// Must be passed `None` if the key is the last one in the storage or if
2933
    /// [`ExternalStorageNextKey`] returns `Some` and the child trie doesn't exist.
2934
1
    pub fn resume(self, follow_up: Option<&[u8]>) -> HostVm {
2935
1
        let key = self
2936
1
            .inner
2937
1
            .vm
2938
1
            .read_memory(self.key_ptr, self.key_size)
2939
1
            .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_22ExternalStorageNextKey6resume0Bb_
Unexecuted instantiation: _RNCNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_22ExternalStorageNextKey6resume0Bb_
2940
1
2941
1
        match follow_up {
2942
1
            Some(next) => {
2943
1
                debug_assert!(key.as_ref() < next);
2944
2945
1
                let value_len_enc = util::encode_scale_compact_usize(next.len());
2946
1
                drop(key);
2947
1
                self.inner.alloc_write_and_return_pointer_size(
2948
1
                    HostFunction::ext_storage_next_key_version_1.name(), // TODO: no
2949
1
                    iter::once(&[1][..])
2950
1
                        .chain(iter::once(value_len_enc.as_ref()))
2951
1
                        .chain(iter::once(next)),
2952
1
                )
2953
            }
2954
            None => {
2955
                // Write a SCALE-encoded `None`.
2956
0
                drop(key);
2957
0
                self.inner.alloc_write_and_return_pointer_size(
2958
0
                    HostFunction::ext_storage_next_key_version_1.name(), // TODO: no
2959
0
                    iter::once(&[0]),
2960
0
                )
2961
            }
2962
        }
2963
1
    }
_RNvMsg_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_22ExternalStorageNextKey6resume
Line
Count
Source
2934
1
    pub fn resume(self, follow_up: Option<&[u8]>) -> HostVm {
2935
1
        let key = self
2936
1
            .inner
2937
1
            .vm
2938
1
            .read_memory(self.key_ptr, self.key_size)
2939
1
            .unwrap_or_else(|_| unreachable!());
2940
1
2941
1
        match follow_up {
2942
1
            Some(next) => {
2943
1
                debug_assert!(key.as_ref() < next);
2944
2945
1
                let value_len_enc = util::encode_scale_compact_usize(next.len());
2946
1
                drop(key);
2947
1
                self.inner.alloc_write_and_return_pointer_size(
2948
1
                    HostFunction::ext_storage_next_key_version_1.name(), // TODO: no
2949
1
                    iter::once(&[1][..])
2950
1
                        .chain(iter::once(value_len_enc.as_ref()))
2951
1
                        .chain(iter::once(next)),
2952
1
                )
2953
            }
2954
            None => {
2955
                // Write a SCALE-encoded `None`.
2956
0
                drop(key);
2957
0
                self.inner.alloc_write_and_return_pointer_size(
2958
0
                    HostFunction::ext_storage_next_key_version_1.name(), // TODO: no
2959
0
                    iter::once(&[0]),
2960
0
                )
2961
            }
2962
        }
2963
1
    }
Unexecuted instantiation: _RNvMsg_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_22ExternalStorageNextKey6resume
2964
}
2965
2966
impl fmt::Debug for ExternalStorageNextKey {
2967
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2968
0
        f.debug_tuple("ExternalStorageNextKey").finish()
2969
0
    }
Unexecuted instantiation: _RNvXsh_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_22ExternalStorageNextKeyNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsh_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_22ExternalStorageNextKeyNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
2970
}
2971
2972
/// Must verify whether a signature is correct.
2973
pub struct SignatureVerification {
2974
    inner: Box<Inner>,
2975
    /// Which cryptographic algorithm.
2976
    algorithm: SignatureVerificationAlgorithm,
2977
    /// Pointer to the signature. The size of the signature depends on the algorithm. Guaranteed
2978
    /// to be in range.
2979
    signature_ptr: u32,
2980
    /// Pointer to the public key. The size of the public key depends on the algorithm. Guaranteed
2981
    /// to be in range.
2982
    public_key_ptr: u32,
2983
    /// Pointer to the message. Guaranteed to be in range.
2984
    message_ptr: u32,
2985
    /// Size of the message. Guaranteed to be in range.
2986
    message_size: u32,
2987
    /// `true` if the host function is a batch verification function.
2988
    is_batch_verification: bool,
2989
}
2990
2991
enum SignatureVerificationAlgorithm {
2992
    Ed25519,
2993
    Sr25519V1,
2994
    Sr25519V2,
2995
    Ecdsa,
2996
    EcdsaPrehashed,
2997
}
2998
2999
impl SignatureVerification {
3000
    /// Returns the message that the signature is expected to sign.
3001
6
    pub fn message(&'_ self) -> impl AsRef<[u8]> + '_ {
3002
6
        self.inner
3003
6
            .vm
3004
6
            .read_memory(self.message_ptr, self.message_size)
3005
6
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification7message0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification7message0Bb_
3006
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification7message
Line
Count
Source
3001
6
    pub fn message(&'_ self) -> impl AsRef<[u8]> + '_ {
3002
6
        self.inner
3003
6
            .vm
3004
6
            .read_memory(self.message_ptr, self.message_size)
3005
6
            .unwrap_or_else(|_| unreachable!())
3006
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification7message
3007
3008
    /// Returns the signature.
3009
    ///
3010
    /// > **Note**: Be aware that this signature is untrusted input and might not be part of the
3011
    /// >           set of valid signatures.
3012
6
    pub fn signature(&'_ self) -> impl AsRef<[u8]> + '_ {
3013
6
        let signature_size = match self.algorithm {
3014
0
            SignatureVerificationAlgorithm::Ed25519 => 64,
3015
0
            SignatureVerificationAlgorithm::Sr25519V1 => 64,
3016
6
            SignatureVerificationAlgorithm::Sr25519V2 => 64,
3017
0
            SignatureVerificationAlgorithm::Ecdsa => 65,
3018
0
            SignatureVerificationAlgorithm::EcdsaPrehashed => 65,
3019
        };
3020
3021
6
        self.inner
3022
6
            .vm
3023
6
            .read_memory(self.signature_ptr, signature_size)
3024
6
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification9signature0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification9signature0Bb_
3025
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification9signature
Line
Count
Source
3012
6
    pub fn signature(&'_ self) -> impl AsRef<[u8]> + '_ {
3013
6
        let signature_size = match self.algorithm {
3014
0
            SignatureVerificationAlgorithm::Ed25519 => 64,
3015
0
            SignatureVerificationAlgorithm::Sr25519V1 => 64,
3016
6
            SignatureVerificationAlgorithm::Sr25519V2 => 64,
3017
0
            SignatureVerificationAlgorithm::Ecdsa => 65,
3018
0
            SignatureVerificationAlgorithm::EcdsaPrehashed => 65,
3019
        };
3020
3021
6
        self.inner
3022
6
            .vm
3023
6
            .read_memory(self.signature_ptr, signature_size)
3024
6
            .unwrap_or_else(|_| unreachable!())
3025
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification9signature
3026
3027
    /// Returns the public key the signature is against.
3028
    ///
3029
    /// > **Note**: Be aware that this public key is untrusted input and might not be part of the
3030
    /// >           set of valid public keys.
3031
6
    pub fn public_key(&'_ self) -> impl AsRef<[u8]> + '_ {
3032
6
        let public_key_size = match self.algorithm {
3033
0
            SignatureVerificationAlgorithm::Ed25519 => 32,
3034
0
            SignatureVerificationAlgorithm::Sr25519V1 => 32,
3035
6
            SignatureVerificationAlgorithm::Sr25519V2 => 32,
3036
0
            SignatureVerificationAlgorithm::Ecdsa => 33,
3037
0
            SignatureVerificationAlgorithm::EcdsaPrehashed => 33,
3038
        };
3039
3040
6
        self.inner
3041
6
            .vm
3042
6
            .read_memory(self.public_key_ptr, public_key_size)
3043
6
            .unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification10public_key0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification10public_key0Bb_
3044
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification10public_key
Line
Count
Source
3031
6
    pub fn public_key(&'_ self) -> impl AsRef<[u8]> + '_ {
3032
6
        let public_key_size = match self.algorithm {
3033
0
            SignatureVerificationAlgorithm::Ed25519 => 32,
3034
0
            SignatureVerificationAlgorithm::Sr25519V1 => 32,
3035
6
            SignatureVerificationAlgorithm::Sr25519V2 => 32,
3036
0
            SignatureVerificationAlgorithm::Ecdsa => 33,
3037
0
            SignatureVerificationAlgorithm::EcdsaPrehashed => 33,
3038
        };
3039
3040
6
        self.inner
3041
6
            .vm
3042
6
            .read_memory(self.public_key_ptr, public_key_size)
3043
6
            .unwrap_or_else(|_| unreachable!())
3044
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification10public_key
3045
3046
    /// Verify the signature. Returns `true` if it is valid.
3047
6
    pub fn is_valid(&self) -> bool {
3048
6
        match self.algorithm {
3049
            SignatureVerificationAlgorithm::Ed25519 => {
3050
0
                let public_key =
3051
0
                    ed25519_zebra::VerificationKey::try_from(self.public_key().as_ref());
3052
3053
0
                if let Ok(public_key) = public_key {
3054
0
                    let signature = ed25519_zebra::Signature::from(
3055
0
                        <[u8; 64]>::try_from(self.signature().as_ref())
3056
0
                            .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valid0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valid0Bb_
3057
0
                    );
3058
0
                    public_key
3059
0
                        .verify(&signature, self.message().as_ref())
3060
0
                        .is_ok()
3061
                } else {
3062
0
                    false
3063
                }
3064
            }
3065
            SignatureVerificationAlgorithm::Sr25519V1 => {
3066
0
                schnorrkel::PublicKey::from_bytes(self.public_key().as_ref()).map_or(false, |pk| {
3067
0
                    pk.verify_simple_preaudit_deprecated(
3068
0
                        b"substrate",
3069
0
                        self.message().as_ref(),
3070
0
                        self.signature().as_ref(),
3071
0
                    )
3072
0
                    .is_ok()
3073
0
                })
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids_0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids_0Bb_
3074
            }
3075
            SignatureVerificationAlgorithm::Sr25519V2 => {
3076
6
                schnorrkel::PublicKey::from_bytes(self.public_key().as_ref()).map_or(false, |pk| {
3077
6
                    pk.verify_simple(
3078
6
                        b"substrate",
3079
6
                        self.message().as_ref(),
3080
6
                        &schnorrkel::Signature::from_bytes(self.signature().as_ref())
3081
6
                            .unwrap_or_else(|_| 
unreachable!()0
),
Unexecuted instantiation: _RNCNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB9_21SignatureVerification8is_valids0_00Bd_
Unexecuted instantiation: _RNCNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB9_21SignatureVerification8is_valids0_00Bd_
3082
6
                    )
3083
6
                    .is_ok()
3084
6
                })
_RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids0_0Bb_
Line
Count
Source
3076
6
                schnorrkel::PublicKey::from_bytes(self.public_key().as_ref()).map_or(false, |pk| {
3077
6
                    pk.verify_simple(
3078
6
                        b"substrate",
3079
6
                        self.message().as_ref(),
3080
6
                        &schnorrkel::Signature::from_bytes(self.signature().as_ref())
3081
6
                            .unwrap_or_else(|_| unreachable!()),
3082
6
                    )
3083
6
                    .is_ok()
3084
6
                })
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids0_0Bb_
3085
            }
3086
            SignatureVerificationAlgorithm::Ecdsa => {
3087
                // NOTE: safe to unwrap here because we supply the nn to blake2b fn
3088
0
                let data = <[u8; 32]>::try_from(
3089
0
                    blake2_rfc::blake2b::blake2b(32, &[], self.message().as_ref()).as_bytes(),
3090
0
                )
3091
0
                .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids1_0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids1_0Bb_
3092
0
                let message = libsecp256k1::Message::parse(&data);
3093
0
3094
0
                // signature (64 bytes) + recovery ID (1 byte)
3095
0
                let sig_bytes = self.signature();
3096
0
                libsecp256k1::Signature::parse_standard_slice(&sig_bytes.as_ref()[..64])
3097
0
                    .and_then(|sig| {
3098
0
                        libsecp256k1::RecoveryId::parse(sig_bytes.as_ref()[64])
3099
0
                            .and_then(|ri| libsecp256k1::recover(&message, &sig, &ri))
Unexecuted instantiation: _RNCNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB9_21SignatureVerification8is_valids2_00Bd_
Unexecuted instantiation: _RNCNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB9_21SignatureVerification8is_valids2_00Bd_
3100
0
                    })
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids2_0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids2_0Bb_
3101
0
                    .map_or(false, |actual| {
3102
0
                        self.public_key().as_ref()[..] == actual.serialize_compressed()[..]
3103
0
                    })
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids3_0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids3_0Bb_
3104
            }
3105
            SignatureVerificationAlgorithm::EcdsaPrehashed => {
3106
                // We can safely unwrap, as the size is checked when the `SignatureVerification`
3107
                // is constructed.
3108
0
                let message = libsecp256k1::Message::parse(
3109
0
                    &<[u8; 32]>::try_from(self.message().as_ref())
3110
0
                        .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids4_0Bb_
Unexecuted instantiation: _RNCNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_21SignatureVerification8is_valids4_0Bb_
3111
0
                );
3112
0
3113
0
                // signature (64 bytes) + recovery ID (1 byte)
3114
0
                let sig_bytes = self.signature();
3115
0
                if let Ok(sig) =
3116
0
                    libsecp256k1::Signature::parse_standard_slice(&sig_bytes.as_ref()[..64])
3117
                {
3118
0
                    if let Ok(ri) = libsecp256k1::RecoveryId::parse(sig_bytes.as_ref()[64]) {
3119
0
                        if let Ok(actual) = libsecp256k1::recover(&message, &sig, &ri) {
3120
0
                            self.public_key().as_ref()[..] == actual.serialize_compressed()[..]
3121
                        } else {
3122
0
                            false
3123
                        }
3124
                    } else {
3125
0
                        false
3126
                    }
3127
                } else {
3128
0
                    false
3129
                }
3130
            }
3131
        }
3132
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification8is_valid
Line
Count
Source
3047
6
    pub fn is_valid(&self) -> bool {
3048
6
        match self.algorithm {
3049
            SignatureVerificationAlgorithm::Ed25519 => {
3050
0
                let public_key =
3051
0
                    ed25519_zebra::VerificationKey::try_from(self.public_key().as_ref());
3052
3053
0
                if let Ok(public_key) = public_key {
3054
0
                    let signature = ed25519_zebra::Signature::from(
3055
0
                        <[u8; 64]>::try_from(self.signature().as_ref())
3056
0
                            .unwrap_or_else(|_| unreachable!()),
3057
0
                    );
3058
0
                    public_key
3059
0
                        .verify(&signature, self.message().as_ref())
3060
0
                        .is_ok()
3061
                } else {
3062
0
                    false
3063
                }
3064
            }
3065
            SignatureVerificationAlgorithm::Sr25519V1 => {
3066
0
                schnorrkel::PublicKey::from_bytes(self.public_key().as_ref()).map_or(false, |pk| {
3067
                    pk.verify_simple_preaudit_deprecated(
3068
                        b"substrate",
3069
                        self.message().as_ref(),
3070
                        self.signature().as_ref(),
3071
                    )
3072
                    .is_ok()
3073
0
                })
3074
            }
3075
            SignatureVerificationAlgorithm::Sr25519V2 => {
3076
6
                schnorrkel::PublicKey::from_bytes(self.public_key().as_ref()).map_or(false, |pk| {
3077
                    pk.verify_simple(
3078
                        b"substrate",
3079
                        self.message().as_ref(),
3080
                        &schnorrkel::Signature::from_bytes(self.signature().as_ref())
3081
                            .unwrap_or_else(|_| unreachable!()),
3082
                    )
3083
                    .is_ok()
3084
6
                })
3085
            }
3086
            SignatureVerificationAlgorithm::Ecdsa => {
3087
                // NOTE: safe to unwrap here because we supply the nn to blake2b fn
3088
0
                let data = <[u8; 32]>::try_from(
3089
0
                    blake2_rfc::blake2b::blake2b(32, &[], self.message().as_ref()).as_bytes(),
3090
0
                )
3091
0
                .unwrap_or_else(|_| unreachable!());
3092
0
                let message = libsecp256k1::Message::parse(&data);
3093
0
3094
0
                // signature (64 bytes) + recovery ID (1 byte)
3095
0
                let sig_bytes = self.signature();
3096
0
                libsecp256k1::Signature::parse_standard_slice(&sig_bytes.as_ref()[..64])
3097
0
                    .and_then(|sig| {
3098
                        libsecp256k1::RecoveryId::parse(sig_bytes.as_ref()[64])
3099
                            .and_then(|ri| libsecp256k1::recover(&message, &sig, &ri))
3100
0
                    })
3101
0
                    .map_or(false, |actual| {
3102
                        self.public_key().as_ref()[..] == actual.serialize_compressed()[..]
3103
0
                    })
3104
            }
3105
            SignatureVerificationAlgorithm::EcdsaPrehashed => {
3106
                // We can safely unwrap, as the size is checked when the `SignatureVerification`
3107
                // is constructed.
3108
0
                let message = libsecp256k1::Message::parse(
3109
0
                    &<[u8; 32]>::try_from(self.message().as_ref())
3110
0
                        .unwrap_or_else(|_| unreachable!()),
3111
0
                );
3112
0
3113
0
                // signature (64 bytes) + recovery ID (1 byte)
3114
0
                let sig_bytes = self.signature();
3115
0
                if let Ok(sig) =
3116
0
                    libsecp256k1::Signature::parse_standard_slice(&sig_bytes.as_ref()[..64])
3117
                {
3118
0
                    if let Ok(ri) = libsecp256k1::RecoveryId::parse(sig_bytes.as_ref()[64]) {
3119
0
                        if let Ok(actual) = libsecp256k1::recover(&message, &sig, &ri) {
3120
0
                            self.public_key().as_ref()[..] == actual.serialize_compressed()[..]
3121
                        } else {
3122
0
                            false
3123
                        }
3124
                    } else {
3125
0
                        false
3126
                    }
3127
                } else {
3128
0
                    false
3129
                }
3130
            }
3131
        }
3132
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification8is_valid
3133
3134
    /// Verify the signature and resume execution.
3135
6
    pub fn verify_and_resume(self) -> HostVm {
3136
6
        let success = self.is_valid();
3137
6
        self.resume(success)
3138
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification17verify_and_resume
Line
Count
Source
3135
6
    pub fn verify_and_resume(self) -> HostVm {
3136
6
        let success = self.is_valid();
3137
6
        self.resume(success)
3138
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification17verify_and_resume
3139
3140
    /// Resume the execution assuming that the signature is valid.
3141
    ///
3142
    /// > **Note**: You are strongly encouraged to call
3143
    /// >           [`SignatureVerification::verify_and_resume`]. This function is meant to be
3144
    /// >           used only in debugging situations.
3145
0
    pub fn resume_success(self) -> HostVm {
3146
0
        self.resume(true)
3147
0
    }
Unexecuted instantiation: _RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification14resume_success
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification14resume_success
3148
3149
    /// Resume the execution assuming that the signature is invalid.
3150
    ///
3151
    /// > **Note**: You are strongly encouraged to call
3152
    /// >           [`SignatureVerification::verify_and_resume`]. This function is meant to be
3153
    /// >           used only in debugging situations.
3154
0
    pub fn resume_failed(self) -> HostVm {
3155
0
        self.resume(false)
3156
0
    }
Unexecuted instantiation: _RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification13resume_failed
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification13resume_failed
3157
3158
6
    fn resume(mut self, success: bool) -> HostVm {
3159
6
        debug_assert!(
3160
6
            !self.is_batch_verification || 
self.inner.signatures_batch_verification.is_some()0
3161
        );
3162
6
        if self.is_batch_verification && 
!success0
{
3163
0
            self.inner.signatures_batch_verification = Some(false);
3164
6
        }
3165
3166
        // All signature-related host functions work the same way in terms of return value.
3167
        HostVm::ReadyToRun(ReadyToRun {
3168
6
            resume_value: Some(vm::WasmValue::I32(if success { 1 } else { 
00
})),
3169
6
            inner: self.inner,
3170
6
        })
3171
6
    }
_RNvMsi_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerification6resume
Line
Count
Source
3158
6
    fn resume(mut self, success: bool) -> HostVm {
3159
6
        debug_assert!(
3160
6
            !self.is_batch_verification || 
self.inner.signatures_batch_verification.is_some()0
3161
        );
3162
6
        if self.is_batch_verification && 
!success0
{
3163
0
            self.inner.signatures_batch_verification = Some(false);
3164
6
        }
3165
3166
        // All signature-related host functions work the same way in terms of return value.
3167
        HostVm::ReadyToRun(ReadyToRun {
3168
6
            resume_value: Some(vm::WasmValue::I32(if success { 1 } else { 
00
})),
3169
6
            inner: self.inner,
3170
6
        })
3171
6
    }
Unexecuted instantiation: _RNvMsi_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerification6resume
3172
}
3173
3174
impl fmt::Debug for SignatureVerification {
3175
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3176
0
        f.debug_struct("SignatureVerification")
3177
0
            .field("message", &self.message().as_ref())
3178
0
            .field("signature", &self.signature().as_ref())
3179
0
            .field("public_key", &self.public_key().as_ref())
3180
0
            .finish()
3181
0
    }
Unexecuted instantiation: _RNvXsj_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21SignatureVerificationNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsj_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21SignatureVerificationNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3182
}
3183
3184
/// Must provide the runtime version obtained by calling the `Core_version` entry point of a Wasm
3185
/// blob.
3186
pub struct CallRuntimeVersion {
3187
    inner: Box<Inner>,
3188
3189
    /// Pointer to the wasm code whose runtime version must be provided. Guaranteed to be in range.
3190
    wasm_blob_ptr: u32,
3191
    /// Size of the wasm code whose runtime version must be provided. Guaranteed to be in range.
3192
    wasm_blob_size: u32,
3193
}
3194
3195
impl CallRuntimeVersion {
3196
    /// Returns the Wasm code whose runtime version must be provided.
3197
0
    pub fn wasm_code(&'_ self) -> impl AsRef<[u8]> + '_ {
3198
0
        self.inner
3199
0
            .vm
3200
0
            .read_memory(self.wasm_blob_ptr, self.wasm_blob_size)
3201
0
            .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMsk_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_18CallRuntimeVersion9wasm_code0Bb_
Unexecuted instantiation: _RNCNvMsk_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_18CallRuntimeVersion9wasm_code0Bb_
3202
0
    }
Unexecuted instantiation: _RNvMsk_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18CallRuntimeVersion9wasm_code
Unexecuted instantiation: _RNvMsk_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18CallRuntimeVersion9wasm_code
3203
3204
    /// Writes the SCALE-encoded runtime version to the memory and prepares for execution.
3205
    ///
3206
    /// If an error happened during the execution (such as an invalid Wasm binary code), pass
3207
    /// an `Err`.
3208
0
    pub fn resume(self, scale_encoded_runtime_version: Result<&[u8], ()>) -> HostVm {
3209
0
        if let Ok(scale_encoded_runtime_version) = scale_encoded_runtime_version {
3210
0
            self.inner.alloc_write_and_return_pointer_size(
3211
0
                HostFunction::ext_misc_runtime_version_version_1.name(),
3212
0
                iter::once(either::Left([1]))
3213
0
                    .chain(iter::once(either::Right(either::Left(
3214
0
                        util::encode_scale_compact_usize(scale_encoded_runtime_version.len()),
3215
0
                    ))))
3216
0
                    .chain(iter::once(either::Right(either::Right(
3217
0
                        scale_encoded_runtime_version,
3218
0
                    )))),
3219
0
            )
3220
        } else {
3221
0
            self.inner.alloc_write_and_return_pointer_size(
3222
0
                HostFunction::ext_misc_runtime_version_version_1.name(),
3223
0
                iter::once([0]),
3224
0
            )
3225
        }
3226
0
    }
Unexecuted instantiation: _RNvMsk_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18CallRuntimeVersion6resume
Unexecuted instantiation: _RNvMsk_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18CallRuntimeVersion6resume
3227
}
3228
3229
impl fmt::Debug for CallRuntimeVersion {
3230
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3231
0
        f.debug_tuple("CallRuntimeVersion").finish()
3232
0
    }
Unexecuted instantiation: _RNvXsl_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18CallRuntimeVersionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsl_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18CallRuntimeVersionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3233
}
3234
3235
/// Must set off-chain index value.
3236
pub struct ExternalOffchainIndexSet {
3237
    inner: Box<Inner>,
3238
3239
    /// Pointer to the key whose value must be set. Guaranteed to be in range.
3240
    key_ptr: u32,
3241
    /// Size of the key whose value must be set. Guaranteed to be in range.
3242
    key_size: u32,
3243
3244
    /// Pointer and size of the value to set. `None` for clearing. Guaranteed to be in range.
3245
    value: Option<(u32, u32)>,
3246
}
3247
3248
impl ExternalOffchainIndexSet {
3249
    /// Returns the key whose value must be set.
3250
0
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
3251
0
        self.inner
3252
0
            .vm
3253
0
            .read_memory(self.key_ptr, self.key_size)
3254
0
            .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMsm_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_24ExternalOffchainIndexSet3key0Bb_
Unexecuted instantiation: _RNCNvMsm_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_24ExternalOffchainIndexSet3key0Bb_
3255
0
    }
Unexecuted instantiation: _RNvMsm_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet3key
Unexecuted instantiation: _RNvMsm_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet3key
3256
3257
    /// Returns the value to set.
3258
    ///
3259
    /// If `None` is returned, the key should be removed from the storage entirely.
3260
0
    pub fn value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
3261
0
        if let Some((ptr, size)) = self.value {
3262
0
            Some(
3263
0
                self.inner
3264
0
                    .vm
3265
0
                    .read_memory(ptr, size)
3266
0
                    .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsm_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_24ExternalOffchainIndexSet5value0Bb_
Unexecuted instantiation: _RNCNvMsm_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_24ExternalOffchainIndexSet5value0Bb_
3267
0
            )
3268
        } else {
3269
0
            None
3270
        }
3271
0
    }
Unexecuted instantiation: _RNvMsm_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet5value
Unexecuted instantiation: _RNvMsm_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet5value
3272
3273
    /// Resumes execution after having set the value.
3274
0
    pub fn resume(self) -> HostVm {
3275
0
        HostVm::ReadyToRun(ReadyToRun {
3276
0
            inner: self.inner,
3277
0
            resume_value: None,
3278
0
        })
3279
0
    }
Unexecuted instantiation: _RNvMsm_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet6resume
Unexecuted instantiation: _RNvMsm_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSet6resume
3280
}
3281
3282
impl fmt::Debug for ExternalOffchainIndexSet {
3283
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3284
0
        f.debug_tuple("ExternalOffchainIndexSet").finish()
3285
0
    }
Unexecuted instantiation: _RNvXsn_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsn_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_24ExternalOffchainIndexSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3286
}
3287
3288
/// Must set the value of the off-chain storage.
3289
pub struct ExternalOffchainStorageSet {
3290
    inner: Box<Inner>,
3291
3292
    /// Pointer to the key whose value must be set. Guaranteed to be in range.
3293
    key_ptr: u32,
3294
    /// Size of the key whose value must be set. Guaranteed to be in range.
3295
    key_size: u32,
3296
3297
    /// Pointer and size of the value to set. `None` for clearing. Guaranteed to be in range.
3298
    value: Option<(u32, u32)>,
3299
3300
    /// Pointer and size of the old value to compare. Guaranteed to be in range.
3301
    old_value: Option<(u32, u32)>,
3302
}
3303
3304
impl ExternalOffchainStorageSet {
3305
    /// Returns the key whose value must be set.
3306
0
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
3307
0
        self.inner
3308
0
            .vm
3309
0
            .read_memory(self.key_ptr, self.key_size)
3310
0
            .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet3key0Bb_
Unexecuted instantiation: _RNCNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet3key0Bb_
3311
0
    }
Unexecuted instantiation: _RNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet3key
Unexecuted instantiation: _RNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet3key
3312
3313
    /// Returns the value to set.
3314
    ///
3315
    /// If `None` is returned, the key should be removed from the storage entirely.
3316
0
    pub fn value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
3317
0
        if let Some((ptr, size)) = self.value {
3318
0
            Some(
3319
0
                self.inner
3320
0
                    .vm
3321
0
                    .read_memory(ptr, size)
3322
0
                    .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet5value0Bb_
Unexecuted instantiation: _RNCNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet5value0Bb_
3323
0
            )
3324
        } else {
3325
0
            None
3326
        }
3327
0
    }
Unexecuted instantiation: _RNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet5value
Unexecuted instantiation: _RNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet5value
3328
3329
    /// Returns the value the current value should be compared against. The operation is a no-op if they don't compare equal.
3330
0
    pub fn old_value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
3331
0
        if let Some((ptr, size)) = self.old_value {
3332
0
            Some(
3333
0
                self.inner
3334
0
                    .vm
3335
0
                    .read_memory(ptr, size)
3336
0
                    .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet9old_value0Bb_
Unexecuted instantiation: _RNCNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalOffchainStorageSet9old_value0Bb_
3337
0
            )
3338
        } else {
3339
0
            None
3340
        }
3341
0
    }
Unexecuted instantiation: _RNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet9old_value
Unexecuted instantiation: _RNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet9old_value
3342
3343
    /// Resumes execution after having set the value. Must indicate whether a value was written.
3344
0
    pub fn resume(self, replaced: bool) -> HostVm {
3345
0
        if self.old_value.is_some() {
3346
            HostVm::ReadyToRun(ReadyToRun {
3347
0
                inner: self.inner,
3348
0
                resume_value: Some(vm::WasmValue::I32(if replaced { 1 } else { 0 })),
3349
            })
3350
        } else {
3351
0
            HostVm::ReadyToRun(ReadyToRun {
3352
0
                inner: self.inner,
3353
0
                resume_value: None,
3354
0
            })
3355
        }
3356
0
    }
Unexecuted instantiation: _RNvMso_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet6resume
Unexecuted instantiation: _RNvMso_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSet6resume
3357
}
3358
3359
impl fmt::Debug for ExternalOffchainStorageSet {
3360
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3361
0
        f.debug_tuple("ExternalOffchainStorageSet").finish()
3362
0
    }
Unexecuted instantiation: _RNvXsp_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsp_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageSetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3363
}
3364
3365
/// Must get the value of the off-chain storage.
3366
pub struct ExternalOffchainStorageGet {
3367
    inner: Box<Inner>,
3368
3369
    /// Function currently being called by the Wasm code. Refers to an index within
3370
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
3371
    calling: usize,
3372
3373
    /// Pointer to the key whose value must be loaded. Guaranteed to be in range.
3374
    key_ptr: u32,
3375
    /// Size of the key whose value must be loaded. Guaranteed to be in range.
3376
    key_size: u32,
3377
}
3378
3379
impl ExternalOffchainStorageGet {
3380
    /// Returns the key whose value must be loaded.
3381
0
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
3382
0
        self.inner
3383
0
            .vm
3384
0
            .read_memory(self.key_ptr, self.key_size)
3385
0
            .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMsq_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_26ExternalOffchainStorageGet3key0Bb_
Unexecuted instantiation: _RNCNvMsq_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_26ExternalOffchainStorageGet3key0Bb_
3386
0
    }
Unexecuted instantiation: _RNvMsq_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGet3key
Unexecuted instantiation: _RNvMsq_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGet3key
3387
3388
    /// Resumes execution after having set the value.
3389
0
    pub fn resume(self, value: Option<&[u8]>) -> HostVm {
3390
0
        let host_fn = match self.inner.common.registered_functions[self.calling] {
3391
0
            FunctionImport::Resolved(f) => f,
3392
0
            FunctionImport::Unresolved { .. } => unreachable!(),
3393
        };
3394
3395
0
        if let Some(value) = value {
3396
0
            let value_len_enc = util::encode_scale_compact_usize(value.len());
3397
0
            self.inner.alloc_write_and_return_pointer_size(
3398
0
                host_fn.name(),
3399
0
                iter::once(&[1][..])
3400
0
                    .chain(iter::once(value_len_enc.as_ref()))
3401
0
                    .map(either::Left)
3402
0
                    .chain(iter::once(value).map(either::Right)),
3403
0
            )
3404
        } else {
3405
            // Write a SCALE-encoded `None`.
3406
0
            self.inner
3407
0
                .alloc_write_and_return_pointer_size(host_fn.name(), iter::once(&[0]))
3408
        }
3409
0
    }
Unexecuted instantiation: _RNvMsq_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGet6resume
Unexecuted instantiation: _RNvMsq_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGet6resume
3410
}
3411
3412
impl fmt::Debug for ExternalOffchainStorageGet {
3413
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3414
0
        f.debug_tuple("ExternalOffchainStorageGet").finish()
3415
0
    }
Unexecuted instantiation: _RNvXsr_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsr_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_26ExternalOffchainStorageGetNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3416
}
3417
3418
/// Must return the current UNIX timestamp.
3419
pub struct OffchainTimestamp {
3420
    inner: Box<Inner>,
3421
}
3422
3423
impl OffchainTimestamp {
3424
    /// Resumes execution after having set the value.
3425
0
    pub fn resume(self, value: u64) -> HostVm {
3426
0
        HostVm::ReadyToRun(ReadyToRun {
3427
0
            inner: self.inner,
3428
0
            resume_value: Some(vm::WasmValue::I64(i64::from_ne_bytes(value.to_ne_bytes()))),
3429
0
        })
3430
0
    }
Unexecuted instantiation: _RNvMss_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_17OffchainTimestamp6resume
Unexecuted instantiation: _RNvMss_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_17OffchainTimestamp6resume
3431
}
3432
3433
impl fmt::Debug for OffchainTimestamp {
3434
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3435
0
        f.debug_tuple("OffchainTimestamp").finish()
3436
0
    }
Unexecuted instantiation: _RNvXst_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_17OffchainTimestampNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXst_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_17OffchainTimestampNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3437
}
3438
3439
/// Must provide a randomly-generate number.
3440
pub struct OffchainRandomSeed {
3441
    inner: Box<Inner>,
3442
3443
    /// Function currently being called by the Wasm code. Refers to an index within
3444
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
3445
    calling: usize,
3446
}
3447
3448
impl OffchainRandomSeed {
3449
    /// Resumes execution after having set the value.
3450
0
    pub fn resume(self, value: [u8; 32]) -> HostVm {
3451
0
        let host_fn = match self.inner.common.registered_functions[self.calling] {
3452
0
            FunctionImport::Resolved(f) => f,
3453
0
            FunctionImport::Unresolved { .. } => unreachable!(),
3454
        };
3455
0
        self.inner
3456
0
            .alloc_write_and_return_pointer(host_fn.name(), iter::once(value))
3457
0
    }
Unexecuted instantiation: _RNvMsu_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18OffchainRandomSeed6resume
Unexecuted instantiation: _RNvMsu_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18OffchainRandomSeed6resume
3458
}
3459
3460
impl fmt::Debug for OffchainRandomSeed {
3461
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3462
0
        f.debug_tuple("OffchainRandomSeed").finish()
3463
0
    }
Unexecuted instantiation: _RNvXsv_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_18OffchainRandomSeedNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsv_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_18OffchainRandomSeedNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3464
}
3465
3466
/// Must submit an off-chain transaction.
3467
pub struct OffchainSubmitTransaction {
3468
    inner: Box<Inner>,
3469
3470
    /// Function currently being called by the Wasm code. Refers to an index within
3471
    /// [`VmCommon::registered_functions`]. Guaranteed to be [`FunctionImport::Resolved`̀].
3472
    calling: usize,
3473
3474
    /// Pointer to the transaction whose value must be set. Guaranteed to be in range.
3475
    tx_ptr: u32,
3476
3477
    /// Size of the transaction whose value must be set. Guaranteed to be in range.
3478
    tx_size: u32,
3479
}
3480
3481
impl OffchainSubmitTransaction {
3482
    /// Returns the SCALE-encoded transaction to submit to the chain.
3483
0
    pub fn transaction(&'_ self) -> impl AsRef<[u8]> + '_ {
3484
0
        self.inner
3485
0
            .vm
3486
0
            .read_memory(self.tx_ptr, self.tx_size)
3487
0
            .unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvMsw_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_25OffchainSubmitTransaction11transaction0Bb_
Unexecuted instantiation: _RNCNvMsw_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_25OffchainSubmitTransaction11transaction0Bb_
3488
0
    }
Unexecuted instantiation: _RNvMsw_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_25OffchainSubmitTransaction11transaction
Unexecuted instantiation: _RNvMsw_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_25OffchainSubmitTransaction11transaction
3489
3490
    /// Resumes execution after having submitted the transaction.
3491
0
    pub fn resume(self, success: bool) -> HostVm {
3492
0
        let host_fn = match self.inner.common.registered_functions[self.calling] {
3493
0
            FunctionImport::Resolved(f) => f,
3494
0
            FunctionImport::Unresolved { .. } => unreachable!(),
3495
        };
3496
3497
0
        self.inner.alloc_write_and_return_pointer_size(
3498
0
            host_fn.name(),
3499
0
            if success {
3500
0
                iter::once(&[0x00])
3501
            } else {
3502
0
                iter::once(&[0x01])
3503
            },
3504
        )
3505
0
    }
Unexecuted instantiation: _RNvMsw_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_25OffchainSubmitTransaction6resume
Unexecuted instantiation: _RNvMsw_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_25OffchainSubmitTransaction6resume
3506
}
3507
3508
impl fmt::Debug for OffchainSubmitTransaction {
3509
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3510
0
        f.debug_tuple("OffchainSubmitTransaction").finish()
3511
0
    }
Unexecuted instantiation: _RNvXsx_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_25OffchainSubmitTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsx_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_25OffchainSubmitTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3512
}
3513
3514
/// Report about a log entry being emitted.
3515
///
3516
/// Use [`LogEmit::info`] to obtain what must be printed.
3517
pub struct LogEmit {
3518
    inner: Box<Inner>,
3519
    log_entry: LogEmitInner,
3520
}
3521
3522
enum LogEmitInner {
3523
    Num(u64),
3524
    Utf8 {
3525
        /// Pointer to the string. Guaranteed to be in range and to be UTF-8.
3526
        str_ptr: u32,
3527
        /// Size of the string. Guaranteed to be in range and to be UTF-8.
3528
        str_size: u32,
3529
    },
3530
    Hex {
3531
        /// Pointer to the data. Guaranteed to be in range.
3532
        data_ptr: u32,
3533
        /// Size of the data. Guaranteed to be in range.
3534
        data_size: u32,
3535
    },
3536
    Log {
3537
        /// Log level. Arbitrary number indicated by runtime, but typically in the `1..=5` range.
3538
        log_level: u32,
3539
        /// Pointer to the string of the log target. Guaranteed to be in range and to be UTF-8.
3540
        target_str_ptr: u32,
3541
        /// Size of the string of the log target. Guaranteed to be in range and to be UTF-8.
3542
        target_str_size: u32,
3543
        /// Pointer to the string of the log message. Guaranteed to be in range and to be UTF-8.
3544
        msg_str_ptr: u32,
3545
        /// Size of the string of the log message. Guaranteed to be in range and to be UTF-8.
3546
        msg_str_size: u32,
3547
    },
3548
}
3549
3550
impl LogEmit {
3551
    /// Returns the data that the runtime would like to print.
3552
0
    pub fn info(&self) -> LogEmitInfo {
3553
0
        match self.log_entry {
3554
0
            LogEmitInner::Num(n) => LogEmitInfo::Num(n),
3555
0
            LogEmitInner::Utf8 { str_ptr, str_size } => LogEmitInfo::Utf8(LogEmitInfoStr {
3556
0
                data: Box::new(
3557
0
                    self.inner
3558
0
                        .vm
3559
0
                        .read_memory(str_ptr, str_size)
3560
0
                        .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_7LogEmit4info0Bb_
Unexecuted instantiation: _RNCNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_7LogEmit4info0Bb_
3561
0
                ),
3562
0
            }),
3563
            LogEmitInner::Hex {
3564
0
                data_ptr,
3565
0
                data_size,
3566
0
            } => LogEmitInfo::Hex(LogEmitInfoHex {
3567
0
                data: Box::new(
3568
0
                    self.inner
3569
0
                        .vm
3570
0
                        .read_memory(data_ptr, data_size)
3571
0
                        .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_7LogEmit4infos_0Bb_
Unexecuted instantiation: _RNCNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_7LogEmit4infos_0Bb_
3572
0
                ),
3573
0
            }),
3574
            LogEmitInner::Log {
3575
0
                msg_str_ptr,
3576
0
                msg_str_size,
3577
0
                target_str_ptr,
3578
0
                target_str_size,
3579
0
                log_level,
3580
0
            } => LogEmitInfo::Log {
3581
0
                log_level,
3582
0
                target: LogEmitInfoStr {
3583
0
                    data: Box::new(
3584
0
                        self.inner
3585
0
                            .vm
3586
0
                            .read_memory(target_str_ptr, target_str_size)
3587
0
                            .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_7LogEmit4infos0_0Bb_
Unexecuted instantiation: _RNCNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_7LogEmit4infos0_0Bb_
3588
0
                    ),
3589
0
                },
3590
0
                message: LogEmitInfoStr {
3591
0
                    data: Box::new(
3592
0
                        self.inner
3593
0
                            .vm
3594
0
                            .read_memory(msg_str_ptr, msg_str_size)
3595
0
                            .unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_7LogEmit4infos1_0Bb_
Unexecuted instantiation: _RNCNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_7LogEmit4infos1_0Bb_
3596
0
                    ),
3597
0
                },
3598
0
            },
3599
        }
3600
0
    }
Unexecuted instantiation: _RNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_7LogEmit4info
Unexecuted instantiation: _RNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_7LogEmit4info
3601
3602
    /// Resumes execution.
3603
0
    pub fn resume(self) -> HostVm {
3604
0
        HostVm::ReadyToRun(ReadyToRun {
3605
0
            inner: self.inner,
3606
0
            resume_value: None,
3607
0
        })
3608
0
    }
Unexecuted instantiation: _RNvMsy_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_7LogEmit6resume
Unexecuted instantiation: _RNvMsy_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_7LogEmit6resume
3609
}
3610
3611
impl fmt::Debug for LogEmit {
3612
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3613
0
        f.debug_struct("LogEmit")
3614
0
            .field("info", &self.info())
3615
0
            .finish()
3616
0
    }
Unexecuted instantiation: _RNvXsz_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_7LogEmitNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsz_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_7LogEmitNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3617
}
3618
3619
/// Detail about what a [`LogEmit`] should output. See [`LogEmit::info`].
3620
#[derive(Debug)]
3621
pub enum LogEmitInfo<'a> {
3622
    /// Must output a single number.
3623
    Num(u64),
3624
    /// Must output a UTF-8 string.
3625
    Utf8(LogEmitInfoStr<'a>),
3626
    /// Must output the hexadecimal encoding of the given buffer.
3627
    Hex(LogEmitInfoHex<'a>),
3628
    /// Must output a log line.
3629
    Log {
3630
        /// Log level. Arbitrary number indicated by runtime, but typically in the `1..=5` range.
3631
        log_level: u32,
3632
        /// "Target" of the log. Arbitrary string indicated by the runtime. Typically indicates
3633
        /// the subsystem which has emitted the log line.
3634
        target: LogEmitInfoStr<'a>,
3635
        /// Actual log message being emitted.
3636
        message: LogEmitInfoStr<'a>,
3637
    },
3638
}
3639
3640
/// See [`LogEmitInfo`]. Use the `AsRef` trait implementation to retrieve the buffer.
3641
pub struct LogEmitInfoHex<'a> {
3642
    // TODO: don't use a Box once Rust supports type Foo = impl Trait;
3643
    data: Box<dyn AsRef<[u8]> + Send + Sync + 'a>,
3644
}
3645
3646
impl<'a> AsRef<[u8]> for LogEmitInfoHex<'a> {
3647
0
    fn as_ref(&self) -> &[u8] {
3648
0
        (*self.data).as_ref()
3649
0
    }
Unexecuted instantiation: _RNvXsA_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoHexINtNtCsaYZPK01V26L_4core7convert5AsRefShE6as_ref
Unexecuted instantiation: _RNvXsA_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoHexINtNtCsaYZPK01V26L_4core7convert5AsRefShE6as_ref
3650
}
3651
3652
impl<'a> fmt::Debug for LogEmitInfoHex<'a> {
3653
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3654
0
        fmt::Debug::fmt(self.as_ref(), f)
3655
0
    }
Unexecuted instantiation: _RNvXsB_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoHexNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsB_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoHexNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3656
}
3657
3658
impl<'a> fmt::Display for LogEmitInfoHex<'a> {
3659
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3660
0
        fmt::Debug::fmt(&hex::encode(self.as_ref()), f)
3661
0
    }
Unexecuted instantiation: _RNvXsC_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoHexNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsC_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoHexNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
3662
}
3663
3664
/// See [`LogEmitInfo`]. Use the `AsRef` trait implementation to retrieve the string.
3665
pub struct LogEmitInfoStr<'a> {
3666
    // TODO: don't use a Box once Rust supports type Foo = impl Trait;
3667
    data: Box<dyn AsRef<[u8]> + Send + Sync + 'a>,
3668
}
3669
3670
impl<'a> AsRef<str> for LogEmitInfoStr<'a> {
3671
0
    fn as_ref(&self) -> &str {
3672
0
        let data = (*self.data).as_ref();
3673
0
        // The creator of `LogEmitInfoStr` always makes sure that the string is indeed UTF-8
3674
0
        // before creating it.
3675
0
        str::from_utf8(data).unwrap_or_else(|_| unreachable!())
Unexecuted instantiation: _RNCNvXsD_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_14LogEmitInfoStrINtNtCsaYZPK01V26L_4core7convert5AsRefeE6as_ref0Bb_
Unexecuted instantiation: _RNCNvXsD_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_14LogEmitInfoStrINtNtCsaYZPK01V26L_4core7convert5AsRefeE6as_ref0Bb_
3676
0
    }
Unexecuted instantiation: _RNvXsD_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoStrINtNtCsaYZPK01V26L_4core7convert5AsRefeE6as_ref
Unexecuted instantiation: _RNvXsD_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoStrINtNtCsaYZPK01V26L_4core7convert5AsRefeE6as_ref
3677
}
3678
3679
impl<'a> fmt::Debug for LogEmitInfoStr<'a> {
3680
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3681
0
        fmt::Debug::fmt(self.as_ref(), f)
3682
0
    }
Unexecuted instantiation: _RNvXsE_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoStrNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsE_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoStrNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3683
}
3684
3685
impl<'a> fmt::Display for LogEmitInfoStr<'a> {
3686
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3687
0
        fmt::Display::fmt(self.as_ref(), f)
3688
0
    }
Unexecuted instantiation: _RNvXsF_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14LogEmitInfoStrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsF_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14LogEmitInfoStrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
3689
}
3690
3691
/// Queries the maximum log level.
3692
pub struct GetMaxLogLevel {
3693
    inner: Box<Inner>,
3694
}
3695
3696
impl GetMaxLogLevel {
3697
    /// Resumes execution after indicating the maximum log level.
3698
    ///
3699
    /// 0 means off, 1 means error, 2 means warn, 3 means info, 4 means debug, 5 means trace.
3700
136
    pub fn resume(self, max_level: u32) -> HostVm {
3701
136
        HostVm::ReadyToRun(ReadyToRun {
3702
136
            inner: self.inner,
3703
136
            resume_value: Some(vm::WasmValue::I32(i32::from_ne_bytes(
3704
136
                max_level.to_ne_bytes(),
3705
136
            ))),
3706
136
        })
3707
136
    }
_RNvMsG_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14GetMaxLogLevel6resume
Line
Count
Source
3700
9
    pub fn resume(self, max_level: u32) -> HostVm {
3701
9
        HostVm::ReadyToRun(ReadyToRun {
3702
9
            inner: self.inner,
3703
9
            resume_value: Some(vm::WasmValue::I32(i32::from_ne_bytes(
3704
9
                max_level.to_ne_bytes(),
3705
9
            ))),
3706
9
        })
3707
9
    }
_RNvMsG_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14GetMaxLogLevel6resume
Line
Count
Source
3700
127
    pub fn resume(self, max_level: u32) -> HostVm {
3701
127
        HostVm::ReadyToRun(ReadyToRun {
3702
127
            inner: self.inner,
3703
127
            resume_value: Some(vm::WasmValue::I32(i32::from_ne_bytes(
3704
127
                max_level.to_ne_bytes(),
3705
127
            ))),
3706
127
        })
3707
127
    }
3708
}
3709
3710
impl fmt::Debug for GetMaxLogLevel {
3711
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3712
0
        f.debug_tuple("GetMaxLogLevel").finish()
3713
0
    }
Unexecuted instantiation: _RNvXsH_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_14GetMaxLogLevelNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsH_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_14GetMaxLogLevelNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3714
}
3715
3716
/// Declares the start of a transaction.
3717
pub struct StartStorageTransaction {
3718
    inner: Box<Inner>,
3719
}
3720
3721
impl StartStorageTransaction {
3722
    /// Resumes execution after having acknowledged the event.
3723
14
    pub fn resume(self) -> HostVm {
3724
14
        HostVm::ReadyToRun(ReadyToRun {
3725
14
            inner: self.inner,
3726
14
            resume_value: None,
3727
14
        })
3728
14
    }
_RNvMsI_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_23StartStorageTransaction6resume
Line
Count
Source
3723
14
    pub fn resume(self) -> HostVm {
3724
14
        HostVm::ReadyToRun(ReadyToRun {
3725
14
            inner: self.inner,
3726
14
            resume_value: None,
3727
14
        })
3728
14
    }
Unexecuted instantiation: _RNvMsI_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_23StartStorageTransaction6resume
3729
}
3730
3731
impl fmt::Debug for StartStorageTransaction {
3732
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3733
0
        f.debug_tuple("StartStorageTransaction").finish()
3734
0
    }
Unexecuted instantiation: _RNvXsJ_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_23StartStorageTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsJ_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_23StartStorageTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3735
}
3736
3737
/// Declares the end of a transaction.
3738
pub struct EndStorageTransaction {
3739
    inner: Box<Inner>,
3740
}
3741
3742
impl EndStorageTransaction {
3743
    /// Resumes execution after having acknowledged the event.
3744
14
    pub fn resume(self) -> HostVm {
3745
14
        HostVm::ReadyToRun(ReadyToRun {
3746
14
            inner: self.inner,
3747
14
            resume_value: None,
3748
14
        })
3749
14
    }
_RNvMsK_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21EndStorageTransaction6resume
Line
Count
Source
3744
14
    pub fn resume(self) -> HostVm {
3745
14
        HostVm::ReadyToRun(ReadyToRun {
3746
14
            inner: self.inner,
3747
14
            resume_value: None,
3748
14
        })
3749
14
    }
Unexecuted instantiation: _RNvMsK_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21EndStorageTransaction6resume
3750
}
3751
3752
impl fmt::Debug for EndStorageTransaction {
3753
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3754
0
        f.debug_tuple("EndStorageTransaction").finish()
3755
0
    }
Unexecuted instantiation: _RNvXsL_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_21EndStorageTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXsL_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_21EndStorageTransactionNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
3756
}
3757
3758
#[derive(Clone)]
3759
enum FunctionImport {
3760
    Resolved(HostFunction),
3761
    Unresolved { module: String, name: String },
3762
}
3763
3764
/// Running virtual machine. Shared between all the variants in [`HostVm`].
3765
struct Inner {
3766
    /// Inner lower-level virtual machine.
3767
    vm: vm::VirtualMachine,
3768
3769
    /// The depth of storage transaction started with `ext_storage_start_transaction_version_1`.
3770
    storage_transaction_depth: u32,
3771
3772
    /// The host provides a "batch signature verification" mechanism, where the runtime can start
3773
    /// verifying multiple signatures at once. This mechanism is deprecated, but is emulated
3774
    /// through a simple field.
3775
    ///
3776
    /// Contains `Some` if and only if the runtime is currently within a batch signatures
3777
    /// verification. If `Some`, contains `true` if all the signatures have been verified
3778
    /// successfully so far.
3779
    signatures_batch_verification: Option<bool>,
3780
3781
    /// Memory allocator in order to answer the calls to `malloc` and `free`.
3782
    allocator: allocator::FreeingBumpHeapAllocator,
3783
3784
    /// Value passed as parameter.
3785
    storage_proof_size_behavior: StorageProofSizeBehavior,
3786
3787
    /// Fields that are kept as is even during the execution.
3788
    common: Box<VmCommon>,
3789
}
3790
3791
impl Inner {
3792
    /// Uses the memory allocator to allocate some memory for the given data, writes the data in
3793
    /// memory, and returns an [`HostVm`] ready for the Wasm `host_fn` return.
3794
    ///
3795
    /// The data is passed as a list of chunks. These chunks will be laid out linearly in memory.
3796
    ///
3797
    /// The function name passed as parameter is used for error-reporting reasons.
3798
    ///
3799
    /// # Panic
3800
    ///
3801
    /// Must only be called while the Wasm is handling an `host_fn`.
3802
    ///
3803
683
    fn alloc_write_and_return_pointer_size(
3804
683
        mut self: Box<Self>,
3805
683
        function_name: &'static str,
3806
683
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
683
    ) -> HostVm {
3808
683
        let mut data_len = 0u32;
3809
1.86k
        for chunk in 
data.clone()683
{
3810
1.86k
            data_len =
3811
1.86k
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
1.86k
        }
3813
3814
683
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
683
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
683
        let mut ptr_iter = dest_ptr;
3825
2.55k
        for 
chunk1.86k
in data {
3826
1.86k
            let chunk = chunk.as_ref();
3827
1.86k
            self.vm
3828
1.86k
                .write_memory(ptr_iter, chunk)
3829
1.86k
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EIB1y_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB2p_7sources4once4OnceB1x_EB3a_EB3a_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1x_Kj2_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_IB1y_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_ERShEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB38_INtNtNtB3e_7sources4once4OnceB1x_EB44_EB44_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherRShB22_EINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB2f_3map3MapIB2b_INtNtNtB2h_7sources4once4OnceB22_EB3o_ENcNtB1x_4Left0EIB33_B3o_NcNtB1x_5Right0EEE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1B_INtNtNtB1H_7sources4once4OnceB1x_EB2x_EB2x_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EIB1z_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB2q_7sources4once4OnceB1y_EB3b_EB3b_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1y_Kj2_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_IB1z_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_ERShEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB39_INtNtNtB3f_7sources4once4OnceB1y_EB45_EB45_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherRShB23_EINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB2g_3map3MapIB2c_INtNtNtB2i_7sources4once4OnceB23_EB3p_ENcNtB1y_4Left0EIB34_B3p_NcNtB1y_5Right0EEE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1C_INtNtNtB1I_7sources4once4OnceB1y_EB2y_EB2y_EE0Bc_
3830
1.86k
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
1.86k
        }
3832
3833
683
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
683
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
683
3836
683
        ReadyToRun {
3837
683
            inner: self,
3838
683
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
683
        }
3840
683
        .into()
3841
683
    }
Unexecuted instantiation: _RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1v_EEBa_
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EIB1w_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB2n_7sources4once4OnceB1v_EB38_EB38_EEBa_
Line
Count
Source
3803
14
    fn alloc_write_and_return_pointer_size(
3804
14
        mut self: Box<Self>,
3805
14
        function_name: &'static str,
3806
14
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
14
    ) -> HostVm {
3808
14
        let mut data_len = 0u32;
3809
16
        for chunk in 
data.clone()14
{
3810
16
            data_len =
3811
16
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
16
        }
3813
3814
14
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
14
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
14
        let mut ptr_iter = dest_ptr;
3825
30
        for 
chunk16
in data {
3826
16
            let chunk = chunk.as_ref();
3827
16
            self.vm
3828
16
                .write_memory(ptr_iter, chunk)
3829
16
                .unwrap_or_else(|_| unreachable!());
3830
16
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
16
        }
3832
3833
14
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
14
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
14
3836
14
        ReadyToRun {
3837
14
            inner: self,
3838
14
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
14
        }
3840
14
        .into()
3841
14
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1v_Kj2_EEBa_
Line
Count
Source
3803
5
    fn alloc_write_and_return_pointer_size(
3804
5
        mut self: Box<Self>,
3805
5
        function_name: &'static str,
3806
5
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
5
    ) -> HostVm {
3808
5
        let mut data_len = 0u32;
3809
10
        for chunk in 
data.clone()5
{
3810
10
            data_len =
3811
10
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
10
        }
3813
3814
5
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
5
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
5
        let mut ptr_iter = dest_ptr;
3825
15
        for 
chunk10
in data {
3826
10
            let chunk = chunk.as_ref();
3827
10
            self.vm
3828
10
                .write_memory(ptr_iter, chunk)
3829
10
                .unwrap_or_else(|_| unreachable!());
3830
10
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
10
        }
3832
3833
5
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
5
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
5
3836
5
        ReadyToRun {
3837
5
            inner: self,
3838
5
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
5
        }
3840
5
        .into()
3841
5
    }
Unexecuted instantiation: _RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_IB1w_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_ERShEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB36_INtNtNtB3c_7sources4once4OnceB1v_EB42_EB42_EEBa_
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherRShB20_EINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB2d_3map3MapIB29_INtNtNtB2f_7sources4once4OnceB20_EB3m_ENcNtB1v_4Left0EIB31_B3m_NcNtB1v_5Right0EEEBa_
Line
Count
Source
3803
504
    fn alloc_write_and_return_pointer_size(
3804
504
        mut self: Box<Self>,
3805
504
        function_name: &'static str,
3806
504
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
504
    ) -> HostVm {
3808
504
        let mut data_len = 0u32;
3809
1.51k
        for chunk in 
data.clone()504
{
3810
1.51k
            data_len =
3811
1.51k
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
1.51k
        }
3813
3814
504
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
504
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
504
        let mut ptr_iter = dest_ptr;
3825
2.01k
        for 
chunk1.51k
in data {
3826
1.51k
            let chunk = chunk.as_ref();
3827
1.51k
            self.vm
3828
1.51k
                .write_memory(ptr_iter, chunk)
3829
1.51k
                .unwrap_or_else(|_| unreachable!());
3830
1.51k
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
1.51k
        }
3832
3833
504
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
504
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
504
3836
504
        ReadyToRun {
3837
504
            inner: self,
3838
504
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
504
        }
3840
504
        .into()
3841
504
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1v_EEBa_
Line
Count
Source
3803
69
    fn alloc_write_and_return_pointer_size(
3804
69
        mut self: Box<Self>,
3805
69
        function_name: &'static str,
3806
69
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
69
    ) -> HostVm {
3808
69
        let mut data_len = 0u32;
3809
69
        for chunk in data.clone() {
3810
69
            data_len =
3811
69
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
69
        }
3813
3814
69
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
69
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
69
        let mut ptr_iter = dest_ptr;
3825
138
        for 
chunk69
in data {
3826
69
            let chunk = chunk.as_ref();
3827
69
            self.vm
3828
69
                .write_memory(ptr_iter, chunk)
3829
69
                .unwrap_or_else(|_| unreachable!());
3830
69
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
69
        }
3832
3833
69
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
69
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
69
3836
69
        ReadyToRun {
3837
69
            inner: self,
3838
69
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
69
        }
3840
69
        .into()
3841
69
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1v_EEBa_
Line
Count
Source
3803
5
    fn alloc_write_and_return_pointer_size(
3804
5
        mut self: Box<Self>,
3805
5
        function_name: &'static str,
3806
5
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
5
    ) -> HostVm {
3808
5
        let mut data_len = 0u32;
3809
5
        for chunk in data.clone() {
3810
5
            data_len =
3811
5
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
5
        }
3813
3814
5
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
5
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
5
        let mut ptr_iter = dest_ptr;
3825
10
        for 
chunk5
in data {
3826
5
            let chunk = chunk.as_ref();
3827
5
            self.vm
3828
5
                .write_memory(ptr_iter, chunk)
3829
5
                .unwrap_or_else(|_| unreachable!());
3830
5
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
5
        }
3832
3833
5
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
5
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
5
3836
5
        ReadyToRun {
3837
5
            inner: self,
3838
5
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
5
        }
3840
5
        .into()
3841
5
    }
Unexecuted instantiation: _RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1v_EEBa_
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1v_EEBa_
Line
Count
Source
3803
1
    fn alloc_write_and_return_pointer_size(
3804
1
        mut self: Box<Self>,
3805
1
        function_name: &'static str,
3806
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
1
    ) -> HostVm {
3808
1
        let mut data_len = 0u32;
3809
1
        for chunk in data.clone() {
3810
1
            data_len =
3811
1
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
1
        }
3813
3814
1
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
1
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
1
        let mut ptr_iter = dest_ptr;
3825
2
        for 
chunk1
in data {
3826
1
            let chunk = chunk.as_ref();
3827
1
            self.vm
3828
1
                .write_memory(ptr_iter, chunk)
3829
1
                .unwrap_or_else(|_| unreachable!());
3830
1
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
1
        }
3832
3833
1
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
1
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
1
3836
1
        ReadyToRun {
3837
1
            inner: self,
3838
1
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
1
        }
3840
1
        .into()
3841
1
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1z_INtNtNtB1F_7sources4once4OnceB1v_EB2v_EB2v_EEBa_
Line
Count
Source
3803
1
    fn alloc_write_and_return_pointer_size(
3804
1
        mut self: Box<Self>,
3805
1
        function_name: &'static str,
3806
1
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
1
    ) -> HostVm {
3808
1
        let mut data_len = 0u32;
3809
3
        for chunk in 
data.clone()1
{
3810
3
            data_len =
3811
3
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
3
        }
3813
3814
1
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
1
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
1
        let mut ptr_iter = dest_ptr;
3825
4
        for 
chunk3
in data {
3826
3
            let chunk = chunk.as_ref();
3827
3
            self.vm
3828
3
                .write_memory(ptr_iter, chunk)
3829
3
                .unwrap_or_else(|_| unreachable!());
3830
3
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
3
        }
3832
3833
1
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
1
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
1
3836
1
        ReadyToRun {
3837
1
            inner: self,
3838
1
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
1
        }
3840
1
        .into()
3841
1
    }
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1w_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EIB1x_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB2o_7sources4once4OnceB1w_EB39_EB39_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_Ahj4_EINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1w_Kj2_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherAhj1_IB1x_INtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_ERShEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB37_INtNtNtB3d_7sources4once4OnceB1w_EB43_EB43_EEBa_
_RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeINtCs1qmLyiTSqYF_6either6EitherRShB21_EINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB2e_3map3MapIB2a_INtNtNtB2g_7sources4once4OnceB21_EB3n_ENcNtB1w_4Left0EIB32_B3n_NcNtB1w_5Right0EEEBa_
Line
Count
Source
3803
84
    fn alloc_write_and_return_pointer_size(
3804
84
        mut self: Box<Self>,
3805
84
        function_name: &'static str,
3806
84
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3807
84
    ) -> HostVm {
3808
84
        let mut data_len = 0u32;
3809
252
        for chunk in 
data.clone()84
{
3810
252
            data_len =
3811
252
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3812
252
        }
3813
3814
84
        let dest_ptr = match self.alloc(function_name, data_len) {
3815
84
            Ok(p) => p,
3816
0
            Err(error) => {
3817
0
                return HostVm::Error {
3818
0
                    error,
3819
0
                    prototype: self.into_prototype(),
3820
0
                }
3821
            }
3822
        };
3823
3824
84
        let mut ptr_iter = dest_ptr;
3825
336
        for 
chunk252
in data {
3826
252
            let chunk = chunk.as_ref();
3827
252
            self.vm
3828
252
                .write_memory(ptr_iter, chunk)
3829
252
                .unwrap_or_else(|_| unreachable!());
3830
252
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3831
252
        }
3832
3833
84
        let ret_val = (u64::from(data_len) << 32) | u64::from(dest_ptr);
3834
84
        let ret_val = i64::from_ne_bytes(ret_val.to_ne_bytes());
3835
84
3836
84
        ReadyToRun {
3837
84
            inner: self,
3838
84
            resume_value: Some(vm::WasmValue::I64(ret_val)),
3839
84
        }
3840
84
        .into()
3841
84
    }
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRAhj1_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1w_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1w_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1w_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1w_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner35alloc_write_and_return_pointer_sizeRShINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1A_INtNtNtB1G_7sources4once4OnceB1w_EB2w_EB2w_EEBa_
3842
3843
    /// Uses the memory allocator to allocate some memory for the given data, writes the data in
3844
    /// memory, and returns an [`HostVm`] ready for the Wasm `host_fn` return.
3845
    ///
3846
    /// The data is passed as a list of chunks. These chunks will be laid out linearly in memory.
3847
    ///
3848
    /// The function name passed as parameter is used for error-reporting reasons.
3849
    ///
3850
    /// # Panic
3851
    ///
3852
    /// Must only be called while the Wasm is handling an `host_fn`.
3853
    ///
3854
2.07k
    fn alloc_write_and_return_pointer(
3855
2.07k
        mut self: Box<Self>,
3856
2.07k
        function_name: &'static str,
3857
2.07k
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
2.07k
    ) -> HostVm {
3859
2.07k
        let mut data_len = 0u32;
3860
3.89k
        for chunk in 
data.clone()2.07k
{
3861
3.89k
            data_len =
3862
3.89k
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
3.89k
        }
3864
3865
2.07k
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
2.07k
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
2.07k
        let mut ptr_iter = dest_ptr;
3876
5.97k
        for 
chunk3.89k
in data {
3877
3.89k
            let chunk = chunk.as_ref();
3878
3.89k
            self.vm
3879
3.89k
                .write_memory(ptr_iter, chunk)
3880
3.89k
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1z_IB1z_INtNtNtB1F_7sources4once4OnceB1s_EB2A_EB2A_EB2A_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB1F_7sources4once4OnceB1s_EB2q_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2f_IB2f_IB2f_IB2f_IB2f_IB2f_NtB2h_5UTermNtNtB2j_3bit2B1ENtB3x_2B0EB3L_EB3L_EB3L_EB3L_EB3L_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2f_IB2f_IB2f_IB2f_IB2f_NtB2h_5UTermNtNtB2j_3bit2B1ENtB3s_2B0EB3G_EB3G_EB3G_EB3G_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1s_Kj2_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1s_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1A_IB1A_INtNtNtB1G_7sources4once4OnceB1t_EB2B_EB2B_EB2B_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB1G_7sources4once4OnceB1t_EB2r_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2g_IB2g_IB2g_IB2g_IB2g_IB2g_NtB2i_5UTermNtNtB2k_3bit2B1ENtB3y_2B0EB3M_EB3M_EB3M_EB3M_EB3M_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2g_IB2g_IB2g_IB2g_IB2g_NtB2i_5UTermNtNtB2k_3bit2B1ENtB3t_2B0EB3H_EB3H_EB3H_EB3H_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1t_Kj2_EE0Bc_
Unexecuted instantiation: _RNCINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB8_5Inner30alloc_write_and_return_pointerRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1t_EE0Bc_
3881
3.89k
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
3.89k
        }
3883
3884
2.07k
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
2.07k
        ReadyToRun {
3886
2.07k
            inner: self,
3887
2.07k
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
2.07k
        }
3889
2.07k
        .into()
3890
2.07k
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
3854
5
    fn alloc_write_and_return_pointer(
3855
5
        mut self: Box<Self>,
3856
5
        function_name: &'static str,
3857
5
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
5
    ) -> HostVm {
3859
5
        let mut data_len = 0u32;
3860
5
        for chunk in data.clone() {
3861
5
            data_len =
3862
5
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
5
        }
3864
3865
5
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
5
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
5
        let mut ptr_iter = dest_ptr;
3876
10
        for 
chunk5
in data {
3877
5
            let chunk = chunk.as_ref();
3878
5
            self.vm
3879
5
                .write_memory(ptr_iter, chunk)
3880
5
                .unwrap_or_else(|_| unreachable!());
3881
5
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
5
        }
3883
3884
5
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
5
        ReadyToRun {
3886
5
            inner: self,
3887
5
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
5
        }
3889
5
        .into()
3890
5
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
3854
67
    fn alloc_write_and_return_pointer(
3855
67
        mut self: Box<Self>,
3856
67
        function_name: &'static str,
3857
67
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
67
    ) -> HostVm {
3859
67
        let mut data_len = 0u32;
3860
67
        for chunk in data.clone() {
3861
67
            data_len =
3862
67
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
67
        }
3864
3865
67
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
67
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
67
        let mut ptr_iter = dest_ptr;
3876
134
        for 
chunk67
in data {
3877
67
            let chunk = chunk.as_ref();
3878
67
            self.vm
3879
67
                .write_memory(ptr_iter, chunk)
3880
67
                .unwrap_or_else(|_| unreachable!());
3881
67
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
67
        }
3883
3884
67
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
67
        ReadyToRun {
3886
67
            inner: self,
3887
67
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
67
        }
3889
67
        .into()
3890
67
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1x_IB1x_INtNtNtB1D_7sources4once4OnceB1q_EB2y_EB2y_EB2y_EEBa_
Line
Count
Source
3854
2
    fn alloc_write_and_return_pointer(
3855
2
        mut self: Box<Self>,
3856
2
        function_name: &'static str,
3857
2
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
2
    ) -> HostVm {
3859
2
        let mut data_len = 0u32;
3860
8
        for chunk in 
data.clone()2
{
3861
8
            data_len =
3862
8
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
8
        }
3864
3865
2
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
2
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
2
        let mut ptr_iter = dest_ptr;
3876
10
        for 
chunk8
in data {
3877
8
            let chunk = chunk.as_ref();
3878
8
            self.vm
3879
8
                .write_memory(ptr_iter, chunk)
3880
8
                .unwrap_or_else(|_| unreachable!());
3881
8
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
8
        }
3883
3884
2
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
2
        ReadyToRun {
3886
2
            inner: self,
3887
2
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
2
        }
3889
2
        .into()
3890
2
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB1D_7sources4once4OnceB1q_EB2o_EEBa_
Line
Count
Source
3854
1.73k
    fn alloc_write_and_return_pointer(
3855
1.73k
        mut self: Box<Self>,
3856
1.73k
        function_name: &'static str,
3857
1.73k
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
1.73k
    ) -> HostVm {
3859
1.73k
        let mut data_len = 0u32;
3860
3.46k
        for chunk in 
data.clone()1.73k
{
3861
3.46k
            data_len =
3862
3.46k
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
3.46k
        }
3864
3865
1.73k
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
1.73k
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
1.73k
        let mut ptr_iter = dest_ptr;
3876
5.19k
        for 
chunk3.46k
in data {
3877
3.46k
            let chunk = chunk.as_ref();
3878
3.46k
            self.vm
3879
3.46k
                .write_memory(ptr_iter, chunk)
3880
3.46k
                .unwrap_or_else(|_| unreachable!());
3881
3.46k
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
3.46k
        }
3883
3884
1.73k
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
1.73k
        ReadyToRun {
3886
1.73k
            inner: self,
3887
1.73k
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
1.73k
        }
3889
1.73k
        .into()
3890
1.73k
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2d_IB2d_IB2d_IB2d_IB2d_IB2d_NtB2f_5UTermNtNtB2h_3bit2B1ENtB3v_2B0EB3J_EB3J_EB3J_EB3J_EB3J_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
3854
2
    fn alloc_write_and_return_pointer(
3855
2
        mut self: Box<Self>,
3856
2
        function_name: &'static str,
3857
2
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
2
    ) -> HostVm {
3859
2
        let mut data_len = 0u32;
3860
2
        for chunk in data.clone() {
3861
2
            data_len =
3862
2
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
2
        }
3864
3865
2
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
2
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
2
        let mut ptr_iter = dest_ptr;
3876
4
        for 
chunk2
in data {
3877
2
            let chunk = chunk.as_ref();
3878
2
            self.vm
3879
2
                .write_memory(ptr_iter, chunk)
3880
2
                .unwrap_or_else(|_| unreachable!());
3881
2
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
2
        }
3883
3884
2
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
2
        ReadyToRun {
3886
2
            inner: self,
3887
2
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
2
        }
3889
2
        .into()
3890
2
    }
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2d_IB2d_IB2d_IB2d_IB2d_NtB2f_5UTermNtNtB2h_3bit2B1ENtB3q_2B0EB3E_EB3E_EB3E_EB3E_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
3854
4
    fn alloc_write_and_return_pointer(
3855
4
        mut self: Box<Self>,
3856
4
        function_name: &'static str,
3857
4
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
4
    ) -> HostVm {
3859
4
        let mut data_len = 0u32;
3860
4
        for chunk in data.clone() {
3861
4
            data_len =
3862
4
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
4
        }
3864
3865
4
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
4
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
4
        let mut ptr_iter = dest_ptr;
3876
8
        for 
chunk4
in data {
3877
4
            let chunk = chunk.as_ref();
3878
4
            self.vm
3879
4
                .write_memory(ptr_iter, chunk)
3880
4
                .unwrap_or_else(|_| unreachable!());
3881
4
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
4
        }
3883
3884
4
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
4
        ReadyToRun {
3886
4
            inner: self,
3887
4
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
4
        }
3889
4
        .into()
3890
4
    }
Unexecuted instantiation: _RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1q_Kj2_EEBa_
_RINvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1q_EEBa_
Line
Count
Source
3854
178
    fn alloc_write_and_return_pointer(
3855
178
        mut self: Box<Self>,
3856
178
        function_name: &'static str,
3857
178
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
178
    ) -> HostVm {
3859
178
        let mut data_len = 0u32;
3860
178
        for chunk in data.clone() {
3861
178
            data_len =
3862
178
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
178
        }
3864
3865
178
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
178
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
178
        let mut ptr_iter = dest_ptr;
3876
356
        for 
chunk178
in data {
3877
178
            let chunk = chunk.as_ref();
3878
178
            self.vm
3879
178
                .write_memory(ptr_iter, chunk)
3880
178
                .unwrap_or_else(|_| unreachable!());
3881
178
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
178
        }
3883
3884
178
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
178
        ReadyToRun {
3886
178
            inner: self,
3887
178
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
178
        }
3889
178
        .into()
3890
178
    }
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj20_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainIB1y_IB1y_INtNtNtB1E_7sources4once4OnceB1r_EB2z_EB2z_EB2z_EEBa_
_RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRAhj8_INtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtNtB1E_7sources4once4OnceB1r_EB2p_EEBa_
Line
Count
Source
3854
84
    fn alloc_write_and_return_pointer(
3855
84
        mut self: Box<Self>,
3856
84
        function_name: &'static str,
3857
84
        data: impl Iterator<Item = impl AsRef<[u8]>> + Clone,
3858
84
    ) -> HostVm {
3859
84
        let mut data_len = 0u32;
3860
168
        for chunk in 
data.clone()84
{
3861
168
            data_len =
3862
168
                data_len.saturating_add(u32::try_from(chunk.as_ref().len()).unwrap_or(u32::MAX));
3863
168
        }
3864
3865
84
        let dest_ptr = match self.alloc(function_name, data_len) {
3866
84
            Ok(p) => p,
3867
0
            Err(error) => {
3868
0
                return HostVm::Error {
3869
0
                    error,
3870
0
                    prototype: self.into_prototype(),
3871
0
                }
3872
            }
3873
        };
3874
3875
84
        let mut ptr_iter = dest_ptr;
3876
252
        for 
chunk168
in data {
3877
168
            let chunk = chunk.as_ref();
3878
168
            self.vm
3879
168
                .write_memory(ptr_iter, chunk)
3880
168
                .unwrap_or_else(|_| unreachable!());
3881
168
            ptr_iter += u32::try_from(chunk.len()).unwrap_or(u32::MAX);
3882
168
        }
3883
3884
84
        let ret_val = i32::from_ne_bytes(dest_ptr.to_ne_bytes());
3885
84
        ReadyToRun {
3886
84
            inner: self,
3887
84
            resume_value: Some(vm::WasmValue::I32(ret_val)),
3888
84
        }
3889
84
        .into()
3890
84
    }
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2e_IB2e_IB2e_IB2e_IB2e_IB2e_NtB2g_5UTermNtNtB2i_3bit2B1ENtB3w_2B0EB3K_EB3K_EB3K_EB3K_EB3K_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRINtCskYLzYmOFGAo_13generic_array12GenericArrayhINtNtCsg8gh8wv4eQn_7typenum4uint4UIntIB2e_IB2e_IB2e_IB2e_IB2e_NtB2g_5UTermNtNtB2i_3bit2B1ENtB3r_2B0EB3F_EB3F_EB3F_EB3F_EEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRShINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterB1r_Kj2_EEBa_
Unexecuted instantiation: _RINvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5Inner30alloc_write_and_return_pointerRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1r_EEBa_
3891
3892
    /// Uses the memory allocator to allocate some memory.
3893
    ///
3894
    /// The function name passed as parameter is used for error-reporting reasons.
3895
    ///
3896
    /// # Panic
3897
    ///
3898
    /// Must only be called while the Wasm is handling an `host_fn`.
3899
    ///
3900
16.8k
    fn alloc(&mut self, function_name: &'static str, size: u32) -> Result<u32, Error> {
3901
        // Use the allocator to decide where the value will be written.
3902
16.8k
        let dest_ptr = match self.allocator.allocate(
3903
16.8k
            &mut MemAccess {
3904
16.8k
                vm: MemAccessVm::Running(&mut self.vm),
3905
16.8k
                memory_total_pages: self.common.memory_total_pages,
3906
16.8k
            },
3907
16.8k
            size,
3908
16.8k
        ) {
3909
16.8k
            Ok(p) => p,
3910
            Err(_) => {
3911
0
                return Err(Error::OutOfMemory {
3912
0
                    function: function_name,
3913
0
                    requested_size: size,
3914
0
                })
3915
            }
3916
        };
3917
3918
        // Unfortunately this function doesn't stop here.
3919
        // We lie to the allocator. The allocator thinks that there are `self.memory_total_pages`
3920
        // allocated and available, while in reality it can be less.
3921
        // The allocator might thus allocate memory at a location above the current memory size.
3922
        // To handle this, we grow the memory.
3923
3924
        // Offset of the memory page where the last allocated byte is found.
3925
16.8k
        let last_byte_memory_page = HeapPages::new((dest_ptr + size - 1) / (64 * 1024));
3926
16.8k
3927
16.8k
        // Grow the memory more if necessary.
3928
16.8k
        // Please note the `=`. For example if we write to page 0, we want to have at least 1 page
3929
16.8k
        // allocated.
3930
16.8k
        let current_num_pages = self.vm.memory_size();
3931
16.8k
        debug_assert!(current_num_pages <= self.common.memory_total_pages);
3932
16.8k
        if current_num_pages <= last_byte_memory_page {
3933
39
            // For now, we grow the memory just enough to fit.
3934
39
            // TODO: do better
3935
39
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
3936
39
            // in case `last_byte_memory_page` is the maximum possible value.
3937
39
            let to_grow = last_byte_memory_page - current_num_pages + HeapPages::new(1);
3938
39
3939
39
            // We check at initialization that the virtual machine is capable of growing up to
3940
39
            // `memory_total_pages`, meaning that this can't panic.
3941
39
            self.vm
3942
39
                .grow_memory(to_grow)
3943
39
                .unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_5Inner5alloc0Bb_
Unexecuted instantiation: _RNCNvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_5Inner5alloc0Bb_
3944
16.8k
        }
3945
3946
16.8k
        Ok(dest_ptr)
3947
16.8k
    }
_RNvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_5Inner5alloc
Line
Count
Source
3900
14.3k
    fn alloc(&mut self, function_name: &'static str, size: u32) -> Result<u32, Error> {
3901
        // Use the allocator to decide where the value will be written.
3902
14.3k
        let dest_ptr = match self.allocator.allocate(
3903
14.3k
            &mut MemAccess {
3904
14.3k
                vm: MemAccessVm::Running(&mut self.vm),
3905
14.3k
                memory_total_pages: self.common.memory_total_pages,
3906
14.3k
            },
3907
14.3k
            size,
3908
14.3k
        ) {
3909
14.3k
            Ok(p) => p,
3910
            Err(_) => {
3911
0
                return Err(Error::OutOfMemory {
3912
0
                    function: function_name,
3913
0
                    requested_size: size,
3914
0
                })
3915
            }
3916
        };
3917
3918
        // Unfortunately this function doesn't stop here.
3919
        // We lie to the allocator. The allocator thinks that there are `self.memory_total_pages`
3920
        // allocated and available, while in reality it can be less.
3921
        // The allocator might thus allocate memory at a location above the current memory size.
3922
        // To handle this, we grow the memory.
3923
3924
        // Offset of the memory page where the last allocated byte is found.
3925
14.3k
        let last_byte_memory_page = HeapPages::new((dest_ptr + size - 1) / (64 * 1024));
3926
14.3k
3927
14.3k
        // Grow the memory more if necessary.
3928
14.3k
        // Please note the `=`. For example if we write to page 0, we want to have at least 1 page
3929
14.3k
        // allocated.
3930
14.3k
        let current_num_pages = self.vm.memory_size();
3931
14.3k
        debug_assert!(current_num_pages <= self.common.memory_total_pages);
3932
14.3k
        if current_num_pages <= last_byte_memory_page {
3933
34
            // For now, we grow the memory just enough to fit.
3934
34
            // TODO: do better
3935
34
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
3936
34
            // in case `last_byte_memory_page` is the maximum possible value.
3937
34
            let to_grow = last_byte_memory_page - current_num_pages + HeapPages::new(1);
3938
34
3939
34
            // We check at initialization that the virtual machine is capable of growing up to
3940
34
            // `memory_total_pages`, meaning that this can't panic.
3941
34
            self.vm
3942
34
                .grow_memory(to_grow)
3943
34
                .unwrap_or_else(|_| unreachable!());
3944
14.3k
        }
3945
3946
14.3k
        Ok(dest_ptr)
3947
14.3k
    }
_RNvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_5Inner5alloc
Line
Count
Source
3900
2.53k
    fn alloc(&mut self, function_name: &'static str, size: u32) -> Result<u32, Error> {
3901
        // Use the allocator to decide where the value will be written.
3902
2.53k
        let dest_ptr = match self.allocator.allocate(
3903
2.53k
            &mut MemAccess {
3904
2.53k
                vm: MemAccessVm::Running(&mut self.vm),
3905
2.53k
                memory_total_pages: self.common.memory_total_pages,
3906
2.53k
            },
3907
2.53k
            size,
3908
2.53k
        ) {
3909
2.53k
            Ok(p) => p,
3910
            Err(_) => {
3911
0
                return Err(Error::OutOfMemory {
3912
0
                    function: function_name,
3913
0
                    requested_size: size,
3914
0
                })
3915
            }
3916
        };
3917
3918
        // Unfortunately this function doesn't stop here.
3919
        // We lie to the allocator. The allocator thinks that there are `self.memory_total_pages`
3920
        // allocated and available, while in reality it can be less.
3921
        // The allocator might thus allocate memory at a location above the current memory size.
3922
        // To handle this, we grow the memory.
3923
3924
        // Offset of the memory page where the last allocated byte is found.
3925
2.53k
        let last_byte_memory_page = HeapPages::new((dest_ptr + size - 1) / (64 * 1024));
3926
2.53k
3927
2.53k
        // Grow the memory more if necessary.
3928
2.53k
        // Please note the `=`. For example if we write to page 0, we want to have at least 1 page
3929
2.53k
        // allocated.
3930
2.53k
        let current_num_pages = self.vm.memory_size();
3931
2.53k
        debug_assert!(current_num_pages <= self.common.memory_total_pages);
3932
2.53k
        if current_num_pages <= last_byte_memory_page {
3933
5
            // For now, we grow the memory just enough to fit.
3934
5
            // TODO: do better
3935
5
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
3936
5
            // in case `last_byte_memory_page` is the maximum possible value.
3937
5
            let to_grow = last_byte_memory_page - current_num_pages + HeapPages::new(1);
3938
5
3939
5
            // We check at initialization that the virtual machine is capable of growing up to
3940
5
            // `memory_total_pages`, meaning that this can't panic.
3941
5
            self.vm
3942
5
                .grow_memory(to_grow)
3943
5
                .unwrap_or_else(|_| unreachable!());
3944
2.53k
        }
3945
3946
2.53k
        Ok(dest_ptr)
3947
2.53k
    }
3948
3949
    /// Turns the virtual machine back into a prototype.
3950
145
    fn into_prototype(self) -> HostVmPrototype {
3951
145
        HostVmPrototype {
3952
145
            vm_proto: self.vm.into_prototype(),
3953
145
            common: self.common,
3954
145
        }
3955
145
    }
_RNvMsM_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_5Inner14into_prototype
Line
Count
Source
3950
19
    fn into_prototype(self) -> HostVmPrototype {
3951
19
        HostVmPrototype {
3952
19
            vm_proto: self.vm.into_prototype(),
3953
19
            common: self.common,
3954
19
        }
3955
19
    }
_RNvMsM_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_5Inner14into_prototype
Line
Count
Source
3950
126
    fn into_prototype(self) -> HostVmPrototype {
3951
126
        HostVmPrototype {
3952
126
            vm_proto: self.vm.into_prototype(),
3953
126
            common: self.common,
3954
126
        }
3955
126
    }
3956
}
3957
3958
/// Error that can happen when initializing a VM.
3959
0
#[derive(Debug, derive_more::From, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXs1m_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_6NewErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs1m_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_6NewErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
3960
pub enum NewErr {
3961
    /// Error in the format of the runtime code.
3962
    #[display(fmt = "{_0}")]
3963
    BadFormat(ModuleFormatError),
3964
    /// Error while initializing the virtual machine.
3965
    #[display(fmt = "{_0}")]
3966
    VirtualMachine(vm::NewErr),
3967
    /// Error while finding the runtime-version-related sections in the Wasm blob.
3968
    #[display(fmt = "Error in runtime spec Wasm sections: {_0}")]
3969
    RuntimeVersion(FindEmbeddedRuntimeVersionError),
3970
    /// Error while calling `Core_version` to determine the runtime version.
3971
    #[display(fmt = "Error while calling Core_version: {_0}")]
3972
    CoreVersion(CoreVersionError),
3973
    /// Couldn't find the `__heap_base` symbol in the Wasm code.
3974
    HeapBaseNotFound,
3975
    /// Maximum size of the Wasm memory found in the module is too low to provide the requested
3976
    /// number of heap pages.
3977
    MemoryMaxSizeTooLow,
3978
}
3979
3980
/// Error while determining .
3981
0
#[derive(Debug, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXs1p_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_31FindEmbeddedRuntimeVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs1p_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_31FindEmbeddedRuntimeVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
3982
pub enum FindEmbeddedRuntimeVersionError {
3983
    /// Error while finding the custom section.
3984
    #[display(fmt = "{_0}")]
3985
    FindSections(FindEncodedEmbeddedRuntimeVersionApisError),
3986
    /// Error while decoding the runtime version.
3987
    RuntimeVersionDecode,
3988
    /// Error while decoding the runtime APIs.
3989
    #[display(fmt = "{_0}")]
3990
    RuntimeApisDecode(CoreVersionApisFromSliceErr),
3991
}
3992
3993
/// Error that can happen when starting a VM.
3994
0
#[derive(Debug, Clone, derive_more::From, derive_more::Display)]
Unexecuted instantiation: _RNvXs1v_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_8StartErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs1v_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_8StartErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
3995
pub enum StartErr {
3996
    /// Error while starting the virtual machine.
3997
    #[display(fmt = "{_0}")]
3998
    VirtualMachine(vm::StartErr),
3999
    /// The size of the input data is too large.
4000
    DataSizeOverflow,
4001
}
4002
4003
/// Reason why the Wasm blob isn't conforming to the runtime environment.
4004
0
#[derive(Debug, Clone, derive_more::Display)]
Unexecuted instantiation: _RNvXs1y_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB6_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs1y_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB6_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
4005
pub enum Error {
4006
    /// Error in the Wasm code execution.
4007
    #[display(fmt = "{_0}")]
4008
    Trap(vm::Trap),
4009
    /// Runtime has called the `ext_panic_handler_abort_on_panic_version_1` host function.
4010
    #[display(fmt = "Runtime has aborted: {message:?}")]
4011
    AbortOnPanic {
4012
        /// Message generated by the runtime.
4013
        message: String,
4014
    },
4015
    /// A non-`i64` value has been returned by the Wasm entry point.
4016
    #[display(fmt = "A non-I64 value has been returned: {actual:?}")]
4017
    BadReturnValue {
4018
        /// Type that has actually gotten returned. `None` for "void".
4019
        actual: Option<vm::ValueType>,
4020
    },
4021
    /// The pointer and size returned by the Wasm entry point function are invalid.
4022
    #[display(fmt = "The pointer and size returned by the function are invalid")]
4023
    ReturnedPtrOutOfRange {
4024
        /// Pointer that got returned.
4025
        pointer: u32,
4026
        /// Size that got returned.
4027
        size: u32,
4028
        /// Size of the virtual memory.
4029
        memory_size: u32,
4030
    },
4031
    /// Called a function that is unknown to the host.
4032
    ///
4033
    /// > **Note**: Can only happen if `allow_unresolved_imports` was `true`.
4034
    #[display(fmt = "Called unresolved function `{module_name}`:`{function}`")]
4035
    UnresolvedFunctionCalled {
4036
        /// Name of the function that was unresolved.
4037
        function: String,
4038
        /// Name of module associated with the unresolved function.
4039
        module_name: String,
4040
    },
4041
    /// Failed to decode a SCALE-encoded parameter.
4042
    ParamDecodeError,
4043
    /// One parameter is expected to point to a buffer, but the pointer is out
4044
    /// of range of the memory of the Wasm VM.
4045
    #[display(
4046
        fmt = "Bad pointer for parameter of index {param_num} of {function}: 0x{pointer:x}, \
4047
        len = 0x{length:x}"
4048
    )]
4049
    ParamOutOfRange {
4050
        /// Name of the function being called where a type mismatch happens.
4051
        function: &'static str,
4052
        /// Index of the invalid parameter. The first parameter has index 0.
4053
        param_num: usize,
4054
        /// Pointer passed as parameter.
4055
        pointer: u32,
4056
        /// Expected length of the buffer.
4057
        ///
4058
        /// Depending on the function, this can either be an implicit length
4059
        /// or a length passed as parameter.
4060
        length: u32,
4061
    },
4062
    /// One parameter is expected to point to a UTF-8 string, but the buffer
4063
    /// isn't valid UTF-8.
4064
    #[display(fmt = "UTF-8 error for parameter of index {param_num} of {function}: {error}")]
4065
    Utf8Error {
4066
        /// Name of the function being called where a type mismatch happens.
4067
        function: &'static str,
4068
        /// Index of the invalid parameter. The first parameter has index 0.
4069
        param_num: usize,
4070
        /// Decoding error that happened.
4071
        error: core::str::Utf8Error,
4072
    },
4073
    /// Called `ext_storage_rollback_transaction_version_1` or
4074
    /// `ext_storage_commit_transaction_version_1` but no transaction was in progress.
4075
    #[display(fmt = "Attempted to end a transaction while none is in progress")]
4076
    NoActiveTransaction,
4077
    /// Execution has finished while a transaction started with
4078
    /// `ext_storage_start_transaction_version_1` was still in progress.
4079
    #[display(fmt = "Execution returned with a pending storage transaction")]
4080
    FinishedWithPendingTransaction,
4081
    /// Error when allocating memory for a return type.
4082
    #[display(fmt = "Out of memory allocating 0x{requested_size:x} bytes during {function}")]
4083
    OutOfMemory {
4084
        /// Name of the function being called.
4085
        function: &'static str,
4086
        /// Size of the requested allocation.
4087
        requested_size: u32,
4088
    },
4089
    /// Called `ext_allocator_free_version_1` with an invalid pointer.
4090
    #[display(fmt = "Bad pointer passed to ext_allocator_free_version_1: 0x{pointer:x}")]
4091
    FreeError {
4092
        /// Pointer that was expected to be freed.
4093
        pointer: u32,
4094
    },
4095
    /// Mismatch between the state trie version provided as parameter and the state trie version
4096
    /// found in the runtime specification.
4097
    #[display(
4098
        fmt = "Mismatch between the state trie version provided as parameter ({parameter:?}) and \
4099
        the state trie version found in the runtime specification ({specification:?})."
4100
    )]
4101
    StateVersionMismatch {
4102
        /// The version passed as parameter.
4103
        parameter: TrieEntryVersion,
4104
        /// The version in the specification.
4105
        specification: TrieEntryVersion,
4106
    },
4107
    /// Called `ext_default_child_storage_root_version_1` or
4108
    /// `ext_default_child_storage_root_version_2` on a child trie that doesn't exist.
4109
    #[display(fmt = "Called `ext_default_child_storage_root_version_1` or
4110
        `ext_default_child_storage_root_version_2` on a child trie that doesn't exist.")]
4111
    ChildStorageRootTrieDoesntExist,
4112
    /// Runtime has tried to perform a signature batch verification before initiating a batch
4113
    /// verification.
4114
    BatchVerifyWithoutStarting,
4115
    /// Runtime has tried to initiate a batch signatures verification while there was already one
4116
    /// in progress.
4117
    AlreadyBatchVerify,
4118
    /// Runtime has tried to finish a batch signatures verification while none is in progress.
4119
    NoBatchVerify,
4120
    /// The host function isn't implemented.
4121
    // TODO: this variant should eventually disappear as all functions are implemented
4122
    #[display(fmt = "Host function not implemented: {function}")]
4123
    HostFunctionNotImplemented {
4124
        /// Name of the function being called.
4125
        function: &'static str,
4126
    },
4127
}
4128
4129
// Glue between the `allocator` module and the `vm` module.
4130
//
4131
// The allocator believes that there are `memory_total_pages` pages available and allocated, where
4132
// `memory_total_pages` is equal to `heap_base + heap_pages`, while in reality, because we grow
4133
// memory lazily, there might be fewer.
4134
struct MemAccess<'a> {
4135
    vm: MemAccessVm<'a>,
4136
    memory_total_pages: HeapPages,
4137
}
4138
4139
enum MemAccessVm<'a> {
4140
    Prepare(&'a mut vm::Prepare),
4141
    Running(&'a mut vm::VirtualMachine),
4142
}
4143
4144
impl<'a> allocator::Memory for MemAccess<'a> {
4145
30.0k
    fn read_le_u64(&self, ptr: u32) -> Result<u64, allocator::Error> {
4146
30.0k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4147
0
            return Err(allocator::Error::Other("out of bounds access"));
4148
30.0k
        }
4149
30.0k
4150
30.0k
        // Note that this function (`read_le_u64`) really should take ̀`&mut self` but that is
4151
30.0k
        // unfortunately not the case, meaning that we can't "just" grow the memory if trying
4152
30.0k
        // to access an out of bound location.
4153
30.0k
        //
4154
30.0k
        // Additionally, the value being read can in theory overlap between an allocated and
4155
30.0k
        // non-allocated parts of the memory, making this more complicated.
4156
30.0k
4157
30.0k
        // Offset of the memory page where the first byte of the value will be read.
4158
30.0k
        let accessed_memory_page_start = HeapPages::new(ptr / (64 * 1024));
4159
30.0k
        // Offset of the memory page where the last byte of the value will be read.
4160
30.0k
        let accessed_memory_page_end = HeapPages::new((ptr + 7) / (64 * 1024));
4161
        // Number of pages currently allocated.
4162
30.0k
        let current_num_pages = match self.vm {
4163
0
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4164
30.0k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4165
        };
4166
30.0k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4167
4168
30.0k
        if accessed_memory_page_end < current_num_pages {
4169
            // This is the simple case: the memory access is in bounds.
4170
30.0k
            match self.vm {
4171
0
                MemAccessVm::Prepare(ref vm) => {
4172
0
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u640Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u640Bb_
4173
0
                    Ok(u64::from_le_bytes(
4174
0
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| unreachable!()),
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s_0Bb_
4175
0
                    ))
4176
                }
4177
30.0k
                MemAccessVm::Running(ref vm) => {
4178
30.0k
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s0_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s0_0Bb_
4179
30.0k
                    Ok(u64::from_le_bytes(
4180
30.0k
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| 
unreachable!()0
),
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s1_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s1_0Bb_
4181
30.0k
                    ))
4182
                }
4183
            }
4184
0
        } else if accessed_memory_page_start < current_num_pages {
4185
            // Memory access is partially in bounds. This is the most complicated situation.
4186
0
            match self.vm {
4187
0
                MemAccessVm::Prepare(ref vm) => {
4188
0
                    let partial_bytes = vm
4189
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4190
0
                        .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s2_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s2_0Bb_
4191
0
                    let partial_bytes = partial_bytes.as_ref();
4192
0
                    debug_assert!(partial_bytes.len() < 8);
4193
4194
0
                    let mut out = [0; 8];
4195
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4196
0
                    Ok(u64::from_le_bytes(out))
4197
                }
4198
0
                MemAccessVm::Running(ref vm) => {
4199
0
                    let partial_bytes = vm
4200
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4201
0
                        .unwrap_or_else(|_| unreachable!());
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s3_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory11read_le_u64s3_0Bb_
4202
0
                    let partial_bytes = partial_bytes.as_ref();
4203
0
                    debug_assert!(partial_bytes.len() < 8);
4204
4205
0
                    let mut out = [0; 8];
4206
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4207
0
                    Ok(u64::from_le_bytes(out))
4208
                }
4209
            }
4210
        } else {
4211
            // Everything out bounds. Memory is zero.
4212
0
            Ok(0)
4213
        }
4214
30.0k
    }
_RNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory11read_le_u64
Line
Count
Source
4145
27.0k
    fn read_le_u64(&self, ptr: u32) -> Result<u64, allocator::Error> {
4146
27.0k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4147
0
            return Err(allocator::Error::Other("out of bounds access"));
4148
27.0k
        }
4149
27.0k
4150
27.0k
        // Note that this function (`read_le_u64`) really should take ̀`&mut self` but that is
4151
27.0k
        // unfortunately not the case, meaning that we can't "just" grow the memory if trying
4152
27.0k
        // to access an out of bound location.
4153
27.0k
        //
4154
27.0k
        // Additionally, the value being read can in theory overlap between an allocated and
4155
27.0k
        // non-allocated parts of the memory, making this more complicated.
4156
27.0k
4157
27.0k
        // Offset of the memory page where the first byte of the value will be read.
4158
27.0k
        let accessed_memory_page_start = HeapPages::new(ptr / (64 * 1024));
4159
27.0k
        // Offset of the memory page where the last byte of the value will be read.
4160
27.0k
        let accessed_memory_page_end = HeapPages::new((ptr + 7) / (64 * 1024));
4161
        // Number of pages currently allocated.
4162
27.0k
        let current_num_pages = match self.vm {
4163
0
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4164
27.0k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4165
        };
4166
27.0k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4167
4168
27.0k
        if accessed_memory_page_end < current_num_pages {
4169
            // This is the simple case: the memory access is in bounds.
4170
27.0k
            match self.vm {
4171
0
                MemAccessVm::Prepare(ref vm) => {
4172
0
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| unreachable!());
4173
0
                    Ok(u64::from_le_bytes(
4174
0
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| unreachable!()),
4175
0
                    ))
4176
                }
4177
27.0k
                MemAccessVm::Running(ref vm) => {
4178
27.0k
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| unreachable!());
4179
27.0k
                    Ok(u64::from_le_bytes(
4180
27.0k
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| unreachable!()),
4181
27.0k
                    ))
4182
                }
4183
            }
4184
0
        } else if accessed_memory_page_start < current_num_pages {
4185
            // Memory access is partially in bounds. This is the most complicated situation.
4186
0
            match self.vm {
4187
0
                MemAccessVm::Prepare(ref vm) => {
4188
0
                    let partial_bytes = vm
4189
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4190
0
                        .unwrap_or_else(|_| unreachable!());
4191
0
                    let partial_bytes = partial_bytes.as_ref();
4192
0
                    debug_assert!(partial_bytes.len() < 8);
4193
4194
0
                    let mut out = [0; 8];
4195
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4196
0
                    Ok(u64::from_le_bytes(out))
4197
                }
4198
0
                MemAccessVm::Running(ref vm) => {
4199
0
                    let partial_bytes = vm
4200
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4201
0
                        .unwrap_or_else(|_| unreachable!());
4202
0
                    let partial_bytes = partial_bytes.as_ref();
4203
0
                    debug_assert!(partial_bytes.len() < 8);
4204
4205
0
                    let mut out = [0; 8];
4206
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4207
0
                    Ok(u64::from_le_bytes(out))
4208
                }
4209
            }
4210
        } else {
4211
            // Everything out bounds. Memory is zero.
4212
0
            Ok(0)
4213
        }
4214
27.0k
    }
_RNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory11read_le_u64
Line
Count
Source
4145
2.94k
    fn read_le_u64(&self, ptr: u32) -> Result<u64, allocator::Error> {
4146
2.94k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4147
0
            return Err(allocator::Error::Other("out of bounds access"));
4148
2.94k
        }
4149
2.94k
4150
2.94k
        // Note that this function (`read_le_u64`) really should take ̀`&mut self` but that is
4151
2.94k
        // unfortunately not the case, meaning that we can't "just" grow the memory if trying
4152
2.94k
        // to access an out of bound location.
4153
2.94k
        //
4154
2.94k
        // Additionally, the value being read can in theory overlap between an allocated and
4155
2.94k
        // non-allocated parts of the memory, making this more complicated.
4156
2.94k
4157
2.94k
        // Offset of the memory page where the first byte of the value will be read.
4158
2.94k
        let accessed_memory_page_start = HeapPages::new(ptr / (64 * 1024));
4159
2.94k
        // Offset of the memory page where the last byte of the value will be read.
4160
2.94k
        let accessed_memory_page_end = HeapPages::new((ptr + 7) / (64 * 1024));
4161
        // Number of pages currently allocated.
4162
2.94k
        let current_num_pages = match self.vm {
4163
0
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4164
2.94k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4165
        };
4166
2.94k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4167
4168
2.94k
        if accessed_memory_page_end < current_num_pages {
4169
            // This is the simple case: the memory access is in bounds.
4170
2.94k
            match self.vm {
4171
0
                MemAccessVm::Prepare(ref vm) => {
4172
0
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| unreachable!());
4173
0
                    Ok(u64::from_le_bytes(
4174
0
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| unreachable!()),
4175
0
                    ))
4176
                }
4177
2.94k
                MemAccessVm::Running(ref vm) => {
4178
2.94k
                    let bytes = vm.read_memory(ptr, 8).unwrap_or_else(|_| unreachable!());
4179
2.94k
                    Ok(u64::from_le_bytes(
4180
2.94k
                        <[u8; 8]>::try_from(bytes.as_ref()).unwrap_or_else(|_| unreachable!()),
4181
2.94k
                    ))
4182
                }
4183
            }
4184
0
        } else if accessed_memory_page_start < current_num_pages {
4185
            // Memory access is partially in bounds. This is the most complicated situation.
4186
0
            match self.vm {
4187
0
                MemAccessVm::Prepare(ref vm) => {
4188
0
                    let partial_bytes = vm
4189
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4190
0
                        .unwrap_or_else(|_| unreachable!());
4191
0
                    let partial_bytes = partial_bytes.as_ref();
4192
0
                    debug_assert!(partial_bytes.len() < 8);
4193
4194
0
                    let mut out = [0; 8];
4195
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4196
0
                    Ok(u64::from_le_bytes(out))
4197
                }
4198
0
                MemAccessVm::Running(ref vm) => {
4199
0
                    let partial_bytes = vm
4200
0
                        .read_memory(ptr, u32::from(current_num_pages) * 64 * 1024 - ptr)
4201
0
                        .unwrap_or_else(|_| unreachable!());
4202
0
                    let partial_bytes = partial_bytes.as_ref();
4203
0
                    debug_assert!(partial_bytes.len() < 8);
4204
4205
0
                    let mut out = [0; 8];
4206
0
                    out[..partial_bytes.len()].copy_from_slice(partial_bytes);
4207
0
                    Ok(u64::from_le_bytes(out))
4208
                }
4209
            }
4210
        } else {
4211
            // Everything out bounds. Memory is zero.
4212
0
            Ok(0)
4213
        }
4214
2.94k
    }
4215
4216
33.8k
    fn write_le_u64(&mut self, ptr: u32, val: u64) -> Result<(), allocator::Error> {
4217
33.8k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4218
0
            return Err(allocator::Error::Other("out of bounds access"));
4219
33.8k
        }
4220
33.8k
4221
33.8k
        let bytes = val.to_le_bytes();
4222
33.8k
4223
33.8k
        // Offset of the memory page where the last byte of the value will be written.
4224
33.8k
        let written_memory_page = HeapPages::new((ptr + 7) / (64 * 1024));
4225
4226
        // Grow the memory more if necessary.
4227
        // Please note the `<=`. For example if we write to page 0, we want to have at least 1 page
4228
        // allocated.
4229
33.8k
        let current_num_pages = match self.vm {
4230
179
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4231
33.6k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4232
        };
4233
33.8k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4234
33.8k
        if current_num_pages <= written_memory_page {
4235
            // For now, we grow the memory just enough to fit.
4236
            // TODO: do better
4237
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
4238
            // in case `written_memory_page` is the maximum possible value.
4239
19
            let to_grow = written_memory_page - current_num_pages + HeapPages::new(1);
4240
19
4241
19
            // We check at initialization that the virtual machine is capable of growing up to
4242
19
            // `memory_total_pages`, meaning that this can't panic.
4243
19
            match self.vm {
4244
14
                MemAccessVm::Prepare(ref mut vm) => {
4245
14
                    vm.grow_memory(to_grow).unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u640Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u640Bb_
4246
                }
4247
5
                MemAccessVm::Running(ref mut vm) => {
4248
5
                    vm.grow_memory(to_grow).unwrap_or_else(|_| 
unreachable!()0
)
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s_0Bb_
4249
                }
4250
            }
4251
33.7k
        }
4252
4253
33.8k
        match self.vm {
4254
179
            MemAccessVm::Prepare(ref mut vm) => vm
4255
179
                .write_memory(ptr, &bytes)
4256
179
                .unwrap_or_else(|_| 
unreachable!()0
),
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s0_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s0_0Bb_
4257
33.6k
            MemAccessVm::Running(ref mut vm) => vm
4258
33.6k
                .write_memory(ptr, &bytes)
4259
33.6k
                .unwrap_or_else(|_| 
unreachable!()0
),
Unexecuted instantiation: _RNCNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s1_0Bb_
Unexecuted instantiation: _RNCNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB7_9MemAccessNtNtB9_9allocator6Memory12write_le_u64s1_0Bb_
4260
        }
4261
33.8k
        Ok(())
4262
33.8k
    }
_RNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory12write_le_u64
Line
Count
Source
4216
28.7k
    fn write_le_u64(&mut self, ptr: u32, val: u64) -> Result<(), allocator::Error> {
4217
28.7k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4218
0
            return Err(allocator::Error::Other("out of bounds access"));
4219
28.7k
        }
4220
28.7k
4221
28.7k
        let bytes = val.to_le_bytes();
4222
28.7k
4223
28.7k
        // Offset of the memory page where the last byte of the value will be written.
4224
28.7k
        let written_memory_page = HeapPages::new((ptr + 7) / (64 * 1024));
4225
4226
        // Grow the memory more if necessary.
4227
        // Please note the `<=`. For example if we write to page 0, we want to have at least 1 page
4228
        // allocated.
4229
28.7k
        let current_num_pages = match self.vm {
4230
52
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4231
28.6k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4232
        };
4233
28.7k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4234
28.7k
        if current_num_pages <= written_memory_page {
4235
            // For now, we grow the memory just enough to fit.
4236
            // TODO: do better
4237
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
4238
            // in case `written_memory_page` is the maximum possible value.
4239
18
            let to_grow = written_memory_page - current_num_pages + HeapPages::new(1);
4240
18
4241
18
            // We check at initialization that the virtual machine is capable of growing up to
4242
18
            // `memory_total_pages`, meaning that this can't panic.
4243
18
            match self.vm {
4244
14
                MemAccessVm::Prepare(ref mut vm) => {
4245
14
                    vm.grow_memory(to_grow).unwrap_or_else(|_| unreachable!())
4246
                }
4247
4
                MemAccessVm::Running(ref mut vm) => {
4248
4
                    vm.grow_memory(to_grow).unwrap_or_else(|_| unreachable!())
4249
                }
4250
            }
4251
28.7k
        }
4252
4253
28.7k
        match self.vm {
4254
52
            MemAccessVm::Prepare(ref mut vm) => vm
4255
52
                .write_memory(ptr, &bytes)
4256
52
                .unwrap_or_else(|_| unreachable!()),
4257
28.6k
            MemAccessVm::Running(ref mut vm) => vm
4258
28.6k
                .write_memory(ptr, &bytes)
4259
28.6k
                .unwrap_or_else(|_| unreachable!()),
4260
        }
4261
28.7k
        Ok(())
4262
28.7k
    }
_RNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory12write_le_u64
Line
Count
Source
4216
5.07k
    fn write_le_u64(&mut self, ptr: u32, val: u64) -> Result<(), allocator::Error> {
4217
5.07k
        if (ptr + 8) > u32::from(self.memory_total_pages) * 64 * 1024 {
4218
0
            return Err(allocator::Error::Other("out of bounds access"));
4219
5.07k
        }
4220
5.07k
4221
5.07k
        let bytes = val.to_le_bytes();
4222
5.07k
4223
5.07k
        // Offset of the memory page where the last byte of the value will be written.
4224
5.07k
        let written_memory_page = HeapPages::new((ptr + 7) / (64 * 1024));
4225
4226
        // Grow the memory more if necessary.
4227
        // Please note the `<=`. For example if we write to page 0, we want to have at least 1 page
4228
        // allocated.
4229
5.07k
        let current_num_pages = match self.vm {
4230
127
            MemAccessVm::Prepare(ref vm) => vm.memory_size(),
4231
4.94k
            MemAccessVm::Running(ref vm) => vm.memory_size(),
4232
        };
4233
5.07k
        debug_assert!(current_num_pages <= self.memory_total_pages);
4234
5.07k
        if current_num_pages <= written_memory_page {
4235
            // For now, we grow the memory just enough to fit.
4236
            // TODO: do better
4237
            // Note the order of operations: we add 1 at the end to avoid a potential overflow
4238
            // in case `written_memory_page` is the maximum possible value.
4239
1
            let to_grow = written_memory_page - current_num_pages + HeapPages::new(1);
4240
1
4241
1
            // We check at initialization that the virtual machine is capable of growing up to
4242
1
            // `memory_total_pages`, meaning that this can't panic.
4243
1
            match self.vm {
4244
0
                MemAccessVm::Prepare(ref mut vm) => {
4245
0
                    vm.grow_memory(to_grow).unwrap_or_else(|_| unreachable!())
4246
                }
4247
1
                MemAccessVm::Running(ref mut vm) => {
4248
1
                    vm.grow_memory(to_grow).unwrap_or_else(|_| unreachable!())
4249
                }
4250
            }
4251
5.07k
        }
4252
4253
5.07k
        match self.vm {
4254
127
            MemAccessVm::Prepare(ref mut vm) => vm
4255
127
                .write_memory(ptr, &bytes)
4256
127
                .unwrap_or_else(|_| unreachable!()),
4257
4.94k
            MemAccessVm::Running(ref mut vm) => vm
4258
4.94k
                .write_memory(ptr, &bytes)
4259
4.94k
                .unwrap_or_else(|_| unreachable!()),
4260
        }
4261
5.07k
        Ok(())
4262
5.07k
    }
4263
4264
84.6k
    fn size(&self) -> u32 {
4265
84.6k
        // Lie to the allocator to pretend that `memory_total_pages` are available.
4266
84.6k
        u32::from(self.memory_total_pages)
4267
84.6k
            .saturating_mul(64)
4268
84.6k
            .saturating_mul(1024)
4269
84.6k
    }
_RNvXsN_NtNtCsN16ciHI6Qf_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory4size
Line
Count
Source
4264
71.8k
    fn size(&self) -> u32 {
4265
71.8k
        // Lie to the allocator to pretend that `memory_total_pages` are available.
4266
71.8k
        u32::from(self.memory_total_pages)
4267
71.8k
            .saturating_mul(64)
4268
71.8k
            .saturating_mul(1024)
4269
71.8k
    }
_RNvXsN_NtNtCseuYC0Zibziv_7smoldot8executor4hostNtB5_9MemAccessNtNtB7_9allocator6Memory4size
Line
Count
Source
4264
12.8k
    fn size(&self) -> u32 {
4265
12.8k
        // Lie to the allocator to pretend that `memory_total_pages` are available.
4266
12.8k
        u32::from(self.memory_total_pages)
4267
12.8k
            .saturating_mul(64)
4268
12.8k
            .saturating_mul(1024)
4269
12.8k
    }
4270
}