Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/chain/chain_information.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
//! Data structures containing the finalized state of the chain, except for its storage.
19
//!
20
//! The types provided in this module contain the state of the chain, other than its storage, that
21
//! has been finalized.
22
//!
23
//! > **Note**: These data structures only provide a way to communicate that finalized state, but
24
//! >           the existence of a [`ChainInformation`] alone does in no way mean that its content
25
//! >           is accurate. As an example, one use case of [`ChainInformation`] is to be written
26
//! >           to disk then later reloaded. It is possible for the user to modify the data on
27
//! >           disk, in which case the loaded [`ChainInformation`] might be erroneous.
28
//!
29
//! These data structures contain all the information that is necessary to verify the
30
//! authenticity (but not the correctness) of blocks that descend from the finalized block
31
//! contained in the structure.
32
//!
33
//! They do not, however, contain the storage of the finalized block, which is necessary to verify
34
//! the correctness of new blocks. It is possible, though, for instance to download the
35
//! storage of the finalized block from another node. This downloaded storage can be verified
36
//! to make sure that it matches the content of the [`ChainInformation`].
37
//!
38
//! They also do not contain the past history of the chain. It is, however, similarly possible to
39
//! for instance download the history from other nodes.
40
41
use crate::header;
42
43
use alloc::{boxed::Box, vec::Vec};
44
use core::num::NonZeroU64;
45
46
pub mod build;
47
48
/// Information about the latest finalized block and state found in its ancestors.
49
///
50
/// Similar to [`ChainInformation`], but guaranteed to be coherent.
51
#[derive(Debug, Clone)]
52
pub struct ValidChainInformation {
53
    inner: ChainInformation,
54
}
55
56
impl From<ValidChainInformation> for ChainInformation {
57
23
    fn from(i: ValidChainInformation) -> Self {
58
23
        i.inner
59
23
    }
_RNvXNtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB2_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB2_21ValidChainInformationE4from
Line
Count
Source
57
2
    fn from(i: ValidChainInformation) -> Self {
58
2
        i.inner
59
2
    }
_RNvXNtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB2_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB2_21ValidChainInformationE4from
Line
Count
Source
57
21
    fn from(i: ValidChainInformation) -> Self {
58
21
        i.inner
59
21
    }
60
}
61
62
impl ValidChainInformation {
63
    /// Gives access to the information.
64
274
    pub fn as_ref(&self) -> ChainInformationRef {
65
274
        From::from(&self.inner)
66
274
    }
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB4_21ValidChainInformation6as_ref
Line
Count
Source
64
1
    pub fn as_ref(&self) -> ChainInformationRef {
65
1
        From::from(&self.inner)
66
1
    }
_RNvMs_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB4_21ValidChainInformation6as_ref
Line
Count
Source
64
273
    pub fn as_ref(&self) -> ChainInformationRef {
65
273
        From::from(&self.inner)
66
273
    }
67
}
68
69
impl<'a> From<ValidChainInformationRef<'a>> for ValidChainInformation {
70
0
    fn from(info: ValidChainInformationRef<'a>) -> ValidChainInformation {
71
0
        ValidChainInformation {
72
0
            inner: info.inner.into(),
73
0
        }
74
0
    }
Unexecuted instantiation: _RNvXs0_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_21ValidChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_24ValidChainInformationRefE4from
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_21ValidChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_24ValidChainInformationRefE4from
75
}
76
77
impl TryFrom<ChainInformation> for ValidChainInformation {
78
    type Error = ValidityError;
79
80
45
    fn try_from(info: ChainInformation) -> Result<Self, Self::Error> {
81
45
        ChainInformationRef::from(&info).validate()
?0
;
82
45
        Ok(ValidChainInformation { inner: info })
83
45
    }
_RNvXs1_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_21ValidChainInformationINtNtCsaYZPK01V26L_4core7convert7TryFromNtB5_16ChainInformationE8try_from
Line
Count
Source
80
3
    fn try_from(info: ChainInformation) -> Result<Self, Self::Error> {
81
3
        ChainInformationRef::from(&info).validate()
?0
;
82
3
        Ok(ValidChainInformation { inner: info })
83
3
    }
_RNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_21ValidChainInformationINtNtCsaYZPK01V26L_4core7convert7TryFromNtB5_16ChainInformationE8try_from
Line
Count
Source
80
42
    fn try_from(info: ChainInformation) -> Result<Self, Self::Error> {
81
42
        ChainInformationRef::from(&info).validate()
?0
;
82
42
        Ok(ValidChainInformation { inner: info })
83
42
    }
84
}
85
86
/// Information about the latest finalized block and state found in its ancestors.
87
///
88
/// Similar to [`ChainInformationRef`], but guaranteed to be coherent.
89
#[derive(Debug, Clone)]
90
pub struct ValidChainInformationRef<'a> {
91
    inner: ChainInformationRef<'a>,
92
}
93
94
impl<'a> From<&'a ValidChainInformation> for ValidChainInformationRef<'a> {
95
0
    fn from(info: &'a ValidChainInformation) -> ValidChainInformationRef<'a> {
96
0
        ValidChainInformationRef {
97
0
            inner: From::from(&info.inner),
98
0
        }
99
0
    }
Unexecuted instantiation: _RNvXs2_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_21ValidChainInformationE4from
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_21ValidChainInformationE4from
100
}
101
102
impl<'a> TryFrom<ChainInformationRef<'a>> for ValidChainInformationRef<'a> {
103
    type Error = ValidityError;
