Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/executor/host/runtime_version.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 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
}
_RNvNtNtNtCsN16ciHI6Qf_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
}
_RNvNtNtNtCseuYC0Zibziv_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
0
#[derive(Debug, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXs7_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_31FindEmbeddedRuntimeVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs7_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_31FindEmbeddedRuntimeVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
66
pub enum FindEmbeddedRuntimeVersionError {
67
    /// Error while finding the custom section.
68
    #[display(fmt = "{_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(fmt = "{_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
            nom::sequence::tuple((
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
152
                || 
(None, None)150
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version42find_encoded_embedded_runtime_version_apis0B9_
Line
Count
Source
102
64
                || (None, None),
_RNCNvNtNtNtCseuYC0Zibziv_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
147
                            }),
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
149
                            }),
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
                },
_RNCNvNtNtNtCsN16ciHI6Qf_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
61
                            }),
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
63
                            }),
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
                },
_RNCNvNtNtNtCseuYC0Zibziv_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
86
                            }),
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
86
                            }),
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
152
            ),
148
152
        )));
149
150
152
    let (
runtime_version_content, runtime_apis_content150
) = match parser(binary_wasm_module) {
151
150
        Ok((_, content)) => content,
152
2
        Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse),
153
    };
154
155
150
    Ok(EmbeddedRuntimeVersionApis {
156
150
        runtime_version_content,
157
150
        runtime_apis_content,
158
150
    })
159
152
}
_RNvNtNtNtCsN16ciHI6Qf_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
            nom::sequence::tuple((
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
66
                || (None, None),
103
66
                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
66
                },
147
66
            ),
148
66
        )));
149
150
66
    let (
runtime_version_content, runtime_apis_content64
) = match parser(binary_wasm_module) {
151
64
        Ok((_, content)) => content,
152
2
        Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse),
153
    };
154
155
64
    Ok(EmbeddedRuntimeVersionApis {
156
64
        runtime_version_content,
157
64
        runtime_apis_content,
158
64
    })
159
66
}
_RNvNtNtNtCseuYC0Zibziv_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
            nom::sequence::tuple((
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
86
                || (None, None),
103
86
                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
86
                },
147
86
            ),
148
86
        )));
149
150
86
    let (runtime_version_content, runtime_apis_content) = match parser(binary_wasm_module) {
151
86
        Ok((_, content)) => content,
152
0
        Err(_) => return Err(FindEncodedEmbeddedRuntimeVersionApisError::FailedToParse),
153
    };
154
155
86
    Ok(EmbeddedRuntimeVersionApis {
156
86
        runtime_version_content,
157
86
        runtime_apis_content,
158
86
    })
159
86
}
160
161
/// Error returned by [`find_encoded_embedded_runtime_version_apis`].
162
0
#[derive(Debug, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXsd_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_42FindEncodedEmbeddedRuntimeVersionApisErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsd_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_42FindEncodedEmbeddedRuntimeVersionApisErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
163
pub enum FindEncodedEmbeddedRuntimeVersionApisError {
164
    /// Failed to parse Wasm binary.
165
    FailedToParse,
166
}
167
168
/// Error while executing `Core_version`.
169
0
#[derive(Debug, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXsg_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_16CoreVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsg_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_16CoreVersionErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
170
pub enum CoreVersionError {
171
    /// Error while decoding the output.
172
    Decode,
173
    /// Error while starting the execution of the `Core_version` function.
174
    #[display(fmt = "Error while starting the execution of the `Core_version` function: {_0}")]
175
    Start(host::StartErr),
176
    /// Error during the execution of the `Core_version` function.
177
    #[display(fmt = "Error during the execution of the `Core_version` function: {_0}")]
178
    Run(host::Error),
179
    /// `Core_version` used a host function that is forbidden in this context.
180
    ForbiddenHostFunction,
181
}
182
183
/// Buffer storing the SCALE-encoded core version.
184
#[derive(Debug, Clone, PartialEq, Eq)]
185
pub struct CoreVersion(Vec<u8>);
186
187
impl CoreVersion {
188
3
    pub fn from_slice(input: Vec<u8>) -> Result<Self, Vec<u8>> {
189
3
        if decode(&input).is_err() {
190
0
            return Err(input);
191
3
        }
192
3
193
3
        Ok(CoreVersion(input))
194
3
    }
_RNvMNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion10from_slice
Line
Count
Source
188
3
    pub fn from_slice(input: Vec<u8>) -> Result<Self, Vec<u8>> {
189
3
        if decode(&input).is_err() {
190
0
            return Err(input);
191
3
        }
192
3
193
3
        Ok(CoreVersion(input))
194
3
    }
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion10from_slice
195
196
233
    pub fn decode(&self) -> CoreVersionRef {
197
233
        decode(&self.0).unwrap()
198
233
    }
_RNvMNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion6decode
Line
Count
Source
196
21
    pub fn decode(&self) -> CoreVersionRef {
197
21
        decode(&self.0).unwrap()
198
21
    }
_RNvMNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB2_11CoreVersion6decode
Line
Count
Source
196
212
    pub fn decode(&self) -> CoreVersionRef {
197
212
        decode(&self.0).unwrap()
198
212
    }
199
}
200
201
impl AsRef<[u8]> for CoreVersion {
202
0
    fn as_ref(&self) -> &[u8] {
203
0
        &self.0
204
0
    }
Unexecuted instantiation: _RNvXs_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB4_11CoreVersionINtNtCsaYZPK01V26L_4core7convert5AsRefShE6as_ref
Unexecuted instantiation: _RNvXs_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB4_11CoreVersionINtNtCsaYZPK01V26L_4core7convert5AsRefShE6as_ref
205
}
206
207
/// Runtime specification, once decoded.
208
// TODO: explain these fields
209
#[derive(Debug, Clone, PartialEq, Eq)]
210
pub struct CoreVersionRef<'a> {
211
    pub spec_name: &'a str,
