Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/chain/chain_information/build.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
//! Build the chain information of a chain given its runtime.
19
//!
20
//! This module contains the [`ChainInformationBuild`] struct, a state machine that drives the
21
//! process of building the chain information of a certain finalized point of a chain.
22
23
use alloc::{boxed::Box, vec::Vec};
24
use core::{fmt, iter, num::NonZeroU64};
25
26
use crate::{
27
    chain::chain_information,
28
    executor::{host, runtime_call},
29
    header, trie,
30
};
31
32
pub use runtime_call::{Nibble, TrieEntryVersion};
33
34
/// Configuration to provide to [`ChainInformationBuild::new`].
35
pub struct Config {
36
    /// Header of the finalized block, whose chain information is to retrieve.
37
    ///
38
    /// Stored within the chain information at the end.
39
    pub finalized_block_header: ConfigFinalizedBlockHeader,
40
41
    /// Runtime of the finalized block. Must be built using the Wasm code found at the `:code` key
42
    /// of the block storage.
43
    pub runtime: host::HostVmPrototype,
44
45
    /// Number of bytes of the block number encoded in the block header.
46
    pub block_number_bytes: usize,
47
}
48
49
/// See [`Config::finalized_block_header`].
50
pub enum ConfigFinalizedBlockHeader {
51
    /// The block is the genesis block of the chain.
52
    Genesis {
53
        /// Hash of the root of the state trie of the genesis.
54
        state_trie_root_hash: [u8; 32],
55
    },
56
    /// The block can any block, genesis block of the chain or not.
57
    Any {
58
        /// Header of the block.
59
        scale_encoded_header: Vec<u8>,
60
        /// Can be used to pass information about the finality of the chain, if already known.
61
        known_finality: Option<chain_information::ChainInformationFinality>,
62
    },
63
}
64
65
/// Current state of the operation.
66
#[must_use]
67
pub enum ChainInformationBuild {
68
    /// Fetching the chain information is over.
69
    Finished {
70
        /// The result of the computation.
71
        ///
72
        /// If successful, the chain information is guaranteed to be valid.
73
        result: Result<chain_information::ValidChainInformation, Error>,
74
        /// Value of [`Config::runtime`] passed back.
75
        virtual_machine: host::HostVmPrototype,
76
    },
77
78
    /// Still in progress.
79
    InProgress(InProgress),
80
}
81
82
/// Chain information building is still in progress.
83
#[must_use]
84
pub enum InProgress {
85
    /// Loading a storage value is required in order to continue.
86
    StorageGet(StorageGet),
87
    /// Obtaining the Merkle value of the closest descendant of a trie node is required in order
88
    /// to continue.
89
    ClosestDescendantMerkleValue(ClosestDescendantMerkleValue),
90
    /// Fetching the key that follows a given one is required in order to continue.
91
    NextKey(NextKey),
92
}
93
94
/// Problem encountered during the chain building process.
95
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXs7_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs7_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
96
pub enum Error {
97
    /// Error while starting the Wasm virtual machine.
98
    #[display(fmt = "While calling {call:?}: {error}")]
99
    WasmStart {
100
        call: RuntimeCall,
101
        error: host::StartErr,
102
    },
103
    /// Error while running the Wasm virtual machine.
104
    #[display(fmt = "While calling {call:?}: {error}")]
105
    WasmVm {
106
        call: RuntimeCall,
107
        error: runtime_call::ErrorDetail,
108
    },
109
    /// Runtime has called an offchain worker host function.
110
    OffchainWorkerHostFunction,
111
    /// Failed to decode the output of the `AuraApi_slot_duration` runtime call.
112
    AuraSlotDurationOutputDecode,
113
    /// Failed to decode the output of the `AuraApi_authorities` runtime call.
114
    AuraAuthoritiesOutputDecode,
115
    /// Failed to decode the output of the `BabeApi_current_epoch` runtime call.
116
    BabeCurrentEpochOutputDecode,
117
    /// Failed to decode the output of the `BabeApi_next_epoch` runtime call.
118
    BabeNextEpochOutputDecode,
119
    /// Failed to decode the output of the `BabeApi_configuration` runtime call.
120
    BabeConfigurationOutputDecode,
121
    /// The version of `GrandaApi` is too old to be able to build the chain information.
122
    GrandpaApiTooOld,
123
    /// Failed to decode the output of the `GrandpaApi_authorities` runtime call.
124
    GrandpaAuthoritiesOutputDecode,
125
    /// Failed to decode the output of the `GrandpaApi_current_set_id` runtime call.
126
    GrandpaCurrentSetIdOutputDecode,
127
    /// The combination of the information retrieved from the runtime doesn't make sense together.
128
    #[display(fmt = "{_0}")]
129
    InvalidChainInformation(chain_information::ValidityError),
130
    /// Multiple consensus algorithms have been detected.
131
    MultipleConsensusAlgorithms,
132
}
133
134
/// Function call to perform or being performed.
135
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
136
pub enum RuntimeCall {
137
    AuraApiSlotDuration,
138
    AuraApiAuthorities,
139
    BabeApiCurrentEpoch,
140
    BabeApiNextEpoch,
141
    BabeApiConfiguration,
142
    GrandpaApiAuthorities,
143
    GrandpaApiCurrentSetId,
144
}
145
146
impl RuntimeCall {
147
    /// Name of the runtime function corresponding to this call.
148
128
    pub fn function_name(&self) -> &'static str {
149
128
        match self {
150
42
            RuntimeCall::AuraApiSlotDuration => "AuraApi_slot_duration",
151
42
            RuntimeCall::AuraApiAuthorities => "AuraApi_authorities",
152
0
            RuntimeCall::BabeApiCurrentEpoch => "BabeApi_current_epoch",
153
0
            RuntimeCall::BabeApiNextEpoch => "BabeApi_next_epoch",
154
1
            RuntimeCall::BabeApiConfiguration => "BabeApi_configuration",
155
43
            RuntimeCall::GrandpaApiAuthorities => "GrandpaApi_grandpa_authorities",
156
0
            RuntimeCall::GrandpaApiCurrentSetId => "GrandpaApi_current_set_id",
157
        }
158
128
    }
_RNvMNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall13function_name
Line
Count
Source
148
2
    pub fn function_name(&self) -> &'static str {
149
2
        match self {
150
0
            RuntimeCall::AuraApiSlotDuration => "AuraApi_slot_duration",
151
0
            RuntimeCall::AuraApiAuthorities => "AuraApi_authorities",
152
0
            RuntimeCall::BabeApiCurrentEpoch => "BabeApi_current_epoch",
153
0
            RuntimeCall::BabeApiNextEpoch => "BabeApi_next_epoch",
154
1
            RuntimeCall::BabeApiConfiguration => "BabeApi_configuration",
155
1
            RuntimeCall::GrandpaApiAuthorities => "GrandpaApi_grandpa_authorities",
156
0
            RuntimeCall::GrandpaApiCurrentSetId => "GrandpaApi_current_set_id",
157
        }
158
2
    }
_RNvMNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall13function_name
Line
Count
Source
148
126
    pub fn function_name(&self) -> &'static str {
149
126
        match self {
150
42
            RuntimeCall::AuraApiSlotDuration => "AuraApi_slot_duration",
151
42
            RuntimeCall::AuraApiAuthorities => "AuraApi_authorities",
152
0
            RuntimeCall::BabeApiCurrentEpoch => "BabeApi_current_epoch",
153
0
            RuntimeCall::BabeApiNextEpoch => "BabeApi_next_epoch",
154
0
            RuntimeCall::BabeApiConfiguration => "BabeApi_configuration",
155
42
            RuntimeCall::GrandpaApiAuthorities => "GrandpaApi_grandpa_authorities",
156
0
            RuntimeCall::GrandpaApiCurrentSetId => "GrandpaApi_current_set_id",
157
        }
158
126
    }
159
160
    /// Returns the list of parameters to pass when making the call.
161
    ///
162
    /// The actual parameters are obtained by putting together all the returned buffers together.
163
128
    pub fn parameter_vectored(
164
128
        &'_ self,
165
128
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_ {
166
128
        iter::empty::<Vec<u8>>()
167
128
    }
_RNvMNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall18parameter_vectored
Line
Count
Source
163
2
    pub fn parameter_vectored(
164
2
        &'_ self,
165
2
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_ {
166
2
        iter::empty::<Vec<u8>>()
167
2
    }
_RNvMNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall18parameter_vectored
Line
Count
Source
163
126
    pub fn parameter_vectored(
164
126
        &'_ self,
165
126
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_ {
166
126
        iter::empty::<Vec<u8>>()
167
126
    }
168
169
    /// Returns the list of parameters to pass when making the call.
170
    ///
171
    /// This function is a convenience around [`RuntimeCall::parameter_vectored`].
172
0
    pub fn parameter_vectored_vec(&self) -> Vec<u8> {
173
0
        Vec::new()
174
0
    }
Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall22parameter_vectored_vec
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB2_11RuntimeCall22parameter_vectored_vec
175
}
176
177
impl fmt::Debug for RuntimeCall {
178
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179
0
        fmt::Debug::fmt(&self.function_name(), f)
180
0
    }
Unexecuted instantiation: _RNvXs_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB4_11RuntimeCallNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB4_11RuntimeCallNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
181
}
182
183
impl ChainInformationBuild {
184
    /// Starts a new chain information build process.
185
    ///
186
    /// # Panic
187
    ///
188
    /// Panics if a [`ConfigFinalizedBlockHeader::Any`] is provided, and the header can't be
189
    /// decoded.
190
    ///
191
43
    pub fn new(config: Config) -> Self {
192
43
        let [aura_version, babe_version, grandpa_version] = config
193
43
            .runtime
194
43
            .runtime_version()
195
43
            .decode()
196
43
            .apis
197
43
            .find_versions(["AuraApi", "BabeApi", "GrandpaApi"]);
198
43
        let runtime_has_aura = aura_version.map_or(false, |version_number| 
version_number == 142
);
Unexecuted instantiation: _RNCNvMs0_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3new0Bd_
_RNCNvMs0_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3new0Bd_
Line
Count
Source
198
42
        let runtime_has_aura = aura_version.map_or(false, |version_number| version_number == 1);
199
43
        let runtime_babeapi_is_v1 = babe_version.and_then(|version_number| 
match version_number1
{
200
0
            1 => Some(true),
201
1
            2 => Some(false),
202
0
            _ => None,
203
43
        
}1
);
_RNCNvMs0_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3news_0Bd_
Line
Count
Source
199
1
        let runtime_babeapi_is_v1 = babe_version.and_then(|version_number| match version_number {
200
0
            1 => Some(true),
201
1
            2 => Some(false),
202
0
            _ => None,
203
1
        });
Unexecuted instantiation: _RNCNvMs0_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3news_0Bd_
204
43
        let runtime_grandpa_supports_currentsetid =
205
43
            grandpa_version.and_then(|version_number| match version_number {
206
                // Version 1 is from 2019 and isn't used by any chain in production, so we don't
207
                // care about it.
208
1
                2 => Some(false),
209
42
                3 => Some(true),
210
0
                _ => None,
211
43
            });
_RNCNvMs0_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3news0_0Bd_
Line
Count
Source
205
1
            grandpa_version.and_then(|version_number| match version_number {
206
                // Version 1 is from 2019 and isn't used by any chain in production, so we don't
207
                // care about it.
208
1
                2 => Some(false),
209
0
                3 => Some(true),
210
0
                _ => None,
211
1
            });
_RNCNvMs0_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB7_21ChainInformationBuild3news0_0Bd_
Line
Count
Source
205
42
            grandpa_version.and_then(|version_number| match version_number {
206
                // Version 1 is from 2019 and isn't used by any chain in production, so we don't
207
                // care about it.
208
0
                2 => Some(false),
209
42
                3 => Some(true),
210
0
                _ => None,
211
42
            });
212
43
213
43
        let inner = ChainInformationBuildInner {
214
43
            finalized_block_header: config.finalized_block_header,
215
43
            block_number_bytes: config.block_number_bytes,
216
43
            call_in_progress: None,
217
43
            virtual_machine: Some(config.runtime),
218
43
            runtime_has_aura,
219
43
            runtime_babeapi_is_v1,
220
43
            runtime_grandpa_supports_currentsetid,
221
43
            aura_autorities_call_output: None,
222
43
            aura_slot_duration_call_output: None,
223
43
            babe_current_epoch_call_output: None,
224
43
            babe_next_epoch_call_output: None,
225
43
            babe_configuration_call_output: None,
226
43
            grandpa_autorities_call_output: None,
227
43
            grandpa_current_set_id_call_output: None,
228
43
        };
229
43
230
43
        ChainInformationBuild::start_next_call(inner)
231
43
    }
_RNvMs0_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild3new
Line
Count
Source
191
1
    pub fn new(config: Config) -> Self {
192
1
        let [aura_version, babe_version, grandpa_version] = config
193
1
            .runtime
194
1
            .runtime_version()
195
1
            .decode()
196
1
            .apis
197
1
            .find_versions(["AuraApi", "BabeApi", "GrandpaApi"]);
198
1
        let runtime_has_aura = aura_version.map_or(false, |version_number| version_number == 1);
199
1
        let runtime_babeapi_is_v1 = babe_version.and_then(|version_number| match version_number {
200
            1 => Some(true),
201
            2 => Some(false),
202
            _ => None,
203
1
        });
204
1
        let runtime_grandpa_supports_currentsetid =
205
1
            grandpa_version.and_then(|version_number| match version_number {
206
                // Version 1 is from 2019 and isn't used by any chain in production, so we don't
207
                // care about it.
208
                2 => Some(false),
209
                3 => Some(true),
210
                _ => None,
211
1
            });
212
1
213
1
        let inner = ChainInformationBuildInner {
214
1
            finalized_block_header: config.finalized_block_header,
215
1
            block_number_bytes: config.block_number_bytes,
216
1
            call_in_progress: None,
217
1
            virtual_machine: Some(config.runtime),
218
1
            runtime_has_aura,
219
1
            runtime_babeapi_is_v1,
220
1
            runtime_grandpa_supports_currentsetid,
221
1
            aura_autorities_call_output: None,
222
1
            aura_slot_duration_call_output: None,
223
1
            babe_current_epoch_call_output: None,
224
1
            babe_next_epoch_call_output: None,
225
1
            babe_configuration_call_output: None,
226
1
            grandpa_autorities_call_output: None,
227
1
            grandpa_current_set_id_call_output: None,
228
1
        };
229
1
230
1
        ChainInformationBuild::start_next_call(inner)
231
1
    }
_RNvMs0_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild3new
Line
Count
Source
191
42
    pub fn new(config: Config) -> Self {
192
42
        let [aura_version, babe_version, grandpa_version] = config
193
42
            .runtime
194
42
            .runtime_version()
195
42
            .decode()
196
42
            .apis
197
42
            .find_versions(["AuraApi", "BabeApi", "GrandpaApi"]);
198
42
        let runtime_has_aura = aura_version.map_or(false, |version_number| version_number == 1);
199
42
        let runtime_babeapi_is_v1 = babe_version.and_then(|version_number| match version_number {
200
            1 => Some(true),
201
            2 => Some(false),
202
            _ => None,
203
42
        });
204
42
        let runtime_grandpa_supports_currentsetid =
205
42
            grandpa_version.and_then(|version_number| match version_number {
206
                // Version 1 is from 2019 and isn't used by any chain in production, so we don't
207
                // care about it.
208
                2 => Some(false),
209
                3 => Some(true),
210
                _ => None,
211
42
            });
212
42
213
42
        let inner = ChainInformationBuildInner {
214
42
            finalized_block_header: config.finalized_block_header,
215
42
            block_number_bytes: config.block_number_bytes,
216
42
            call_in_progress: None,
217
42
            virtual_machine: Some(config.runtime),
218
42
            runtime_has_aura,
219
42
            runtime_babeapi_is_v1,
220
42
            runtime_grandpa_supports_currentsetid,
221
42
            aura_autorities_call_output: None,
222
42
            aura_slot_duration_call_output: None,
223
42
            babe_current_epoch_call_output: None,
224
42
            babe_next_epoch_call_output: None,
225
42
            babe_configuration_call_output: None,
226
42
            grandpa_autorities_call_output: None,
227
42
            grandpa_current_set_id_call_output: None,
228
42
        };
229
42
230
42
        ChainInformationBuild::start_next_call(inner)
231
42
    }
232
}
233
234
impl InProgress {
235
    /// Returns the list of runtime calls that will be performed. Always includes the value
236
    /// returned by [`InProgress::call_in_progress`].
237
    ///
238
    /// This list never changes, except for the fact that it gets shorter over time.
239
0
    pub fn remaining_calls(&self) -> impl Iterator<Item = RuntimeCall> {
240
0
        let inner = match self {
241
0
            InProgress::StorageGet(StorageGet(_, shared)) => shared,
242
0
            InProgress::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(_, shared)) => {
243
0
                shared
244
            }
245
0
            InProgress::NextKey(NextKey(_, shared)) => shared,
246
        };
247
248
0
        ChainInformationBuild::necessary_calls(inner)
249
0
    }
Unexecuted instantiation: _RNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_10InProgress15remaining_calls
Unexecuted instantiation: _RNvMs1_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_10InProgress15remaining_calls
250
251
    /// Returns the runtime call currently being made.
252
0
    pub fn call_in_progress(&self) -> RuntimeCall {
253
0
        let inner = match self {
254
0
            InProgress::StorageGet(StorageGet(_, shared)) => shared,
255
0
            InProgress::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(_, shared)) => {
256
0
                shared
257
            }
258
0
            InProgress::NextKey(NextKey(_, shared)) => shared,
259
        };
260
261
0
        inner.call_in_progress.unwrap()
262
0
    }