104
105
0
    fn try_from(info: ChainInformationRef<'a>) -> Result<Self, Self::Error> {
106
0
        info.validate()?;
107
0
        Ok(ValidChainInformationRef { inner: info })
108
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRefINtNtCsaYZPK01V26L_4core7convert7TryFromNtB5_19ChainInformationRefE8try_from
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRefINtNtCsaYZPK01V26L_4core7convert7TryFromNtB5_19ChainInformationRefE8try_from
109
}
110
111
impl<'a> ValidChainInformationRef<'a> {
112
    /// Gives access to the information.
113
0
    pub fn as_ref(&self) -> ChainInformationRef<'a> {
114
0
        self.inner.clone()
115
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRef6as_ref
Unexecuted instantiation: _RNvMs4_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_24ValidChainInformationRef6as_ref
116
}
117
118
/// Information about the latest finalized block and state found in its ancestors.
119
#[derive(Debug, Clone)]
120
pub struct ChainInformation {
121
    /// Header of the highest known finalized block.
122
    pub finalized_block_header: Box<header::Header>,
123
124
    /// Extra items that depend on the consensus engine.
125
    pub consensus: ChainInformationConsensus,
126
127
    /// Extra items that depend on the finality engine.
128
    pub finality: ChainInformationFinality,
129
}
130
131
impl<'a> From<ChainInformationRef<'a>> for ChainInformation {
132
0
    fn from(info: ChainInformationRef<'a>) -> ChainInformation {
133
0
        ChainInformation {
134
0
            finalized_block_header: Box::new(info.finalized_block_header.into()),
135
0
            consensus: match info.consensus {
136
0
                ChainInformationConsensusRef::Unknown => ChainInformationConsensus::Unknown,
137
                ChainInformationConsensusRef::Aura {
138
0
                    finalized_authorities_list,
139
0
                    slot_duration,
140
0
                } => ChainInformationConsensus::Aura {
141
0
                    finalized_authorities_list: finalized_authorities_list
142
0
                        .map(|a| a.into())
Unexecuted instantiation: _RNCNvXs5_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB7_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB7_19ChainInformationRefE4from0Bb_
Unexecuted instantiation: _RNCNvXs5_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB7_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB7_19ChainInformationRefE4from0Bb_
143
0
                        .collect(),
144
0
                    slot_duration,
145
0
                },
146
                ChainInformationConsensusRef::Babe {
147
0
                    slots_per_epoch,
148
0
                    finalized_next_epoch_transition,
149
0
                    finalized_block_epoch_information,
150
0
                } => ChainInformationConsensus::Babe {
151
0
                    slots_per_epoch,
152
0
                    finalized_block_epoch_information: finalized_block_epoch_information
153
0
                        .map(|i| Box::new(i.into())),
Unexecuted instantiation: _RNCNvXs5_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB7_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB7_19ChainInformationRefE4froms_0Bb_
Unexecuted instantiation: _RNCNvXs5_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB7_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB7_19ChainInformationRefE4froms_0Bb_
154
0
                    finalized_next_epoch_transition: Box::new(
155
0
                        finalized_next_epoch_transition.into(),
156
0
                    ),
157
0
                },
158
            },
159
0
            finality: info.finality.into(),
160
0
        }
161
0
    }
Unexecuted instantiation: _RNvXs5_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_19ChainInformationRefE4from
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_16ChainInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_19ChainInformationRefE4from
162
}
163
164
/// Extra items that depend on the consensus engine.
165
#[derive(Debug, Clone)]
166
pub enum ChainInformationConsensus {
167
    /// Any node on the chain is allowed to produce blocks.
168
    ///
169
    /// > **Note**: Be warned that this variant makes it possible for a huge number of blocks to
170
    /// >           be produced. If this variant is used, the user is encouraged to limit, through
171
    /// >           other means, the number of blocks being accepted.
172
    Unknown,
173
174
    /// Chain is using the Aura consensus engine.
175
    Aura {
176
        /// List of authorities that must validate children of the block referred to by
177
        /// [`ChainInformation::finalized_block_header`].
178
        finalized_authorities_list: Vec<header::AuraAuthority>,
179
180
        /// Duration, in milliseconds, of an Aura slot.
181
        slot_duration: NonZeroU64,
182
    },
183
184
    /// Chain is using the Babe consensus engine.
185
    Babe {
186
        /// Number of slots per epoch. Configured at the genesis block and never touched later.
187
        slots_per_epoch: NonZeroU64,
188
189
        /// Babe epoch information about the epoch the finalized block belongs to.
190
        ///
191
        /// If the finalized block belongs to epoch #0, which starts at block #1, then this must
192
        /// contain the information about the epoch #0, which can be found by calling the
193
        /// `BabeApi_configuration` runtime function.
194
        ///
195
        /// Must be `None` if and only if the finalized block is block #0.
196
        ///
197
        /// > **Note**: The information about the epoch the finalized block belongs to isn't
198
        /// >           necessary, but the information about the epoch the children of the
199
        /// >           finalized block belongs to *is*. However, due to possibility of missed
200
        /// >           slots, it is often not possible to know in advance whether the children
201
        /// >           of a block will belong to the same epoch as their parent. This is the
202
        /// >           reason why the "parent" (i.e. finalized block)'s information are demanded.
203
        finalized_block_epoch_information: Option<Box<BabeEpochInformation>>,
204
205
        /// Babe epoch information about the epoch right after the one the finalized block belongs
206
        /// to.
207
        ///
208
        /// If [`ChainInformationConsensus::Babe::finalized_block_epoch_information`] is `Some`,
209
        /// this field must contain the epoch that follows.
210
        ///
211
        /// If the finalized block is block #0, then this must contain the information about the
212
        /// epoch #0, which can be found by calling the `BabeApi_configuration` runtime function.
213
        finalized_next_epoch_transition: Box<BabeEpochInformation>,
214
    },
215
}
216
217
/// Information about a Babe epoch.
218
#[derive(Debug, Clone)]
219
pub struct BabeEpochInformation {
220
    /// Index of the epoch.
221
    ///
222
    /// Epoch number 0 starts at the slot number of block 1. Epoch indices increase one by one.
223
    pub epoch_index: u64,
224
225
    /// Slot at which the epoch starts.
226
    ///
227
    /// Must be `None` if and only if the context is
228
    /// [`ChainInformationConsensus::Babe::finalized_next_epoch_transition`] and
229
    /// [`BabeEpochInformation::epoch_index`] is 0.
230
    pub start_slot_number: Option<u64>,
231
232
    /// List of authorities allowed to author blocks during this epoch.
233
    pub authorities: Vec<header::BabeAuthority>,
234
235
    /// Randomness value for this epoch.
236
    ///
237
    /// Determined using the VRF output of the validators of the epoch before.
238
    pub randomness: [u8; 32],
239
240
    /// Value of the constant that allows determining the chances of a VRF being generated by a
241
    /// given slot.
242
    ///
243
    /// This constant represents a fraction, where the first element of the tuple is the numerator
244
    /// and the second element is the denominator. The fraction should always be `<= 1`, meaning
245
    /// that the numerator should always be inferior or equal to the denominator.
246
    pub c: (u64, u64),
247
248
    /// Types of blocks allowed for this epoch.
249
    pub allowed_slots: header::BabeAllowedSlots,
250
}
251
252
impl BabeEpochInformation {
253
    /// Checks whether the fields in this struct make sense.
254
2
    pub fn validate(&self) -> Result<(), BabeValidityError> {
255
2
        BabeEpochInformationRef::from(self).validate()
256
2
    }
_RNvMs6_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_20BabeEpochInformation8validate
Line
Count
Source
254
2
    pub fn validate(&self) -> Result<(), BabeValidityError> {
255
2
        BabeEpochInformationRef::from(self).validate()
256
2
    }
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_20BabeEpochInformation8validate
257
}
258
259
impl<'a> From<BabeEpochInformationRef<'a>> for BabeEpochInformation {
260
0
    fn from(info: BabeEpochInformationRef<'a>) -> BabeEpochInformation {
261
0
        BabeEpochInformation {
262
0
            epoch_index: info.epoch_index,
263
0
            start_slot_number: info.start_slot_number,
264
0
            authorities: info.authorities.map(Into::into).collect(),
265
0
            randomness: *info.randomness,
266
0
            c: info.c,
267
0
            allowed_slots: info.allowed_slots,
268
0
        }
269
0
    }
Unexecuted instantiation: _RNvXs7_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_20BabeEpochInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_23BabeEpochInformationRefE4from
Unexecuted instantiation: _RNvXs7_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_20BabeEpochInformationINtNtCsaYZPK01V26L_4core7convert4FromNtB5_23BabeEpochInformationRefE4from
270
}
271
272
/// Extra items that depend on the finality engine.
273
#[derive(Debug, Clone)]
274
pub enum ChainInformationFinality {
275
    /// Blocks themselves don't contain any information concerning finality. Finality is provided
276
    /// by a mechanism that is entirely external to the chain.
277
    ///
278
    /// > **Note**: This is the mechanism used for parachains. Finality is provided entirely by
279
    /// >           the relay chain.
280
    Outsourced,
281
282
    /// Chain uses the Grandpa finality algorithm.
283
    Grandpa {
284
        /// Grandpa authorities set ID of the block right after finalized block.
285
        ///
286
        /// If the finalized block is the genesis block, should be 0. Otherwise, must be
287
        /// incremented by one for every change in the Grandpa authorities reported by the
288
        /// headers since the genesis block.
289
        after_finalized_block_authorities_set_id: u64,
290
291
        /// List of GrandPa authorities that need to finalize the block right after the finalized
292
        /// block.
293
        finalized_triggered_authorities: Vec<header::GrandpaAuthority>,
294
295
        /// Change in the GrandPa authorities list that has been scheduled by a block that is already
296
        /// finalized, but the change is not triggered yet. These changes will for sure happen.
297
        /// Contains the block number where the changes are to be triggered.
298
        ///
299
        /// The block whose height is contained in this field must still be finalized using the
300
        /// authorities found in [`ChainInformationFinality::Grandpa::finalized_triggered_authorities`].
301
        /// Only the next block and further use the new list of authorities.
302
        ///
303
        /// The block height must always be strictly superior to the height found in
304
        /// [`ChainInformation::finalized_block_header`].
305
        ///
306
        /// > **Note**: When a header contains a GrandPa scheduled changes log item with a delay of N,
307
        /// >           the block where the changes are triggered is
308
        /// >           `height(block_with_log_item) + N`. If `N` is 0, then the block where the
309
        /// >           change is triggered is the same as the one where it is scheduled.
310
        finalized_scheduled_change: Option<(u64, Vec<header::GrandpaAuthority>)>,
311
    },
312
}
313
314
impl<'a> From<ChainInformationFinalityRef<'a>> for ChainInformationFinality {
315
21
    fn from(finality: ChainInformationFinalityRef<'a>) -> ChainInformationFinality {
316
21
        match finality {
317
0
            ChainInformationFinalityRef::Outsourced => ChainInformationFinality::Outsourced,
318
            ChainInformationFinalityRef::Grandpa {
319
21
                after_finalized_block_authorities_set_id,
320
21
                finalized_triggered_authorities,
321
21
                finalized_scheduled_change,
322
21
            } => ChainInformationFinality::Grandpa {
323
21
                after_finalized_block_authorities_set_id,
324
21
                finalized_scheduled_change: finalized_scheduled_change.map(|(n, l)| 
(n, l.into())0
),
Unexecuted instantiation: _RNCNvXs8_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB7_24ChainInformationFinalityINtNtCsaYZPK01V26L_4core7convert4FromNtB7_27ChainInformationFinalityRefE4from0Bb_
Unexecuted instantiation: _RNCNvXs8_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB7_24ChainInformationFinalityINtNtCsaYZPK01V26L_4core7convert4FromNtB7_27ChainInformationFinalityRefE4from0Bb_
325
21
                finalized_triggered_authorities: finalized_triggered_authorities.into(),
326
21
            },
327
        }
328
21
    }
Unexecuted instantiation: _RNvXs8_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_24ChainInformationFinalityINtNtCsaYZPK01V26L_4core7convert4FromNtB5_27ChainInformationFinalityRefE4from
_RNvXs8_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_24ChainInformationFinalityINtNtCsaYZPK01V26L_4core7convert4FromNtB5_27ChainInformationFinalityRefE4from
Line
Count
Source
315
21
    fn from(finality: ChainInformationFinalityRef<'a>) -> ChainInformationFinality {
316
21
        match finality {
317
0
            ChainInformationFinalityRef::Outsourced => ChainInformationFinality::Outsourced,
318
            ChainInformationFinalityRef::Grandpa {
319
21
                after_finalized_block_authorities_set_id,
320
21
                finalized_triggered_authorities,
321
21
                finalized_scheduled_change,
322
21
            } => ChainInformationFinality::Grandpa {
323
21
                after_finalized_block_authorities_set_id,
324
21
                finalized_scheduled_change: finalized_scheduled_change.map(|(n, l)| (n, l.into())),
325
21
                finalized_triggered_authorities: finalized_triggered_authorities.into(),
326
21
            },
327
        }
328
21
    }
329
}
330
331
/// Equivalent to a [`ChainInformation`] but referencing an existing structure. Cheap to copy.
332
#[derive(Debug, Clone)]
333
pub struct ChainInformationRef<'a> {
334
    /// See equivalent field in [`ChainInformation`].