212
    pub impl_name: &'a str,
213
    pub authoring_version: u32,
214
    pub spec_version: u32,
215
    pub impl_version: u32,
216
217
    /// List of "API"s that the runtime supports.
218
    ///
219
    /// Each API corresponds to a certain list of runtime entry points.
220
    ///
221
    /// This field can thus be used in order to determine which runtime entry points are
222
    /// available.
223
    pub apis: CoreVersionApisRefIter<'a>,
224
225
    /// Arbitrary version number corresponding to the transactions encoding version.
226
    ///
227
    /// Whenever this version number changes, all transactions encoding generated earlier are
228
    /// invalidated and should be regenerated.
229
    ///
230
    /// Older versions of Substrate didn't provide this field. `None` if the field is missing.
231
    pub transaction_version: Option<u32>,
232
233
    /// Version number of the state trie encoding version.
234
    ///
235
    /// Version 0 corresponds to a different trie encoding than version 1.
236
    ///
237
    /// This field has been added to Substrate on 24th December 2021. Older versions of Substrate
238
    /// didn't provide this field, in which case it will contain `None`.
239
    ///
240
    /// `None` should be interpreted the same way as `Some(0)`.
241
    pub state_version: Option<TrieEntryVersion>,
242
}
243
244
impl<'a> CoreVersionRef<'a> {
245
    /// Returns the SCALE encoding of this data structure.
246
147
    pub fn scale_encoding_vec(&self) -> Vec<u8> {
247
147
        // See https://spec.polkadot.network/#defn-rt-core-version
248
147
249
147
        let num_apis = self.apis.clone().count();
250
147
251
147
        // Reserve enough capacity for the various calls to `extend` below.
252
147
        // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded
253
147
        // lengths. In the case of very very very long names, the capacity might be too low.
254
147
        let mut out = Vec::<u8>::with_capacity(
255
147
            2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1,
256
147
        );
257
147
258
147
        out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref());
259
147
        out.extend(self.spec_name.as_bytes());
260
147
261
147
        out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref());
262
147
        out.extend(self.impl_name.as_bytes());
263
147
264
147
        out.extend(self.authoring_version.to_le_bytes());
265
147
        out.extend(self.spec_version.to_le_bytes());
266
147
        out.extend(self.impl_version.to_le_bytes());
267
147
268
147
        out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref());
269
945
        for api in 
self.apis.clone()147
{
270
945
            out.extend(api.name_hash);
271
945
            out.extend(api.version.to_le_bytes());
272
945
        }
273
274
147
        if let Some(transaction_version) = self.transaction_version {
275
147
            out.extend(transaction_version.to_le_bytes());
276
147
        }
0
277
278
        // 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
279
147
        if let Some(
state_version61
) = self.state_version {
280
61
            out.extend(u8::from(state_version).to_le_bytes());
281
86
        }
282
283
147
        out
284
147
    }
_RNvMs0_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_14CoreVersionRef18scale_encoding_vec
Line
Count
Source
246
61
    pub fn scale_encoding_vec(&self) -> Vec<u8> {
247
61
        // See https://spec.polkadot.network/#defn-rt-core-version
248
61
249
61
        let num_apis = self.apis.clone().count();
250
61
251
61
        // Reserve enough capacity for the various calls to `extend` below.
252
61
        // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded
253
61
        // lengths. In the case of very very very long names, the capacity might be too low.
254
61
        let mut out = Vec::<u8>::with_capacity(
255
61
            2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1,
256
61
        );
257
61
258
61
        out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref());
259
61
        out.extend(self.spec_name.as_bytes());
260
61
261
61
        out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref());
262
61
        out.extend(self.impl_name.as_bytes());
263
61
264
61
        out.extend(self.authoring_version.to_le_bytes());
265
61
        out.extend(self.spec_version.to_le_bytes());
266
61
        out.extend(self.impl_version.to_le_bytes());
267
61
268
61
        out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref());
269
85
        for api in 
self.apis.clone()61
{
270
85
            out.extend(api.name_hash);
271
85
            out.extend(api.version.to_le_bytes());
272
85
        }
273
274
61
        if let Some(transaction_version) = self.transaction_version {
275
61
            out.extend(transaction_version.to_le_bytes());
276
61
        }
0
277
278
        // 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
279
61
        if let Some(state_version) = self.state_version {
280
61
            out.extend(u8::from(state_version).to_le_bytes());
281
61
        }
0
282
283
61
        out
284
61
    }