Unexecuted instantiation: _RNvMs1_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_10InProgress16call_in_progress
Unexecuted instantiation: _RNvMs1_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_10InProgress16call_in_progress
263
}
264
265
/// Loading a storage value is required in order to continue.
266
#[must_use]
267
pub struct StorageGet(runtime_call::StorageGet, ChainInformationBuildInner);
268
269
impl StorageGet {
270
    /// Returns the key whose value must be passed to [`StorageGet::inject_value`].
271
87
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
272
87
        self.0.key()
273
87
    }
_RNvMs2_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_10StorageGet3key
Line
Count
Source
271
3
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
272
3
        self.0.key()
273
3
    }
_RNvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_10StorageGet3key
Line
Count
Source
271
84
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
272
84
        self.0.key()
273
84
    }
274
275
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
276
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
277
0
        self.0.child_trie()
278
0
    }
Unexecuted instantiation: _RNvMs2_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_10StorageGet10child_trie
Unexecuted instantiation: _RNvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_10StorageGet10child_trie
279
280
    /// Injects the corresponding storage value.
281
87
    pub fn inject_value(
282
87
        self,
283
87
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
284
87
    ) -> ChainInformationBuild {
285
87
        ChainInformationBuild::from_call_in_progress(self.0.inject_value(value), self.1)
286
87
    }
_RINvMs2_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1x_EEBc_
Line
Count
Source
281
3
    pub fn inject_value(
282
3
        self,
283
3
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
284
3
    ) -> ChainInformationBuild {
285
3
        ChainInformationBuild::from_call_in_progress(self.0.inject_value(value), self.1)
286
3
    }
Unexecuted instantiation: _RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EECsDDUKWWCHAU_18smoldot_light_wasm
_RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EEBc_
Line
Count
Source
281
42
    pub fn inject_value(
282
42
        self,
283
42
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
284
42
    ) -> ChainInformationBuild {
285
42
        ChainInformationBuild::from_call_in_progress(self.0.inject_value(value), self.1)
286
42
    }
_RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EEBc_
Line
Count
Source
281
42
    pub fn inject_value(
282
42
        self,
283
42
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
284
42
    ) -> ChainInformationBuild {
285
42
        ChainInformationBuild::from_call_in_progress(self.0.inject_value(value), self.1)
286
42
    }
Unexecuted instantiation: _RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1y_EECsibGXYHQB8Ea_25json_rpc_general_requests
287
288
    /// Returns the runtime call currently being made.
289
0
    pub fn call_in_progress(&self) -> RuntimeCall {
290
0
        self.1.call_in_progress.unwrap()
291
0
    }
Unexecuted instantiation: _RNvMs2_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_10StorageGet16call_in_progress
Unexecuted instantiation: _RNvMs2_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_10StorageGet16call_in_progress
292
}
293
294
/// Obtaining the Merkle value of the closest descendant of a trie node is required in order
295
/// to continue.
296
#[must_use]
297
pub struct ClosestDescendantMerkleValue(
298
    runtime_call::ClosestDescendantMerkleValue,
299
    ChainInformationBuildInner,
300
);
301
302
impl ClosestDescendantMerkleValue {
303
    /// Returns the key whose closest descendant Merkle value must be passed to
304
    /// [`ClosestDescendantMerkleValue::inject_merkle_value`].
305
0
    pub fn key(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
306
0
        self.0.key()
307
0
    }
Unexecuted instantiation: _RNvMs3_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue3key
Unexecuted instantiation: _RNvMs3_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue3key
308
309
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
310
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
311
0
        self.0.child_trie()
312
0
    }
Unexecuted instantiation: _RNvMs3_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue10child_trie
Unexecuted instantiation: _RNvMs3_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue10child_trie
313
314
    /// Indicate that the value is unknown and resume the calculation.
315
    ///
316
    /// This function be used if you are unaware of the Merkle value. The algorithm will perform
317
    /// the calculation of this Merkle value manually, which takes more time.
318
0
    pub fn resume_unknown(self) -> ChainInformationBuild {
319
0
        ChainInformationBuild::from_call_in_progress(self.0.resume_unknown(), self.1)
320
0
    }
Unexecuted instantiation: _RNvMs3_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue14resume_unknown
Unexecuted instantiation: _RNvMs3_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue14resume_unknown
321
322
    /// Injects the corresponding Merkle value.
323
    ///
324
    /// `None` can be passed if there is no descendant or, in the case of a child trie read, in
325
    /// order to indicate that the child trie does not exist.
326
0
    pub fn inject_merkle_value(self, merkle_value: Option<&[u8]>) -> ChainInformationBuild {
327
0
        ChainInformationBuild::from_call_in_progress(
328
0
            self.0.inject_merkle_value(merkle_value),
329
0
            self.1,
330
0
        )
331
0
    }
Unexecuted instantiation: _RNvMs3_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue19inject_merkle_value
Unexecuted instantiation: _RNvMs3_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue19inject_merkle_value
332
333
    /// Returns the runtime call currently being made.
334
0
    pub fn call_in_progress(&self) -> RuntimeCall {
335
0
        self.1.call_in_progress.unwrap()
336
0
    }