335
    pub finalized_block_header: header::HeaderRef<'a>,
336
337
    /// Extra items that depend on the consensus engine.
338
    pub consensus: ChainInformationConsensusRef<'a>,
339
340
    /// Extra items that depend on the finality engine.
341
    pub finality: ChainInformationFinalityRef<'a>,
342
}
343
344
impl<'a> ChainInformationRef<'a> {
345
    /// Checks whether the information is coherent.
346
45
    pub fn validate(&self) -> Result<(), ValidityError> {
347
        if let ChainInformationConsensusRef::Babe {
348
3
            finalized_next_epoch_transition,
349
3
            finalized_block_epoch_information,
350
            ..
351
45
        } = &self.consensus
352
        {
353
3
            if let Err(
err0
) = finalized_next_epoch_transition.validate() {
354
0
                return Err(ValidityError::InvalidBabe(err));
355
3
            }
356
3
357
3
            if finalized_next_epoch_transition.start_slot_number.is_some()
358
0
                && (finalized_next_epoch_transition.epoch_index == 0)
359
            {
360
0
                return Err(ValidityError::UnexpectedBabeSlotStartNumber);
361
3
            }
362
3
            if finalized_next_epoch_transition.start_slot_number.is_none()
363
3
                && (finalized_next_epoch_transition.epoch_index != 0)
364
            {
365
0
                return Err(ValidityError::MissingBabeSlotStartNumber);
366
3
            }
367
368
3
            if let Some(
finalized_block_epoch_information0
) = &finalized_block_epoch_information {
369
0
                if let Err(err) = finalized_block_epoch_information.validate() {
370
0
                    return Err(ValidityError::InvalidBabe(err));
371
0
                }
372
0
373
0
                if self.finalized_block_header.number == 0 {
374
0
                    return Err(ValidityError::UnexpectedBabeFinalizedEpoch);
375
0
                }
376
377
0
                if let Some(epoch_start_slot_number) =
378
0
                    finalized_block_epoch_information.start_slot_number
379
                {
380
0
                    if let Some(babe_preruntime) =
381
0
                        self.finalized_block_header.digest.babe_pre_runtime()
382
                    {
383
0
                        if self.finalized_block_header.number == 0 {
384
0
                            return Err(ValidityError::ConsensusAlgorithmMismatch);
385
0
                        }
386
0
                        if babe_preruntime.slot_number() < epoch_start_slot_number {
387
0
                            return Err(ValidityError::HeaderBabeSlotInferiorToEpochStartSlot);
388
0
                        }
389
0
                    } else if self.finalized_block_header.number != 0 {
390
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
391
0
                    }
392
0
                    if (self.finalized_block_header.digest.babe_seal().is_some()
393
0
                        != (self.finalized_block_header.number != 0))
394
0
                        || self.finalized_block_header.digest.has_any_aura()
395
                    {
396
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
397
0
                    }
398
0
                    if let Some((epoch_change, _new_config)) =
399
0
                        self.finalized_block_header.digest.babe_epoch_information()
400
                    {
401
0
                        if epoch_change.authorities != finalized_next_epoch_transition.authorities
402
0
                            || epoch_change.randomness != finalized_next_epoch_transition.randomness
403
                        {
404
0
                            return Err(ValidityError::BabeEpochInfoMismatch);
405
0
                        }
406
0
                    }
407
                } else {
408
0
                    return Err(ValidityError::MissingBabeSlotStartNumber);
409
                }
410
3
            }
411
412
3
            if finalized_block_epoch_information.is_none()
413
3
                && self.finalized_block_header.number != 0
414
            {
415
0
                return Err(ValidityError::NoBabeFinalizedEpoch);
416
3
            }
417
42
        }
418
419
45
        if let ChainInformationConsensusRef::Aura { .. } = &self.consensus {
420
42
            if (self
421
42
                .finalized_block_header
422
42
                .digest
423
42
                .aura_pre_runtime()
424
42
                .is_some()
425
42
                != (self.finalized_block_header.number != 0))
426
42
                || (self.finalized_block_header.digest.aura_seal().is_some()
427
42
                    != (self.finalized_block_header.number != 0))
428
42
                || self.finalized_block_header.digest.has_any_babe()
429
            {
430
0
                return Err(ValidityError::ConsensusAlgorithmMismatch);
431
42
            }
432
3
        }
433
434
        if let ChainInformationFinalityRef::Grandpa {
435
45
            after_finalized_block_authorities_set_id,
436
45
            finalized_scheduled_change,
437
            ..
438
45
        } = &self.finality
439
        {
440
            // TODO: check consistency with the finalized block header
441
45
            if let Some(
change0
) = finalized_scheduled_change.as_ref() {
442
0
                if change.0 <= self.finalized_block_header.number {
443
0
                    return Err(ValidityError::ScheduledGrandPaChangeBeforeFinalized);
444
0
                }
445
45
            }
446
45
            if self.finalized_block_header.number == 0
447
45
                && *after_finalized_block_authorities_set_id != 0
448
            {
449
0
                return Err(ValidityError::FinalizedZeroButNonZeroAuthoritiesSetId);
450
45
            }
451
0
        }
452
453
45
        Ok(())
454
45
    }
_RNvMs9_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_19ChainInformationRef8validate
Line
Count
Source
346
3
    pub fn validate(&self) -> Result<(), ValidityError> {
347
        if let ChainInformationConsensusRef::Babe {
348
3
            finalized_next_epoch_transition,
349
3
            finalized_block_epoch_information,
350
            ..
351
3
        } = &self.consensus
352
        {
353
3
            if let Err(
err0
) = finalized_next_epoch_transition.validate() {
354
0
                return Err(ValidityError::InvalidBabe(err));
355
3
            }
356
3
357
3
            if finalized_next_epoch_transition.start_slot_number.is_some()
358
0
                && (finalized_next_epoch_transition.epoch_index == 0)
359
            {
360
0
                return Err(ValidityError::UnexpectedBabeSlotStartNumber);
361
3
            }
362
3
            if finalized_next_epoch_transition.start_slot_number.is_none()
363
3
                && (finalized_next_epoch_transition.epoch_index != 0)
364
            {
365
0
                return Err(ValidityError::MissingBabeSlotStartNumber);
366
3
            }
367
368
3
            if let Some(
finalized_block_epoch_information0
) = &finalized_block_epoch_information {
369
0
                if let Err(err) = finalized_block_epoch_information.validate() {
370
0
                    return Err(ValidityError::InvalidBabe(err));
371
0
                }
372
0
373
0
                if self.finalized_block_header.number == 0 {
374
0
                    return Err(ValidityError::UnexpectedBabeFinalizedEpoch);
375
0
                }
376
377
0
                if let Some(epoch_start_slot_number) =
378
0
                    finalized_block_epoch_information.start_slot_number
379
                {
380
0
                    if let Some(babe_preruntime) =
381
0
                        self.finalized_block_header.digest.babe_pre_runtime()
382
                    {
383
0
                        if self.finalized_block_header.number == 0 {
384
0
                            return Err(ValidityError::ConsensusAlgorithmMismatch);
385
0
                        }
386
0
                        if babe_preruntime.slot_number() < epoch_start_slot_number {
387
0
                            return Err(ValidityError::HeaderBabeSlotInferiorToEpochStartSlot);
388
0
                        }
389
0
                    } else if self.finalized_block_header.number != 0 {
390
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
391
0
                    }
392
0
                    if (self.finalized_block_header.digest.babe_seal().is_some()
393
0
                        != (self.finalized_block_header.number != 0))
394
0
                        || self.finalized_block_header.digest.has_any_aura()
395
                    {
396
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
397
0
                    }
398
0
                    if let Some((epoch_change, _new_config)) =
399
0
                        self.finalized_block_header.digest.babe_epoch_information()
400
                    {
401
0
                        if epoch_change.authorities != finalized_next_epoch_transition.authorities
402
0
                            || epoch_change.randomness != finalized_next_epoch_transition.randomness
403
                        {
404
0
                            return Err(ValidityError::BabeEpochInfoMismatch);
405
0
                        }
406
0
                    }
407
                } else {
408
0
                    return Err(ValidityError::MissingBabeSlotStartNumber);
409
                }
410
3
            }
411
412
3
            if finalized_block_epoch_information.is_none()
413
3
                && self.finalized_block_header.number != 0
414
            {
415
0
                return Err(ValidityError::NoBabeFinalizedEpoch);
416
3
            }
417
0
        }
418
419
3
        if let ChainInformationConsensusRef::Aura { .. } = &self.consensus {
420
0
            if (self
421
0
                .finalized_block_header
422
0
                .digest
423
0
                .aura_pre_runtime()
424
0
                .is_some()
425
0
                != (self.finalized_block_header.number != 0))
426
0
                || (self.finalized_block_header.digest.aura_seal().is_some()
427
0
                    != (self.finalized_block_header.number != 0))
428
0
                || self.finalized_block_header.digest.has_any_babe()
429
            {
430
0
                return Err(ValidityError::ConsensusAlgorithmMismatch);
431
0
            }
432
3
        }
433
434
        if let ChainInformationFinalityRef::Grandpa {
435
3
            after_finalized_block_authorities_set_id,
436
3
            finalized_scheduled_change,
437
            ..
438
3
        } = &self.finality
439
        {
440
            // TODO: check consistency with the finalized block header
441
3
            if let Some(
change0
) = finalized_scheduled_change.as_ref() {
442
0
                if change.0 <= self.finalized_block_header.number {
443
0
                    return Err(ValidityError::ScheduledGrandPaChangeBeforeFinalized);
444
0
                }
445
3
            }
446
3
            if self.finalized_block_header.number == 0
447
3
                && *after_finalized_block_authorities_set_id != 0
448
            {
449
0
                return Err(ValidityError::FinalizedZeroButNonZeroAuthoritiesSetId);
450
3
            }
451
0
        }
452
453
3
        Ok(())
454
3
    }
_RNvMs9_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_19ChainInformationRef8validate
Line
Count
Source
346
42
    pub fn validate(&self) -> Result<(), ValidityError> {
347
        if let ChainInformationConsensusRef::Babe {
348
0
            finalized_next_epoch_transition,
349
0
            finalized_block_epoch_information,
350
            ..
351
42
        } = &self.consensus
352
        {
353
0
            if let Err(err) = finalized_next_epoch_transition.validate() {
354
0
                return Err(ValidityError::InvalidBabe(err));
355
0
            }
356
0
357
0
            if finalized_next_epoch_transition.start_slot_number.is_some()
358
0
                && (finalized_next_epoch_transition.epoch_index == 0)
359
            {
360
0
                return Err(ValidityError::UnexpectedBabeSlotStartNumber);
361
0
            }
362
0
            if finalized_next_epoch_transition.start_slot_number.is_none()
363
0
                && (finalized_next_epoch_transition.epoch_index != 0)
364
            {
365
0
                return Err(ValidityError::MissingBabeSlotStartNumber);
366
0
            }
367
368
0
            if let Some(finalized_block_epoch_information) = &finalized_block_epoch_information {
369
0
                if let Err(err) = finalized_block_epoch_information.validate() {
370
0
                    return Err(ValidityError::InvalidBabe(err));
371
0
                }
372
0
373
0
                if self.finalized_block_header.number == 0 {
374
0
                    return Err(ValidityError::UnexpectedBabeFinalizedEpoch);
375
0
                }
376
377
0
                if let Some(epoch_start_slot_number) =
378
0
                    finalized_block_epoch_information.start_slot_number
379
                {
380
0
                    if let Some(babe_preruntime) =
381
0
                        self.finalized_block_header.digest.babe_pre_runtime()
382
                    {
383
0
                        if self.finalized_block_header.number == 0 {
384
0
                            return Err(ValidityError::ConsensusAlgorithmMismatch);
385
0
                        }
386
0
                        if babe_preruntime.slot_number() < epoch_start_slot_number {
387
0
                            return Err(ValidityError::HeaderBabeSlotInferiorToEpochStartSlot);
388
0
                        }
389
0
                    } else if self.finalized_block_header.number != 0 {
390
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
391
0
                    }
392
0
                    if (self.finalized_block_header.digest.babe_seal().is_some()
393
0
                        != (self.finalized_block_header.number != 0))
394
0
                        || self.finalized_block_header.digest.has_any_aura()
395
                    {
396
0
                        return Err(ValidityError::ConsensusAlgorithmMismatch);
397
0
                    }
398
0
                    if let Some((epoch_change, _new_config)) =
399
0
                        self.finalized_block_header.digest.babe_epoch_information()
400
                    {
401
0
                        if epoch_change.authorities != finalized_next_epoch_transition.authorities
402
0
                            || epoch_change.randomness != finalized_next_epoch_transition.randomness
403
                        {
404
0
                            return Err(ValidityError::BabeEpochInfoMismatch);
405
0
                        }
406
0
                    }
407
                } else {
408
0
                    return Err(ValidityError::MissingBabeSlotStartNumber);
409
                }
410
0
            }
411
412
0
            if finalized_block_epoch_information.is_none()
413
0
                && self.finalized_block_header.number != 0
414
            {
415
0
                return Err(ValidityError::NoBabeFinalizedEpoch);
416
0
            }
417
42
        }
418
419
42
        if let ChainInformationConsensusRef::Aura { .. } = &self.consensus {
420
42
            if (self
421
42
                .finalized_block_header
422
42
                .digest
423
42
                .aura_pre_runtime()
424
42
                .is_some()
425
42
                != (self.finalized_block_header.number != 0))
426
42
                || (self.finalized_block_header.digest.aura_seal().is_some()
427
42
                    != (self.finalized_block_header.number != 0))
428
42
                || self.finalized_block_header.digest.has_any_babe()
429
            {
430
0
                return Err(ValidityError::ConsensusAlgorithmMismatch);
431
42
            }
432
0
        }
433
434
        if let ChainInformationFinalityRef::Grandpa {
435
42
            after_finalized_block_authorities_set_id,
436
42
            finalized_scheduled_change,
437
            ..
438
42
        } = &self.finality
439
        {
440
            // TODO: check consistency with the finalized block header
441
42
            if let Some(
change0
) = finalized_scheduled_change.as_ref() {
442
0
                if change.0 <= self.finalized_block_header.number {
443
0
                    return Err(ValidityError::ScheduledGrandPaChangeBeforeFinalized);
444
0
                }
445
42
            }
446
42
            if self.finalized_block_header.number == 0
447
42
                && *after_finalized_block_authorities_set_id != 0
448
            {
449
0
                return Err(ValidityError::FinalizedZeroButNonZeroAuthoritiesSetId);
450
42
            }
451
0
        }
452
453
42
        Ok(())
454
42
    }
455
}
456
457
impl<'a> From<&'a ChainInformation> for ChainInformationRef<'a> {
458
319
    fn from(info: &'a ChainInformation) -> ChainInformationRef<'a> {
459
319
        ChainInformationRef {
460
319
            finalized_block_header: (&*info.finalized_block_header).into(),
461
319
            consensus: match &info.consensus {
462
0
                ChainInformationConsensus::Unknown => ChainInformationConsensusRef::Unknown,
463
                ChainInformationConsensus::Aura {
464
315
                    finalized_authorities_list,
465
315
                    slot_duration,
466
315
                } => ChainInformationConsensusRef::Aura {
467
315
                    finalized_authorities_list: header::AuraAuthoritiesIter::from_slice(
468
315
                        finalized_authorities_list,
469
315
                    ),
470
315
                    slot_duration: *slot_duration,
471
315
                },
472
                ChainInformationConsensus::Babe {
473
4
                    slots_per_epoch,
474
4
                    finalized_block_epoch_information,
475
4
                    finalized_next_epoch_transition,
476
4
                } => ChainInformationConsensusRef::Babe {
477
4
                    slots_per_epoch: *slots_per_epoch,
478
4
                    finalized_block_epoch_information: finalized_block_epoch_information
479
4
                        .as_ref()
480
4
                        .map(|i| 
(&**i).into()0
),
Unexecuted instantiation: _RNCNvXsa_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB7_19ChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB7_16ChainInformationE4from0Bb_
Unexecuted instantiation: _RNCNvXsa_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB7_19ChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB7_16ChainInformationE4from0Bb_
481
4
                    finalized_next_epoch_transition: (&**finalized_next_epoch_transition).into(),
482
4
                },
483
            },
484
319
            finality: (&info.finality).into(),
485
319
        }
486
319
    }
_RNvXsa_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_19ChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_16ChainInformationE4from
Line
Count
Source
458
4
    fn from(info: &'a ChainInformation) -> ChainInformationRef<'a> {
459
4
        ChainInformationRef {
460
4
            finalized_block_header: (&*info.finalized_block_header).into(),
461
4
            consensus: match &info.consensus {
462
0
                ChainInformationConsensus::Unknown => ChainInformationConsensusRef::Unknown,
463
                ChainInformationConsensus::Aura {
464
0
                    finalized_authorities_list,
465
0
                    slot_duration,
466
0
                } => ChainInformationConsensusRef::Aura {
467
0
                    finalized_authorities_list: header::AuraAuthoritiesIter::from_slice(
468
0
                        finalized_authorities_list,
469
0
                    ),
470
0
                    slot_duration: *slot_duration,
471
0
                },
472
                ChainInformationConsensus::Babe {
473
4
                    slots_per_epoch,
474
4
                    finalized_block_epoch_information,
475
4
                    finalized_next_epoch_transition,
476
4
                } => ChainInformationConsensusRef::Babe {
477
4
                    slots_per_epoch: *slots_per_epoch,
478
4
                    finalized_block_epoch_information: finalized_block_epoch_information
479
4
                        .as_ref()
480
4
                        .map(|i| (&**i).into()),
481
4
                    finalized_next_epoch_transition: (&**finalized_next_epoch_transition).into(),
482
4
                },
483
            },
484
4
            finality: (&info.finality).into(),
485
4
        }
486
4
    }
_RNvXsa_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_19ChainInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_16ChainInformationE4from
Line
Count
Source
458
315
    fn from(info: &'a ChainInformation) -> ChainInformationRef<'a> {
459
315
        ChainInformationRef {
460
315
            finalized_block_header: (&*info.finalized_block_header).into(),
461
315
            consensus: match &info.consensus {
462
0
                ChainInformationConsensus::Unknown => ChainInformationConsensusRef::Unknown,
463
                ChainInformationConsensus::Aura {
464
315
                    finalized_authorities_list,
465
315
                    slot_duration,
466
315
                } => ChainInformationConsensusRef::Aura {
467
315
                    finalized_authorities_list: header::AuraAuthoritiesIter::from_slice(
468
315
                        finalized_authorities_list,
469
315
                    ),
470
315
                    slot_duration: *slot_duration,
471
315
                },
472
                ChainInformationConsensus::Babe {
473
0
                    slots_per_epoch,
474
0
                    finalized_block_epoch_information,
475
0
                    finalized_next_epoch_transition,
476
0
                } => ChainInformationConsensusRef::Babe {
477
0
                    slots_per_epoch: *slots_per_epoch,
478
0
                    finalized_block_epoch_information: finalized_block_epoch_information
479
0
                        .as_ref()
480
0
                        .map(|i| (&**i).into()),
481
0
                    finalized_next_epoch_transition: (&**finalized_next_epoch_transition).into(),
482
0
                },
483
            },
484
315
            finality: (&info.finality).into(),
485
315
        }
486
315
    }
487
}
488
489
/// Extra items that depend on the consensus engine.
490
#[derive(Debug, Clone)]
491
pub enum ChainInformationConsensusRef<'a> {
492
    /// See [`ChainInformationConsensus::Unknown`].
493
    Unknown,
494
495
    /// Chain is using the Aura consensus engine.
496
    Aura {
497
        /// See equivalent field in [`ChainInformationConsensus`].
498
        finalized_authorities_list: header::AuraAuthoritiesIter<'a>,
499
500
        /// See equivalent field in [`ChainInformationConsensus`].
501
        slot_duration: NonZeroU64,
502
    },
503
504
    /// Chain is using the Babe consensus engine.
505
    Babe {
506
        /// See equivalent field in [`ChainInformationConsensus`].
507
        slots_per_epoch: NonZeroU64,
508
509
        /// See equivalent field in [`ChainInformationConsensus`].
510
        finalized_block_epoch_information: Option<BabeEpochInformationRef<'a>>,
511
512
        /// See equivalent field in [`ChainInformationConsensus`].
513
        finalized_next_epoch_transition: BabeEpochInformationRef<'a>,
514
    },
515
}
516
517
/// Information about a Babe epoch.
518
#[derive(Debug, Clone)]
519
pub struct BabeEpochInformationRef<'a> {
520
    /// See equivalent field in [`BabeEpochInformation`].
521
    pub epoch_index: u64,
522
523
    /// See equivalent field in [`BabeEpochInformation`].
524
    pub start_slot_number: Option<u64>,
525
526
    /// See equivalent field in [`BabeEpochInformation`].
527
    pub authorities: header::BabeAuthoritiesIter<'a>,
528
529
    /// See equivalent field in [`BabeEpochInformation`].
530
    pub randomness: &'a [u8; 32],
531
532
    /// See equivalent field in [`BabeEpochInformation`].
533
    pub c: (u64, u64),
534
535
    /// See equivalent field in [`BabeEpochInformation`].
536
    pub allowed_slots: header::BabeAllowedSlots,
537
}
538
539
impl<'a> BabeEpochInformationRef<'a> {
540
    /// Checks whether the fields in this struct make sense.
541
5
    pub fn validate(&self) -> Result<(), BabeValidityError> {
542
5
        if self.c.0 > self.c.1 {
543
0
            return Err(BabeValidityError::InvalidConstant);
544
5
        }
545
5
546
5
        Ok(())
547
5
    }
_RNvMsb_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_23BabeEpochInformationRef8validate
Line
Count
Source
541
5
    pub fn validate(&self) -> Result<(), BabeValidityError> {
542
5
        if self.c.0 > self.c.1 {
543
0
            return Err(BabeValidityError::InvalidConstant);
544
5
        }
545
5
546
5
        Ok(())
547
5
    }
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_23BabeEpochInformationRef8validate
548
}
549
550
impl<'a> From<&'a BabeEpochInformation> for BabeEpochInformationRef<'a> {
551
12
    fn from(info: &'a BabeEpochInformation) -> BabeEpochInformationRef<'a> {
552
12
        BabeEpochInformationRef {
553
12
            epoch_index: info.epoch_index,
554
12
            start_slot_number: info.start_slot_number,
555
12
            authorities: header::BabeAuthoritiesIter::from_slice(&info.authorities),
556
12
            randomness: &info.randomness,
557
12
            c: info.c,
558
12
            allowed_slots: info.allowed_slots,
559
12
        }
560
12
    }
_RNvXsc_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_23BabeEpochInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_20BabeEpochInformationE4from
Line
Count
Source
551
12
    fn from(info: &'a BabeEpochInformation) -> BabeEpochInformationRef<'a> {
552
12
        BabeEpochInformationRef {
553
12
            epoch_index: info.epoch_index,
554
12
            start_slot_number: info.start_slot_number,
555
12
            authorities: header::BabeAuthoritiesIter::from_slice(&info.authorities),
556
12
            randomness: &info.randomness,
557
12
            c: info.c,
558
12
            allowed_slots: info.allowed_slots,
559
12
        }
560
12
    }
Unexecuted instantiation: _RNvXsc_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_23BabeEpochInformationRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_20BabeEpochInformationE4from
561
}
562
563
/// Extra items that depend on the finality engine.
564
#[derive(Debug, Clone)]
565
pub enum ChainInformationFinalityRef<'a> {
566
    /// See equivalent variant in [`ChainInformationFinality`].
567
    Outsourced,
568
569
    /// See equivalent variant in [`ChainInformationFinality`].
570
    Grandpa {
571
        /// See equivalent field in [`ChainInformationFinality`].
572
        after_finalized_block_authorities_set_id: u64,
573
574
        /// See equivalent field in [`ChainInformationFinality`].
575
        finalized_triggered_authorities: &'a [header::GrandpaAuthority],
576
577
        /// See equivalent field in [`ChainInformationFinality`].
578
        finalized_scheduled_change: Option<(u64, &'a [header::GrandpaAuthority])>,
579
    },
580
}
581
582
impl<'a> From<&'a ChainInformationFinality> for ChainInformationFinalityRef<'a> {
583
319
    fn from(finality: &'a ChainInformationFinality) -> ChainInformationFinalityRef<'a> {
584
319
        match finality {
585
0
            ChainInformationFinality::Outsourced => ChainInformationFinalityRef::Outsourced,
586
            ChainInformationFinality::Grandpa {
587
319
                finalized_triggered_authorities,
588
319
                after_finalized_block_authorities_set_id,
589
319
                finalized_scheduled_change,
590
319
            } => ChainInformationFinalityRef::Grandpa {
591
319
                after_finalized_block_authorities_set_id: *after_finalized_block_authorities_set_id,
592
319
                finalized_triggered_authorities,
593
319
                finalized_scheduled_change: finalized_scheduled_change
594
319
                    .as_ref()
595
319
                    .map(|(n, l)| 
(*n, &l[..])0
),
Unexecuted instantiation: _RNCNvXsd_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB7_27ChainInformationFinalityRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB7_24ChainInformationFinalityE4from0Bb_
Unexecuted instantiation: _RNCNvXsd_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB7_27ChainInformationFinalityRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB7_24ChainInformationFinalityE4from0Bb_
596
319
            },
597
        }
598
319
    }
_RNvXsd_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_27ChainInformationFinalityRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_24ChainInformationFinalityE4from
Line
Count
Source
583
4
    fn from(finality: &'a ChainInformationFinality) -> ChainInformationFinalityRef<'a> {
584
4
        match finality {
585
0
            ChainInformationFinality::Outsourced => ChainInformationFinalityRef::Outsourced,
586
            ChainInformationFinality::Grandpa {
587
4
                finalized_triggered_authorities,
588
4
                after_finalized_block_authorities_set_id,
589
4
                finalized_scheduled_change,
590
4
            } => ChainInformationFinalityRef::Grandpa {
591
4
                after_finalized_block_authorities_set_id: *after_finalized_block_authorities_set_id,
592
4
                finalized_triggered_authorities,
593
4
                finalized_scheduled_change: finalized_scheduled_change
594
4
                    .as_ref()
595
4
                    .map(|(n, l)| (*n, &l[..])),
596
4
            },
597
        }
598
4
    }
_RNvXsd_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_27ChainInformationFinalityRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_24ChainInformationFinalityE4from
Line
Count
Source
583
315
    fn from(finality: &'a ChainInformationFinality) -> ChainInformationFinalityRef<'a> {
584
315
        match finality {
585
0
            ChainInformationFinality::Outsourced => ChainInformationFinalityRef::Outsourced,
586
            ChainInformationFinality::Grandpa {
587
315
                finalized_triggered_authorities,
588
315
                after_finalized_block_authorities_set_id,
589
315
                finalized_scheduled_change,
590
315
            } => ChainInformationFinalityRef::Grandpa {
591
315
                after_finalized_block_authorities_set_id: *after_finalized_block_authorities_set_id,
592
315
                finalized_triggered_authorities,
593
315
                finalized_scheduled_change: finalized_scheduled_change
594
315
                    .as_ref()
595
315
                    .map(|(n, l)| (*n, &l[..])),
596
315
            },
597
        }
598
315
    }
599
}
600
601
/// Error when turning a [`ChainInformation`] into a [`ValidChainInformation`].
602
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXsz_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_13ValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsz_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_13ValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
603
pub enum ValidityError {
604
    /// The finalized block doesn't use the same consensus algorithm as the one in the chain
605
    /// information.
606
    ConsensusAlgorithmMismatch,
607
    /// Found a Babe slot start number for future Babe epoch number 0. A future Babe epoch 0 has
608
    /// no known starting slot.
609
    UnexpectedBabeSlotStartNumber,
610
    /// Missing Babe slot start number for Babe epoch number other than future epoch 0.
611
    MissingBabeSlotStartNumber,
612
    /// Finalized block is block number 0, and a Babe epoch information has been provided. This
613
    /// would imply the existence of a block -1 and below.
614
    UnexpectedBabeFinalizedEpoch,
615
    /// Finalized block is not number 0, but no Babe epoch information has been provided.
616
    NoBabeFinalizedEpoch,
617
    /// The slot of the finalized block is inferior to the start slot of the epoch it belongs to.
618
    HeaderBabeSlotInferiorToEpochStartSlot,
619
    /// Mismatch between the finalized block header digest and the Babe next epoch information.
620
    BabeEpochInfoMismatch,
621
    /// Scheduled GrandPa authorities change is before finalized block.
622
    ScheduledGrandPaChangeBeforeFinalized,
623
    /// The finalized block is block number 0, but the GrandPa authorities set id is not 0.
624
    FinalizedZeroButNonZeroAuthoritiesSetId,
625
    /// Error in a Babe epoch information.
626
    #[display(fmt = "Error in a Babe epoch information: {_0}")]
627
    InvalidBabe(BabeValidityError),
628
}
629
630
/// Error when checking the validity of a Babe epoch.
631
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXsB_NtNtCsN16ciHI6Qf_7smoldot5chain17chain_informationNtB5_17BabeValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsB_NtNtCseuYC0Zibziv_7smoldot5chain17chain_informationNtB5_17BabeValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
632
pub enum BabeValidityError {
633
    /// Babe constant should be a fraction where the numerator is inferior or equal to the
634
    /// denominator.
635
    InvalidConstant,
636
}