_RNvMs0_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_14CoreVersionRef18scale_encoding_vec
Line
Count
Source
246
86
    pub fn scale_encoding_vec(&self) -> Vec<u8> {
247
86
        // See https://spec.polkadot.network/#defn-rt-core-version
248
86
249
86
        let num_apis = self.apis.clone().count();
250
86
251
86
        // Reserve enough capacity for the various calls to `extend` below.
252
86
        // This is only a reasonable estimate, as we assume 2 bytes for the SCALE-compact-encoded
253
86
        // lengths. In the case of very very very long names, the capacity might be too low.
254
86
        let mut out = Vec::<u8>::with_capacity(
255
86
            2 + self.spec_name.len() + 2 + self.impl_name.len() + 4 + 4 + 4 + num_apis * 12 + 4 + 1,
256
86
        );
257
86
258
86
        out.extend(crate::util::encode_scale_compact_usize(self.spec_name.len()).as_ref());
259
86
        out.extend(self.spec_name.as_bytes());
260
86
261
86
        out.extend(crate::util::encode_scale_compact_usize(self.impl_name.len()).as_ref());
262
86
        out.extend(self.impl_name.as_bytes());
263
86
264
86
        out.extend(self.authoring_version.to_le_bytes());
265
86
        out.extend(self.spec_version.to_le_bytes());
266
86
        out.extend(self.impl_version.to_le_bytes());
267
86
268
86
        out.extend(crate::util::encode_scale_compact_usize(num_apis).as_ref());
269
860
        for api in 
self.apis.clone()86
{
270
860
            out.extend(api.name_hash);
271
860
            out.extend(api.version.to_le_bytes());
272
860
        }
273
274
86
        if let Some(transaction_version) = self.transaction_version {
275
86
            out.extend(transaction_version.to_le_bytes());
276
86
        }
0
277
278
        // 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
279
86
        if let Some(
state_version0
) = self.state_version {
280
0
            out.extend(u8::from(state_version).to_le_bytes());
281
86
        }
282
283
86
        out
284
86
    }
285
}
286
287
/// Iterator to a list of APIs. See [`CoreVersionRef::apis`].
288
#[derive(Clone)]
289
pub struct CoreVersionApisRefIter<'a> {
290
    inner: &'a [u8],
291
}
292
293
impl<'a> CoreVersionApisRefIter<'a> {
294
    /// Decodes a SCALE-encoded list of APIs.
295
    ///
296
    /// The input slice isn't expected to contain the number of APIs.
297
147
    pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> {
298
147
        let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> =
299
147
            nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
300
147
                nom::combinator::recognize(nom::multi::fold_many0(
301
147
                    nom::combinator::complete(core_version_api),
302
147
                    || {},
_RNCNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_length0Bd_
Line
Count
Source
302
61
                    || {},
_RNCNvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_length0Bd_
Line
Count
Source
302
86
                    || {},
303
945
                    |(), _| (),
_RNCNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths_0Bd_
Line
Count
Source
303
85
                    |(), _| (),
_RNCNvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths_0Bd_
Line
Count
Source
303
860
                    |(), _| (),
304
147
                )),
305
147
                |inner| CoreVersionApisRefIter { inner },
_RNCNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths0_0Bd_
Line
Count
Source
305
61
                |inner| CoreVersionApisRefIter { inner },
_RNCNvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB7_22CoreVersionApisRefIter20from_slice_no_lengths0_0Bd_
Line
Count
Source
305
86
                |inner| CoreVersionApisRefIter { inner },
306
147
            )))(input);
307
147
308
147
        match result {
309
147
            Ok((_, me)) => Ok(me),
310
0
            Err(_) => Err(CoreVersionApisFromSliceErr()),
311
        }
312
147
    }
_RNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter20from_slice_no_length
Line
Count
Source
297
61
    pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> {
298
61
        let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> =
299
61
            nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
300
61
                nom::combinator::recognize(nom::multi::fold_many0(
301
61
                    nom::combinator::complete(core_version_api),
302
61
                    || {},
303
61
                    |(), _| (),
304
61
                )),
305
61
                |inner| CoreVersionApisRefIter { inner },
306
61
            )))(input);
307
61
308
61
        match result {
309
61
            Ok((_, me)) => Ok(me),
310
0
            Err(_) => Err(CoreVersionApisFromSliceErr()),
311
        }
312
61
    }
_RNvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter20from_slice_no_length
Line
Count
Source
297
86
    pub fn from_slice_no_length(input: &'a [u8]) -> Result<Self, CoreVersionApisFromSliceErr> {
298
86
        let result: Result<_, nom::Err<nom::error::Error<&[u8]>>> =
299
86
            nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
300
86
                nom::combinator::recognize(nom::multi::fold_many0(
301
86
                    nom::combinator::complete(core_version_api),
302
86
                    || {},
303
86
                    |(), _| (),
304
86
                )),
305
86
                |inner| CoreVersionApisRefIter { inner },
306
86
            )))(input);
307
86
308
86
        match result {
309
86
            Ok((_, me)) => Ok(me),
310
0
            Err(_) => Err(CoreVersionApisFromSliceErr()),
311
        }
312
86
    }
313
314
    /// Tries to find within this iterator the given API, and if found returns the version number.
315
    ///
316
    /// If multiple API versions are found, the highest one is returned.
317
    ///
318
    /// > **Note**: If you start iterating (for example by calling `next()`) then call this
319
    /// >           function, the search will only be performed on the rest of the iterator,
320
    /// >           which is typically not what you want. Preferably always call this function
321
    /// >           on a fresh iterator.
322
0
    pub fn find_version(&self, api: &str) -> Option<u32> {
323
0
        self.find_versions([api])[0]
324
0
    }
Unexecuted instantiation: _RNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter12find_version
Unexecuted instantiation: _RNvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIter12find_version
325
326
    /// Similar to [`CoreVersionApisRefIter::find_version`], but allows passing multiple API names
327
    /// at once. This is more optimized if multiple API names are to be queried.
328
43
    pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] {
329
129
        let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n]));
_RNCINvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj3_E0Be_
Line
Count
Source
329
3
        let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n]));
Unexecuted instantiation: _RNCINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj1_E0Be_
_RNCINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter13find_versionsKj3_E0Be_
Line
Count
Source
329
126
        let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n]));
330
43
        let mut out = [None; N];
331
332
432
        for api in 
self.clone()43
{
333
1.29k
            for (n, expected) in 
hashed.iter().enumerate()432
{
334
1.29k
                if *expected == api.name_hash {
335
86
                    match out[n] {
336
0
                        Some(ref mut v) if *v < api.version => *v = api.version,
337
0
                        Some(_) => {}
338
86
                        ref mut v @ None => *v = Some(api.version),
339
                    }
340
1.21k
                }
341
            }
342
        }