Unexecuted instantiation: _RNvMs3_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue16call_in_progress
Unexecuted instantiation: _RNvMs3_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_28ClosestDescendantMerkleValue16call_in_progress
337
}
338
339
/// Fetching the key that follows a given one is required in order to continue.
340
#[must_use]
341
pub struct NextKey(runtime_call::NextKey, ChainInformationBuildInner);
342
343
impl NextKey {
344
    /// Returns the key whose next key must be passed back.
345
0
    pub fn key(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
346
0
        self.0.key()
347
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey3key
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey3key
348
349
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
350
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
351
0
        self.0.child_trie()
352
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey10child_trie
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey10child_trie
353
354
    /// If `true`, then the provided value must the one superior or equal to the requested key.
355
    /// If `false`, then the provided value must be strictly superior to the requested key.
356
0
    pub fn or_equal(&self) -> bool {
357
0
        self.0.or_equal()
358
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey8or_equal
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey8or_equal
359
360
    /// If `true`, then the search must include both branch nodes and storage nodes. If `false`,
361
    /// the search only covers storage nodes.
362
0
    pub fn branch_nodes(&self) -> bool {
363
0
        self.0.branch_nodes()
364
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey12branch_nodes
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey12branch_nodes
365
366
    /// Returns the prefix the next key must start with. If the next key doesn't start with the
367
    /// given prefix, then `None` should be provided.
368
0
    pub fn prefix(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
369
0
        self.0.prefix()
370
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey6prefix
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey6prefix
371
372
    /// Injects the key.
373
    ///
374
    /// # Panic
375
    ///
376
    /// Panics if the key passed as parameter isn't strictly superior to the requested key.
377
    /// Panics if the key passed as parameter doesn't start with the requested prefix.
378
    ///
379
0
    pub fn inject_key(self, key: Option<impl Iterator<Item = Nibble>>) -> ChainInformationBuild {
380
0
        ChainInformationBuild::from_call_in_progress(self.0.inject_key(key), self.1)
381
0
    }
Unexecuted instantiation: _RINvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keypEBc_
Unexecuted instantiation: _RINvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keyINtNtNtBc_4trie12proof_decode12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhENCNCNvMNtNtBc_8database11full_sqliteNtB3d_18SqliteFullDatabase20to_chain_informations_00EEBc_
Unexecuted instantiation: _RINvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keyINtNtNtBc_4trie12proof_decode12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keyINtNtNtBc_4trie12proof_decode12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB6_7NextKey10inject_keyINtNtNtBc_4trie12proof_decode12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEECsibGXYHQB8Ea_25json_rpc_general_requests
382
383
    /// Returns the runtime call currently being made.
384
0
    pub fn call_in_progress(&self) -> RuntimeCall {
385
0
        self.1.call_in_progress.unwrap()
386
0
    }
Unexecuted instantiation: _RNvMs4_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_7NextKey16call_in_progress
Unexecuted instantiation: _RNvMs4_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_7NextKey16call_in_progress
387
}
388
389
impl ChainInformationBuild {
390
171
    fn necessary_calls(inner: &ChainInformationBuildInner) -> impl Iterator<Item = RuntimeCall> {
391
171
        let aura_api_authorities =
392
171
            if inner.runtime_has_aura && 
inner.aura_autorities_call_output.is_none()168
{
393
42
                Some(RuntimeCall::AuraApiAuthorities)
394
            } else {
395
129
                None
396
            };
397
398
171
        let aura_slot_duration =
399
171
            if inner.runtime_has_aura && 
inner.aura_slot_duration_call_output.is_none()168
{
400
84
                Some(RuntimeCall::AuraApiSlotDuration)
401
            } else {
402
87
                None
403
            };
404
405
171
        let babe_current_epoch = if 
matches!0
(
406
84
            inner.finalized_block_header,
407
84
            ConfigFinalizedBlockHeader::Any {
408
84
                ref scale_encoded_header,
409
84
                ..
410
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
411
0
        ) && inner.runtime_babeapi_is_v1.is_some()
412
0
            && inner.babe_current_epoch_call_output.is_none()
413
        {
414
0
            Some(RuntimeCall::BabeApiCurrentEpoch)
415
        } else {
416
171
            None
417
        };
418
419
171
        let babe_next_epoch = if 
matches!0
(
420
84
            inner.finalized_block_header,
421
84
            ConfigFinalizedBlockHeader::Any {
422
84
                ref scale_encoded_header,
423
84
                ..
424
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
425
0
        ) && inner.runtime_babeapi_is_v1.is_some()
426
0
            && inner.babe_next_epoch_call_output.is_none()
427
        {
428
0
            Some(RuntimeCall::BabeApiNextEpoch)
429
        } else {
430
171
            None
431
        };
432
433
171
        let babe_configuration = if inner.runtime_babeapi_is_v1.is_some()
434
3
            && inner.babe_configuration_call_output.is_none()
435
        {
436
1
            Some(RuntimeCall::BabeApiConfiguration)
437
        } else {
438
170
            None
439
        };
440
441
171
        let grandpa_authorities = if !matches!(
442
0
            inner.finalized_block_header,
443
            ConfigFinalizedBlockHeader::Any {
444
                known_finality: Some(chain_information::ChainInformationFinality::Grandpa { .. }),
445
                ..
446
            },
447
171
        ) && inner.runtime_grandpa_supports_currentsetid.is_some()
448
171
            && inner.grandpa_autorities_call_output.is_none()
449
        {
450
128
            Some(RuntimeCall::GrandpaApiAuthorities)
451
        } else {
452
43
            None
453
        };
454
455
        // The grandpa set ID doesn't need to be retrieved if finality was provided by the user,
456
        // but also doesn't need to be retrieved for the genesis block because we know it's
457
        // always 0.
458
171
        let grandpa_current_set_id = if 
matches!0
(
459
84
            inner.finalized_block_header,
460
84
            ConfigFinalizedBlockHeader::Any {
461
84
                ref scale_encoded_header,
462
84
                known_finality: None,
463
84
                ..
464
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
,
465
0
        ) && inner.runtime_grandpa_supports_currentsetid
466
0
            == Some(true)
467
0
            && inner.grandpa_current_set_id_call_output.is_none()
468
        {
469
0
            Some(RuntimeCall::GrandpaApiCurrentSetId)
470
        } else {
471
171
            None
472
        };
473
474
171
        [
475
171
            aura_api_authorities,
476
171
            aura_slot_duration,
477
171
            babe_current_epoch,
478
171
            babe_next_epoch,
479
171
            babe_configuration,
480
171
            grandpa_authorities,
481
171
            grandpa_current_set_id,
482
171
        ]
483
171
        .into_iter()
484
171
        .flatten()
485
171
    }
_RNvMs5_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild15necessary_calls
Line
Count
Source
390
3
    fn necessary_calls(inner: &ChainInformationBuildInner) -> impl Iterator<Item = RuntimeCall> {
391
3
        let aura_api_authorities =
392
3
            if inner.runtime_has_aura && 
inner.aura_autorities_call_output.is_none()0
{
393
0
                Some(RuntimeCall::AuraApiAuthorities)
394
            } else {
395
3
                None
396
            };
397
398
3
        let aura_slot_duration =
399
3
            if inner.runtime_has_aura && 
inner.aura_slot_duration_call_output.is_none()0
{
400
0
                Some(RuntimeCall::AuraApiSlotDuration)
401
            } else {
402
3
                None
403
            };
404
405
3
        let babe_current_epoch = if 
matches!0
(
406
0
            inner.finalized_block_header,
407
0
            ConfigFinalizedBlockHeader::Any {
408
0
                ref scale_encoded_header,
409
0
                ..
410
0
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 0
411
0
        ) && inner.runtime_babeapi_is_v1.is_some()
412
0
            && inner.babe_current_epoch_call_output.is_none()
413
        {
414
0
            Some(RuntimeCall::BabeApiCurrentEpoch)
415
        } else {
416
3
            None
417
        };
418
419
3
        let babe_next_epoch = if 
matches!0
(
420
0
            inner.finalized_block_header,
421
0
            ConfigFinalizedBlockHeader::Any {
422
0
                ref scale_encoded_header,
423
0
                ..
424
0
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 0
425
0
        ) && inner.runtime_babeapi_is_v1.is_some()
426
0
            && inner.babe_next_epoch_call_output.is_none()
427
        {
428
0
            Some(RuntimeCall::BabeApiNextEpoch)
429
        } else {
430
3
            None
431
        };
432
433
3
        let babe_configuration = if inner.runtime_babeapi_is_v1.is_some()
434
3
            && inner.babe_configuration_call_output.is_none()
435
        {
436
1
            Some(RuntimeCall::BabeApiConfiguration)
437
        } else {
438
2
            None
439
        };
440
441
3
        let grandpa_authorities = if !matches!(
442
0
            inner.finalized_block_header,
443
            ConfigFinalizedBlockHeader::Any {
444
                known_finality: Some(chain_information::ChainInformationFinality::Grandpa { .. }),
445
                ..
446
            },
447
3
        ) && inner.runtime_grandpa_supports_currentsetid.is_some()
448
3
            && inner.grandpa_autorities_call_output.is_none()
449
        {
450
2
            Some(RuntimeCall::GrandpaApiAuthorities)
451
        } else {
452
1
            None
453
        };
454
455
        // The grandpa set ID doesn't need to be retrieved if finality was provided by the user,
456
        // but also doesn't need to be retrieved for the genesis block because we know it's
457
        // always 0.
458
3
        let grandpa_current_set_id = if 
matches!0
(
459
0
            inner.finalized_block_header,
460
0
            ConfigFinalizedBlockHeader::Any {
461
0
                ref scale_encoded_header,
462
0
                known_finality: None,
463
0
                ..
464
0
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 0,
465
0
        ) && inner.runtime_grandpa_supports_currentsetid
466
0
            == Some(true)
467
0
            && inner.grandpa_current_set_id_call_output.is_none()
468
        {
469
0
            Some(RuntimeCall::GrandpaApiCurrentSetId)
470
        } else {
471
3
            None
472
        };
473
474
3
        [
475
3
            aura_api_authorities,
476
3
            aura_slot_duration,
477
3
            babe_current_epoch,
478
3
            babe_next_epoch,
479
3
            babe_configuration,
480
3
            grandpa_authorities,
481
3
            grandpa_current_set_id,
482
3
        ]
483
3
        .into_iter()
484
3
        .flatten()
485
3
    }
_RNvMs5_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild15necessary_calls
Line
Count
Source
390
168
    fn necessary_calls(inner: &ChainInformationBuildInner) -> impl Iterator<Item = RuntimeCall> {
391
168
        let aura_api_authorities =
392
168
            if inner.runtime_has_aura && inner.aura_autorities_call_output.is_none() {
393
42
                Some(RuntimeCall::AuraApiAuthorities)
394
            } else {
395
126
                None
396
            };
397
398
168
        let aura_slot_duration =
399
168
            if inner.runtime_has_aura && inner.aura_slot_duration_call_output.is_none() {
400
84
                Some(RuntimeCall::AuraApiSlotDuration)
401
            } else {
402
84
                None
403
            };
404
405
168
        let babe_current_epoch = if 
matches!0
(
406
84
            inner.finalized_block_header,
407
84
            ConfigFinalizedBlockHeader::Any {
408
84
                ref scale_encoded_header,
409
84
                ..
410
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
411
0
        ) && inner.runtime_babeapi_is_v1.is_some()
412
0
            && inner.babe_current_epoch_call_output.is_none()
413
        {
414
0
            Some(RuntimeCall::BabeApiCurrentEpoch)
415
        } else {
416
168
            None
417
        };
418
419
168
        let babe_next_epoch = if 
matches!0
(
420
84
            inner.finalized_block_header,
421
84
            ConfigFinalizedBlockHeader::Any {
422
84
                ref scale_encoded_header,
423
84
                ..
424
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
425
0
        ) && inner.runtime_babeapi_is_v1.is_some()
426
0
            && inner.babe_next_epoch_call_output.is_none()
427
        {
428
0
            Some(RuntimeCall::BabeApiNextEpoch)
429
        } else {
430
168
            None
431
        };
432
433
168
        let babe_configuration = if inner.runtime_babeapi_is_v1.is_some()
434
0
            && inner.babe_configuration_call_output.is_none()
435
        {
436
0
            Some(RuntimeCall::BabeApiConfiguration)
437
        } else {
438
168
            None
439
        };
440
441
168
        let grandpa_authorities = if !matches!(
442
0
            inner.finalized_block_header,
443
            ConfigFinalizedBlockHeader::Any {
444
                known_finality: Some(chain_information::ChainInformationFinality::Grandpa { .. }),
445
                ..
446
            },
447
168
        ) && inner.runtime_grandpa_supports_currentsetid.is_some()
448
168
            && inner.grandpa_autorities_call_output.is_none()
449
        {
450
126
            Some(RuntimeCall::GrandpaApiAuthorities)
451
        } else {
452
42
            None
453
        };
454
455
        // The grandpa set ID doesn't need to be retrieved if finality was provided by the user,
456
        // but also doesn't need to be retrieved for the genesis block because we know it's
457
        // always 0.
458
168
        let grandpa_current_set_id = if 
matches!0
(
459
84
            inner.finalized_block_header,
460
84
            ConfigFinalizedBlockHeader::Any {
461
84
                ref scale_encoded_header,
462
84
                known_finality: None,
463
84
                ..
464
84
            } if header::decode(scale_encoded_header, inner.block_number_bytes).unwrap().number != 
00
,
465
0
        ) && inner.runtime_grandpa_supports_currentsetid
466
0
            == Some(true)
467
0
            && inner.grandpa_current_set_id_call_output.is_none()
468
        {
469
0
            Some(RuntimeCall::GrandpaApiCurrentSetId)
470
        } else {
471
168
            None
472
        };
473
474
168
        [
475
168
            aura_api_authorities,
476
168
            aura_slot_duration,
477
168
            babe_current_epoch,
478
168
            babe_next_epoch,
479
168
            babe_configuration,
480
168
            grandpa_authorities,
481
168
            grandpa_current_set_id,
482
168
        ]
483
168
        .into_iter()
484
168
        .flatten()
485
168
    }
486
487
171
    fn start_next_call(mut inner: ChainInformationBuildInner) -> Self {
488
171
        debug_assert!(inner.call_in_progress.is_none());
489
171
        debug_assert!(inner.virtual_machine.is_some());
490
491
171
        if let Some(
call128
) = ChainInformationBuild::necessary_calls(&inner).next() {
492
128
            let vm_start_result = runtime_call::run(runtime_call::Config {
493
128
                function_to_call: call.function_name(),
494
128
                parameter: call.parameter_vectored(),
495
128
                virtual_machine: inner.virtual_machine.take().unwrap(),
496
128
                max_log_level: 0,
497
128
                storage_proof_size_behavior:
498
128
                    runtime_call::StorageProofSizeBehavior::proof_recording_disabled(),
499
128
                storage_main_trie_changes: Default::default(),
500
128
                calculate_trie_changes: false,
501
128
            });
502
503
128
            let vm = match vm_start_result {
504
128
                Ok(vm) => vm,
505
0
                Err((error, virtual_machine)) => {
506
0
                    return ChainInformationBuild::Finished {
507
0
                        result: Err(Error::WasmStart { call, error }),
508
0
                        virtual_machine,
509
0
                    }
510
                }
511
            };
512
513
128
            inner.call_in_progress = Some(call);
514
128
            ChainInformationBuild::from_call_in_progress(vm, inner)
515
        } else {
516
            // If the logic of this module is correct, all the information that we need has been
517
            // retrieved at this point.
518
519
43
            let consensus = match (
520
43
                inner.runtime_has_aura,
521
43
                inner.runtime_babeapi_is_v1,
522
43
                &inner.finalized_block_header,
523
            ) {
524
                (true, Some(_), _) => {
525
0
                    return ChainInformationBuild::Finished {
526
0
                        result: Err(Error::MultipleConsensusAlgorithms),
527
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
528
0
                    }
529
                }
530
0
                (false, None, _) => chain_information::ChainInformationConsensus::Unknown,
531
                (
532
                    false,
533
                    Some(_),
534
                    ConfigFinalizedBlockHeader::Any {
535
0
                        scale_encoded_header,
536
0
                        ..
537
0
                    },
538
0
                ) if header::decode(scale_encoded_header, inner.block_number_bytes)
539
0
                    .unwrap()
540
0
                    .number
541
0
                    != 0 =>
542
0
                {
543
0
                    chain_information::ChainInformationConsensus::Babe {
544
0
                        finalized_block_epoch_information: Some(Box::new(
545
0
                            inner.babe_current_epoch_call_output.take().unwrap(),
546
0
                        )),
547
0
                        finalized_next_epoch_transition: Box::new(
548
0
                            inner.babe_next_epoch_call_output.take().unwrap(),
549
0
                        ),
550
0
                        slots_per_epoch: inner
551
0
                            .babe_configuration_call_output
552
0
                            .take()
553
0
                            .unwrap()
554
0
                            .slots_per_epoch,
555
0
                    }
556
                }
557
                (false, Some(_), _) => {
558
1
                    let config = inner.babe_configuration_call_output.take().unwrap();
559
1
                    chain_information::ChainInformationConsensus::Babe {
560
1
                        slots_per_epoch: config.slots_per_epoch,
561
1
                        finalized_block_epoch_information: None,
562
1
                        finalized_next_epoch_transition: Box::new(
563
1
                            chain_information::BabeEpochInformation {
564
1
                                epoch_index: 0,
565
1
                                start_slot_number: None,
566
1
                                authorities: config.epoch0_information.authorities,
567
1
                                randomness: config.epoch0_information.randomness,
568
1
                                c: config.epoch0_configuration.c,
569
1
                                allowed_slots: config.epoch0_configuration.allowed_slots,
570
1
                            },
571
1
                        ),
572
1
                    }
573
                }
574
42
                (true, None, _) => chain_information::ChainInformationConsensus::Aura {
575
42
                    finalized_authorities_list: inner.aura_autorities_call_output.take().unwrap(),
576
42
                    slot_duration: inner.aura_slot_duration_call_output.take().unwrap(),
577
42
                },
578
            };
579
580
            // Build the finalized block header, and extract the information about finality if it
581
            // was already provided by the API user.
582
43
            let (finalized_block_header, known_finality) = match inner.finalized_block_header {
583
                ConfigFinalizedBlockHeader::Genesis {
584
22
                    state_trie_root_hash,
585
22
                } => {
586
22
                    let header = header::HeaderRef {
587
22
                        parent_hash: &[0; 32],
588
22
                        number: 0,
589
22
                        state_root: &state_trie_root_hash,
590
22
                        extrinsics_root: &trie::EMPTY_BLAKE2_TRIE_MERKLE_VALUE,
591
22
                        digest: header::DigestRef::empty(),
592
22
                    }
593
22
                    .scale_encoding_vec(inner.block_number_bytes);
594
22
595
22
                    (header, None)
596
                }
597
                ConfigFinalizedBlockHeader::Any {
598
21
                    scale_encoded_header: header,
599
21
                    known_finality,
600
21
                } => (header, known_finality),
601
            };
602
603
            // Build the finality information if not known yet.
604
43
            let finality = if let Some(
known_finality0
) = known_finality {
605
0
                known_finality
606
43
            } else if inner.runtime_grandpa_supports_currentsetid.is_some() {
607
                chain_information::ChainInformationFinality::Grandpa {
608
43
                    after_finalized_block_authorities_set_id: if header::decode(
609
43
                        &finalized_block_header,
610
43
                        inner.block_number_bytes,
611
43
                    )
612
43
                    .unwrap()
613
43
                    .number
614
43
                        == 0
615
                    {
616
43
                        0
617
                    } else {
618
                        // If the GrandPa runtime API version is too old, it is not possible to
619
                        // determine the current set ID.
620
0
                        let Some(grandpa_current_set_id_call_output) =
621
0
                            inner.grandpa_current_set_id_call_output.take()
622
                        else {
623
0
                            debug_assert_eq!(
624
0
                                inner.runtime_grandpa_supports_currentsetid,
625
0
                                Some(false)
626
0
                            );
627
0
                            return ChainInformationBuild::Finished {
628
0
                                result: Err(Error::GrandpaApiTooOld),
629
0
                                virtual_machine: inner.virtual_machine.take().unwrap(),
630
0
                            };
631
                        };
632
633
0
                        grandpa_current_set_id_call_output
634
                    },
635
                    // TODO: The runtime doesn't give us a way to know the current scheduled change. At the moment the runtime it never schedules changes with a delay of more than 0. So in practice this `None` is correct, but it relies on implementation details
636
43
                    finalized_scheduled_change: None,
637
43
                    finalized_triggered_authorities: inner
638
43
                        .grandpa_autorities_call_output
639
43
                        .take()
640
43
                        .unwrap(),
641
                }
642
            } else {
643
0
                chain_information::ChainInformationFinality::Outsourced
644
            };
645
646
            // Build a `ChainInformation` using the parameters found in the runtime.
647
            // It is possible, however, that the runtime produces parameters that aren't
648
            // coherent. For example the runtime could give "current" and "next" Babe
649
            // epochs that don't follow each other.
650
43
            let chain_information = match chain_information::ValidChainInformation::try_from(
651
43
                chain_information::ChainInformation {
652
43
                    finalized_block_header: Box::new(
653
43
                        header::decode(&finalized_block_header, inner.block_number_bytes)
654
43
                            .unwrap()
655
43
                            .into(),
656
43
                    ),
657
43
                    finality,
658
43
                    consensus,
659
43
                },
660
43
            ) {
661
43
                Ok(ci) => ci,
662
0
                Err(err) => {
663
0
                    return ChainInformationBuild::Finished {
664
0
                        result: Err(Error::InvalidChainInformation(err)),
665
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
666
0
                    }
667
                }
668
            };
669
670
43
            ChainInformationBuild::Finished {
671
43
                result: Ok(chain_information),
672
43
                virtual_machine: inner.virtual_machine.take().unwrap(),
673
43
            }
674
        }
675
171
    }
_RNvMs5_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild15start_next_call
Line
Count
Source
487
3
    fn start_next_call(mut inner: ChainInformationBuildInner) -> Self {
488
3
        debug_assert!(inner.call_in_progress.is_none());
489
3
        debug_assert!(inner.virtual_machine.is_some());
490
491
3
        if let Some(
call2
) = ChainInformationBuild::necessary_calls(&inner).next() {
492
2
            let vm_start_result = runtime_call::run(runtime_call::Config {
493
2
                function_to_call: call.function_name(),
494
2
                parameter: call.parameter_vectored(),
495
2
                virtual_machine: inner.virtual_machine.take().unwrap(),
496
2
                max_log_level: 0,
497
2
                storage_proof_size_behavior:
498
2
                    runtime_call::StorageProofSizeBehavior::proof_recording_disabled(),
499
2
                storage_main_trie_changes: Default::default(),
500
2
                calculate_trie_changes: false,
501
2
            });
502
503
2
            let vm = match vm_start_result {
504
2
                Ok(vm) => vm,
505
0
                Err((error, virtual_machine)) => {
506
0
                    return ChainInformationBuild::Finished {
507
0
                        result: Err(Error::WasmStart { call, error }),
508
0
                        virtual_machine,
509
0
                    }
510
                }
511
            };
512
513
2
            inner.call_in_progress = Some(call);
514
2
            ChainInformationBuild::from_call_in_progress(vm, inner)
515
        } else {
516
            // If the logic of this module is correct, all the information that we need has been
517
            // retrieved at this point.
518
519
1
            let consensus = match (
520
1
                inner.runtime_has_aura,
521
1
                inner.runtime_babeapi_is_v1,
522
1
                &inner.finalized_block_header,
523
            ) {
524
                (true, Some(_), _) => {
525
0
                    return ChainInformationBuild::Finished {
526
0
                        result: Err(Error::MultipleConsensusAlgorithms),
527
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
528
0
                    }
529
                }
530
0
                (false, None, _) => chain_information::ChainInformationConsensus::Unknown,
531
                (
532
                    false,
533
                    Some(_),
534
                    ConfigFinalizedBlockHeader::Any {
535
0
                        scale_encoded_header,
536
0
                        ..
537
0
                    },
538
0
                ) if header::decode(scale_encoded_header, inner.block_number_bytes)
539
0
                    .unwrap()
540
0
                    .number
541
0
                    != 0 =>
542
0
                {
543
0
                    chain_information::ChainInformationConsensus::Babe {
544
0
                        finalized_block_epoch_information: Some(Box::new(
545
0
                            inner.babe_current_epoch_call_output.take().unwrap(),
546
0
                        )),
547
0
                        finalized_next_epoch_transition: Box::new(
548
0
                            inner.babe_next_epoch_call_output.take().unwrap(),
549
0
                        ),
550
0
                        slots_per_epoch: inner
551
0
                            .babe_configuration_call_output
552
0
                            .take()
553
0
                            .unwrap()
554
0
                            .slots_per_epoch,
555
0
                    }
556
                }
557
                (false, Some(_), _) => {
558
1
                    let config = inner.babe_configuration_call_output.take().unwrap();
559
1
                    chain_information::ChainInformationConsensus::Babe {
560
1
                        slots_per_epoch: config.slots_per_epoch,
561
1
                        finalized_block_epoch_information: None,
562
1
                        finalized_next_epoch_transition: Box::new(
563
1
                            chain_information::BabeEpochInformation {
564
1
                                epoch_index: 0,
565
1
                                start_slot_number: None,
566
1
                                authorities: config.epoch0_information.authorities,
567
1
                                randomness: config.epoch0_information.randomness,
568
1
                                c: config.epoch0_configuration.c,
569
1
                                allowed_slots: config.epoch0_configuration.allowed_slots,
570
1
                            },
571
1
                        ),
572
1
                    }
573
                }
574
0
                (true, None, _) => chain_information::ChainInformationConsensus::Aura {
575
0
                    finalized_authorities_list: inner.aura_autorities_call_output.take().unwrap(),
576
0
                    slot_duration: inner.aura_slot_duration_call_output.take().unwrap(),
577
0
                },
578
            };
579
580
            // Build the finalized block header, and extract the information about finality if it
581
            // was already provided by the API user.
582
1
            let (finalized_block_header, known_finality) = match inner.finalized_block_header {
583
                ConfigFinalizedBlockHeader::Genesis {
584
1
                    state_trie_root_hash,
585
1
                } => {
586
1
                    let header = header::HeaderRef {
587
1
                        parent_hash: &[0; 32],
588
1
                        number: 0,
589
1
                        state_root: &state_trie_root_hash,
590
1
                        extrinsics_root: &trie::EMPTY_BLAKE2_TRIE_MERKLE_VALUE,
591
1
                        digest: header::DigestRef::empty(),
592
1
                    }
593
1
                    .scale_encoding_vec(inner.block_number_bytes);
594
1
595
1
                    (header, None)
596
                }
597
                ConfigFinalizedBlockHeader::Any {
598
0
                    scale_encoded_header: header,
599
0
                    known_finality,
600
0
                } => (header, known_finality),
601
            };
602
603
            // Build the finality information if not known yet.
604
1
            let finality = if let Some(
known_finality0
) = known_finality {
605
0
                known_finality
606
1
            } else if inner.runtime_grandpa_supports_currentsetid.is_some() {
607
                chain_information::ChainInformationFinality::Grandpa {
608
1
                    after_finalized_block_authorities_set_id: if header::decode(
609
1
                        &finalized_block_header,
610
1
                        inner.block_number_bytes,
611
1
                    )
612
1
                    .unwrap()
613
1
                    .number
614
1
                        == 0
615
                    {
616
1
                        0
617
                    } else {
618
                        // If the GrandPa runtime API version is too old, it is not possible to
619
                        // determine the current set ID.
620
0
                        let Some(grandpa_current_set_id_call_output) =
621
0
                            inner.grandpa_current_set_id_call_output.take()
622
                        else {
623
0
                            debug_assert_eq!(
624
0
                                inner.runtime_grandpa_supports_currentsetid,
625
0
                                Some(false)
626
0
                            );
627
0
                            return ChainInformationBuild::Finished {
628
0
                                result: Err(Error::GrandpaApiTooOld),
629
0
                                virtual_machine: inner.virtual_machine.take().unwrap(),
630
0
                            };
631
                        };
632
633
0
                        grandpa_current_set_id_call_output
634
                    },
635
                    // TODO: The runtime doesn't give us a way to know the current scheduled change. At the moment the runtime it never schedules changes with a delay of more than 0. So in practice this `None` is correct, but it relies on implementation details
636
1
                    finalized_scheduled_change: None,
637
1
                    finalized_triggered_authorities: inner
638
1
                        .grandpa_autorities_call_output
639
1
                        .take()
640
1
                        .unwrap(),
641
                }
642
            } else {
643
0
                chain_information::ChainInformationFinality::Outsourced
644
            };
645
646
            // Build a `ChainInformation` using the parameters found in the runtime.
647
            // It is possible, however, that the runtime produces parameters that aren't
648
            // coherent. For example the runtime could give "current" and "next" Babe
649
            // epochs that don't follow each other.
650
1
            let chain_information = match chain_information::ValidChainInformation::try_from(
651
1
                chain_information::ChainInformation {
652
1
                    finalized_block_header: Box::new(
653
1
                        header::decode(&finalized_block_header, inner.block_number_bytes)
654
1
                            .unwrap()
655
1
                            .into(),
656
1
                    ),
657
1
                    finality,
658
1
                    consensus,
659
1
                },
660
1
            ) {
661
1
                Ok(ci) => ci,
662
0
                Err(err) => {
663
0
                    return ChainInformationBuild::Finished {
664
0
                        result: Err(Error::InvalidChainInformation(err)),
665
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
666
0
                    }
667
                }
668
            };
669
670
1
            ChainInformationBuild::Finished {
671
1
                result: Ok(chain_information),
672
1
                virtual_machine: inner.virtual_machine.take().unwrap(),
673
1
            }
674
        }
675
3
    }
_RNvMs5_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild15start_next_call
Line
Count
Source
487
168
    fn start_next_call(mut inner: ChainInformationBuildInner) -> Self {
488
168
        debug_assert!(inner.call_in_progress.is_none());
489
168
        debug_assert!(inner.virtual_machine.is_some());
490
491
168
        if let Some(
call126
) = ChainInformationBuild::necessary_calls(&inner).next() {
492
126
            let vm_start_result = runtime_call::run(runtime_call::Config {
493
126
                function_to_call: call.function_name(),
494
126
                parameter: call.parameter_vectored(),
495
126
                virtual_machine: inner.virtual_machine.take().unwrap(),
496
126
                max_log_level: 0,
497
126
                storage_proof_size_behavior:
498
126
                    runtime_call::StorageProofSizeBehavior::proof_recording_disabled(),
499
126
                storage_main_trie_changes: Default::default(),
500
126
                calculate_trie_changes: false,
501
126
            });
502
503
126
            let vm = match vm_start_result {
504
126
                Ok(vm) => vm,
505
0
                Err((error, virtual_machine)) => {
506
0
                    return ChainInformationBuild::Finished {
507
0
                        result: Err(Error::WasmStart { call, error }),
508
0
                        virtual_machine,
509
0
                    }
510
                }
511
            };
512
513
126
            inner.call_in_progress = Some(call);
514
126
            ChainInformationBuild::from_call_in_progress(vm, inner)
515
        } else {
516
            // If the logic of this module is correct, all the information that we need has been
517
            // retrieved at this point.
518
519
42
            let consensus = match (
520
42
                inner.runtime_has_aura,
521
42
                inner.runtime_babeapi_is_v1,
522
42
                &inner.finalized_block_header,
523
            ) {
524
                (true, Some(_), _) => {
525
0
                    return ChainInformationBuild::Finished {
526
0
                        result: Err(Error::MultipleConsensusAlgorithms),
527
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
528
0
                    }
529
                }
530
0
                (false, None, _) => chain_information::ChainInformationConsensus::Unknown,
531
                (
532
                    false,
533
                    Some(_),
534
                    ConfigFinalizedBlockHeader::Any {
535
0
                        scale_encoded_header,
536
0
                        ..
537
0
                    },
538
0
                ) if header::decode(scale_encoded_header, inner.block_number_bytes)
539
0
                    .unwrap()
540
0
                    .number
541
0
                    != 0 =>
542
0
                {
543
0
                    chain_information::ChainInformationConsensus::Babe {
544
0
                        finalized_block_epoch_information: Some(Box::new(
545
0
                            inner.babe_current_epoch_call_output.take().unwrap(),
546
0
                        )),
547
0
                        finalized_next_epoch_transition: Box::new(
548
0
                            inner.babe_next_epoch_call_output.take().unwrap(),
549
0
                        ),
550
0
                        slots_per_epoch: inner
551
0
                            .babe_configuration_call_output
552
0
                            .take()
553
0
                            .unwrap()
554
0
                            .slots_per_epoch,
555
0
                    }
556
                }
557
                (false, Some(_), _) => {
558
0
                    let config = inner.babe_configuration_call_output.take().unwrap();
559
0
                    chain_information::ChainInformationConsensus::Babe {
560
0
                        slots_per_epoch: config.slots_per_epoch,
561
0
                        finalized_block_epoch_information: None,
562
0
                        finalized_next_epoch_transition: Box::new(
563
0
                            chain_information::BabeEpochInformation {
564
0
                                epoch_index: 0,
565
0
                                start_slot_number: None,
566
0
                                authorities: config.epoch0_information.authorities,
567
0
                                randomness: config.epoch0_information.randomness,
568
0
                                c: config.epoch0_configuration.c,
569
0
                                allowed_slots: config.epoch0_configuration.allowed_slots,
570
0
                            },
571
0
                        ),
572
0
                    }
573
                }
574
42
                (true, None, _) => chain_information::ChainInformationConsensus::Aura {
575
42
                    finalized_authorities_list: inner.aura_autorities_call_output.take().unwrap(),
576
42
                    slot_duration: inner.aura_slot_duration_call_output.take().unwrap(),
577
42
                },
578
            };
579
580
            // Build the finalized block header, and extract the information about finality if it
581
            // was already provided by the API user.
582
42
            let (finalized_block_header, known_finality) = match inner.finalized_block_header {
583
                ConfigFinalizedBlockHeader::Genesis {
584
21
                    state_trie_root_hash,
585
21
                } => {
586
21
                    let header = header::HeaderRef {
587
21
                        parent_hash: &[0; 32],
588
21
                        number: 0,
589
21
                        state_root: &state_trie_root_hash,
590
21
                        extrinsics_root: &trie::EMPTY_BLAKE2_TRIE_MERKLE_VALUE,
591
21
                        digest: header::DigestRef::empty(),
592
21
                    }
593
21
                    .scale_encoding_vec(inner.block_number_bytes);
594
21
595
21
                    (header, None)
596
                }
597
                ConfigFinalizedBlockHeader::Any {
598
21
                    scale_encoded_header: header,
599
21
                    known_finality,
600
21
                } => (header, known_finality),
601
            };
602
603
            // Build the finality information if not known yet.
604
42
            let finality = if let Some(
known_finality0
) = known_finality {
605
0
                known_finality
606
42
            } else if inner.runtime_grandpa_supports_currentsetid.is_some() {
607
                chain_information::ChainInformationFinality::Grandpa {
608
42
                    after_finalized_block_authorities_set_id: if header::decode(
609
42
                        &finalized_block_header,
610
42
                        inner.block_number_bytes,
611
42
                    )
612
42
                    .unwrap()
613
42
                    .number
614
42
                        == 0
615
                    {
616
42
                        0
617
                    } else {
618
                        // If the GrandPa runtime API version is too old, it is not possible to
619
                        // determine the current set ID.
620
0
                        let Some(grandpa_current_set_id_call_output) =
621
0
                            inner.grandpa_current_set_id_call_output.take()
622
                        else {
623
0
                            debug_assert_eq!(
624
0
                                inner.runtime_grandpa_supports_currentsetid,
625
0
                                Some(false)
626
0
                            );
627
0
                            return ChainInformationBuild::Finished {
628
0
                                result: Err(Error::GrandpaApiTooOld),
629
0
                                virtual_machine: inner.virtual_machine.take().unwrap(),
630
0
                            };
631
                        };
632
633
0
                        grandpa_current_set_id_call_output
634
                    },
635
                    // TODO: The runtime doesn't give us a way to know the current scheduled change. At the moment the runtime it never schedules changes with a delay of more than 0. So in practice this `None` is correct, but it relies on implementation details
636
42
                    finalized_scheduled_change: None,
637
42
                    finalized_triggered_authorities: inner
638
42
                        .grandpa_autorities_call_output
639
42
                        .take()
640
42
                        .unwrap(),
641
                }
642
            } else {
643
0
                chain_information::ChainInformationFinality::Outsourced
644
            };
645
646
            // Build a `ChainInformation` using the parameters found in the runtime.
647
            // It is possible, however, that the runtime produces parameters that aren't
648
            // coherent. For example the runtime could give "current" and "next" Babe
649
            // epochs that don't follow each other.
650
42
            let chain_information = match chain_information::ValidChainInformation::try_from(
651
42
                chain_information::ChainInformation {
652
42
                    finalized_block_header: Box::new(
653
42
                        header::decode(&finalized_block_header, inner.block_number_bytes)
654
42
                            .unwrap()
655
42
                            .into(),
656
42
                    ),
657
42
                    finality,
658
42
                    consensus,
659
42
                },
660
42
            ) {
661
42
                Ok(ci) => ci,
662
0
                Err(err) => {
663
0
                    return ChainInformationBuild::Finished {
664
0
                        result: Err(Error::InvalidChainInformation(err)),
665
0
                        virtual_machine: inner.virtual_machine.take().unwrap(),
666
0
                    }
667
                }
668
            };
669
670
42
            ChainInformationBuild::Finished {
671
42
                result: Ok(chain_information),
672
42
                virtual_machine: inner.virtual_machine.take().unwrap(),
673
42
            }
674
        }
675
168
    }
676
677
215
    fn from_call_in_progress(
678
215
        mut call: runtime_call::RuntimeCall,
679
215
        mut inner: ChainInformationBuildInner,
680
215
    ) -> Self {
681
215
        loop {
682
215
            debug_assert!(inner.call_in_progress.is_some());
683
684
128
            match call {
685
128
                runtime_call::RuntimeCall::Finished(Ok(success)) => {
686
128
                    inner.virtual_machine = Some(match inner.call_in_progress.take() {
687
0
                        None => unreachable!(),
688
                        Some(RuntimeCall::AuraApiSlotDuration) => {
689
42
                            let result = decode_aura_slot_duration_output(
690
42
                                success.virtual_machine.value().as_ref(),
691
42
                            );
692
42
                            let virtual_machine = success.virtual_machine.into_prototype();
693
42
                            match result {
694
42
                                Ok(output) => inner.aura_slot_duration_call_output = Some(output),
695
0
                                Err(err) => {
696
0
                                    return ChainInformationBuild::Finished {
697
0
                                        result: Err(err),
698
0
                                        virtual_machine,
699
0
                                    };
700
                                }
701
                            }
702
42
                            virtual_machine
703
                        }
704
                        Some(RuntimeCall::AuraApiAuthorities) => {
705
42
                            let result = decode_aura_authorities_output(
706
42
                                success.virtual_machine.value().as_ref(),
707
42
                            );
708
42
                            let virtual_machine = success.virtual_machine.into_prototype();
709
42
                            match result {
710
42
                                Ok(output) => inner.aura_autorities_call_output = Some(output),
711
0
                                Err(err) => {
712
0
                                    return ChainInformationBuild::Finished {
713
0
                                        result: Err(err),
714
0
                                        virtual_machine,
715
0
                                    };
716
                                }
717
                            }
718
42
                            virtual_machine
719
                        }
720
                        Some(RuntimeCall::BabeApiCurrentEpoch) => {
721
0
                            let result = decode_babe_epoch_output(
722
0
                                success.virtual_machine.value().as_ref(),
723
0
                                false,
724
0
                            );
725
0
                            let virtual_machine = success.virtual_machine.into_prototype();
726
0
                            match result {
727
0
                                Ok(output) => inner.babe_current_epoch_call_output = Some(output),
728
0
                                Err(err) => {
729
0
                                    return ChainInformationBuild::Finished {
730
0
                                        result: Err(err),
731
0
                                        virtual_machine,
732
0
                                    };
733
                                }
734
                            }
735
0
                            virtual_machine
736
                        }
737
                        Some(RuntimeCall::BabeApiNextEpoch) => {
738
0
                            let result = decode_babe_epoch_output(
739
0
                                success.virtual_machine.value().as_ref(),
740
0
                                true,
741
0
                            );
742
0
                            let virtual_machine = success.virtual_machine.into_prototype();
743
0
                            match result {
744
0
                                Ok(output) => inner.babe_next_epoch_call_output = Some(output),
745
0
                                Err(err) => {
746
0
                                    return ChainInformationBuild::Finished {
747
0
                                        result: Err(err),
748
0
                                        virtual_machine,
749
0
                                    };
750
                                }
751
                            }
752
0
                            virtual_machine
753
                        }
754
                        Some(RuntimeCall::BabeApiConfiguration) => {
755
1
                            let result = decode_babe_configuration_output(
756
1
                                success.virtual_machine.value().as_ref(),
757
1
                                inner.runtime_babeapi_is_v1.unwrap(),
758
1
                            );
759
1
                            let virtual_machine = success.virtual_machine.into_prototype();
760
1
                            match result {
761
1
                                Ok(output) => inner.babe_configuration_call_output = Some(output),
762
0
                                Err(err) => {
763
0
                                    return ChainInformationBuild::Finished {
764
0
                                        result: Err(err),
765
0
                                        virtual_machine,
766
0
                                    };
767
                                }
768
                            }
769
1
                            virtual_machine
770
                        }
771
                        Some(RuntimeCall::GrandpaApiAuthorities) => {
772
43
                            let result = decode_grandpa_authorities_output(
773
43
                                success.virtual_machine.value().as_ref(),
774
43
                            );
775
43
                            let virtual_machine = success.virtual_machine.into_prototype();
776
43
                            match result {
777
43
                                Ok(output) => inner.grandpa_autorities_call_output = Some(output),
778
0
                                Err(err) => {
779
0
                                    return ChainInformationBuild::Finished {
780
0
                                        result: Err(err),
781
0
                                        virtual_machine,
782
0
                                    };
783
                                }
784
                            }
785
43
                            virtual_machine
786
                        }
787
                        Some(RuntimeCall::GrandpaApiCurrentSetId) => {
788
0
                            let result = decode_grandpa_current_set_id_output(
789
0
                                success.virtual_machine.value().as_ref(),
790
0
                            );
791
0
                            let virtual_machine = success.virtual_machine.into_prototype();
792
0
                            match result {
793
0
                                Ok(output) => {
794
0
                                    inner.grandpa_current_set_id_call_output = Some(output)
795
                                }
796
0
                                Err(err) => {
797
0
                                    return ChainInformationBuild::Finished {
798
0
                                        result: Err(err),
799
0
                                        virtual_machine,
800
0
                                    };
801
                                }
802
                            }
803
0
                            virtual_machine
804
                        }
805
                    });
806
807
128
                    break ChainInformationBuild::start_next_call(inner);
808
                }
809
0
                runtime_call::RuntimeCall::Finished(Err(err)) => {
810
0
                    break ChainInformationBuild::Finished {
811
0
                        result: Err(Error::WasmVm {
812
0
                            call: inner.call_in_progress.unwrap(),
813
0
                            error: err.detail,
814
0
                        }),
815
0
                        virtual_machine: err.prototype,
816
0
                    }
817
                }
818
87
                runtime_call::RuntimeCall::StorageGet(call) => {
819
87
                    break ChainInformationBuild::InProgress(InProgress::StorageGet(StorageGet(
820
87
                        call, inner,
821
87
                    )))
822
                }
823
0
                runtime_call::RuntimeCall::NextKey(call) => {
824
0
                    break ChainInformationBuild::InProgress(InProgress::NextKey(NextKey(
825
0
                        call, inner,
826
0
                    )))
827
                }
828
0
                runtime_call::RuntimeCall::ClosestDescendantMerkleValue(call) => {
829
0
                    break ChainInformationBuild::InProgress(
830
0
                        InProgress::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(
831
0
                            call, inner,
832
0
                        )),
833
0
                    )
834
                }
835
0
                runtime_call::RuntimeCall::SignatureVerification(sig) => {
836
0
                    call = sig.verify_and_resume();
837
0
                }
838
0
                runtime_call::RuntimeCall::OffchainStorageSet(req) => {
839
0
                    // Do nothing.
840
0
                    call = req.resume();
841
0
                }
842
0
                runtime_call::RuntimeCall::Offchain(req) => {
843
0
                    let virtual_machine = runtime_call::RuntimeCall::Offchain(req).into_prototype();
844
0
                    break ChainInformationBuild::Finished {
845
0
                        result: Err(Error::OffchainWorkerHostFunction),
846
0
                        virtual_machine,
847
0
                    };
848
                }
849
0
                runtime_call::RuntimeCall::LogEmit(req) => {
850
0
                    // Generated logs are ignored.
851
0
                    call = req.resume();
852
0
                }
853
            }
854
        }
855
215
    }
_RNvMs5_NtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild21from_call_in_progress
Line
Count
Source
677
5
    fn from_call_in_progress(
678
5
        mut call: runtime_call::RuntimeCall,
679
5
        mut inner: ChainInformationBuildInner,
680
5
    ) -> Self {
681
5
        loop {
682
5
            debug_assert!(inner.call_in_progress.is_some());
683
684
2
            match call {
685
2
                runtime_call::RuntimeCall::Finished(Ok(success)) => {
686
2
                    inner.virtual_machine = Some(match inner.call_in_progress.take() {
687
0
                        None => unreachable!(),
688
                        Some(RuntimeCall::AuraApiSlotDuration) => {
689
0
                            let result = decode_aura_slot_duration_output(
690
0
                                success.virtual_machine.value().as_ref(),
691
0
                            );
692
0
                            let virtual_machine = success.virtual_machine.into_prototype();
693
0
                            match result {
694
0
                                Ok(output) => inner.aura_slot_duration_call_output = Some(output),
695
0
                                Err(err) => {
696
0
                                    return ChainInformationBuild::Finished {
697
0
                                        result: Err(err),
698
0
                                        virtual_machine,
699
0
                                    };
700
                                }
701
                            }
702
0
                            virtual_machine
703
                        }
704
                        Some(RuntimeCall::AuraApiAuthorities) => {
705
0
                            let result = decode_aura_authorities_output(
706
0
                                success.virtual_machine.value().as_ref(),
707
0
                            );
708
0
                            let virtual_machine = success.virtual_machine.into_prototype();
709
0
                            match result {
710
0
                                Ok(output) => inner.aura_autorities_call_output = Some(output),
711
0
                                Err(err) => {
712
0
                                    return ChainInformationBuild::Finished {
713
0
                                        result: Err(err),
714
0
                                        virtual_machine,
715
0
                                    };
716
                                }
717
                            }
718
0
                            virtual_machine
719
                        }
720
                        Some(RuntimeCall::BabeApiCurrentEpoch) => {
721
0
                            let result = decode_babe_epoch_output(
722
0
                                success.virtual_machine.value().as_ref(),
723
0
                                false,
724
0
                            );
725
0
                            let virtual_machine = success.virtual_machine.into_prototype();
726
0
                            match result {
727
0
                                Ok(output) => inner.babe_current_epoch_call_output = Some(output),
728
0
                                Err(err) => {
729
0
                                    return ChainInformationBuild::Finished {
730
0
                                        result: Err(err),
731
0
                                        virtual_machine,
732
0
                                    };
733
                                }
734
                            }
735
0
                            virtual_machine
736
                        }
737
                        Some(RuntimeCall::BabeApiNextEpoch) => {
738
0
                            let result = decode_babe_epoch_output(
739
0
                                success.virtual_machine.value().as_ref(),
740
0
                                true,
741
0
                            );
742
0
                            let virtual_machine = success.virtual_machine.into_prototype();
743
0
                            match result {
744
0
                                Ok(output) => inner.babe_next_epoch_call_output = Some(output),
745
0
                                Err(err) => {
746
0
                                    return ChainInformationBuild::Finished {
747
0
                                        result: Err(err),
748
0
                                        virtual_machine,
749
0
                                    };
750
                                }
751
                            }
752
0
                            virtual_machine
753
                        }
754
                        Some(RuntimeCall::BabeApiConfiguration) => {
755
1
                            let result = decode_babe_configuration_output(
756
1
                                success.virtual_machine.value().as_ref(),
757
1
                                inner.runtime_babeapi_is_v1.unwrap(),
758
1
                            );
759
1
                            let virtual_machine = success.virtual_machine.into_prototype();
760
1
                            match result {
761
1
                                Ok(output) => inner.babe_configuration_call_output = Some(output),
762
0
                                Err(err) => {
763
0
                                    return ChainInformationBuild::Finished {
764
0
                                        result: Err(err),
765
0
                                        virtual_machine,
766
0
                                    };
767
                                }
768
                            }
769
1
                            virtual_machine
770
                        }
771
                        Some(RuntimeCall::GrandpaApiAuthorities) => {
772
1
                            let result = decode_grandpa_authorities_output(
773
1
                                success.virtual_machine.value().as_ref(),
774
1
                            );
775
1
                            let virtual_machine = success.virtual_machine.into_prototype();
776
1
                            match result {
777
1
                                Ok(output) => inner.grandpa_autorities_call_output = Some(output),
778
0
                                Err(err) => {
779
0
                                    return ChainInformationBuild::Finished {
780
0
                                        result: Err(err),
781
0
                                        virtual_machine,
782
0
                                    };
783
                                }
784
                            }
785
1
                            virtual_machine
786
                        }
787
                        Some(RuntimeCall::GrandpaApiCurrentSetId) => {
788
0
                            let result = decode_grandpa_current_set_id_output(
789
0
                                success.virtual_machine.value().as_ref(),
790
0
                            );
791
0
                            let virtual_machine = success.virtual_machine.into_prototype();
792
0
                            match result {
793
0
                                Ok(output) => {
794
0
                                    inner.grandpa_current_set_id_call_output = Some(output)
795
                                }
796
0
                                Err(err) => {
797
0
                                    return ChainInformationBuild::Finished {
798
0
                                        result: Err(err),
799
0
                                        virtual_machine,
800
0
                                    };
801
                                }
802
                            }
803
0
                            virtual_machine
804
                        }
805
                    });
806
807
2
                    break ChainInformationBuild::start_next_call(inner);
808
                }
809
0
                runtime_call::RuntimeCall::Finished(Err(err)) => {
810
0
                    break ChainInformationBuild::Finished {
811
0
                        result: Err(Error::WasmVm {
812
0
                            call: inner.call_in_progress.unwrap(),
813
0
                            error: err.detail,
814
0
                        }),
815
0
                        virtual_machine: err.prototype,
816
0
                    }
817
                }
818
3
                runtime_call::RuntimeCall::StorageGet(call) => {
819
3
                    break ChainInformationBuild::InProgress(InProgress::StorageGet(StorageGet(
820
3
                        call, inner,
821
3
                    )))
822
                }
823
0
                runtime_call::RuntimeCall::NextKey(call) => {
824
0
                    break ChainInformationBuild::InProgress(InProgress::NextKey(NextKey(
825
0
                        call, inner,
826
0
                    )))
827
                }
828
0
                runtime_call::RuntimeCall::ClosestDescendantMerkleValue(call) => {
829
0
                    break ChainInformationBuild::InProgress(
830
0
                        InProgress::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(
831
0
                            call, inner,
832
0
                        )),
833
0
                    )
834
                }
835
0
                runtime_call::RuntimeCall::SignatureVerification(sig) => {
836
0
                    call = sig.verify_and_resume();
837
0
                }
838
0
                runtime_call::RuntimeCall::OffchainStorageSet(req) => {
839
0
                    // Do nothing.
840
0
                    call = req.resume();
841
0
                }
842
0
                runtime_call::RuntimeCall::Offchain(req) => {
843
0
                    let virtual_machine = runtime_call::RuntimeCall::Offchain(req).into_prototype();
844
0
                    break ChainInformationBuild::Finished {
845
0
                        result: Err(Error::OffchainWorkerHostFunction),
846
0
                        virtual_machine,
847
0
                    };
848
                }
849
0
                runtime_call::RuntimeCall::LogEmit(req) => {
850
0
                    // Generated logs are ignored.
851
0
                    call = req.resume();
852
0
                }
853
            }
854
        }
855
5
    }
_RNvMs5_NtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5buildNtB5_21ChainInformationBuild21from_call_in_progress
Line
Count
Source
677
210
    fn from_call_in_progress(
678
210
        mut call: runtime_call::RuntimeCall,
679
210
        mut inner: ChainInformationBuildInner,
680
210
    ) -> Self {
681
210
        loop {
682
210
            debug_assert!(inner.call_in_progress.is_some());
683
684
126
            match call {
685
126
                runtime_call::RuntimeCall::Finished(Ok(success)) => {
686
126
                    inner.virtual_machine = Some(match inner.call_in_progress.take() {
687
0
                        None => unreachable!(),
688
                        Some(RuntimeCall::AuraApiSlotDuration) => {
689
42
                            let result = decode_aura_slot_duration_output(
690
42
                                success.virtual_machine.value().as_ref(),
691
42
                            );
692
42
                            let virtual_machine = success.virtual_machine.into_prototype();
693
42
                            match result {
694
42
                                Ok(output) => inner.aura_slot_duration_call_output = Some(output),
695
0
                                Err(err) => {
696
0
                                    return ChainInformationBuild::Finished {
697
0
                                        result: Err(err),
698
0
                                        virtual_machine,
699
0
                                    };
700
                                }
701
                            }
702
42
                            virtual_machine
703
                        }
704
                        Some(RuntimeCall::AuraApiAuthorities) => {
705
42
                            let result = decode_aura_authorities_output(
706
42
                                success.virtual_machine.value().as_ref(),
707
42
                            );
708
42
                            let virtual_machine = success.virtual_machine.into_prototype();
709
42
                            match result {
710
42
                                Ok(output) => inner.aura_autorities_call_output = Some(output),
711
0
                                Err(err) => {
712
0
                                    return ChainInformationBuild::Finished {
713
0
                                        result: Err(err),
714
0
                                        virtual_machine,
715
0
                                    };
716
                                }
717
                            }
718
42
                            virtual_machine
719
                        }
720
                        Some(RuntimeCall::BabeApiCurrentEpoch) => {
721
0
                            let result = decode_babe_epoch_output(
722
0
                                success.virtual_machine.value().as_ref(),
723
0
                                false,
724
0
                            );
725
0
                            let virtual_machine = success.virtual_machine.into_prototype();
726
0
                            match result {
727
0
                                Ok(output) => inner.babe_current_epoch_call_output = Some(output),
728
0
                                Err(err) => {
729
0
                                    return ChainInformationBuild::Finished {
730
0
                                        result: Err(err),
731
0
                                        virtual_machine,
732
0
                                    };
733
                                }
734
                            }
735
0
                            virtual_machine
736
                        }
737
                        Some(RuntimeCall::BabeApiNextEpoch) => {
738
0
                            let result = decode_babe_epoch_output(
739
0
                                success.virtual_machine.value().as_ref(),
740
0
                                true,
741
0
                            );
742
0
                            let virtual_machine = success.virtual_machine.into_prototype();
743
0
                            match result {
744
0
                                Ok(output) => inner.babe_next_epoch_call_output = Some(output),
745
0
                                Err(err) => {
746
0
                                    return ChainInformationBuild::Finished {
747
0
                                        result: Err(err),
748
0
                                        virtual_machine,
749
0
                                    };
750
                                }
751
                            }
752
0
                            virtual_machine
753
                        }
754
                        Some(RuntimeCall::BabeApiConfiguration) => {
755
0
                            let result = decode_babe_configuration_output(
756
0
                                success.virtual_machine.value().as_ref(),
757
0
                                inner.runtime_babeapi_is_v1.unwrap(),
758
0
                            );
759
0
                            let virtual_machine = success.virtual_machine.into_prototype();
760
0
                            match result {
761
0
                                Ok(output) => inner.babe_configuration_call_output = Some(output),
762
0
                                Err(err) => {
763
0
                                    return ChainInformationBuild::Finished {
764
0
                                        result: Err(err),
765
0
                                        virtual_machine,
766
0
                                    };
767
                                }
768
                            }
769
0
                            virtual_machine
770
                        }
771
                        Some(RuntimeCall::GrandpaApiAuthorities) => {
772
42
                            let result = decode_grandpa_authorities_output(
773
42
                                success.virtual_machine.value().as_ref(),
774
42
                            );
775
42
                            let virtual_machine = success.virtual_machine.into_prototype();
776
42
                            match result {
777
42
                                Ok(output) => inner.grandpa_autorities_call_output = Some(output),
778
0
                                Err(err) => {
779
0
                                    return ChainInformationBuild::Finished {
780
0
                                        result: Err(err),
781
0
                                        virtual_machine,
782
0
                                    };
783
                                }
784
                            }
785
42
                            virtual_machine
786
                        }
787
                        Some(RuntimeCall::GrandpaApiCurrentSetId) => {
788
0
                            let result = decode_grandpa_current_set_id_output(
789
0
                                success.virtual_machine.value().as_ref(),
790
0
                            );
791
0
                            let virtual_machine = success.virtual_machine.into_prototype();
792
0
                            match result {
793
0
                                Ok(output) => {
794
0
                                    inner.grandpa_current_set_id_call_output = Some(output)
795
                                }
796
0
                                Err(err) => {
797
0
                                    return ChainInformationBuild::Finished {
798
0
                                        result: Err(err),
799
0
                                        virtual_machine,
800
0
                                    };
801
                                }
802
                            }
803
0
                            virtual_machine
804
                        }
805
                    });
806
807
126
                    break ChainInformationBuild::start_next_call(inner);
808
                }
809
0
                runtime_call::RuntimeCall::Finished(Err(err)) => {
810
0
                    break ChainInformationBuild::Finished {
811
0
                        result: Err(Error::WasmVm {
812
0
                            call: inner.call_in_progress.unwrap(),
813
0
                            error: err.detail,
814
0
                        }),
815
0
                        virtual_machine: err.prototype,
816
0
                    }
817
                }
818
84
                runtime_call::RuntimeCall::StorageGet(call) => {
819
84
                    break ChainInformationBuild::InProgress(InProgress::StorageGet(StorageGet(
820
84
                        call, inner,
821
84
                    )))
822
                }
823
0
                runtime_call::RuntimeCall::NextKey(call) => {
824
0
                    break ChainInformationBuild::InProgress(InProgress::NextKey(NextKey(
825
0
                        call, inner,
826
0
                    )))
827
                }
828
0
                runtime_call::RuntimeCall::ClosestDescendantMerkleValue(call) => {
829
0
                    break ChainInformationBuild::InProgress(
830
0
                        InProgress::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(
831
0
                            call, inner,
832
0
                        )),
833
0
                    )
834
                }
835
0
                runtime_call::RuntimeCall::SignatureVerification(sig) => {
836
0
                    call = sig.verify_and_resume();
837
0
                }
838
0
                runtime_call::RuntimeCall::OffchainStorageSet(req) => {
839
0
                    // Do nothing.
840
0
                    call = req.resume();
841
0
                }
842
0
                runtime_call::RuntimeCall::Offchain(req) => {
843
0
                    let virtual_machine = runtime_call::RuntimeCall::Offchain(req).into_prototype();
844
0
                    break ChainInformationBuild::Finished {
845
0
                        result: Err(Error::OffchainWorkerHostFunction),
846
0
                        virtual_machine,
847
0
                    };
848
                }
849
0
                runtime_call::RuntimeCall::LogEmit(req) => {
850
0
                    // Generated logs are ignored.
851
0
                    call = req.resume();
852
0
                }
853
            }
854
        }
855
210
    }
856
}
857
858
/// Struct shared by all the variants of the [`ChainInformationBuild`] enum. Contains the actual
859
/// progress of the building.
860
struct ChainInformationBuildInner {
861
    /// See [`Config::finalized_block_header`].
862
    finalized_block_header: ConfigFinalizedBlockHeader,
863
    /// See [`Config::block_number_bytes`].
864
    block_number_bytes: usize,
865
866
    /// Which call is currently in progress, if any.
867
    call_in_progress: Option<RuntimeCall>,
868
    /// Runtime to use to start the calls.
869
    ///
870
    /// [`ChainInformationBuildInner::call_in_progress`] and
871
    /// [`ChainInformationBuildInner::virtual_machine`] are never `Some` at the same time. However,
872
    /// using an enum wouldn't make the code cleaner because we need to be able to extract the
873
    /// values temporarily.
874
    virtual_machine: Option<host::HostVmPrototype>,
875
876
    /// If `true`, the runtime supports `AuraApi` functions.
877
    runtime_has_aura: bool,
878
    /// If `Some`, the runtime supports `BabeApi` functions. If `true`, the version is 1 (the old
879
    /// version). If `false`, the version is 2.
880
    runtime_babeapi_is_v1: Option<bool>,
881
    /// If `Some`, the runtime supports `GrandpaApi` functions. If `true`, the API supports the
882
    /// `GrandpaApi_current_set_id` runtime call.
883
    runtime_grandpa_supports_currentsetid: Option<bool>,
884
885
    /// Output of the call to `AuraApi_slot_duration`, if it was already made.
886
    aura_slot_duration_call_output: Option<NonZeroU64>,
887
    /// Output of the call to `AuraApi_authorities`, if it was already made.
888
    aura_autorities_call_output: Option<Vec<header::AuraAuthority>>,
889
    /// Output of the call to `BabeApi_current_epoch`, if it was already made.
890
    babe_current_epoch_call_output: Option<chain_information::BabeEpochInformation>,
891
    /// Output of the call to `BabeApi_next_epoch`, if it was already made.
892
    babe_next_epoch_call_output: Option<chain_information::BabeEpochInformation>,
893
    /// Output of the call to `BabeApi_configuration`, if it was already made.
894
    babe_configuration_call_output: Option<BabeGenesisConfiguration>,
895
    /// Output of the call to `GrandpaApi_grandpa_authorities`, if it was already made.
896
    grandpa_autorities_call_output: Option<Vec<header::GrandpaAuthority>>,
897
    /// Output of the call to `GrandpaApi_current_set_id`, if it was already made.
898
    grandpa_current_set_id_call_output: Option<u64>,
899
}
900
901
/// Decodes the output of a call to `AuraApi_slot_duration`.
902
42
fn decode_aura_slot_duration_output(bytes: &[u8]) -> Result<NonZeroU64, Error> {
903
42
    <[u8; 8]>::try_from(bytes)
904
42
        .ok()
905
42
        .and_then(|b| NonZeroU64::new(u64::from_le_bytes(b)))
Unexecuted instantiation: _RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_aura_slot_duration_output0B9_
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_aura_slot_duration_output0B9_
Line
Count
Source
905
42
        .and_then(|b| NonZeroU64::new(u64::from_le_bytes(b)))
906
42
        .ok_or(Error::AuraSlotDurationOutputDecode)
907
42
}
Unexecuted instantiation: _RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_aura_slot_duration_output
_RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_aura_slot_duration_output
Line
Count
Source
902
42
fn decode_aura_slot_duration_output(bytes: &[u8]) -> Result<NonZeroU64, Error> {
903
42
    <[u8; 8]>::try_from(bytes)
904
42
        .ok()
905
42
        .and_then(|b| NonZeroU64::new(u64::from_le_bytes(b)))
906
42
        .ok_or(Error::AuraSlotDurationOutputDecode)
907
42
}
908
909
/// Decodes the output of a call to `AuraApi_authorities`.
910
42
fn decode_aura_authorities_output(
911
42
    scale_encoded: &[u8],
912
42
) -> Result<Vec<header::AuraAuthority>, Error> {
913
42
    match header::AuraAuthoritiesIter::decode(scale_encoded) {
914
42
        Ok(iter) => Ok(iter.map(header::AuraAuthority::from).collect::<Vec<_>>()),
915
0
        Err(_) => Err(Error::AuraSlotDurationOutputDecode),
916
    }
917
42
}
Unexecuted instantiation: _RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build30decode_aura_authorities_output
_RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build30decode_aura_authorities_output
Line
Count
Source
910
42
fn decode_aura_authorities_output(
911
42
    scale_encoded: &[u8],
912
42
) -> Result<Vec<header::AuraAuthority>, Error> {
913
42
    match header::AuraAuthoritiesIter::decode(scale_encoded) {
914
42
        Ok(iter) => Ok(iter.map(header::AuraAuthority::from).collect::<Vec<_>>()),
915
0
        Err(_) => Err(Error::AuraSlotDurationOutputDecode),
916
    }
917
42
}
918
919
#[derive(Debug, Clone, PartialEq, Eq)]
920
struct BabeGenesisConfiguration {
921
    slots_per_epoch: NonZeroU64,
922
    epoch0_configuration: header::BabeNextConfig,
923
    epoch0_information: header::BabeNextEpoch,
924
}
925
926
/// Decodes the output of a call to `BabeApi_configuration`.
927
2
fn decode_babe_configuration_output(
928
2
    bytes: &[u8],
929
2
    is_babe_api_v1: bool,
930
2
) -> Result<BabeGenesisConfiguration, Error> {
931
2
    let result: nom::IResult<_, _> =
932
2
        nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
933
2
            nom::sequence::tuple((
934
2
                nom::number::streaming::le_u64,
935
2
                nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
936
2
                nom::number::streaming::le_u64,
937
2
                nom::number::streaming::le_u64,
938
2
                nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
939
2
                    nom::multi::many_m_n(
940
2
                        num_elems,
941
2
                        num_elems,
942
2
                        nom::combinator::map(
943
2
                            nom::sequence::tuple((
944
2
                                nom::bytes::streaming::take(32u32),
945
2
                                nom::number::streaming::le_u64,
946
2
                            )),
947
7
                            move |(public_key, weight)| header::BabeAuthority {
948
7
                                public_key: <[u8; 32]>::try_from(public_key).unwrap(),
949
7
                                weight,
950
7
                            },
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_output00Bb_
Line
Count
Source
947
7
                            move |(public_key, weight)| header::BabeAuthority {
948
7
                                public_key: <[u8; 32]>::try_from(public_key).unwrap(),
949
7
                                weight,
950
7
                            },
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_output00Bb_
951
2
                        ),
952
2
                    )
953
2
                }),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_output0B9_
Line
Count
Source
938
2
                nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
939
2
                    nom::multi::many_m_n(
940
2
                        num_elems,
941
2
                        num_elems,
942
2
                        nom::combinator::map(
943
2
                            nom::sequence::tuple((
944
2
                                nom::bytes::streaming::take(32u32),
945
2
                                nom::number::streaming::le_u64,
946
2
                            )),
947
2
                            move |(public_key, weight)| header::BabeAuthority {
948
                                public_key: <[u8; 32]>::try_from(public_key).unwrap(),
949
                                weight,
950
2
                            },
951
2
                        ),
952
2
                    )
953
2
                }),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_output0B9_
954
2
                nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
955
2
                    <[u8; 32]>::try_from(b).unwrap()
956
2
                }),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs_0B9_
Line
Count
Source
954
2
                nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
955
2
                    <[u8; 32]>::try_from(b).unwrap()
956
2
                }),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs_0B9_
957
2
                |b| {
958
2
                    if is_babe_api_v1 {
959
1
                        nom::branch::alt((
960
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
961
0
                                header::BabeAllowedSlots::PrimarySlots
962
1
                            }),
Unexecuted instantiation: _RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_00Bb_
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_00Bb_
963
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
964
1
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
965
1
                            }),
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s_0Bb_
Line
Count
Source
963
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
964
1
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
965
1
                            }),
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s_0Bb_
966
1
                        ))(b)
