/__w/smoldot/smoldot/repo/lib/src/executor/host/runtime_version.rs
Line | Count | Source |
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 runtimes can optionally contain a custom section (as defined in the official WebAssembly |
19 | | //! core specification). |
20 | | //! |
21 | | //! This module is dedicated to finding the custom sections containing the runtime version. |
22 | | |
23 | | use crate::executor::host; |
24 | | |
25 | | use alloc::vec::Vec; |
26 | | use core::{fmt, ops, str}; |
27 | | |
28 | | pub use super::TrieEntryVersion; |
29 | | |
30 | | /// Tries to find the custom section containing the runtime version and checks its validity. |
31 | 152 | pub fn find_embedded_runtime_version( |
32 | 152 | binary_wasm_module: &[u8], |
33 | 152 | ) -> Result<Option<CoreVersion>, FindEmbeddedRuntimeVersionError> { |
34 | 147 | let (runtime_version_content, runtime_apis_content) = |
35 | 152 | match find_encoded_embedded_runtime_version_apis(binary_wasm_module) { |
36 | | Ok(EmbeddedRuntimeVersionApis { |
37 | 147 | runtime_version_content: Some(v), |
38 | 147 | runtime_apis_content: Some(a), |
39 | 147 | }) => (v, a), |
40 | | Ok(EmbeddedRuntimeVersionApis { |
41 | | runtime_version_content: None, |
42 | | runtime_apis_content: None, |
43 | 1 | }) => return Ok(None), |
44 | 2 | Ok(_) => return Err(FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch), |
45 | 2 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::FindSections(err)), |
46 | | }; |
47 | | |
48 | 147 | let mut decoded_runtime_version = match decode(runtime_version_content) { |
49 | 147 | Ok(d) => d, |
50 | 0 | Err(()) => return Err(FindEmbeddedRuntimeVersionError::RuntimeVersionDecode), |
51 | | }; |
52 | | |
53 | | decoded_runtime_version.apis = |
54 | 147 | match CoreVersionApisRefIter::from_slice_no_length(runtime_apis_content) { |
55 | 147 | Ok(d) => d, |
56 | 0 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)), |
57 | | }; |
58 | | |
59 | 147 | Ok(Some(CoreVersion( |
60 | 147 | decoded_runtime_version.scale_encoding_vec(), |
61 | 147 | ))) |
62 | 152 | } _RNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version29find_embedded_runtime_version Line | Count | Source | 31 | 66 | pub fn find_embedded_runtime_version( | 32 | 66 | binary_wasm_module: &[u8], | 33 | 66 | ) -> Result<Option<CoreVersion>, FindEmbeddedRuntimeVersionError> { | 34 | 61 | let (runtime_version_content, runtime_apis_content) = | 35 | 66 | match find_encoded_embedded_runtime_version_apis(binary_wasm_module) { | 36 | | Ok(EmbeddedRuntimeVersionApis { | 37 | 61 | runtime_version_content: Some(v), | 38 | 61 | runtime_apis_content: Some(a), | 39 | 61 | }) => (v, a), | 40 | | Ok(EmbeddedRuntimeVersionApis { | 41 | | runtime_version_content: None, | 42 | | runtime_apis_content: None, | 43 | 1 | }) => return Ok(None), | 44 | 2 | Ok(_) => return Err(FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch), | 45 | 2 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::FindSections(err)), | 46 | | }; | 47 | | | 48 | 61 | let mut decoded_runtime_version = match decode(runtime_version_content) { | 49 | 61 | Ok(d) => d, | 50 | 0 | Err(()) => return Err(FindEmbeddedRuntimeVersionError::RuntimeVersionDecode), | 51 | | }; | 52 | | | 53 | | decoded_runtime_version.apis = | 54 | 61 | match CoreVersionApisRefIter::from_slice_no_length(runtime_apis_content) { | 55 | 61 | Ok(d) => d, | 56 | 0 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)), | 57 | | }; | 58 | | | 59 | 61 | Ok(Some(CoreVersion( | 60 | 61 | decoded_runtime_version.scale_encoding_vec(), | 61 | 61 | ))) | 62 | 66 | } |
_RNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version29find_embedded_runtime_version Line | Count | Source | 31 | 86 | pub fn find_embedded_runtime_version( | 32 | 86 | binary_wasm_module: &[u8], | 33 | 86 | ) -> Result<Option<CoreVersion>, FindEmbeddedRuntimeVersionError> { | 34 | 86 | let (runtime_version_content, runtime_apis_content) = | 35 | 86 | match find_encoded_embedded_runtime_version_apis(binary_wasm_module) { | 36 | | Ok(EmbeddedRuntimeVersionApis { | 37 | 86 | runtime_version_content: Some(v), | 38 | 86 | runtime_apis_content: Some(a), | 39 | 86 | }) => (v, a), | 40 | | Ok(EmbeddedRuntimeVersionApis { | 41 | | runtime_version_content: None, | 42 | | runtime_apis_content: None, | 43 | 0 | }) => return Ok(None), | 44 | 0 | Ok(_) => return Err(FindEmbeddedRuntimeVersionError::CustomSectionsPresenceMismatch), | 45 | 0 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::FindSections(err)), | 46 | | }; | 47 | | | 48 | 86 | let mut decoded_runtime_version = match decode(runtime_version_content) { | 49 | 86 | Ok(d) => d, | 50 | 0 | Err(()) => return Err(FindEmbeddedRuntimeVersionError::RuntimeVersionDecode), | 51 | | }; | 52 | | | 53 | | decoded_runtime_version.apis = | 54 | 86 | match CoreVersionApisRefIter::from_slice_no_length(runtime_apis_content) { | 55 | 86 | Ok(d) => d, | 56 | 0 | Err(err) => return Err(FindEmbeddedRuntimeVersionError::RuntimeApisDecode(err)), | 57 | | }; | 58 | | | 59 | 86 | Ok(Some(CoreVersion( | 60 | 86 | decoded_runtime_version.scale_encoding_vec(), | 61 | 86 | ))) | 62 | 86 | } |
|
63 | | |
64 | | /// Error returned by [`find_embedded_runtime_version`]. |
65 | | #[derive(Debug, derive_more::Display, derive_more::Error, Clone)] |
66 | | pub enum FindEmbeddedRuntimeVersionError { |
67 | | /// Error while finding the custom section. |
68 | | #[display("{_0}")] |
69 | | FindSections(FindEncodedEmbeddedRuntimeVersionApisError), |
70 | | /// Only one of the two desired custom sections is present. |
71 | | CustomSectionsPresenceMismatch, |
72 | | /// Error while decoding the runtime version. |
73 | | RuntimeVersionDecode, |
74 | | /// Error while decoding the runtime APIs. |
75 | | #[display("{_0}")] |
76 | | RuntimeApisDecode(CoreVersionApisFromSliceErr), |
77 | | } |
78 | | |
79 | | /// Returns by [`find_encoded_embedded_runtime_version_apis`]. |
80 | | #[derive(Debug, Copy, Clone)] |
81 | | pub struct EmbeddedRuntimeVersionApis<'a> { |
82 | | /// Content of the `runtime_version` section, if any was found. |
83 | | pub runtime_version_content: Option<&'a [u8]>, |
84 | | /// Content of the `runtime_apis` section, if any was found. |
85 | | pub runtime_apis_content: Option<&'a [u8]>, |
86 | | } |
87 | | |
88 | | /// Tries to find the custom sections containing the runtime version and APIs. |
89 | | /// |
90 | | /// This function does not attempt to decode the content of the custom sections. |
91 | 152 | pub fn find_encoded_embedded_runtime_version_apis( |
92 | 152 | binary_wasm_module: &[u8], |
93 | 152 | ) -> Result<EmbeddedRuntimeVersionApis, FindEncodedEmbeddedRuntimeVersionApisError> { |
94 | 152 | let mut parser = |
95 | 152 | nom::combinator::all_consuming(nom::combinator::complete(nom::sequence::preceded( |
96 | 152 | ( |
97 | 152 | nom::bytes::streaming::tag(&b"\0asm"[..]), |
98 | 152 | nom::bytes::streaming::tag(&[0x1, 0x0, 0x0, 0x0][..]), |
99 | 152 | ), |
100 | 152 | nom::multi::fold_many0( |
101 | 152 | nom::combinator::complete(wasm_section), |
102 | 150 | || (None, None), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apis0B9_ Line | Count | Source | 102 | 64 | || (None, None), |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apis0B9_ Line | Count | Source | 102 | 86 | || (None, None), |
|
103 | 1.70k | move |prev_found, in_section| { |
104 | 1.70k | match (prev_found, in_section) { |
105 | | // Not a custom section. |
106 | 1.21k | (prev_found, None) => prev_found, |
107 | | |
108 | | // We found a custom section with a name that interests us, but we already |
109 | | // parsed a custom section with that same name earlier. Continue with the |
110 | | // value that was parsed earlier. |
111 | | ( |
112 | 0 | prev_found @ (Some(_), _), |
113 | | Some(WasmSection { |
114 | 235 | name: b"runtime_version", |
115 | | .. |
116 | | }), |
117 | 0 | ) => prev_found, |
118 | | ( |
119 | 0 | prev_found @ (_, Some(_)), |
120 | | Some(WasmSection { |
121 | 278 | name: b"runtime_apis", |
122 | | .. |
123 | | }), |
124 | 0 | ) => prev_found, |
125 | | |
126 | | // Found a custom section that interests us, and we didn't find one |
127 | | // before. |
128 | | ( |
129 | 147 | (None, prev_rt_apis), |
130 | | Some(WasmSection { |
131 | 253 | name: b"runtime_version", |
132 | 147 | content, |
133 | | }), |
134 | 147 | ) => (Some(content), prev_rt_apis), |
135 | | ( |
136 | 149 | (prev_rt_version, None), |
137 | | Some(WasmSection { |
138 | 156 | name: b"runtime_apis", |
139 | 149 | content, |
140 | | }), |
141 | 149 | ) => (prev_rt_version, Some(content)), |
142 | | |
143 | | // Found a custom section with a name that doesn't interest us. |
144 | 192 | (prev_found, Some(_)) => prev_found, |
145 | | } |
146 | 1.70k | }, _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apiss_0B9_ Line | Count | Source | 103 | 582 | move |prev_found, in_section| { | 104 | 582 | match (prev_found, in_section) { | 105 | | // Not a custom section. | 106 | 438 | (prev_found, None) => prev_found, | 107 | | | 108 | | // We found a custom section with a name that interests us, but we already | 109 | | // parsed a custom section with that same name earlier. Continue with the | 110 | | // value that was parsed earlier. | 111 | | ( | 112 | 0 | prev_found @ (Some(_), _), | 113 | | Some(WasmSection { | 114 | 63 | name: b"runtime_version", | 115 | | .. | 116 | | }), | 117 | 0 | ) => prev_found, | 118 | | ( | 119 | 0 | prev_found @ (_, Some(_)), | 120 | | Some(WasmSection { | 121 | 20 | name: b"runtime_apis", | 122 | | .. | 123 | | }), | 124 | 0 | ) => prev_found, | 125 | | | 126 | | // Found a custom section that interests us, and we didn't find one | 127 | | // before. | 128 | | ( | 129 | 61 | (None, prev_rt_apis), | 130 | | Some(WasmSection { | 131 | 81 | name: b"runtime_version", | 132 | 61 | content, | 133 | | }), | 134 | 61 | ) => (Some(content), prev_rt_apis), | 135 | | ( | 136 | 63 | (prev_rt_version, None), | 137 | | Some(WasmSection { | 138 | 70 | name: b"runtime_apis", | 139 | 63 | content, | 140 | | }), | 141 | 63 | ) => (prev_rt_version, Some(content)), | 142 | | | 143 | | // Found a custom section with a name that doesn't interest us. | 144 | 20 | (prev_found, Some(_)) => prev_found, | 145 | | } | 146 | 582 | }, |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apiss_0B9_ Line | Count | Source | 103 | 1.11k | move |prev_found, in_section| { | 104 | 1.11k | match (prev_found, in_section) { | 105 | | // Not a custom section. | 106 | 774 | (prev_found, None) => prev_found, | 107 | | | 108 | | // We found a custom section with a name that interests us, but we already | 109 | | // parsed a custom section with that same name earlier. Continue with the | 110 | | // value that was parsed earlier. | 111 | | ( | 112 | 0 | prev_found @ (Some(_), _), | 113 | | Some(WasmSection { | 114 | 172 | name: b"runtime_version", | 115 | | .. | 116 | | }), | 117 | 0 | ) => prev_found, | 118 | | ( | 119 | 0 | prev_found @ (_, Some(_)), | 120 | | Some(WasmSection { | 121 | 258 | name: b"runtime_apis", | 122 | | .. | 123 | | }), | 124 | 0 | ) => prev_found, | 125 | | | 126 | | // Found a custom section that interests us, and we didn't find one | 127 | | // before. | 128 | | ( | 129 | 86 | (None, prev_rt_apis), | 130 | | Some(WasmSection { | 131 | 172 | name: b"runtime_version", | 132 | 86 | content, | 133 | | }), | 134 | 86 | ) => (Some(content), prev_rt_apis), | 135 | | ( | 136 | 86 | (prev_rt_version, None), | 137 | | Some(WasmSection { | 138 | 86 | name: b"runtime_apis", | 139 | 86 | content, | 140 | | }), | 141 | 86 | ) => (prev_rt_version, Some(content)), | 142 | | | 143 | | // Found a custom section with a name that doesn't interest us. | 144 | 172 | (prev_found, Some(_)) => prev_found, | 145 | | } | 146 | 1.11k | }, |
|
147 | | ), |
148 | | ))); |
149 | | |
150 | 150 | let (runtime_version_content, runtime_apis_content) = |
151 | 152 | match nom::Parser::parse(&mut parser, binary_wasm_module) { |
152 | 150 | Ok((_, content)) => content, |
153 | 2 | Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse), |
154 | | }; |
155 | | |
156 | 150 | Ok(EmbeddedRuntimeVersionApis { |
157 | 150 | runtime_version_content, |
158 | 150 | runtime_apis_content, |
159 | 150 | }) |
160 | 152 | } _RNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apis Line | Count | Source | 91 | 66 | pub fn find_encoded_embedded_runtime_version_apis( | 92 | 66 | binary_wasm_module: &[u8], | 93 | 66 | ) -> Result<EmbeddedRuntimeVersionApis, FindEncodedEmbeddedRuntimeVersionApisError> { | 94 | 66 | let mut parser = | 95 | 66 | nom::combinator::all_consuming(nom::combinator::complete(nom::sequence::preceded( | 96 | 66 | ( | 97 | 66 | nom::bytes::streaming::tag(&b"\0asm"[..]), | 98 | 66 | nom::bytes::streaming::tag(&[0x1, 0x0, 0x0, 0x0][..]), | 99 | 66 | ), | 100 | 66 | nom::multi::fold_many0( | 101 | 66 | nom::combinator::complete(wasm_section), | 102 | | || (None, None), | 103 | | move |prev_found, in_section| { | 104 | | match (prev_found, in_section) { | 105 | | // Not a custom section. | 106 | | (prev_found, None) => prev_found, | 107 | | | 108 | | // We found a custom section with a name that interests us, but we already | 109 | | // parsed a custom section with that same name earlier. Continue with the | 110 | | // value that was parsed earlier. | 111 | | ( | 112 | | prev_found @ (Some(_), _), | 113 | | Some(WasmSection { | 114 | | name: b"runtime_version", | 115 | | .. | 116 | | }), | 117 | | ) => prev_found, | 118 | | ( | 119 | | prev_found @ (_, Some(_)), | 120 | | Some(WasmSection { | 121 | | name: b"runtime_apis", | 122 | | .. | 123 | | }), | 124 | | ) => prev_found, | 125 | | | 126 | | // Found a custom section that interests us, and we didn't find one | 127 | | // before. | 128 | | ( | 129 | | (None, prev_rt_apis), | 130 | | Some(WasmSection { | 131 | | name: b"runtime_version", | 132 | | content, | 133 | | }), | 134 | | ) => (Some(content), prev_rt_apis), | 135 | | ( | 136 | | (prev_rt_version, None), | 137 | | Some(WasmSection { | 138 | | name: b"runtime_apis", | 139 | | content, | 140 | | }), | 141 | | ) => (prev_rt_version, Some(content)), | 142 | | | 143 | | // Found a custom section with a name that doesn't interest us. | 144 | | (prev_found, Some(_)) => prev_found, | 145 | | } | 146 | | }, | 147 | | ), | 148 | | ))); | 149 | | | 150 | 64 | let (runtime_version_content, runtime_apis_content) = | 151 | 66 | match nom::Parser::parse(&mut parser, binary_wasm_module) { | 152 | 64 | Ok((_, content)) => content, | 153 | 2 | Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse), | 154 | | }; | 155 | | | 156 | 64 | Ok(EmbeddedRuntimeVersionApis { | 157 | 64 | runtime_version_content, | 158 | 64 | runtime_apis_content, | 159 | 64 | }) | 160 | 66 | } |
_RNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apis Line | Count | Source | 91 | 86 | pub fn find_encoded_embedded_runtime_version_apis( | 92 | 86 | binary_wasm_module: &[u8], | 93 | 86 | ) -> Result<EmbeddedRuntimeVersionApis, FindEncodedEmbeddedRuntimeVersionApisError> { | 94 | 86 | let mut parser = | 95 | 86 | nom::combinator::all_consuming(nom::combinator::complete(nom::sequence::preceded( | 96 | 86 | ( | 97 | 86 | nom::bytes::streaming::tag(&b"\0asm"[..]), | 98 | 86 | nom::bytes::streaming::tag(&[0x1, 0x0, 0x0, 0x0][..]), | 99 | 86 | ), | 100 | 86 | nom::multi::fold_many0( | 101 | 86 | nom::combinator::complete(wasm_section), | 102 | | || (None, None), | 103 | | move |prev_found, in_section| { | 104 | | match (prev_found, in_section) { | 105 | | // Not a custom section. | 106 | | (prev_found, None) => prev_found, | 107 | | | 108 | | // We found a custom section with a name that interests us, but we already | 109 | | // parsed a custom section with that same name earlier. Continue with the | 110 | | // value that was parsed earlier. | 111 | | ( | 112 | | prev_found @ (Some(_), _), | 113 | | Some(WasmSection { | 114 | | name: b"runtime_version", | 115 | | .. | 116 | | }), | 117 | | ) => prev_found, | 118 | | ( | 119 | | prev_found @ (_, Some(_)), | 120 | | Some(WasmSection { | 121 | | name: b"runtime_apis", | 122 | | .. | 123 | | }), | 124 | | ) => prev_found, | 125 | | | 126 | | // Found a custom section that interests us, and we didn't find one | 127 | | // before. | 128 | | ( | 129 | | (None, prev_rt_apis), | 130 | | Some(WasmSection { | 131 | | name: b"runtime_version", | 132 | | content, | 133 | | }), | 134 | | ) => (Some(content), prev_rt_apis), | 135 | | ( | 136 | | (prev_rt_version, None), | 137 | | Some(WasmSection { | 138 | | name: b"runtime_apis", | 139 | | content, | 140 | | }), | 141 | | ) => (prev_rt_version, Some(content)), | 142 | | | 143 | | // Found a custom section with a name that doesn't interest us. | 144 | | (prev_found, Some(_)) => prev_found, | 145 | | } | 146 | | }, | 147 | | ), | 148 | | ))); | 149 | | | 150 | 86 | let (runtime_version_content, runtime_apis_content) = | 151 | 86 | match nom::Parser::parse(&mut parser, binary_wasm_module) { | 152 | 86 | Ok((_, content)) => content, | 153 | 0 | Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse), | 154 | | }; | 155 | | | 156 | 86 | Ok(EmbeddedRuntimeVersionApis { | 157 | 86 | runtime_version_content, | 158 | 86 | runtime_apis_content, | 159 | 86 | }) | 160 | 86 | } |
|
161 | | |
162 | | /// Error returned by [`find_encoded_embedded_runtime_version_apis`]. |
163 | | #[derive(Debug, derive_more::Display, derive_more::Error, Clone)] |
164 | | pub enum FindEncodedEmbeddedRuntimeVersionApisError { |
165 | | /// Failed to parse Wasm binary. |
166 | | FailedToParse, |
167 | | } |
168 | | |
169 | | /// Error while executing `Core_version`. |
170 | | #[derive(Debug, derive_more::Display, derive_more::Error, Clone)] |
171 | | pub enum CoreVersionError { |
172 | | /// Error while decoding the output. |
173 | | Decode, |
174 | | /// Error while starting the execution of the `Core_version` function. |
175 | | #[display("Error while starting the execution of the `Core_version` function: {_0}")] |
176 | | Start(host::StartErr), |
177 | | /// Error during the execution of the `Core_version` function. |
178 | | #[display("Error during the execution of the `Core_version` function: {_0}")] |
179 | | Run(host::Error), |
180 | | /// `Core_version` used a host function that is forbidden in this context. |
181 | | ForbiddenHostFunction, |
182 | | } |
183 | | |
184 | | /// Buffer storing the SCALE-encoded core version. |
185 | | #[derive(Debug, Clone, PartialEq, Eq)] |
186 | | pub struct CoreVersion(Vec<u8>); |
187 | | |
188 | | impl CoreVersion { |
189 | 3 | pub fn from_slice(input: Vec<u8>) -> Result<Self, Vec<u8>> { |
190 | 3 | if decode(&input).is_err() { |
191 | 0 | return Err(input); |
192 | 3 | } |
193 | | |
194 | 3 | Ok(CoreVersion(input)) |
195 | 3 | } _RNvMNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion10from_slice Line | Count | Source | 189 | 3 | pub fn from_slice(input: Vec<u8>) -> Result<Self, Vec<u8>> { | 190 | 3 | if decode(&input).is_err() { | 191 | 0 | return Err(input); | 192 | 3 | } | 193 | | | 194 | 3 | Ok(CoreVersion(input)) | 195 | 3 | } |
Unexecuted instantiation: _RNvMNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion10from_slice |
196 | | |
197 | 233 | pub fn decode(&self) -> CoreVersionRef { |
198 | 233 | decode(&self.0).unwrap() |
199 | 233 | } _RNvMNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion6decode Line | Count | Source | 197 | 21 | pub fn decode(&self) -> CoreVersionRef { | 198 | 21 | decode(&self.0).unwrap() | 199 | 21 | } |
_RNvMNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion6decode Line | Count | Source | 197 | 212 | pub fn decode(&self) -> CoreVersionRef { | 198 | 212 | decode(&self.0).unwrap() | 199 | 212 | } |
|
200 | | } |
201 | | |
202 | | impl AsRef<[u8]> for CoreVersion { |
203 | 0 | fn as_ref(&self) -> &[u8] { |
204 | 0 | &self.0 |
205 | 0 | } Unexecuted instantiation: _RNvXs_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB4_11CoreVersionINtNtCs1p5UDGgVI4d_4core7convert5AsRefShE6as_ref Unexecuted instantiation: _RNvXs_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB4_11CoreVersionINtNtCs1p5UDGgVI4d_4core7convert5AsRefShE6as_ref |
206 | | } |
207 | | |
208 | | /// Runtime specification, once decoded. |
209 | | // TODO: explain these fields |
210 | | #[derive(Debug, Clone, PartialEq, Eq)] |
211 | | pub struct CoreVersionRef<'a> { |
212 | | pub spec_name: &'a str, |
213 | | pub impl_name: &'a str, |
214 | | pub authoring_version: u32, |
215 | | pub spec_version: u32, |
216 | | pub impl_version: u32, |
217 | | |
218 | | /// List of "API"s that the runtime supports. |
219 | | /// |
220 | | /// Each API corresponds to a certain list of runtime entry points. |
221 | | /// |
222 | | /// This field can thus be used in order to determine which runtime entry points are |
223 | | /// available. |
224 | | pub apis: CoreVersionApisRefIter<'a>, |
225 | | |
226 | | /// Arbitrary version number corresponding to the transactions encoding version. |
227 | | /// |
228 | | /// Whenever this version number changes, all transactions encoding generated earlier are |
229 | | /// invalidated and should be regenerated. |
230 | | /// |
231 | | /// Older versions of Substrate didn't provide this field. `None` if the field is missing. |
232 | | pub transaction_version: Option<u32>, |
233 | | |
234 | | /// Version number of the state trie encoding version. |
235 | | /// |
236 | | /// Version 0 corresponds to a different trie encoding than version 1. |
237 | | /// |
238 | | /// This field has been added to Substrate on 24th December 2021. Older versions of Substrate |
239 | | /// didn't provide this field, in which case it will contain `None`. |
240 | | /// |
241 | | /// `None` should be interpreted the same way as `Some(0)`. |
242 | | pub state_version: Option<TrieEntryVersion>, |
243 | | } |
244 | | |
245 | | impl CoreVersionRef<'_> { |
246 | | /// Returns the SCALE encoding of this data structure. |
247 | 147 | pub fn scale_encoding_vec(&self) -> Vec<u8> { |
248 | | // See https://spec.polkadot.network/#defn-rt-core-version |
249 | | |
250 | 147 | let num_apis = self.apis.clone().count(); |
251 | | |
252 | | // Reserve enough capacity for the various calls to `extend` below. |
253 | | // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded |
254 | | // lengths. In the case of very very very long names, the capacity might be too low. |
255 | 147 | let mut out = Vec::<u8>::with_capacity( |
256 | 147 | 2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1, |
257 | | ); |
258 | | |
259 | 147 | out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref()); |
260 | 147 | out.extend(self.spec_name.as_bytes()); |
261 | | |
262 | 147 | out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref()); |
263 | 147 | out.extend(self.impl_name.as_bytes()); |
264 | | |
265 | 147 | out.extend(self.authoring_version.to_le_bytes()); |
266 | 147 | out.extend(self.spec_version.to_le_bytes()); |
267 | 147 | out.extend(self.impl_version.to_le_bytes()); |
268 | | |
269 | 147 | out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref()); |
270 | 945 | for api in self.apis147 .clone147 () { |
271 | 945 | out.extend(api.name_hash); |
272 | 945 | out.extend(api.version.to_le_bytes()); |
273 | 945 | } |
274 | | |
275 | 147 | if let Some(transaction_version) = self.transaction_version { |
276 | 147 | out.extend(transaction_version.to_le_bytes()); |
277 | 147 | }0 |
278 | | |
279 | | // TODO: it's not supposed to be allowed to have a CoreVersionRef with a state_version but no transaction_version; the CoreVersionRef struct lets you do that because it was initially designed only for decoding |
280 | 147 | if let Some(state_version61 ) = self.state_version { |
281 | 61 | out.extend(u8::from(state_version).to_le_bytes()); |
282 | 86 | } |
283 | | |
284 | 147 | out |
285 | 147 | } _RNvMs0_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_14CoreVersionRef18scale_encoding_vec Line | Count | Source | 247 | 61 | pub fn scale_encoding_vec(&self) -> Vec<u8> { | 248 | | // See https://spec.polkadot.network/#defn-rt-core-version | 249 | | | 250 | 61 | let num_apis = self.apis.clone().count(); | 251 | | | 252 | | // Reserve enough capacity for the various calls to `extend` below. | 253 | | // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded | 254 | | // lengths. In the case of very very very long names, the capacity might be too low. | 255 | 61 | let mut out = Vec::<u8>::with_capacity( | 256 | 61 | 2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1, | 257 | | ); | 258 | | | 259 | 61 | out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref()); | 260 | 61 | out.extend(self.spec_name.as_bytes()); | 261 | | | 262 | 61 | out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref()); | 263 | 61 | out.extend(self.impl_name.as_bytes()); | 264 | | | 265 | 61 | out.extend(self.authoring_version.to_le_bytes()); | 266 | 61 | out.extend(self.spec_version.to_le_bytes()); | 267 | 61 | out.extend(self.impl_version.to_le_bytes()); | 268 | | | 269 | 61 | out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref()); | 270 | 85 | for api in self.apis61 .clone61 () { | 271 | 85 | out.extend(api.name_hash); | 272 | 85 | out.extend(api.version.to_le_bytes()); | 273 | 85 | } | 274 | | | 275 | 61 | if let Some(transaction_version) = self.transaction_version { | 276 | 61 | out.extend(transaction_version.to_le_bytes()); | 277 | 61 | }0 | 278 | | | 279 | | // TODO: it's not supposed to be allowed to have a CoreVersionRef with a state_version but no transaction_version; the CoreVersionRef struct lets you do that because it was initially designed only for decoding | 280 | 61 | if let Some(state_version) = self.state_version { | 281 | 61 | out.extend(u8::from(state_version).to_le_bytes()); | 282 | 61 | }0 | 283 | | | 284 | 61 | out | 285 | 61 | } |
_RNvMs0_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_14CoreVersionRef18scale_encoding_vec Line | Count | Source | 247 | 86 | pub fn scale_encoding_vec(&self) -> Vec<u8> { | 248 | | // See https://spec.polkadot.network/#defn-rt-core-version | 249 | | | 250 | 86 | let num_apis = self.apis.clone().count(); | 251 | | | 252 | | // Reserve enough capacity for the various calls to `extend` below. | 253 | | // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded | 254 | | // lengths. In the case of very very very long names, the capacity might be too low. | 255 | 86 | let mut out = Vec::<u8>::with_capacity( | 256 | 86 | 2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1, | 257 | | ); | 258 | | | 259 | 86 | out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref()); | 260 | 86 | out.extend(self.spec_name.as_bytes()); | 261 | | | 262 | 86 | out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref()); | 263 | 86 | out.extend(self.impl_name.as_bytes()); | 264 | | | 265 | 86 | out.extend(self.authoring_version.to_le_bytes()); | 266 | 86 | out.extend(self.spec_version.to_le_bytes()); | 267 | 86 | out.extend(self.impl_version.to_le_bytes()); | 268 | | | 269 | 86 | out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref()); | 270 | 860 | for api in self.apis86 .clone86 () { | 271 | 860 | out.extend(api.name_hash); | 272 | 860 | out.extend(api.version.to_le_bytes()); | 273 | 860 | } | 274 | | | 275 | 86 | if let Some(transaction_version) = self.transaction_version { | 276 | 86 | out.extend(transaction_version.to_le_bytes()); | 277 | 86 | }0 | 278 | | | 279 | | // TODO: it's not supposed to be allowed to have a CoreVersionRef with a state_version but no transaction_version; the CoreVersionRef struct lets you do that because it was initially designed only for decoding | 280 | 86 | if let Some(state_version0 ) = self.state_version { | 281 | 0 | out.extend(u8::from(state_version).to_le_bytes()); | 282 | 86 | } | 283 | | | 284 | 86 | out | 285 | 86 | } |
|
286 | | } |
287 | | |
288 | | /// Iterator to a list of APIs. See [`CoreVersionRef::apis`]. |
289 | | #[derive(Clone)] |
290 | | pub struct CoreVersionApisRefIter<'a> { |
291 | | inner: &'a [u8], |
292 | | } |
293 | | |
294 | | impl<'a> CoreVersionApisRefIter<'a> { |
295 | | /// Decodes a SCALE-encoded list of APIs. |
296 | | /// |
297 | | /// The input slice isn't expected to contain the number of APIs. |
298 | 147 | pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> { |
299 | 147 | let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> = nom::Parser::parse( |
300 | 147 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( |
301 | 147 | nom::combinator::recognize(nom::multi::fold_many0( |
302 | 147 | nom::combinator::complete(core_version_api), |
303 | 0 | || {}, Unexecuted instantiation: _RNCNvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_length0Bd_ Unexecuted instantiation: _RNCNvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_length0Bd_ |
304 | | |(), _| (), |
305 | | )), |
306 | 147 | |inner| CoreVersionApisRefIter { inner }, _RNCNvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths0_0Bd_ Line | Count | Source | 306 | 61 | |inner| CoreVersionApisRefIter { inner }, |
_RNCNvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths0_0Bd_ Line | Count | Source | 306 | 86 | |inner| CoreVersionApisRefIter { inner }, |
|
307 | | ))), |
308 | 147 | input, |
309 | | ); |
310 | | |
311 | 147 | match result { |
312 | 147 | Ok((_, me)) => Ok(me), |
313 | 0 | Err(_) => Err(CoreVersionApisFromSliceErr()), |
314 | | } |
315 | 147 | } _RNvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter20from_slice_no_length Line | Count | Source | 298 | 61 | pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> { | 299 | 61 | let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> = nom::Parser::parse( | 300 | 61 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( | 301 | 61 | nom::combinator::recognize(nom::multi::fold_many0( | 302 | 61 | nom::combinator::complete(core_version_api), | 303 | | || {}, | 304 | | |(), _| (), | 305 | | )), | 306 | | |inner| CoreVersionApisRefIter { inner }, | 307 | | ))), | 308 | 61 | input, | 309 | | ); | 310 | | | 311 | 61 | match result { | 312 | 61 | Ok((_, me)) => Ok(me), | 313 | 0 | Err(_) => Err(CoreVersionApisFromSliceErr()), | 314 | | } | 315 | 61 | } |
_RNvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter20from_slice_no_length Line | Count | Source | 298 | 86 | pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> { | 299 | 86 | let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> = nom::Parser::parse( | 300 | 86 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( | 301 | 86 | nom::combinator::recognize(nom::multi::fold_many0( | 302 | 86 | nom::combinator::complete(core_version_api), | 303 | | || {}, | 304 | | |(), _| (), | 305 | | )), | 306 | | |inner| CoreVersionApisRefIter { inner }, | 307 | | ))), | 308 | 86 | input, | 309 | | ); | 310 | | | 311 | 86 | match result { | 312 | 86 | Ok((_, me)) => Ok(me), | 313 | 0 | Err(_) => Err(CoreVersionApisFromSliceErr()), | 314 | | } | 315 | 86 | } |
|
316 | | |
317 | | /// Tries to find within this iterator the given API, and if found returns the version number. |
318 | | /// |
319 | | /// If multiple API versions are found, the highest one is returned. |
320 | | /// |
321 | | /// > **Note**: If you start iterating (for example by calling `next()`) then call this |
322 | | /// > function, the search will only be performed on the rest of the iterator, |
323 | | /// > which is typically not what you want. Preferably always call this function |
324 | | /// > on a fresh iterator. |
325 | 0 | pub fn find_version(&self, api: &str) -> Option<u32> { |
326 | 0 | self.find_versions([api])[0] |
327 | 0 | } Unexecuted instantiation: _RNvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter12find_version Unexecuted instantiation: _RNvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter12find_version |
328 | | |
329 | | /// Similar to [`CoreVersionApisRefIter::find_version`], but allows passing multiple API names |
330 | | /// at once. This is more optimized if multiple API names are to be queried. |
331 | 43 | pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] { |
332 | 129 | let hashed43 = core::array::from_fn::<_, N, _>43 (|n| hash_api_name(apis[n])); _RNCINvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj3_E0Be_ Line | Count | Source | 332 | 3 | let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n])); |
Unexecuted instantiation: _RNCINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj1_E0Be_ _RNCINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj3_E0Be_ Line | Count | Source | 332 | 126 | let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n])); |
|
333 | 43 | let mut out = [None; N]; |
334 | | |
335 | 432 | for api in self43 .clone43 () { |
336 | 1.29k | for (n, expected) in hashed432 .iter432 ().enumerate432 () { |
337 | 1.29k | if *expected == api.name_hash { |
338 | 86 | match out[n] { |
339 | 0 | Some(ref mut v) if *v < api.version => *v = api.version, |
340 | 0 | Some(_) => {} |
341 | 86 | ref mut v @ None => *v = Some(api.version), |
342 | | } |
343 | 1.21k | } |
344 | | } |
345 | | } |
346 | | |
347 | 43 | out |
348 | 43 | } _RINvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj3_EBc_ Line | Count | Source | 331 | 1 | pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] { | 332 | 1 | let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n])); | 333 | 1 | let mut out = [None; N]; | 334 | | | 335 | 12 | for api in self1 .clone1 () { | 336 | 36 | for (n, expected) in hashed12 .iter12 ().enumerate12 () { | 337 | 36 | if *expected == api.name_hash { | 338 | 2 | match out[n] { | 339 | 0 | Some(ref mut v) if *v < api.version => *v = api.version, | 340 | 0 | Some(_) => {} | 341 | 2 | ref mut v @ None => *v = Some(api.version), | 342 | | } | 343 | 34 | } | 344 | | } | 345 | | } | 346 | | | 347 | 1 | out | 348 | 1 | } |
Unexecuted instantiation: _RINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj1_EBc_ _RINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj3_EBc_ Line | Count | Source | 331 | 42 | pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] { | 332 | 42 | let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n])); | 333 | 42 | let mut out = [None; N]; | 334 | | | 335 | 420 | for api in self42 .clone42 () { | 336 | 1.26k | for (n, expected) in hashed420 .iter420 ().enumerate420 () { | 337 | 1.26k | if *expected == api.name_hash { | 338 | 84 | match out[n] { | 339 | 0 | Some(ref mut v) if *v < api.version => *v = api.version, | 340 | 0 | Some(_) => {} | 341 | 84 | ref mut v @ None => *v = Some(api.version), | 342 | | } | 343 | 1.17k | } | 344 | | } | 345 | | } | 346 | | | 347 | 42 | out | 348 | 42 | } |
|
349 | | |
350 | | /// Returns `true` if this iterator contains the API with the given name and its version is in |
351 | | /// the provided range. |
352 | | /// |
353 | | /// > **Note**: If you start iterating (for example by calling `next()`) then call this |
354 | | /// > function, the search will only be performed on the rest of the iterator, |
355 | | /// > which is typically not what you want. Preferably always call this function |
356 | | /// > on a fresh iterator. |
357 | 0 | pub fn contains(&self, api_name: &str, version_number: impl ops::RangeBounds<u32>) -> bool { |
358 | 0 | self.contains_hashed(&hash_api_name(api_name), version_number) |
359 | 0 | } Unexecuted instantiation: _RINvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter8containspEBc_ Unexecuted instantiation: _RINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter8containspEBc_ |
360 | | |
361 | | /// Similar to [`CoreVersionApisRefIter::contains`], but allows passing the hash of the |
362 | | /// API name instead of its unhashed version. |
363 | 0 | pub fn contains_hashed( |
364 | 0 | &self, |
365 | 0 | api_name_hash: &[u8; 8], |
366 | 0 | version_number: impl ops::RangeBounds<u32>, |
367 | 0 | ) -> bool { |
368 | 0 | self.clone() |
369 | 0 | .any(|api| api.name_hash == *api_name_hash && version_number.contains(&api.version)) Unexecuted instantiation: _RNCINvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter15contains_hashedpE0Be_ Unexecuted instantiation: _RNCINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter15contains_hashedpE0Be_ |
370 | 0 | } Unexecuted instantiation: _RINvMs1_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter15contains_hashedpEBc_ Unexecuted instantiation: _RINvMs1_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter15contains_hashedpEBc_ |
371 | | } |
372 | | |
373 | | impl Iterator for CoreVersionApisRefIter<'_> { |
374 | | type Item = CoreVersionApi; |
375 | | |
376 | 2.67k | fn next(&mut self) -> Option<Self::Item> { |
377 | 2.67k | if self.inner.is_empty() { |
378 | 338 | return None; |
379 | 2.33k | } |
380 | | |
381 | 2.33k | match core_version_api::<nom::error::Error<&[u8]>>(self.inner) { |
382 | 2.33k | Ok((rest, item)) => { |
383 | 2.33k | self.inner = rest; |
384 | 2.33k | Some(item) |
385 | | } |
386 | | |
387 | | // The content is always checked to be valid before creating a |
388 | | // `CoreVersionApisRefIter`. |
389 | 0 | Err(_) => unreachable!(), |
390 | | } |
391 | 2.67k | } _RNvXs2_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 376 | 305 | fn next(&mut self) -> Option<Self::Item> { | 377 | 305 | if self.inner.is_empty() { | 378 | 123 | return None; | 379 | 182 | } | 380 | | | 381 | 182 | match core_version_api::<nom::error::Error<&[u8]>>(self.inner) { | 382 | 182 | Ok((rest, item)) => { | 383 | 182 | self.inner = rest; | 384 | 182 | Some(item) | 385 | | } | 386 | | | 387 | | // The content is always checked to be valid before creating a | 388 | | // `CoreVersionApisRefIter`. | 389 | 0 | Err(_) => unreachable!(), | 390 | | } | 391 | 305 | } |
_RNvXs2_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 376 | 2.36k | fn next(&mut self) -> Option<Self::Item> { | 377 | 2.36k | if self.inner.is_empty() { | 378 | 215 | return None; | 379 | 2.15k | } | 380 | | | 381 | 2.15k | match core_version_api::<nom::error::Error<&[u8]>>(self.inner) { | 382 | 2.15k | Ok((rest, item)) => { | 383 | 2.15k | self.inner = rest; | 384 | 2.15k | Some(item) | 385 | | } | 386 | | | 387 | | // The content is always checked to be valid before creating a | 388 | | // `CoreVersionApisRefIter`. | 389 | 0 | Err(_) => unreachable!(), | 390 | | } | 391 | 2.36k | } |
|
392 | | } |
393 | | |
394 | | impl PartialEq for CoreVersionApisRefIter<'_> { |
395 | 0 | fn eq(&self, other: &Self) -> bool { |
396 | 0 | let mut a = self.clone(); |
397 | 0 | let mut b = other.clone(); |
398 | | loop { |
399 | 0 | match (a.next(), b.next()) { |
400 | 0 | (Some(a), Some(b)) if a == b => {} |
401 | 0 | (None, None) => return true, |
402 | 0 | _ => return false, |
403 | | } |
404 | | } |
405 | 0 | } Unexecuted instantiation: _RNvXs3_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCs1p5UDGgVI4d_4core3cmp9PartialEq2eq Unexecuted instantiation: _RNvXs3_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCs1p5UDGgVI4d_4core3cmp9PartialEq2eq |
406 | | } |
407 | | |
408 | | impl Eq for CoreVersionApisRefIter<'_> {} |
409 | | |
410 | | impl fmt::Debug for CoreVersionApisRefIter<'_> { |
411 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
412 | 0 | f.debug_list().entries(self.clone()).finish() |
413 | 0 | } Unexecuted instantiation: _RNvXs5_NtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt Unexecuted instantiation: _RNvXs5_NtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt |
414 | | } |
415 | | |
416 | | /// Error potentially returned by [`CoreVersionApisRefIter::from_slice_no_length`]. |
417 | | #[derive(Debug, Clone, derive_more::Display, derive_more::Error)] |
418 | | #[display("Error decoding core version APIs")] |
419 | | pub struct CoreVersionApisFromSliceErr(); |
420 | | |
421 | | /// Hashes the name of an API in order to be able to compare it to [`CoreVersionApi::name_hash`]. |
422 | 129 | pub fn hash_api_name(api_name: &str) -> [u8; 8] { |
423 | 129 | let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes()); |
424 | 129 | result.as_bytes().try_into().unwrap() |
425 | 129 | } _RNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version13hash_api_name Line | Count | Source | 422 | 3 | pub fn hash_api_name(api_name: &str) -> [u8; 8] { | 423 | 3 | let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes()); | 424 | 3 | result.as_bytes().try_into().unwrap() | 425 | 3 | } |
_RNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version13hash_api_name Line | Count | Source | 422 | 126 | pub fn hash_api_name(api_name: &str) -> [u8; 8] { | 423 | 126 | let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes()); | 424 | 126 | result.as_bytes().try_into().unwrap() | 425 | 126 | } |
|
426 | | |
427 | | /// One API that the runtime supports. |
428 | | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
429 | | pub struct CoreVersionApi { |
430 | | /// BLAKE2 hash of length 8 of the name of the API. |
431 | | /// |
432 | | /// > **Note**: Available APIs can be found by searching for `decl_runtime_apis!` in the |
433 | | /// > Substrate code base. The value stored in this field is the BLAKE2 hash of |
434 | | /// > length 8 of the trait name declared within `decl_runtime_apis!`. |
435 | | pub name_hash: [u8; 8], |
436 | | |
437 | | /// Version of the module. Typical values are `1`, `2`, `3`, ... |
438 | | pub version: u32, |
439 | | } |
440 | | |
441 | 383 | fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> { |
442 | | // See https://spec.polkadot.network/#defn-rt-core-version |
443 | 383 | let result: nom::IResult<_, _> = nom::Parser::parse( |
444 | 383 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( |
445 | | ( |
446 | | crate::util::nom_string_decode, |
447 | | crate::util::nom_string_decode, |
448 | | nom::number::streaming::le_u32, |
449 | | nom::number::streaming::le_u32, |
450 | | nom::number::streaming::le_u32, |
451 | | core_version_apis, |
452 | 383 | nom::branch::alt(( |
453 | 383 | nom::combinator::complete(nom::combinator::map( |
454 | | nom::number::streaming::le_u32, |
455 | | Some, |
456 | | )), |
457 | 383 | nom::combinator::map(nom::combinator::eof, |_| None), |
458 | | )), |
459 | 383 | nom::branch::alt(( |
460 | 383 | nom::combinator::complete(nom::combinator::map( |
461 | 383 | nom::bytes::streaming::tag(&[0][..]), |
462 | 58 | |_| Some(TrieEntryVersion::V0), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version6decodes_0B9_ Line | Count | Source | 462 | 58 | |_| Some(TrieEntryVersion::V0), |
Unexecuted instantiation: _RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version6decodes_0B9_ |
463 | | )), |
464 | 383 | nom::combinator::complete(nom::combinator::map( |
465 | 383 | nom::bytes::streaming::tag(&[1][..]), |
466 | 18 | |_| Some(TrieEntryVersion::V1), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version6decodes0_0B9_ Line | Count | Source | 466 | 18 | |_| Some(TrieEntryVersion::V1), |
Unexecuted instantiation: _RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version6decodes0_0B9_ |
467 | | )), |
468 | 383 | nom::combinator::map(nom::combinator::eof, |_| None), |
469 | | )), |
470 | | ), |
471 | | |( |
472 | | spec_name, |
473 | | impl_name, |
474 | | authoring_version, |
475 | | spec_version, |
476 | | impl_version, |
477 | | apis, |
478 | | transaction_version, |
479 | | state_version, |
480 | | )| CoreVersionRef { |
481 | 383 | spec_name, |
482 | 383 | impl_name, |
483 | 383 | authoring_version, |
484 | 383 | spec_version, |
485 | 383 | impl_version, |
486 | 383 | apis, |
487 | 383 | transaction_version, |
488 | 383 | state_version, |
489 | 383 | }, _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version6decodes2_0B9_ Line | Count | Source | 481 | 85 | spec_name, | 482 | 85 | impl_name, | 483 | 85 | authoring_version, | 484 | 85 | spec_version, | 485 | 85 | impl_version, | 486 | 85 | apis, | 487 | 85 | transaction_version, | 488 | 85 | state_version, | 489 | 85 | }, |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version6decodes2_0B9_ Line | Count | Source | 481 | 298 | spec_name, | 482 | 298 | impl_name, | 483 | 298 | authoring_version, | 484 | 298 | spec_version, | 485 | 298 | impl_version, | 486 | 298 | apis, | 487 | 298 | transaction_version, | 488 | 298 | state_version, | 489 | 298 | }, |
|
490 | | ))), |
491 | 383 | scale_encoded, |
492 | | ); |
493 | | |
494 | 0 | match result { |
495 | 383 | Ok((_, out)) => Ok(out), |
496 | 0 | Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()), |
497 | 0 | Err(_) => unreachable!(), |
498 | | } |
499 | 383 | } _RNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version6decode Line | Count | Source | 441 | 85 | fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> { | 442 | | // See https://spec.polkadot.network/#defn-rt-core-version | 443 | 85 | let result: nom::IResult<_, _> = nom::Parser::parse( | 444 | 85 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( | 445 | | ( | 446 | | crate::util::nom_string_decode, | 447 | | crate::util::nom_string_decode, | 448 | | nom::number::streaming::le_u32, | 449 | | nom::number::streaming::le_u32, | 450 | | nom::number::streaming::le_u32, | 451 | | core_version_apis, | 452 | 85 | nom::branch::alt(( | 453 | 85 | nom::combinator::complete(nom::combinator::map( | 454 | | nom::number::streaming::le_u32, | 455 | | Some, | 456 | | )), | 457 | 85 | nom::combinator::map(nom::combinator::eof, |_| None), | 458 | | )), | 459 | 85 | nom::branch::alt(( | 460 | 85 | nom::combinator::complete(nom::combinator::map( | 461 | 85 | nom::bytes::streaming::tag(&[0][..]), | 462 | | |_| Some(TrieEntryVersion::V0), | 463 | | )), | 464 | 85 | nom::combinator::complete(nom::combinator::map( | 465 | 85 | nom::bytes::streaming::tag(&[1][..]), | 466 | | |_| Some(TrieEntryVersion::V1), | 467 | | )), | 468 | 85 | nom::combinator::map(nom::combinator::eof, |_| None), | 469 | | )), | 470 | | ), | 471 | | |( | 472 | | spec_name, | 473 | | impl_name, | 474 | | authoring_version, | 475 | | spec_version, | 476 | | impl_version, | 477 | | apis, | 478 | | transaction_version, | 479 | | state_version, | 480 | | )| CoreVersionRef { | 481 | | spec_name, | 482 | | impl_name, | 483 | | authoring_version, | 484 | | spec_version, | 485 | | impl_version, | 486 | | apis, | 487 | | transaction_version, | 488 | | state_version, | 489 | | }, | 490 | | ))), | 491 | 85 | scale_encoded, | 492 | | ); | 493 | | | 494 | 0 | match result { | 495 | 85 | Ok((_, out)) => Ok(out), | 496 | 0 | Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()), | 497 | 0 | Err(_) => unreachable!(), | 498 | | } | 499 | 85 | } |
_RNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version6decode Line | Count | Source | 441 | 298 | fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> { | 442 | | // See https://spec.polkadot.network/#defn-rt-core-version | 443 | 298 | let result: nom::IResult<_, _> = nom::Parser::parse( | 444 | 298 | &mut nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map( | 445 | | ( | 446 | | crate::util::nom_string_decode, | 447 | | crate::util::nom_string_decode, | 448 | | nom::number::streaming::le_u32, | 449 | | nom::number::streaming::le_u32, | 450 | | nom::number::streaming::le_u32, | 451 | | core_version_apis, | 452 | 298 | nom::branch::alt(( | 453 | 298 | nom::combinator::complete(nom::combinator::map( | 454 | | nom::number::streaming::le_u32, | 455 | | Some, | 456 | | )), | 457 | 298 | nom::combinator::map(nom::combinator::eof, |_| None), | 458 | | )), | 459 | 298 | nom::branch::alt(( | 460 | 298 | nom::combinator::complete(nom::combinator::map( | 461 | 298 | nom::bytes::streaming::tag(&[0][..]), | 462 | | |_| Some(TrieEntryVersion::V0), | 463 | | )), | 464 | 298 | nom::combinator::complete(nom::combinator::map( | 465 | 298 | nom::bytes::streaming::tag(&[1][..]), | 466 | | |_| Some(TrieEntryVersion::V1), | 467 | | )), | 468 | 298 | nom::combinator::map(nom::combinator::eof, |_| None), | 469 | | )), | 470 | | ), | 471 | | |( | 472 | | spec_name, | 473 | | impl_name, | 474 | | authoring_version, | 475 | | spec_version, | 476 | | impl_version, | 477 | | apis, | 478 | | transaction_version, | 479 | | state_version, | 480 | | )| CoreVersionRef { | 481 | | spec_name, | 482 | | impl_name, | 483 | | authoring_version, | 484 | | spec_version, | 485 | | impl_version, | 486 | | apis, | 487 | | transaction_version, | 488 | | state_version, | 489 | | }, | 490 | | ))), | 491 | 298 | scale_encoded, | 492 | | ); | 493 | | | 494 | 0 | match result { | 495 | 298 | Ok((_, out)) => Ok(out), | 496 | 0 | Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()), | 497 | 0 | Err(_) => unreachable!(), | 498 | | } | 499 | 298 | } |
|
500 | | |
501 | 383 | fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>( |
502 | 383 | bytes: &'a [u8], |
503 | 383 | ) -> nom::IResult<&'a [u8], CoreVersionApisRefIter<'a>, E> { |
504 | 383 | nom::Parser::parse( |
505 | 383 | &mut nom::combinator::map( |
506 | 383 | nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { |
507 | 383 | nom::combinator::recognize(nom::multi::fold_many_m_n( |
508 | 383 | num_elems, |
509 | 383 | num_elems, |
510 | | core_version_api, |
511 | 0 | || {}, Unexecuted instantiation: _RNCNCINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version17core_version_apispE00Bc_ Unexecuted instantiation: _RNCNCINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version17core_version_apispE00Bc_ |
512 | | |(), _| (), |
513 | | )) |
514 | 383 | }), _RNCINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEE0Ba_ Line | Count | Source | 506 | 85 | nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { | 507 | 85 | nom::combinator::recognize(nom::multi::fold_many_m_n( | 508 | 85 | num_elems, | 509 | 85 | num_elems, | 510 | | core_version_api, | 511 | | || {}, | 512 | | |(), _| (), | 513 | | )) | 514 | 85 | }), |
_RNCINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEE0Ba_ Line | Count | Source | 506 | 298 | nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { | 507 | 298 | nom::combinator::recognize(nom::multi::fold_many_m_n( | 508 | 298 | num_elems, | 509 | 298 | num_elems, | 510 | | core_version_api, | 511 | | || {}, | 512 | | |(), _| (), | 513 | | )) | 514 | 298 | }), |
|
515 | 383 | |inner| CoreVersionApisRefIter { inner }, _RNCINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEs_0Ba_ Line | Count | Source | 515 | 85 | |inner| CoreVersionApisRefIter { inner }, |
_RNCINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEs_0Ba_ Line | Count | Source | 515 | 298 | |inner| CoreVersionApisRefIter { inner }, |
|
516 | | ), |
517 | 383 | bytes, |
518 | | ) |
519 | 383 | } _RINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEB8_ Line | Count | Source | 501 | 85 | fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>( | 502 | 85 | bytes: &'a [u8], | 503 | 85 | ) -> nom::IResult<&'a [u8], CoreVersionApisRefIter<'a>, E> { | 504 | 85 | nom::Parser::parse( | 505 | 85 | &mut nom::combinator::map( | 506 | 85 | nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { | 507 | | nom::combinator::recognize(nom::multi::fold_many_m_n( | 508 | | num_elems, | 509 | | num_elems, | 510 | | core_version_api, | 511 | | || {}, | 512 | | |(), _| (), | 513 | | )) | 514 | | }), | 515 | | |inner| CoreVersionApisRefIter { inner }, | 516 | | ), | 517 | 85 | bytes, | 518 | | ) | 519 | 85 | } |
_RINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version17core_version_apisINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEB8_ Line | Count | Source | 501 | 298 | fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>( | 502 | 298 | bytes: &'a [u8], | 503 | 298 | ) -> nom::IResult<&'a [u8], CoreVersionApisRefIter<'a>, E> { | 504 | 298 | nom::Parser::parse( | 505 | 298 | &mut nom::combinator::map( | 506 | 298 | nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| { | 507 | | nom::combinator::recognize(nom::multi::fold_many_m_n( | 508 | | num_elems, | 509 | | num_elems, | 510 | | core_version_api, | 511 | | || {}, | 512 | | |(), _| (), | 513 | | )) | 514 | | }), | 515 | | |inner| CoreVersionApisRefIter { inner }, | 516 | | ), | 517 | 298 | bytes, | 518 | | ) | 519 | 298 | } |
|
520 | | |
521 | 5.81k | fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>( |
522 | 5.81k | bytes: &'a [u8], |
523 | 5.81k | ) -> nom::IResult<&'a [u8], CoreVersionApi, E> { |
524 | 5.81k | nom::Parser::parse( |
525 | 5.81k | &mut nom::combinator::map( |
526 | 5.81k | ( |
527 | 5.81k | nom::bytes::streaming::take(8u32), |
528 | 5.81k | nom::number::streaming::le_u32, |
529 | 5.81k | ), |
530 | | move |(name, version)| CoreVersionApi { |
531 | 5.66k | name_hash: <[u8; 8]>::try_from(name).unwrap(), |
532 | 5.66k | version, |
533 | 5.66k | }, _RNCINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version16core_version_apiINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEE0Ba_ Line | Count | Source | 531 | 536 | name_hash: <[u8; 8]>::try_from(name).unwrap(), | 532 | 536 | version, | 533 | 536 | }, |
_RNCINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version16core_version_apiINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEE0Ba_ Line | Count | Source | 531 | 5.13k | name_hash: <[u8; 8]>::try_from(name).unwrap(), | 532 | 5.13k | version, | 533 | 5.13k | }, |
|
534 | | ), |
535 | 5.81k | bytes, |
536 | | ) |
537 | 5.81k | } _RINvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version16core_version_apiINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEB8_ Line | Count | Source | 521 | 597 | fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>( | 522 | 597 | bytes: &'a [u8], | 523 | 597 | ) -> nom::IResult<&'a [u8], CoreVersionApi, E> { | 524 | 597 | nom::Parser::parse( | 525 | 597 | &mut nom::combinator::map( | 526 | 597 | ( | 527 | 597 | nom::bytes::streaming::take(8u32), | 528 | 597 | nom::number::streaming::le_u32, | 529 | 597 | ), | 530 | | move |(name, version)| CoreVersionApi { | 531 | | name_hash: <[u8; 8]>::try_from(name).unwrap(), | 532 | | version, | 533 | | }, | 534 | | ), | 535 | 597 | bytes, | 536 | | ) | 537 | 597 | } |
_RINvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version16core_version_apiINtNtCsfjEU5fc64iO_3nom5error5ErrorRShEEB8_ Line | Count | Source | 521 | 5.21k | fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>( | 522 | 5.21k | bytes: &'a [u8], | 523 | 5.21k | ) -> nom::IResult<&'a [u8], CoreVersionApi, E> { | 524 | 5.21k | nom::Parser::parse( | 525 | 5.21k | &mut nom::combinator::map( | 526 | 5.21k | ( | 527 | 5.21k | nom::bytes::streaming::take(8u32), | 528 | 5.21k | nom::number::streaming::le_u32, | 529 | 5.21k | ), | 530 | | move |(name, version)| CoreVersionApi { | 531 | | name_hash: <[u8; 8]>::try_from(name).unwrap(), | 532 | | version, | 533 | | }, | 534 | | ), | 535 | 5.21k | bytes, | 536 | | ) | 537 | 5.21k | } |
|
538 | | |
539 | | struct WasmSection<'a> { |
540 | | name: &'a [u8], |
541 | | content: &'a [u8], |
542 | | } |
543 | | |
544 | | /// Parses a Wasm section. If it is a custom section, returns its name and content. |
545 | 1.85k | fn wasm_section(bytes: &[u8]) -> nom::IResult<&[u8], Option<WasmSection>> { |
546 | 1.85k | nom::Parser::parse( |
547 | 1.85k | &mut nom::branch::alt(( |
548 | 1.85k | nom::combinator::map( |
549 | 1.85k | nom::combinator::map_parser( |
550 | 1.85k | nom::sequence::preceded( |
551 | 1.85k | nom::bytes::streaming::tag(&[0][..]), |
552 | 1.85k | nom::multi::length_data(nom::combinator::map_opt( |
553 | | crate::util::leb128::nom_leb128_u64, |
554 | 488 | |n| u32::try_from(n).ok(), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version12wasm_section0B9_ Line | Count | Source | 554 | 144 | |n| u32::try_from(n).ok(), |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version12wasm_section0B9_ Line | Count | Source | 554 | 344 | |n| u32::try_from(n).ok(), |
|
555 | | )), |
556 | | ), |
557 | | ( |
558 | 1.85k | nom::multi::length_data(nom::combinator::map_opt( |
559 | | crate::util::leb128::nom_leb128_u64, |
560 | 488 | |n| u32::try_from(n).ok(), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version12wasm_sections_0B9_ Line | Count | Source | 560 | 144 | |n| u32::try_from(n).ok(), |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version12wasm_sections_0B9_ Line | Count | Source | 560 | 344 | |n| u32::try_from(n).ok(), |
|
561 | | )), |
562 | | nom::combinator::rest, |
563 | | ), |
564 | | ), |
565 | 488 | |(name, content)| Some(WasmSection { name, content }), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version12wasm_sections0_0B9_ Line | Count | Source | 565 | 144 | |(name, content)| Some(WasmSection { name, content }), |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version12wasm_sections0_0B9_ Line | Count | Source | 565 | 344 | |(name, content)| Some(WasmSection { name, content }), |
|
566 | | ), |
567 | 1.85k | nom::combinator::map( |
568 | | ( |
569 | | nom::number::streaming::u8, |
570 | 1.85k | nom::multi::length_data(nom::combinator::map_opt( |
571 | | crate::util::leb128::nom_leb128_u64, |
572 | 1.21k | |n| u32::try_from(n).ok(), _RNCNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version12wasm_sections1_0B9_ Line | Count | Source | 572 | 438 | |n| u32::try_from(n).ok(), |
_RNCNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version12wasm_sections1_0B9_ Line | Count | Source | 572 | 774 | |n| u32::try_from(n).ok(), |
|
573 | | )), |
574 | | ), |
575 | | |_| None, |
576 | | ), |
577 | | )), |
578 | 1.85k | bytes, |
579 | | ) |
580 | 1.85k | } _RNvNtNtNtCsjlkOsLH0Zfj_7smoldot8executor4host15runtime_version12wasm_section Line | Count | Source | 545 | 646 | fn wasm_section(bytes: &[u8]) -> nom::IResult<&[u8], Option<WasmSection>> { | 546 | 646 | nom::Parser::parse( | 547 | 646 | &mut nom::branch::alt(( | 548 | 646 | nom::combinator::map( | 549 | 646 | nom::combinator::map_parser( | 550 | 646 | nom::sequence::preceded( | 551 | 646 | nom::bytes::streaming::tag(&[0][..]), | 552 | 646 | nom::multi::length_data(nom::combinator::map_opt( | 553 | | crate::util::leb128::nom_leb128_u64, | 554 | | |n| u32::try_from(n).ok(), | 555 | | )), | 556 | | ), | 557 | | ( | 558 | 646 | nom::multi::length_data(nom::combinator::map_opt( | 559 | | crate::util::leb128::nom_leb128_u64, | 560 | | |n| u32::try_from(n).ok(), | 561 | | )), | 562 | | nom::combinator::rest, | 563 | | ), | 564 | | ), | 565 | | |(name, content)| Some(WasmSection { name, content }), | 566 | | ), | 567 | 646 | nom::combinator::map( | 568 | | ( | 569 | | nom::number::streaming::u8, | 570 | 646 | nom::multi::length_data(nom::combinator::map_opt( | 571 | | crate::util::leb128::nom_leb128_u64, | 572 | | |n| u32::try_from(n).ok(), | 573 | | )), | 574 | | ), | 575 | | |_| None, | 576 | | ), | 577 | | )), | 578 | 646 | bytes, | 579 | | ) | 580 | 646 | } |
_RNvNtNtNtCsc1ywvx6YAnK_7smoldot8executor4host15runtime_version12wasm_section Line | Count | Source | 545 | 1.20k | fn wasm_section(bytes: &[u8]) -> nom::IResult<&[u8], Option<WasmSection>> { | 546 | 1.20k | nom::Parser::parse( | 547 | 1.20k | &mut nom::branch::alt(( | 548 | 1.20k | nom::combinator::map( | 549 | 1.20k | nom::combinator::map_parser( | 550 | 1.20k | nom::sequence::preceded( | 551 | 1.20k | nom::bytes::streaming::tag(&[0][..]), | 552 | 1.20k | nom::multi::length_data(nom::combinator::map_opt( | 553 | | crate::util::leb128::nom_leb128_u64, | 554 | | |n| u32::try_from(n).ok(), | 555 | | )), | 556 | | ), | 557 | | ( | 558 | 1.20k | nom::multi::length_data(nom::combinator::map_opt( | 559 | | crate::util::leb128::nom_leb128_u64, | 560 | | |n| u32::try_from(n).ok(), | 561 | | )), | 562 | | nom::combinator::rest, | 563 | | ), | 564 | | ), | 565 | | |(name, content)| Some(WasmSection { name, content }), | 566 | | ), | 567 | 1.20k | nom::combinator::map( | 568 | | ( | 569 | | nom::number::streaming::u8, | 570 | 1.20k | nom::multi::length_data(nom::combinator::map_opt( | 571 | | crate::util::leb128::nom_leb128_u64, | 572 | | |n| u32::try_from(n).ok(), | 573 | | )), | 574 | | ), | 575 | | |_| None, | 576 | | ), | 577 | | )), | 578 | 1.20k | bytes, | 579 | | ) | 580 | 1.20k | } |
|