343
344
43
        out
345
43
    }
_RINvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj3_EBc_
Line
Count
Source
328
1
    pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] {
329
1
        let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n]));
330
1
        let mut out = [None; N];
331
332
12
        for api in 
self.clone()1
{
333
36
            for (n, expected) in 
hashed.iter().enumerate()12
{
334
36
                if *expected == api.name_hash {
335
2
                    match out[n] {
336
0
                        Some(ref mut v) if *v < api.version => *v = api.version,
337
0
                        Some(_) => {}
338
2
                        ref mut v @ None => *v = Some(api.version),
339
                    }
340
34
                }
341
            }
342
        }
343
344
1
        out
345
1
    }
Unexecuted instantiation: _RINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj1_EBc_
_RINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter13find_versionsKj3_EBc_
Line
Count
Source
328
42
    pub fn find_versions<const N: usize>(&self, apis: [&str; N]) -> [Option<u32>; N] {
329
42
        let hashed = core::array::from_fn::<_, N, _>(|n| hash_api_name(apis[n]));
330
42
        let mut out = [None; N];
331
332
420
        for api in 
self.clone()42
{
333
1.26k
            for (n, expected) in 
hashed.iter().enumerate()420
{
334
1.26k
                if *expected == api.name_hash {
335
84
                    match out[n] {
336
0
                        Some(ref mut v) if *v < api.version => *v = api.version,
337
0
                        Some(_) => {}
338
84
                        ref mut v @ None => *v = Some(api.version),
339
                    }
340
1.17k
                }
341
            }
342
        }
343
344
42
        out
345
42
    }
346
347
    /// Returns `true` if this iterator contains the API with the given name and its version is in
348
    /// the provided range.
349
    ///
350
    /// > **Note**: If you start iterating (for example by calling `next()`) then call this
351
    /// >           function, the search will only be performed on the rest of the iterator,
352
    /// >           which is typically not what you want. Preferably always call this function
353
    /// >           on a fresh iterator.
354
0
    pub fn contains(&self, api_name: &str, version_number: impl ops::RangeBounds<u32>) -> bool {
355
0
        self.contains_hashed(&hash_api_name(api_name), version_number)
356
0
    }
Unexecuted instantiation: _RINvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter8containspEBc_
Unexecuted instantiation: _RINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter8containspEBc_
357
358
    /// Similar to [`CoreVersionApisRefIter::contains`], but allows passing the hash of the
359
    /// API name instead of its unhashed version.
360
0
    pub fn contains_hashed(
361
0
        &self,
362
0
        api_name_hash: &[u8; 8],
363
0
        version_number: impl ops::RangeBounds<u32>,
364
0
    ) -> bool {
365
0
        self.clone()
366
0
            .any(|api| api.name_hash == *api_name_hash && version_number.contains(&api.version))
Unexecuted instantiation: _RNCINvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter15contains_hashedpE0Be_
Unexecuted instantiation: _RNCINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB8_22CoreVersionApisRefIter15contains_hashedpE0Be_
367
0
    }
Unexecuted instantiation: _RINvMs1_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter15contains_hashedpEBc_
Unexecuted instantiation: _RINvMs1_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB6_22CoreVersionApisRefIter15contains_hashedpEBc_
368
}
369
370
impl<'a> Iterator for CoreVersionApisRefIter<'a> {
371
    type Item = CoreVersionApi;
372
373
2.67k
    fn next(&mut self) -> Option<Self::Item> {
374
2.67k
        if self.inner.is_empty() {
375
338
            return None;
376
2.33k
        }
377
2.33k
378
2.33k
        match core_version_api::<nom::error::Error<&[u8]>>(self.inner) {
379
2.33k
            Ok((rest, item)) => {
380
2.33k
                self.inner = rest;
381
2.33k
                Some(item)
382
            }
383
384
            // The content is always checked to be valid before creating a
385
            // `CoreVersionApisRefIter`.
386
0
            Err(_) => unreachable!(),
387
        }
388
2.67k
    }
_RNvXs2_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
373
305
    fn next(&mut self) -> Option<Self::Item> {
374
305
        if self.inner.is_empty() {
375
123
            return None;
376
182
        }
377
182
378
182
        match core_version_api::<nom::error::Error<&[u8]>>(self.inner) {
379
182
            Ok((rest, item)) => {
380
182
                self.inner = rest;
381
182
                Some(item)
382
            }
383
384
            // The content is always checked to be valid before creating a
385
            // `CoreVersionApisRefIter`.
386
0
            Err(_) => unreachable!(),
387
        }
388
305
    }
_RNvXs2_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
373
2.36k
    fn next(&mut self) -> Option<Self::Item> {
374
2.36k
        if self.inner.is_empty() {
375
215
            return None;
376
2.15k
        }
377
2.15k
378
2.15k
        match core_version_api::<nom::error::Error<&[u8]>>(self.inner) {
379
2.15k
            Ok((rest, item)) => {
380
2.15k
                self.inner = rest;
381
2.15k
                Some(item)
382
            }
383
384
            // The content is always checked to be valid before creating a
385
            // `CoreVersionApisRefIter`.
386
0
            Err(_) => unreachable!(),
387
        }
388
2.36k
    }
389
}
390
391
impl<'a> PartialEq for CoreVersionApisRefIter<'a> {
392
0
    fn eq(&self, other: &Self) -> bool {
393
0
        let mut a = self.clone();
394
0
        let mut b = other.clone();
395
        loop {
396
0
            match (a.next(), b.next()) {
397
0
                (Some(a), Some(b)) if a == b => {}
398
0
                (None, None) => return true,
399
0
                _ => return false,
400
            }
401
        }
402
0
    }
Unexecuted instantiation: _RNvXs3_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCsaYZPK01V26L_4core3cmp9PartialEq2eq
Unexecuted instantiation: _RNvXs3_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCsaYZPK01V26L_4core3cmp9PartialEq2eq
403
}
404
405
impl<'a> Eq for CoreVersionApisRefIter<'a> {}
406
407
impl<'a> fmt::Debug for CoreVersionApisRefIter<'a> {
408
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409
0
        f.debug_list().entries(self.clone()).finish()
410
0
    }