967
                    } else {
968
1
                        nom::branch::alt((
969
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
970
0
                                header::BabeAllowedSlots::PrimarySlots
971
1
                            }),
Unexecuted instantiation: _RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s0_0Bb_
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s0_0Bb_
972
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
973
1
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
974
1
                            }),
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s1_0Bb_
Line
Count
Source
972
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
973
1
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
974
1
                            }),
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s1_0Bb_
975
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| {
976
0
                                header::BabeAllowedSlots::PrimaryAndSecondaryVrfSlots
977
1
                            }),
Unexecuted instantiation: _RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s2_0Bb_
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0s2_0Bb_
978
1
                        ))(b)
979
                    }
980
2
                },
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0B9_
Line
Count
Source
957
2
                |b| {
958
2
                    if is_babe_api_v1 {
959
1
                        nom::branch::alt((
960
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
961
                                header::BabeAllowedSlots::PrimarySlots
962
1
                            }),
963
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
964
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
965
1
                            }),
966
1
                        ))(b)
967
                    } else {
968
1
                        nom::branch::alt((
969
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
970
                                header::BabeAllowedSlots::PrimarySlots
971
1
                            }),
972
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
973
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
974
1
                            }),
975
1
                            nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| {
976
                                header::BabeAllowedSlots::PrimaryAndSecondaryVrfSlots
977
1
                            }),