Unexecuted instantiation: _RNvXs5_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs5_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_22CoreVersionApisRefIterNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
411
}
412
413
/// Error potentially returned by [`CoreVersionApisRefIter::from_slice_no_length`].
414
0
#[derive(Debug, Clone, derive_more::Display)]
Unexecuted instantiation: _RNvXsv_NtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_versionNtB5_27CoreVersionApisFromSliceErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsv_NtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_versionNtB5_27CoreVersionApisFromSliceErrNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
415
#[display(fmt = "Error decoding core version APIs")]
416
pub struct CoreVersionApisFromSliceErr();
417
418
/// Hashes the name of an API in order to be able to compare it to [`CoreVersionApi::name_hash`].
419
129
pub fn hash_api_name(api_name: &str) -> [u8; 8] {
420
129
    let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes());
421
129
    result.as_bytes().try_into().unwrap()
422
129
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version13hash_api_name
Line
Count
Source
419
3
pub fn hash_api_name(api_name: &str) -> [u8; 8] {
420
3
    let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes());
421
3
    result.as_bytes().try_into().unwrap()
422
3
}
_RNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version13hash_api_name
Line
Count
Source
419
126
pub fn hash_api_name(api_name: &str) -> [u8; 8] {
420
126
    let result = blake2_rfc::blake2b::blake2b(8, &[], api_name.as_bytes());
421
126
    result.as_bytes().try_into().unwrap()
422
126
}
423
424
/// One API that the runtime supports.
425
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
426
pub struct CoreVersionApi {
427
    /// BLAKE2 hash of length 8 of the name of the API.
428
    ///
429
    /// > **Note**: Available APIs can be found by searching for `decl_runtime_apis!` in the
430
    /// >           Substrate code base. The value stored in this field is the BLAKE2 hash of
431
    /// >           length 8 of the trait name declared within `decl_runtime_apis!`.
432
    pub name_hash: [u8; 8],
433
434
    /// Version of the module. Typical values are `1`, `2`, `3`, ...
435
    pub version: u32,
436
}
437
438
383
fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> {
439
383
    // See https://spec.polkadot.network/#defn-rt-core-version
440
383
    let result: nom::IResult<_, _> =
441
383
        nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
442
383
            nom::sequence::tuple((
443
383
                crate::util::nom_string_decode,
444
383
                crate::util::nom_string_decode,
445
383
                nom::number::streaming::le_u32,
446
383
                nom::number::streaming::le_u32,
447
383
                nom::number::streaming::le_u32,
448
383
                core_version_apis,
449
383
                nom::branch::alt((
450
383
                    nom::combinator::complete(nom::combinator::map(
451
383
                        nom::number::streaming::le_u32,
452
383
                        Some,
453
383
                    )),
454
383
                    nom::combinator::map(nom::combinator::eof, |_| 
None0
),
Unexecuted instantiation: _RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decode0B9_
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decode0B9_
455
383
                )),
456
383
                nom::branch::alt((
457
383
                    nom::combinator::complete(nom::combinator::map(
458
383
                        nom::bytes::streaming::tag(&[0]),
459
383
                        |_| 
Some(TrieEntryVersion::V0)58
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decodes_0B9_
Line
Count
Source
459
58
                        |_| Some(TrieEntryVersion::V0),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decodes_0B9_
460
383
                    )),
461
383
                    nom::combinator::complete(nom::combinator::map(
462
383
                        nom::bytes::streaming::tag(&[1]),
463
383
                        |_| 
Some(TrieEntryVersion::V1)18
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decodes0_0B9_
Line
Count
Source
463
18
                        |_| Some(TrieEntryVersion::V1),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decodes0_0B9_
464
383
                    )),
465
383
                    nom::combinator::map(nom::combinator::eof, |_| 
None307
),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decodes1_0B9_
Line
Count
Source
465
9
                    nom::combinator::map(nom::combinator::eof, |_| None),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decodes1_0B9_
Line
Count
Source
465
298
                    nom::combinator::map(nom::combinator::eof, |_| None),
466
383
                )),
467
383
            )),
468
383
            |(
469
                spec_name,
470
                impl_name,
471
                authoring_version,
472
                spec_version,
473
                impl_version,
474
                apis,
475
                transaction_version,
476
                state_version,
477
383
            )| CoreVersionRef {
478
383
                spec_name,
479
383
                impl_name,
480
383
                authoring_version,
481
383
                spec_version,
482
383
                impl_version,
483
383
                apis,
484
383
                transaction_version,
485
383
                state_version,
486
383
            },
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decodes2_0B9_
Line
Count
Source
477
85
            )| CoreVersionRef {
478
85
                spec_name,
479
85
                impl_name,
480
85
                authoring_version,
481
85
                spec_version,
482
85
                impl_version,
483
85
                apis,
484
85
                transaction_version,
485
85
                state_version,
486
85
            },
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decodes2_0B9_
Line
Count
Source
477
298
            )| CoreVersionRef {
478
298
                spec_name,
479
298
                impl_name,
480
298
                authoring_version,
481
298
                spec_version,
482
298
                impl_version,
483
298
                apis,
484
298
                transaction_version,
485
298
                state_version,
486
298
            },