978
1
                        ))(b)
979
                    }
980
2
                },
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs0_0B9_
981
2
            )),
982
2
            |(_slot_duration, slots_per_epoch, c0, c1, authorities, randomness, allowed_slots)| {
983
2
                // Note that the slot duration is unused as it is not modifiable anyway.
984
2
                BabeGenesisConfiguration {
985
2
                    slots_per_epoch,
986
2
                    epoch0_configuration: header::BabeNextConfig {
987
2
                        c: (c0, c1),
988
2
                        allowed_slots,
989
2
                    },
990
2
                    epoch0_information: header::BabeNextEpoch {
991
2
                        randomness,
992
2
                        authorities,
993
2
                    },
994
2
                }
995
2
            },
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs1_0B9_
Line
Count
Source
982
2
            |(_slot_duration, slots_per_epoch, c0, c1, authorities, randomness, allowed_slots)| {
983
2
                // Note that the slot duration is unused as it is not modifiable anyway.
984
2
                BabeGenesisConfiguration {
985
2
                    slots_per_epoch,
986
2
                    epoch0_configuration: header::BabeNextConfig {
987
2
                        c: (c0, c1),
988
2
                        allowed_slots,
989
2
                    },
990
2
                    epoch0_information: header::BabeNextEpoch {
991
2
                        randomness,
992
2
                        authorities,
993
2
                    },
994
2
                }
995
2
            },
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_outputs1_0B9_
996
2
        )))(bytes);