487
383
        )))(scale_encoded);
488
489
0
    match result {
490
383
        Ok((_, out)) => Ok(out),
491
0
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()),
492
0
        Err(_) => unreachable!(),
493
    }
494
383
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version6decode
Line
Count
Source
438
85
fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> {
439
85
    // See https://spec.polkadot.network/#defn-rt-core-version
440
85
    let result: nom::IResult<_, _> =
441
85
        nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
442
85
            nom::sequence::tuple((
443
85
                crate::util::nom_string_decode,
444
85
                crate::util::nom_string_decode,
445
85
                nom::number::streaming::le_u32,
446
85
                nom::number::streaming::le_u32,
447
85
                nom::number::streaming::le_u32,
448
85
                core_version_apis,
449
85
                nom::branch::alt((
450
85
                    nom::combinator::complete(nom::combinator::map(
451
85
                        nom::number::streaming::le_u32,
452
85
                        Some,
453
85
                    )),
454
85
                    nom::combinator::map(nom::combinator::eof, |_| None),
455
85
                )),
456
85
                nom::branch::alt((
457
85
                    nom::combinator::complete(nom::combinator::map(
458
85
                        nom::bytes::streaming::tag(&[0]),
459
85
                        |_| Some(TrieEntryVersion::V0),
460
85
                    )),
461
85
                    nom::combinator::complete(nom::combinator::map(
462
85
                        nom::bytes::streaming::tag(&[1]),
463
85
                        |_| Some(TrieEntryVersion::V1),
464
85
                    )),
465
85
                    nom::combinator::map(nom::combinator::eof, |_| None),
466
85
                )),
467
85
            )),
468
85
            |(
469
                spec_name,
470
                impl_name,
471
                authoring_version,
472
                spec_version,
473
                impl_version,
474
                apis,
475
                transaction_version,
476
                state_version,
477
            )| CoreVersionRef {
478
                spec_name,
479
                impl_name,
480
                authoring_version,
481
                spec_version,
482
                impl_version,
483
                apis,
484
                transaction_version,
485
                state_version,
486
85
            },
487
85
        )))(scale_encoded);
488
489
0
    match result {
490
85
        Ok((_, out)) => Ok(out),
491
0
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()),
492
0
        Err(_) => unreachable!(),
493
    }
494
85
}
_RNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version6decode
Line
Count
Source
438
298
fn decode(scale_encoded: &[u8]) -> Result<CoreVersionRef, ()> {
439
298
    // See https://spec.polkadot.network/#defn-rt-core-version
440
298
    let result: nom::IResult<_, _> =
441
298
        nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
442
298
            nom::sequence::tuple((
443
298
                crate::util::nom_string_decode,
444
298
                crate::util::nom_string_decode,
445
298
                nom::number::streaming::le_u32,
446
298
                nom::number::streaming::le_u32,
447
298
                nom::number::streaming::le_u32,
448
298
                core_version_apis,
449
298
                nom::branch::alt((
450
298
                    nom::combinator::complete(nom::combinator::map(
451
298
                        nom::number::streaming::le_u32,
452
298
                        Some,
453
298
                    )),
454
298
                    nom::combinator::map(nom::combinator::eof, |_| None),
455
298
                )),
456
298
                nom::branch::alt((
457
298
                    nom::combinator::complete(nom::combinator::map(
458
298
                        nom::bytes::streaming::tag(&[0]),
459
298
                        |_| Some(TrieEntryVersion::V0),
460
298
                    )),
461
298
                    nom::combinator::complete(nom::combinator::map(
462
298
                        nom::bytes::streaming::tag(&[1]),
463
298
                        |_| Some(TrieEntryVersion::V1),
464
298
                    )),
465
298
                    nom::combinator::map(nom::combinator::eof, |_| None),
466
298
                )),
467
298
            )),
468
298
            |(
469
                spec_name,
470
                impl_name,
471
                authoring_version,
472
                spec_version,
473
                impl_version,
474
                apis,
475
                transaction_version,
476
                state_version,
477
            )| CoreVersionRef {
478
                spec_name,
479
                impl_name,
480
                authoring_version,
481
                spec_version,
482
                impl_version,
483
                apis,
484
                transaction_version,
485
                state_version,
486
298
            },
487
298
        )))(scale_encoded);
488
489
0
    match result {
490
298
        Ok((_, out)) => Ok(out),
491
0
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(()),
492
0
        Err(_) => unreachable!(),
493
    }
494
298
}
495
496
383
fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>(
497
383
    bytes: &'a [u8],
498
383
) -> nom::IResult<&'a [u8], CoreVersionApisRefIter, E> {
499
383
    nom::combinator::map(
500
383
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
501
383
            nom::combinator::recognize(nom::multi::fold_many_m_n(
502
383
                num_elems,
503
383
                num_elems,
504
383
                core_version_api,
505
383
                || {},
_RNCNCINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE00Bc_
Line
Count
Source
505
85
                || {},
_RNCNCINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE00Bc_
Line
Count
Source
505
298
                || {},
506
2.38k
                |(), _| (),
_RNCNCINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0s_0Bc_
Line
Count
Source
506
269
                |(), _| (),
_RNCNCINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0s_0Bc_
Line
Count
Source
506
2.12k
                |(), _| (),
507
383
            ))
508
383
        }),
_RNCINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0Ba_
Line
Count
Source
500
85
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
501
85
            nom::combinator::recognize(nom::multi::fold_many_m_n(
502
85
                num_elems,
503
85
                num_elems,
504
85
                core_version_api,
505
85
                || {},
506
85
                |(), _| (),
507
85
            ))
508
85
        }),
_RNCINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0Ba_
Line
Count
Source
500
298
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
501
298
            nom::combinator::recognize(nom::multi::fold_many_m_n(
502
298
                num_elems,
503
298
                num_elems,
504
298
                core_version_api,
505
298
                || {},
506
298
                |(), _| (),
507
298
            ))
508
298
        }),
509
383
        |inner| CoreVersionApisRefIter { inner },
_RNCINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEs_0Ba_
Line
Count
Source
509
85
        |inner| CoreVersionApisRefIter { inner },
_RNCINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEs_0Ba_
Line
Count
Source
509
298
        |inner| CoreVersionApisRefIter { inner },
510
383
    )(bytes)
511
383
}
_RINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB8_
Line
Count
Source
496
85
fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>(
497
85
    bytes: &'a [u8],
498
85
) -> nom::IResult<&'a [u8], CoreVersionApisRefIter, E> {
499
85
    nom::combinator::map(
500
85
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
501
            nom::combinator::recognize(nom::multi::fold_many_m_n(
502
                num_elems,
503
                num_elems,
504
                core_version_api,
505
                || {},
506
                |(), _| (),
507
            ))
508
85
        }),
509
85
        |inner| CoreVersionApisRefIter { inner },
510
85
    )(bytes)
511
85
}
_RINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version17core_version_apisINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB8_
Line
Count
Source
496
298
fn core_version_apis<'a, E: nom::error::ParseError<&'a [u8]>>(
497
298
    bytes: &'a [u8],
498
298
) -> nom::IResult<&'a [u8], CoreVersionApisRefIter, E> {
499
298
    nom::combinator::map(
500
298
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
501
            nom::combinator::recognize(nom::multi::fold_many_m_n(
502
                num_elems,
503
                num_elems,
504
                core_version_api,
505
                || {},
506
                |(), _| (),
507
            ))
508
298
        }),
509
298
        |inner| CoreVersionApisRefIter { inner },
510
298
    )(bytes)
511
298
}
512
513
5.81k
fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>(
514
5.81k
    bytes: &'a [u8],
515
5.81k
) -> nom::IResult<&'a [u8], CoreVersionApi, E> {
516
5.81k
    nom::combinator::map(
517
5.81k
        nom::sequence::tuple((
518
5.81k
            nom::bytes::streaming::take(8u32),
519
5.81k
            nom::number::streaming::le_u32,
520
5.81k
        )),
521
5.81k
        move |(name, version)| CoreVersionApi {
522
5.66k
            name_hash: <[u8; 8]>::try_from(name).unwrap(),
523
5.66k
            version,
524
5.81k
        },
_RNCINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version16core_version_apiINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0Ba_
Line
Count
Source
521
536
        move |(name, version)| CoreVersionApi {
522
536
            name_hash: <[u8; 8]>::try_from(name).unwrap(),
523
536
            version,
524
536
        },
_RNCINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version16core_version_apiINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEE0Ba_
Line
Count
Source
521
5.13k
        move |(name, version)| CoreVersionApi {
522
5.13k
            name_hash: <[u8; 8]>::try_from(name).unwrap(),
523
5.13k
            version,
524
5.13k
        },
525
5.81k
    )(bytes)
526
5.81k
}
_RINvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version16core_version_apiINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB8_
Line
Count
Source
513
597
fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>(
514
597
    bytes: &'a [u8],
515
597
) -> nom::IResult<&'a [u8], CoreVersionApi, E> {
516
597
    nom::combinator::map(
517
597
        nom::sequence::tuple((
518
597
            nom::bytes::streaming::take(8u32),
519
597
            nom::number::streaming::le_u32,
520
597
        )),
521
597
        move |(name, version)| CoreVersionApi {
522
            name_hash: <[u8; 8]>::try_from(name).unwrap(),
523
            version,
524
597
        },
525
597
    )(bytes)
526
597
}
_RINvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version16core_version_apiINtNtCs6ga8gEqbpRc_3nom5error5ErrorRShEEB8_
Line
Count
Source
513
5.21k
fn core_version_api<'a, E: nom::error::ParseError<&'a [u8]>>(
514
5.21k
    bytes: &'a [u8],
515
5.21k
) -> nom::IResult<&'a [u8], CoreVersionApi, E> {
516
5.21k
    nom::combinator::map(
517
5.21k
        nom::sequence::tuple((
518
5.21k
            nom::bytes::streaming::take(8u32),
519
5.21k
            nom::number::streaming::le_u32,
520
5.21k
        )),
521
5.21k
        move |(name, version)| CoreVersionApi {
522
            name_hash: <[u8; 8]>::try_from(name).unwrap(),
523
            version,
524
5.21k
        },
525
5.21k
    )(bytes)
526
5.21k
}
527
528
struct WasmSection<'a> {
529
    name: &'a [u8],
530
    content: &'a [u8],