997
998
0
    match result {
999
2
        Ok((_, out)) => Ok(out),
1000
0
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(Error::BabeConfigurationOutputDecode),
1001
0
        Err(_) => unreachable!(),
1002
    }
1003
2
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build32decode_babe_configuration_output
Line
Count
Source
927
2
fn decode_babe_configuration_output(
928
2
    bytes: &[u8],
929
2
    is_babe_api_v1: bool,
930
2
) -> Result<BabeGenesisConfiguration, Error> {
931
2
    let result: nom::IResult<_, _> =
932
2
        nom::combinator::all_consuming(nom::combinator::complete(nom::combinator::map(
933
2
            nom::sequence::tuple((
934
2
                nom::number::streaming::le_u64,
935
2
                nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
936
2
                nom::number::streaming::le_u64,
937
2
                nom::number::streaming::le_u64,
938
2
                nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
939
                    nom::multi::many_m_n(
940
                        num_elems,
941
                        num_elems,
942
                        nom::combinator::map(
943
                            nom::sequence::tuple((
944
                                nom::bytes::streaming::take(32u32),
945
                                nom::number::streaming::le_u64,
946
                            )),
947
                            move |(public_key, weight)| header::BabeAuthority {
948
                                public_key: <[u8; 32]>::try_from(public_key).unwrap(),
949
                                weight,
950
                            },
951
                        ),
952
                    )
953
2
                }),
954
2
                nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
955
                    <[u8; 32]>::try_from(b).unwrap()
956
2
                }),
957
2
                |b| {
958
                    if is_babe_api_v1 {
959
                        nom::branch::alt((
960
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
961
                                header::BabeAllowedSlots::PrimarySlots
962
                            }),
963
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
964
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
965
                            }),
966
                        ))(b)