531
}
532
533
/// Parses a Wasm section. If it is a custom section, returns its name and content.
534
1.85k
fn wasm_section(bytes: &'_ [u8]) -> nom::IResult<&'_ [u8], Option<WasmSection<'_>>> {
535
1.85k
    nom::branch::alt((
536
1.85k
        nom::combinator::map(
537
1.85k
            nom::combinator::map_parser(
538
1.85k
                nom::sequence::preceded(
539
1.85k
                    nom::bytes::streaming::tag(&[0]),
540
1.85k
                    nom::multi::length_data(nom::combinator::map_opt(
541
1.85k
                        crate::util::leb128::nom_leb128_u64,
542
1.85k
                        |n| 
u32::try_from(n).ok()488
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_section0B9_
Line
Count
Source
542
144
                        |n| u32::try_from(n).ok(),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_section0B9_
Line
Count
Source
542
344
                        |n| u32::try_from(n).ok(),
543
1.85k
                    )),
544
1.85k
                ),
545
1.85k
                nom::sequence::tuple((
546
1.85k
                    nom::multi::length_data(nom::combinator::map_opt(
547
1.85k
                        crate::util::leb128::nom_leb128_u64,
548
1.85k
                        |n| 
u32::try_from(n).ok()488
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_sections_0B9_
Line
Count
Source
548
144
                        |n| u32::try_from(n).ok(),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_sections_0B9_
Line
Count
Source
548
344
                        |n| u32::try_from(n).ok(),
549
1.85k
                    )),
550
1.85k
                    nom::combinator::rest,
551
1.85k
                )),
552
1.85k
            ),
553
1.85k
            |(name, content)| 
Some(WasmSection { name, content })488
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_sections0_0B9_
Line
Count
Source
553
144
            |(name, content)| Some(WasmSection { name, content }),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_sections0_0B9_
Line
Count
Source
553
344
            |(name, content)| Some(WasmSection { name, content }),
554
1.85k
        ),
555
1.85k
        nom::combinator::map(
556
1.85k
            nom::sequence::tuple((
557
1.85k
                nom::number::streaming::u8,
558
1.85k
                nom::multi::length_data(nom::combinator::map_opt(
559
1.85k
                    crate::util::leb128::nom_leb128_u64,
560
1.85k
                    |n| 
u32::try_from(n).ok()1.21k
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_sections1_0B9_
Line
Count
Source
560
438
                    |n| u32::try_from(n).ok(),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_sections1_0B9_
Line
Count
Source
560
774
                    |n| u32::try_from(n).ok(),
561
1.85k
                )),
562
1.85k
            )),
563
1.85k
            |_| 
None1.21k
,
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_sections2_0B9_
Line
Count
Source
563
438
            |_| None,
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_sections2_0B9_
Line
Count
Source
563
774
            |_| None,
564
1.85k
        ),
565
1.85k
    ))(bytes)
566
1.85k
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot8executor4host15runtime_version12wasm_section
Line
Count
Source
534
646
fn wasm_section(bytes: &'_ [u8]) -> nom::IResult<&'_ [u8], Option<WasmSection<'_>>> {
535
646
    nom::branch::alt((
536
646
        nom::combinator::map(
537
646
            nom::combinator::map_parser(
538
646
                nom::sequence::preceded(
539
646
                    nom::bytes::streaming::tag(&[0]),
540
646
                    nom::multi::length_data(nom::combinator::map_opt(
541
646
                        crate::util::leb128::nom_leb128_u64,
542
646
                        |n| u32::try_from(n).ok(),
543
646
                    )),
544
646
                ),
545
646
                nom::sequence::tuple((
546
646
                    nom::multi::length_data(nom::combinator::map_opt(
547
646
                        crate::util::leb128::nom_leb128_u64,
548
646
                        |n| u32::try_from(n).ok(),
549
646
                    )),
550
646
                    nom::combinator::rest,
551
646
                )),
552
646
            ),
553
646
            |(name, content)| Some(WasmSection { name, content }),
554
646
        ),
555
646
        nom::combinator::map(
556
646
            nom::sequence::tuple((
557
646
                nom::number::streaming::u8,
558
646
                nom::multi::length_data(nom::combinator::map_opt(
559
646
                    crate::util::leb128::nom_leb128_u64,
560
646
                    |n| u32::try_from(n).ok(),
561
646
                )),
562
646
            )),
563
646
            |_| None,
564
646
        ),
565
646
    ))(bytes)
566
646
}
_RNvNtNtNtCseuYC0Zibziv_7smoldot8executor4host15runtime_version12wasm_section
Line
Count
Source
534
1.20k
fn wasm_section(bytes: &'_ [u8]) -> nom::IResult<&'_ [u8], Option<WasmSection<'_>>> {
535
1.20k
    nom::branch::alt((
536
1.20k
        nom::combinator::map(
537
1.20k
            nom::combinator::map_parser(
538
1.20k
                nom::sequence::preceded(
539
1.20k
                    nom::bytes::streaming::tag(&[0]),
540
1.20k
                    nom::multi::length_data(nom::combinator::map_opt(
541
1.20k
                        crate::util::leb128::nom_leb128_u64,
542
1.20k
                        |n| u32::try_from(n).ok(),
543
1.20k
                    )),
544
1.20k
                ),
545
1.20k
                nom::sequence::tuple((
546
1.20k
                    nom::multi::length_data(nom::combinator::map_opt(
547
1.20k
                        crate::util::leb128::nom_leb128_u64,
548
1.20k
                        |n| u32::try_from(n).ok(),
549
1.20k
                    )),
550
1.20k
                    nom::combinator::rest,
551
1.20k
                )),
552
1.20k
            ),
553
1.20k
            |(name, content)| Some(WasmSection { name, content }),
554
1.20k
        ),
555
1.20k
        nom::combinator::map(
556
1.20k
            nom::sequence::tuple((
557
1.20k
                nom::number::streaming::u8,
558
1.20k
                nom::multi::length_data(nom::combinator::map_opt(
559
1.20k
                    crate::util::leb128::nom_leb128_u64,
560
1.20k
                    |n| u32::try_from(n).ok(),
561
1.20k
                )),
562
1.20k
            )),
563
1.20k
            |_| None,
564
1.20k
        ),
565
1.20k
    ))(bytes)
566
1.20k
}