967
                    } else {
968
                        nom::branch::alt((
969
                            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
970
                                header::BabeAllowedSlots::PrimarySlots
971
                            }),
972
                            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
973
                                header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots
974
                            }),
975
                            nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| {
976
                                header::BabeAllowedSlots::PrimaryAndSecondaryVrfSlots
977
                            }),
978
                        ))(b)
979
                    }
980
2
                },
981
2
            )),
982
2
            |(_slot_duration, slots_per_epoch, c0, c1, authorities, randomness, allowed_slots)| {
983
                // Note that the slot duration is unused as it is not modifiable anyway.
984
                BabeGenesisConfiguration {
985
                    slots_per_epoch,
986
                    epoch0_configuration: header::BabeNextConfig {
987
                        c: (c0, c1),
988
                        allowed_slots,
989
                    },
990
                    epoch0_information: header::BabeNextEpoch {
991
                        randomness,
992
                        authorities,
993
                    },
994
                }
995
2
            },
996
2
        )))(bytes);
997
998
0
    match result {
999
2
        Ok((_, out)) => Ok(out),
1000
0
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => Err(Error::BabeConfigurationOutputDecode),
1001
0
        Err(_) => unreachable!(),
1002
    }
1003
2
}
Unexecuted instantiation: _RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build32decode_babe_configuration_output
1004
1005
/// Decodes the output of a call to `BabeApi_current_epoch` (`is_next_epoch` is `false`) or
1006
/// `BabeApi_next_epoch` (`is_next_epoch` is `true`).
1007
1
fn decode_babe_epoch_output(
1008
1
    scale_encoded: &'_ [u8],
1009
1
    is_next_epoch: bool,
1010
1
) -> Result<chain_information::BabeEpochInformation, Error> {
1011
1
    let mut combinator = nom::combinator::all_consuming(nom::combinator::map(
1012
1
        nom::sequence::tuple((
1013
1
            nom::number::streaming::le_u64,
1014
1
            nom::number::streaming::le_u64,
1015
1
            nom::number::streaming::le_u64,
1016
1
            nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1017
1
                nom::multi::many_m_n(
1018
1
                    num_elems,
1019
1
                    num_elems,
1020
1
                    nom::combinator::map(
1021
1
                        nom::sequence::tuple((
1022
1
                            nom::bytes::streaming::take(32u32),
1023
1
                            nom::number::streaming::le_u64,
1024
1
                        )),
1025
4
                        move |(public_key, weight)| header::BabeAuthority {
1026
4
                            public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1027
4
                            weight,
1028
4
                        },
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_output00Bb_
Line
Count
Source
1025
4
                        move |(public_key, weight)| header::BabeAuthority {
1026
4
                            public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1027
4
                            weight,
1028
4
                        },
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_output00Bb_
1029
1
                    ),
1030
1
                )
1031
1
            }),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_output0B9_
Line
Count
Source
1016
1
            nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1017
1
                nom::multi::many_m_n(
1018
1
                    num_elems,
1019
1
                    num_elems,
1020
1
                    nom::combinator::map(
1021
1
                        nom::sequence::tuple((
1022
1
                            nom::bytes::streaming::take(32u32),
1023
1
                            nom::number::streaming::le_u64,
1024
1
                        )),
1025
1
                        move |(public_key, weight)| header::BabeAuthority {
1026
                            public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1027
                            weight,
1028
1
                        },
1029
1
                    ),
1030
1
                )
1031
1
            }),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_output0B9_
1032
1
            nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
1033
1
                <[u8; 32]>::try_from(b).unwrap()
1034
1
            }),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs_0B9_
Line
Count
Source
1032
1
            nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
1033
1
                <[u8; 32]>::try_from(b).unwrap()
1034
1
            }),
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs_0B9_
1035
1
            nom::number::streaming::le_u64,
1036
1
            nom::number::streaming::le_u64,
1037
1
            |b| {
1038
1
                header::BabeAllowedSlots::from_slice(b)
1039
1
                    .map(|v| (&[][..], v))
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_00Bb_
Line
Count
Source
1039
1
                    .map(|v| (&[][..], v))
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_00Bb_
1040
1
                    .map_err(|_| {
1041
0
                        nom::Err::Error(nom::error::make_error(b, nom::error::ErrorKind::Verify))
1042
1
                    })
Unexecuted instantiation: _RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_0s_0Bb_
Unexecuted instantiation: _RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_0s_0Bb_
1043
1
            },
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_0B9_
Line
Count
Source
1037
1
            |b| {
1038
1
                header::BabeAllowedSlots::from_slice(b)
1039
1
                    .map(|v| (&[][..], v))
1040
1
                    .map_err(|_| {
1041
                        nom::Err::Error(nom::error::make_error(b, nom::error::ErrorKind::Verify))
1042
1
                    })
1043
1
            },
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs0_0B9_
1044
1
        )),
1045
1
        |(
1046
            epoch_index,
1047
            start_slot_number,
1048
            _duration,
1049
            authorities,
1050
            randomness,
1051
            c0,
1052
            c1,
1053
            allowed_slots,
1054
1
        )| {
1055
1
            chain_information::BabeEpochInformation {
1056
1
                epoch_index,
1057
1
                // Smoldot requires `start_slot_number` to be `None` in the context of next
1058
1
                // epoch #0, because its start slot number can't be known. The runtime function,
1059
1
                // however, as it doesn't have a way to represent `None`, instead returns an
1060
1
                // unspecified value (typically `0`).
1061
1
                start_slot_number: if !is_next_epoch || epoch_index != 0 {
1062
1
                    Some(start_slot_number)
1063
                } else {
1064
0
                    None
1065
                },
1066
1
                authorities,
1067
1
                randomness,
1068
1
                c: (c0, c1),
1069
1
                allowed_slots,
1070
1
            }
1071
1
        },
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs1_0B9_
Line
Count
Source
1054
1
        )| {
1055
1
            chain_information::BabeEpochInformation {
1056
1
                epoch_index,
1057
1
                // Smoldot requires `start_slot_number` to be `None` in the context of next
1058
1
                // epoch #0, because its start slot number can't be known. The runtime function,
1059
1
                // however, as it doesn't have a way to represent `None`, instead returns an
1060
1
                // unspecified value (typically `0`).
1061
1
                start_slot_number: if !is_next_epoch || epoch_index != 0 {
1062
1
                    Some(start_slot_number)
1063
                } else {
1064
0
                    None
1065
                },
1066
1
                authorities,
1067
1
                randomness,
1068
1
                c: (c0, c1),
1069
1
                allowed_slots,
1070
1
            }
1071
1
        },
Unexecuted instantiation: _RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_outputs1_0B9_
1072
1
    ));
1073
1
1074
1
    let result: Result<_, nom::Err<nom::error::Error<&'_ [u8]>>> = combinator(scale_encoded);
1075
1
    match result {
1076
1
        Ok((_, info)) => Ok(info),
1077
0
        Err(_) => Err(if is_next_epoch {
1078
0
            Error::BabeNextEpochOutputDecode
1079
        } else {
1080
0
            Error::BabeCurrentEpochOutputDecode
1081
        }),
1082
    }
1083
1
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build24decode_babe_epoch_output
Line
Count
Source
1007
1
fn decode_babe_epoch_output(
1008
1
    scale_encoded: &'_ [u8],
1009
1
    is_next_epoch: bool,
1010
1
) -> Result<chain_information::BabeEpochInformation, Error> {
1011
1
    let mut combinator = nom::combinator::all_consuming(nom::combinator::map(
1012
1
        nom::sequence::tuple((
1013
1
            nom::number::streaming::le_u64,
1014
1
            nom::number::streaming::le_u64,
1015
1
            nom::number::streaming::le_u64,
1016
1
            nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1017
                nom::multi::many_m_n(
1018
                    num_elems,
1019
                    num_elems,
1020
                    nom::combinator::map(
1021
                        nom::sequence::tuple((
1022
                            nom::bytes::streaming::take(32u32),
1023
                            nom::number::streaming::le_u64,
1024
                        )),
1025
                        move |(public_key, weight)| header::BabeAuthority {
1026
                            public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1027
                            weight,
1028
                        },
1029
                    ),
1030
                )
1031
1
            }),
1032
1
            nom::combinator::map(nom::bytes::streaming::take(32u32), |b| {
1033
                <[u8; 32]>::try_from(b).unwrap()
1034
1
            }),
1035
1
            nom::number::streaming::le_u64,
1036
1
            nom::number::streaming::le_u64,
1037
1
            |b| {
1038
                header::BabeAllowedSlots::from_slice(b)
1039
                    .map(|v| (&[][..], v))
1040
                    .map_err(|_| {
1041
                        nom::Err::Error(nom::error::make_error(b, nom::error::ErrorKind::Verify))
1042
                    })
1043
1
            },
1044
1
        )),
1045
1
        |(
1046
            epoch_index,
1047
            start_slot_number,
1048
            _duration,
1049
            authorities,
1050
            randomness,
1051
            c0,
1052
            c1,
1053
            allowed_slots,
1054
        )| {
1055
            chain_information::BabeEpochInformation {
1056
                epoch_index,
1057
                // Smoldot requires `start_slot_number` to be `None` in the context of next
1058
                // epoch #0, because its start slot number can't be known. The runtime function,
1059
                // however, as it doesn't have a way to represent `None`, instead returns an
1060
                // unspecified value (typically `0`).
1061
                start_slot_number: if !is_next_epoch || epoch_index != 0 {
1062
                    Some(start_slot_number)
1063
                } else {
1064
                    None
1065
                },
1066
                authorities,
1067
                randomness,
1068
                c: (c0, c1),
1069
                allowed_slots,
1070
            }
1071
1
        },
1072
1
    ));
1073
1
1074
1
    let result: Result<_, nom::Err<nom::error::Error<&'_ [u8]>>> = combinator(scale_encoded);
1075
1
    match result {
1076
1
        Ok((_, info)) => Ok(info),
1077
0
        Err(_) => Err(if is_next_epoch {
1078
0
            Error::BabeNextEpochOutputDecode
1079
        } else {
1080
0
            Error::BabeCurrentEpochOutputDecode
1081
        }),
1082
    }
1083
1
}
Unexecuted instantiation: _RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build24decode_babe_epoch_output
1084
1085
/// Decodes the output of a call to `GrandpaApi_grandpa_authorities`, or the content of the
1086
/// `:grandpa_authorities` storage item.
1087
43
fn decode_grandpa_authorities_output(
1088
43
    scale_encoded: &[u8],
1089
43
) -> Result<Vec<header::GrandpaAuthority>, Error> {
1090
43
    let result: nom::IResult<_, _> = nom::combinator::all_consuming(nom::combinator::complete(
1091
43
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1092
43
            nom::multi::fold_many_m_n(
1093
43
                num_elems,
1094
43
                num_elems,
1095
43
                nom::sequence::tuple((
1096
43
                    nom::bytes::streaming::take(32u32),
1097
43
                    nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
1098
43
                )),
1099
43
                move || Vec::with_capacity(num_elems),
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output00Bb_
Line
Count
Source
1099
1
                move || Vec::with_capacity(num_elems),
_RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output00Bb_
Line
Count
Source
1099
42
                move || Vec::with_capacity(num_elems),
1100
85
                |mut acc, (public_key, weight)| {
1101
85
                    acc.push(header::GrandpaAuthority {
1102
85
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
85
                        weight,
1104
85
                    });
1105
85
                    acc
1106
85
                },
_RNCNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output0s_0Bb_
Line
Count
Source
1100
1
                |mut acc, (public_key, weight)| {
1101
1
                    acc.push(header::GrandpaAuthority {
1102
1
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
1
                        weight,
1104
1
                    });
1105
1
                    acc
1106
1
                },
_RNCNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output0s_0Bb_
Line
Count
Source
1100
84
                |mut acc, (public_key, weight)| {
1101
84
                    acc.push(header::GrandpaAuthority {
1102
84
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
84
                        weight,
1104
84
                    });
1105
84
                    acc
1106
84
                },
1107
43
            )
1108
43
        }),
_RNCNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output0B9_
Line
Count
Source
1091
1
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1092
1
            nom::multi::fold_many_m_n(
1093
1
                num_elems,
1094
1
                num_elems,
1095
1
                nom::sequence::tuple((
1096
1
                    nom::bytes::streaming::take(32u32),
1097
1
                    nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
1098
1
                )),
1099
1
                move || Vec::with_capacity(num_elems),
1100
1
                |mut acc, (public_key, weight)| {
1101
                    acc.push(header::GrandpaAuthority {
1102
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
                        weight,
1104
                    });
1105
                    acc
1106
1
                },
1107
1
            )
1108
1
        }),
_RNCNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output0B9_
Line
Count
Source
1091
42
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1092
42
            nom::multi::fold_many_m_n(
1093
42
                num_elems,
1094
42
                num_elems,
1095
42
                nom::sequence::tuple((
1096
42
                    nom::bytes::streaming::take(32u32),
1097
42
                    nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
1098
42
                )),
1099
42
                move || Vec::with_capacity(num_elems),
1100
42
                |mut acc, (public_key, weight)| {
1101
                    acc.push(header::GrandpaAuthority {
1102
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
                        weight,
1104
                    });
1105
                    acc
1106
42
                },
1107
42
            )
1108
42
        }),
1109
43
    ))(scale_encoded);
1110
1111
0
    match result {
1112
43
        Ok((_, out)) => Ok(out),
1113
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => {
1114
0
            Err(Error::GrandpaAuthoritiesOutputDecode)
1115
        }
1116
0
        Err(_) => unreachable!(),
1117
    }
1118
43
}
_RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output
Line
Count
Source
1087
1
fn decode_grandpa_authorities_output(
1088
1
    scale_encoded: &[u8],
1089
1
) -> Result<Vec<header::GrandpaAuthority>, Error> {
1090
1
    let result: nom::IResult<_, _> = nom::combinator::all_consuming(nom::combinator::complete(
1091
1
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1092
            nom::multi::fold_many_m_n(
1093
                num_elems,
1094
                num_elems,
1095
                nom::sequence::tuple((
1096
                    nom::bytes::streaming::take(32u32),
1097
                    nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
1098
                )),
1099
                move || Vec::with_capacity(num_elems),
1100
                |mut acc, (public_key, weight)| {
1101
                    acc.push(header::GrandpaAuthority {
1102
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
                        weight,
1104
                    });
1105
                    acc
1106
                },
1107
            )
1108
1
        }),
1109
1
    ))(scale_encoded);
1110
1111
0
    match result {
1112
1
        Ok((_, out)) => Ok(out),
1113
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => {
1114
0
            Err(Error::GrandpaAuthoritiesOutputDecode)
1115
        }
1116
0
        Err(_) => unreachable!(),
1117
    }
1118
1
}
_RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build33decode_grandpa_authorities_output
Line
Count
Source
1087
42
fn decode_grandpa_authorities_output(
1088
42
    scale_encoded: &[u8],
1089
42
) -> Result<Vec<header::GrandpaAuthority>, Error> {
1090
42
    let result: nom::IResult<_, _> = nom::combinator::all_consuming(nom::combinator::complete(
1091
42
        nom::combinator::flat_map(crate::util::nom_scale_compact_usize, |num_elems| {
1092
            nom::multi::fold_many_m_n(
1093
                num_elems,
1094
                num_elems,
1095
                nom::sequence::tuple((
1096
                    nom::bytes::streaming::take(32u32),
1097
                    nom::combinator::map_opt(nom::number::streaming::le_u64, NonZeroU64::new),
1098
                )),
1099
                move || Vec::with_capacity(num_elems),
1100
                |mut acc, (public_key, weight)| {
1101
                    acc.push(header::GrandpaAuthority {
1102
                        public_key: <[u8; 32]>::try_from(public_key).unwrap(),
1103
                        weight,
1104
                    });
1105
                    acc
1106
                },
1107
            )
1108
42
        }),
1109
42
    ))(scale_encoded);
1110
1111
0
    match result {
1112
42
        Ok((_, out)) => Ok(out),
1113
        Err(nom::Err::Error(_) | nom::Err::Failure(_)) => {
1114
0
            Err(Error::GrandpaAuthoritiesOutputDecode)
1115
        }
1116
0
        Err(_) => unreachable!(),
1117
    }
1118
42
}
1119
1120
/// Decodes the output of a call to `GrandpaApi_current_set_id`.
1121
0
fn decode_grandpa_current_set_id_output(bytes: &[u8]) -> Result<u64, Error> {
1122
0
    <[u8; 8]>::try_from(bytes)
1123
0
        .ok()
1124
0
        .map(u64::from_le_bytes)
1125
0
        .ok_or(Error::GrandpaCurrentSetIdOutputDecode)
1126
0
}
Unexecuted instantiation: _RNvNtNtNtCsN16ciHI6Qf_7smoldot5chain17chain_information5build36decode_grandpa_current_set_id_output
Unexecuted instantiation: _RNvNtNtNtCseuYC0Zibziv_7smoldot5chain17chain_information5build36decode_grandpa_current_set_id_output
1127
1128
#[cfg(test)]
1129
mod tests {
1130
    use crate::header;
1131
    use core::num::NonZeroU64;
1132
1133
    #[test]
1134
1
    fn decode_babe_epoch_output_sample_decode() {
1135
1
        // Sample taken from an actual Westend block.
1136
1
        let sample_data = [
1137
1
            100, 37, 0, 0, 0, 0, 0, 0, 215, 191, 25, 16, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 16,
1138
1
            102, 85, 132, 42, 246, 238, 38, 228, 88, 181, 254, 162, 211, 181, 190, 178, 221, 140,
1139
1
            249, 107, 36, 180, 72, 56, 145, 158, 26, 226, 150, 72, 223, 12, 1, 0, 0, 0, 0, 0, 0, 0,
1140
1
            92, 167, 131, 48, 94, 202, 168, 131, 131, 232, 44, 215, 20, 97, 44, 22, 227, 205, 24,
1141
1
            232, 243, 118, 34, 15, 45, 159, 187, 181, 132, 214, 138, 105, 1, 0, 0, 0, 0, 0, 0, 0,
1142
1
            212, 81, 34, 24, 150, 248, 208, 236, 69, 62, 90, 78, 252, 0, 125, 32, 86, 208, 73, 44,
1143
1
            151, 210, 88, 169, 187, 105, 170, 28, 165, 137, 126, 3, 1, 0, 0, 0, 0, 0, 0, 0, 236,
1144
1
            198, 169, 213, 112, 57, 219, 36, 157, 140, 107, 231, 182, 155, 98, 72, 224, 156, 194,
1145
1
            252, 107, 138, 97, 201, 177, 9, 13, 248, 167, 93, 218, 91, 1, 0, 0, 0, 0, 0, 0, 0, 150,
1146
1
            40, 172, 215, 156, 152, 22, 33, 79, 35, 203, 8, 40, 43, 0, 242, 126, 30, 241, 56, 206,
1147
1
            56, 36, 189, 60, 22, 121, 195, 168, 34, 207, 236, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
1148
1
            0, 0, 0, 0, 2,
1149
1
        ];
1150
1
1151
1
        super::decode_babe_epoch_output(&sample_data, true).unwrap();
1152
1
    }
1153
1154
    #[test]
1155
1
    fn decode_babe_configuration_output_v1() {
1156
1
        let data = [
1157
1
            112, 23, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
1158
1
            0, 0, 0, 0, 24, 202, 35, 147, 146, 150, 4, 115, 254, 27, 198, 95, 148, 238, 39, 216,
1159
1
            144, 164, 156, 27, 32, 12, 0, 111, 245, 220, 197, 37, 51, 14, 204, 22, 119, 1, 0, 0, 0,
1160
1
            0, 0, 0, 0, 180, 111, 1, 135, 76, 231, 171, 187, 82, 32, 232, 253, 137, 190, 222, 10,
1161
1
            218, 209, 76, 115, 3, 157, 145, 226, 142, 136, 24, 35, 67, 62, 114, 63, 1, 0, 0, 0, 0,
1162
1
            0, 0, 0, 214, 132, 217, 23, 109, 110, 182, 152, 135, 84, 12, 154, 137, 250, 96, 151,
1163
1
            173, 234, 130, 252, 75, 15, 242, 109, 16, 98, 180, 136, 243, 82, 225, 121, 1, 0, 0, 0,
1164
1
            0, 0, 0, 0, 104, 25, 90, 113, 189, 222, 73, 17, 122, 97, 100, 36, 189, 198, 10, 23, 51,
1165
1
            233, 106, 203, 29, 165, 174, 171, 93, 38, 140, 242, 165, 114, 233, 65, 1, 0, 0, 0, 0,
1166
1
            0, 0, 0, 26, 5, 117, 239, 74, 226, 75, 223, 211, 31, 76, 181, 189, 97, 35, 154, 230,
1167
1
            124, 18, 212, 230, 74, 229, 26, 199, 86, 4, 74, 166, 173, 130, 0, 1, 0, 0, 0, 0, 0, 0,
1168
1
            0, 24, 22, 143, 42, 173, 0, 129, 162, 87, 40, 150, 30, 224, 6, 39, 207, 227, 94, 57,
1169
1
            131, 60, 128, 80, 22, 99, 43, 247, 193, 77, 165, 128, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1170
1
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1171
1
            0, 1,
1172
1
        ];
1173
1
1174
1
        assert_eq!(
1175
1
            super::decode_babe_configuration_output(&data, true).unwrap(),
1176
1
            super::BabeGenesisConfiguration {
1177
1
                slots_per_epoch: NonZeroU64::new(600).unwrap(),
1178
1
                epoch0_configuration: header::BabeNextConfig {
1179
1
                    allowed_slots: header::BabeAllowedSlots::PrimaryAndSecondaryPlainSlots,
1180
1
                    c: (1, 4),
1181
1
                },
1182
1
                epoch0_information: header::BabeNextEpoch {
1183
1
                    authorities: vec![
1184
1
                        header::BabeAuthority {
1185
1
                            public_key: [
1186
1
                                202, 35, 147, 146, 150, 4, 115, 254, 27, 198, 95, 148, 238, 39,
1187
1
                                216, 144, 164, 156, 27, 32, 12, 0, 111, 245, 220, 197, 37, 51, 14,
1188
1
                                204, 22, 119
1189
1
                            ],
1190
1
                            weight: 1
1191
1
                        },
1192
1
                        header::BabeAuthority {
1193
1
                            public_key: [
1194
1
                                180, 111, 1, 135, 76, 231, 171, 187, 82, 32, 232, 253, 137, 190,
1195
1
                                222, 10, 218, 209, 76, 115, 3, 157, 145, 226, 142, 136, 24, 35, 67,
1196
1
                                62, 114, 63
1197
1
                            ],
1198
1
                            weight: 1
1199
1
                        },
1200
1
                        header::BabeAuthority {
1201
1
                            public_key: [
1202
1
                                214, 132, 217, 23, 109, 110, 182, 152, 135, 84, 12, 154, 137, 250,
1203
1
                                96, 151, 173, 234, 130, 252, 75, 15, 242, 109, 16, 98, 180, 136,
1204
1
                                243, 82, 225, 121
1205
1
                            ],
1206
1
                            weight: 1
1207
1
                        },
1208
1
                        header::BabeAuthority {
1209
1
                            public_key: [
1210
1
                                104, 25, 90, 113, 189, 222, 73, 17, 122, 97, 100, 36, 189, 198, 10,
1211
1
                                23, 51, 233, 106, 203, 29, 165, 174, 171, 93, 38, 140, 242, 165,
1212
1
                                114, 233, 65
1213
1
                            ],
1214
1
                            weight: 1
1215
1
                        },
1216
1
                        header::BabeAuthority {
1217
1
                            public_key: [
1218
1
                                26, 5, 117, 239, 74, 226, 75, 223, 211, 31, 76, 181, 189, 97, 35,
1219
1
                                154, 230, 124, 18, 212, 230, 74, 229, 26, 199, 86, 4, 74, 166, 173,
1220
1
                                130, 0
1221
1
                            ],
1222
1
                            weight: 1
1223
1
                        },
1224
1
                        header::BabeAuthority {
1225
1
                            public_key: [
1226
1
                                24, 22, 143, 42, 173, 0, 129, 162, 87, 40, 150, 30, 224, 6, 39,
1227
1
                                207, 227, 94, 57, 131, 60, 128, 80, 22, 99, 43, 247, 193, 77, 165,
1228
1
                                128, 9
1229
1
                            ],
1230
1
                            weight: 1
1231
1
                        }
1232
1
                    ],
1233
1
                    randomness: [0; 32]
1234
1
                },
1235
1
            }
1236
1
        );
1237
1
    }
1238
}