Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/chain/blocks_tree.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
//! Finalized block header, plus tree of authenticated non-finalized block headers.
19
//!
20
//! This module provides the [`NonFinalizedTree`] type. This type is a data structure
21
//! containing a valid tree of block headers, plus the state necessary to verify new blocks with
22
//! the intent to add them to that tree. Each block header additionally holds a user-chosen
23
//! opaque data.
24
//!
25
//! The state in the [`NonFinalizedTree`] consists of:
26
//!
27
//! - One "latest finalized" block and various information about its ancestors, akin to a
28
//!   [`chain_information::ChainInformation`].
29
//! - Zero or more blocks that descend from that latest finalized block.
30
//!
31
//! The latest finalized block is a block that is guaranteed to never be reverted. While it can
32
//! always be set to the genesis block of the chain, it is preferable, in order to reduce
33
//! memory utilization, to maintain it to a block that is as high as possible in the chain.
34
//!
35
//! > **Note**: While mechanisms such as GrandPa provide a network-wide way to designate a block
36
//! >           as final, the concept of GrandPa-provided finality doesn't necessarily have to
37
//! >           match the concept of finality in the [`NonFinalizedTree`]. For example, an API
38
//! >           user might decide to optimistically assume that the block whose number is
39
//! >           `highest_block - 5` is automatically finalized, and fall back to rebuilding a new
40
//! >           [`NonFinalizedTree`] if that assumption turns out to not be true. The finalized
41
//! >           block in the [`NonFinalizedTree`] only represents a block that the
42
//! >           [`NonFinalizedTree`] itself cannot remove, not a block that cannot be removed in
43
//! >           the absolute.
44
//!
45
//! A block can be added to the chain by calling [`NonFinalizedTree::verify_header`] then
46
//! [`NonFinalizedTree::insert_verified_header`]. As explained in details in
47
//! [the `verify` module](crate::verify), verifying the header only verifies the authenticity of
48
//! a block and not its correctness. Additionally verifying the body of the block provides the
49
//! strongest guarantee, but is the responsibility of the API user and is out of the scope of
50
//! this module.
51
//!
52
//! > **Note**: There typically exists two kinds of clients: full and light. Full clients store
53
//! >           the state of the storage, while light clients don't. For this reason, light
54
//! >           clients can only verify the header of new blocks. Both full and light clients
55
//! >           should wait for a block to be finalized if they want to be certain that it will
56
//! >           forever remain part of the chain.
57
//!
58
//! Additionally, a [`NonFinalizedTree::verify_justification`] method is provided in order to
59
//! verify the correctness of a [justification](crate::finality).
60
61
// TODO: expand this doc ^
62
63
use crate::{
64
    chain::{chain_information, fork_tree},
65
    header,
66
};
67
68
use alloc::{
69
    collections::{BTreeMap, BTreeSet},
70
    format,
71
    sync::Arc,
72
    vec::Vec,
73
};
74
use core::{cmp, fmt, mem, num::NonZeroU64, ops, time::Duration};
75
use hashbrown::HashMap;
76
77
mod finality;
78
mod tests;
79
mod verify;
80
81
pub use self::finality::*;
82
pub use self::verify::*;
83
84
/// Configuration for the [`NonFinalizedTree`].
85
#[derive(Debug, Clone)]
86
pub struct Config {
87
    /// Information about the latest finalized block and its ancestors.
88
    pub chain_information: chain_information::ValidChainInformation,
89
90
    /// Number of bytes used when encoding/decoding the block number. Influences how various data
91
    /// structures should be parsed.
92
    pub block_number_bytes: usize,
93
94
    /// Pre-allocated size of the chain, in number of non-finalized blocks.
95
    pub blocks_capacity: usize,
96
97
    /// If `false`, blocks containing digest items with an unknown consensus engine will fail to
98
    /// verify.
99
    ///
100
    /// Note that blocks must always contain digest items that are relevant to the current
101
    /// consensus algorithm. This option controls what happens when blocks contain additional
102
    /// digest items that aren't recognized by the implementation.
103
    ///
104
    /// Passing `true` can lead to blocks being considered as valid when they shouldn't, as these
105
    /// additional digest items could have some logic attached to them that restricts which blocks
106
    /// are valid and which are not.
107
    ///
108
    /// However, since a recognized consensus engine must always be present, both `true` and
109
    /// `false` guarantee that the number of authorable blocks over the network is bounded.
110
    pub allow_unknown_consensus_engines: bool,
111
}
112
113
/// Holds state about the current state of the chain for the purpose of verifying headers.
114
pub struct NonFinalizedTree<T> {
115
    /// Header of the highest known finalized block.
116
    ///
117
    /// Guaranteed to be valid.
118
    finalized_block_header: Vec<u8>,
119
    /// Hash of [`NonFinalizedTree::finalized_block_header`].
120
    finalized_block_hash: [u8; 32],
121
    /// Number of [`NonFinalizedTree::finalized_block_header`].
122
    finalized_block_number: u64,
123
    /// State of the chain finality engine.
124
    finality: Finality,
125
    /// State of the consensus of the finalized block.
126
    finalized_consensus: FinalizedConsensus,
127
    /// Best score of the finalized block.
128
    finalized_best_score: BestScore,
129
130
    /// Container for non-finalized blocks.
131
    blocks: fork_tree::ForkTree<Block<T>>,
132
    /// Counter increased by 1 every time a block is inserted in the collection. This value is used
133
    /// in order to guarantee that blocks inserted before are always considered as better than
134
    /// blocks inserted later.
135
    /// We use a `u128` rather than a `u64`. While it is unlikely that `2^64` blocks ever get
136
    /// inserted into the collection, the fact that the block number is a `u64`, and that there
137
    /// are potentially more than one block per height, means that a `u64` here is technically
138
    /// too small.
139
    blocks_insertion_counter: u128,
140
    /// For each block hash, the index of this block in [`NonFinalizedTree::blocks`].
141
    /// Must always have the same number of entries as [`NonFinalizedTree::blocks`].
142
    blocks_by_hash: HashMap<[u8; 32], fork_tree::NodeIndex, fnv::FnvBuildHasher>,
143
    /// Blocks indexed by the value in [`Block::best_score`]. The best block is the one with the
144
    /// highest score.
145
    blocks_by_best_score: BTreeMap<BestScore, fork_tree::NodeIndex>,
146
    /// Subset of [`NonFinalizedTree::blocks`] whose [`BlockFinality::Grandpa::triggers_change`]
147
    /// is `true`, indexed by the value in
148
    /// [`BlockFinality::Grandpa::prev_auth_change_trigger_number`].
149
    blocks_trigger_gp_change: BTreeSet<(Option<u64>, fork_tree::NodeIndex)>,
150
    /// See [`Config::block_number_bytes`].
151
    block_number_bytes: usize,
152
    /// See [`Config::allow_unknown_consensus_engines`].
153
    allow_unknown_consensus_engines: bool,
154
}
155
156
impl<T> NonFinalizedTree<T> {
157
    /// Initializes a new queue.
158
    ///
159
    /// # Panic
160
    ///
161
    /// Panics if the chain information is incorrect.
162
    ///
163
23
    pub fn new(config: Config) -> Self {
164
23
        let chain_information: chain_information::ChainInformation =
165
23
            config.chain_information.into();
166
23
167
23
        NonFinalizedTree {
168
23
            finalized_block_number: chain_information.finalized_block_header.number,
169
23
            finalized_block_hash: chain_information
170
23
                .finalized_block_header
171
23
                .hash(config.block_number_bytes),
172
23
            finalized_block_header: chain_information
173
23
                .finalized_block_header
174
23
                .scale_encoding_vec(config.block_number_bytes),
175
23
            finality: match chain_information.finality {
176
0
                chain_information::ChainInformationFinality::Outsourced => Finality::Outsourced,
177
                chain_information::ChainInformationFinality::Grandpa {
178
23
                    after_finalized_block_authorities_set_id,
179
23
                    finalized_scheduled_change,
180
23
                    finalized_triggered_authorities,
181
23
                } => Finality::Grandpa {
182
23
                    after_finalized_block_authorities_set_id,
183
23
                    finalized_scheduled_change: finalized_scheduled_change
184
23
                        .map(|(n, l)| 
(n, l.into_iter().collect())0
),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeuE3new0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE3new0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE3new0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3new0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3new0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3new0CsibGXYHQB8Ea_25json_rpc_general_requests
185
23
                    finalized_triggered_authorities: finalized_triggered_authorities
186
23
                        .into_iter()
187
23
                        .collect(),
188
23
                },
189
            },
190
23
            finalized_consensus: match chain_information.consensus {
191
                chain_information::ChainInformationConsensus::Unknown => {
192
0
                    FinalizedConsensus::Unknown
193
                }
194
                chain_information::ChainInformationConsensus::Aura {
195
21
                    finalized_authorities_list,
196
21
                    slot_duration,
197
21
                } => FinalizedConsensus::Aura {
198
21
                    authorities_list: Arc::new(finalized_authorities_list),
199
21
                    slot_duration,
200
21
                },
201
                chain_information::ChainInformationConsensus::Babe {
202
2
                    finalized_block_epoch_information,
203
2
                    finalized_next_epoch_transition,
204
2
                    slots_per_epoch,
205
2
                } => FinalizedConsensus::Babe {
206
2
                    slots_per_epoch,
207
2
                    block_epoch_information: finalized_block_epoch_information.map(Arc::from),
208
2
                    next_epoch_transition: Arc::from(finalized_next_epoch_transition),
209
2
                },
210
            },
211
23
            finalized_best_score: BestScore {
212
23
                num_primary_slots: 0,
213
23
                num_secondary_slots: 0,
214
23
                insertion_counter: 0,
215
23
            },
216
23
            blocks: fork_tree::ForkTree::with_capacity(config.blocks_capacity),
217
23
            blocks_insertion_counter: 1,
218
23
            blocks_by_hash: hashbrown::HashMap::with_capacity_and_hasher(
219
23
                config.blocks_capacity,
220
23
                Default::default(),
221
23
            ),
222
23
            blocks_by_best_score: BTreeMap::new(),
223
23
            blocks_trigger_gp_change: BTreeSet::new(),
224
23
            block_number_bytes: config.block_number_bytes,
225
23
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
226
23
        }
227
23
    }
_RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeuE3newB6_
Line
Count
Source
163
2
    pub fn new(config: Config) -> Self {
164
2
        let chain_information: chain_information::ChainInformation =
165
2
            config.chain_information.into();
166
2
167
2
        NonFinalizedTree {
168
2
            finalized_block_number: chain_information.finalized_block_header.number,
169
2
            finalized_block_hash: chain_information
170
2
                .finalized_block_header
171
2
                .hash(config.block_number_bytes),
172
2
            finalized_block_header: chain_information
173
2
                .finalized_block_header
174
2
                .scale_encoding_vec(config.block_number_bytes),
175
2
            finality: match chain_information.finality {
176
0
                chain_information::ChainInformationFinality::Outsourced => Finality::Outsourced,
177
                chain_information::ChainInformationFinality::Grandpa {
178
2
                    after_finalized_block_authorities_set_id,
179
2
                    finalized_scheduled_change,
180
2
                    finalized_triggered_authorities,
181
2
                } => Finality::Grandpa {
182
2
                    after_finalized_block_authorities_set_id,
183
2
                    finalized_scheduled_change: finalized_scheduled_change
184
2
                        .map(|(n, l)| (n, l.into_iter().collect())),
185
2
                    finalized_triggered_authorities: finalized_triggered_authorities
186
2
                        .into_iter()
187
2
                        .collect(),
188
2
                },
189
            },
190
2
            finalized_consensus: match chain_information.consensus {
191
                chain_information::ChainInformationConsensus::Unknown => {
192
0
                    FinalizedConsensus::Unknown
193
                }
194
                chain_information::ChainInformationConsensus::Aura {
195
0
                    finalized_authorities_list,
196
0
                    slot_duration,
197
0
                } => FinalizedConsensus::Aura {
198
0
                    authorities_list: Arc::new(finalized_authorities_list),
199
0
                    slot_duration,
200
0
                },
201
                chain_information::ChainInformationConsensus::Babe {
202
2
                    finalized_block_epoch_information,
203
2
                    finalized_next_epoch_transition,
204
2
                    slots_per_epoch,
205
2
                } => FinalizedConsensus::Babe {
206
2
                    slots_per_epoch,
207
2
                    block_epoch_information: finalized_block_epoch_information.map(Arc::from),
208
2
                    next_epoch_transition: Arc::from(finalized_next_epoch_transition),
209
2
                },
210
            },
211
2
            finalized_best_score: BestScore {
212
2
                num_primary_slots: 0,
213
2
                num_secondary_slots: 0,
214
2
                insertion_counter: 0,
215
2
            },
216
2
            blocks: fork_tree::ForkTree::with_capacity(config.blocks_capacity),
217
2
            blocks_insertion_counter: 1,
218
2
            blocks_by_hash: hashbrown::HashMap::with_capacity_and_hasher(
219
2
                config.blocks_capacity,
220
2
                Default::default(),
221
2
            ),
222
2
            blocks_by_best_score: BTreeMap::new(),
223
2
            blocks_trigger_gp_change: BTreeSet::new(),
224
2
            block_number_bytes: config.block_number_bytes,
225
2
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
226
2
        }
227
2
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE3newCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE3newB6_
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3newCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
163
2
    pub fn new(config: Config) -> Self {
164
2
        let chain_information: chain_information::ChainInformation =
165
2
            config.chain_information.into();
166
2
167
2
        NonFinalizedTree {
168
2
            finalized_block_number: chain_information.finalized_block_header.number,
169
2
            finalized_block_hash: chain_information
170
2
                .finalized_block_header
171
2
                .hash(config.block_number_bytes),
172
2
            finalized_block_header: chain_information
173
2
                .finalized_block_header
174
2
                .scale_encoding_vec(config.block_number_bytes),
175
2
            finality: match chain_information.finality {
176
0
                chain_information::ChainInformationFinality::Outsourced => Finality::Outsourced,
177
                chain_information::ChainInformationFinality::Grandpa {
178
2
                    after_finalized_block_authorities_set_id,
179
2
                    finalized_scheduled_change,
180
2
                    finalized_triggered_authorities,
181
2
                } => Finality::Grandpa {
182
2
                    after_finalized_block_authorities_set_id,
183
2
                    finalized_scheduled_change: finalized_scheduled_change
184
2
                        .map(|(n, l)| (n, l.into_iter().collect())),
185
2
                    finalized_triggered_authorities: finalized_triggered_authorities
186
2
                        .into_iter()
187
2
                        .collect(),
188
2
                },
189
            },
190
2
            finalized_consensus: match chain_information.consensus {
191
                chain_information::ChainInformationConsensus::Unknown => {
192
0
                    FinalizedConsensus::Unknown
193
                }
194
                chain_information::ChainInformationConsensus::Aura {
195
2
                    finalized_authorities_list,
196
2
                    slot_duration,
197
2
                } => FinalizedConsensus::Aura {
198
2
                    authorities_list: Arc::new(finalized_authorities_list),
199
2
                    slot_duration,
200
2
                },
201
                chain_information::ChainInformationConsensus::Babe {
202
0
                    finalized_block_epoch_information,
203
0
                    finalized_next_epoch_transition,
204
0
                    slots_per_epoch,
205
0
                } => FinalizedConsensus::Babe {
206
0
                    slots_per_epoch,
207
0
                    block_epoch_information: finalized_block_epoch_information.map(Arc::from),
208
0
                    next_epoch_transition: Arc::from(finalized_next_epoch_transition),
209
0
                },
210
            },
211
2
            finalized_best_score: BestScore {
212
2
                num_primary_slots: 0,
213
2
                num_secondary_slots: 0,
214
2
                insertion_counter: 0,
215
2
            },
216
2
            blocks: fork_tree::ForkTree::with_capacity(config.blocks_capacity),
217
2
            blocks_insertion_counter: 1,
218
2
            blocks_by_hash: hashbrown::HashMap::with_capacity_and_hasher(
219
2
                config.blocks_capacity,
220
2
                Default::default(),
221
2
            ),
222
2
            blocks_by_best_score: BTreeMap::new(),
223
2
            blocks_trigger_gp_change: BTreeSet::new(),
224
2
            block_number_bytes: config.block_number_bytes,
225
2
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
226
2
        }
227
2
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3newCscDgN54JpMGG_6author
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE3newCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
163
19
    pub fn new(config: Config) -> Self {
164
19
        let chain_information: chain_information::ChainInformation =
165
19
            config.chain_information.into();
166
19
167
19
        NonFinalizedTree {
168
19
            finalized_block_number: chain_information.finalized_block_header.number,
169
19
            finalized_block_hash: chain_information
170
19
                .finalized_block_header
171
19
                .hash(config.block_number_bytes),
172
19
            finalized_block_header: chain_information
173
19
                .finalized_block_header
174
19
                .scale_encoding_vec(config.block_number_bytes),
175
19
            finality: match chain_information.finality {
176
0
                chain_information::ChainInformationFinality::Outsourced => Finality::Outsourced,
177
                chain_information::ChainInformationFinality::Grandpa {
178
19
                    after_finalized_block_authorities_set_id,
179
19
                    finalized_scheduled_change,
180
19
                    finalized_triggered_authorities,
181
19
                } => Finality::Grandpa {
182
19
                    after_finalized_block_authorities_set_id,
183
19
                    finalized_scheduled_change: finalized_scheduled_change
184
19
                        .map(|(n, l)| (n, l.into_iter().collect())),
185
19
                    finalized_triggered_authorities: finalized_triggered_authorities
186
19
                        .into_iter()
187
19
                        .collect(),
188
19
                },
189
            },
190
19
            finalized_consensus: match chain_information.consensus {
191
                chain_information::ChainInformationConsensus::Unknown => {
192
0
                    FinalizedConsensus::Unknown
193
                }
194
                chain_information::ChainInformationConsensus::Aura {
195
19
                    finalized_authorities_list,
196
19
                    slot_duration,
197
19
                } => FinalizedConsensus::Aura {
198
19
                    authorities_list: Arc::new(finalized_authorities_list),
199
19
                    slot_duration,
200
19
                },
201
                chain_information::ChainInformationConsensus::Babe {
202
0
                    finalized_block_epoch_information,
203
0
                    finalized_next_epoch_transition,
204
0
                    slots_per_epoch,
205
0
                } => FinalizedConsensus::Babe {
206
0
                    slots_per_epoch,
207
0
                    block_epoch_information: finalized_block_epoch_information.map(Arc::from),
208
0
                    next_epoch_transition: Arc::from(finalized_next_epoch_transition),
209
0
                },
210
            },
211
19
            finalized_best_score: BestScore {
212
19
                num_primary_slots: 0,
213
19
                num_secondary_slots: 0,
214
19
                insertion_counter: 0,
215
19
            },
216
19
            blocks: fork_tree::ForkTree::with_capacity(config.blocks_capacity),
217
19
            blocks_insertion_counter: 1,
218
19
            blocks_by_hash: hashbrown::HashMap::with_capacity_and_hasher(
219
19
                config.blocks_capacity,
220
19
                Default::default(),
221
19
            ),
222
19
            blocks_by_best_score: BTreeMap::new(),
223
19
            blocks_trigger_gp_change: BTreeSet::new(),
224
19
            block_number_bytes: config.block_number_bytes,
225
19
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
226
19
        }
227
19
    }
228
229
    /// Removes all non-finalized blocks from the tree.
230
0
    pub fn clear(&mut self) {
231
0
        self.blocks.clear();
232
0
        self.blocks_by_hash.clear();
233
0
        self.blocks_by_best_score.clear();
234
0
        self.blocks_trigger_gp_change.clear();
235
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE5clearB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE5clearB6_
236
237
    /// Returns true if there isn't any non-finalized block in the chain.
238
0
    pub fn is_empty(&self) -> bool {
239
0
        self.blocks.is_empty()
240
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE8is_emptyB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE8is_emptyB6_
241
242
    /// Returns the number of non-finalized blocks in the chain.
243
0
    pub fn len(&self) -> usize {
244
0
        self.blocks.len()
245
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE3lenB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE3lenB6_
246
247
    /// Returns the header of all known non-finalized blocks in the chain without any specific
248
    /// order.
249
0
    pub fn iter_unordered(&'_ self) -> impl Iterator<Item = header::HeaderRef<'_>> + '_ {
250
0
        self.blocks
251
0
            .iter_unordered()
252
0
            .map(move |(_, b)| header::decode(&b.header, self.block_number_bytes).unwrap())
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE14iter_unordered0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE14iter_unordered0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE14iter_unordered0B8_
253
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE14iter_unorderedB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE14iter_unorderedCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE14iter_unorderedB6_
254
255
    /// Returns the header of all known non-finalized blocks in the chain.
256
    ///
257
    /// The returned items are guaranteed to be in an order in which the parents are found before
258
    /// their children.
259
0
    pub fn iter_ancestry_order(&'_ self) -> impl Iterator<Item = header::HeaderRef<'_>> + '_ {
260
0
        self.blocks
261
0
            .iter_ancestry_order()
262
0
            .map(move |(_, b)| header::decode(&b.header, self.block_number_bytes).unwrap())
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE19iter_ancestry_order0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE19iter_ancestry_order0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE19iter_ancestry_order0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_order0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_order0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_order0CsibGXYHQB8Ea_25json_rpc_general_requests
263
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE19iter_ancestry_orderB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE19iter_ancestry_orderCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE19iter_ancestry_orderB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_orderCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_orderCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE19iter_ancestry_orderCsibGXYHQB8Ea_25json_rpc_general_requests
264
265
    /// Reserves additional capacity for at least `additional` new blocks without allocating.
266
0
    pub fn reserve(&mut self, additional: usize) {
267
0
        self.blocks_by_hash.reserve(additional);
268
0
        self.blocks.reserve(additional);
269
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE7reserveB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE7reserveB6_
270
271
    /// Shrink the capacity of the chain as much as possible.
272
0
    pub fn shrink_to_fit(&mut self) {
273
0
        self.blocks_by_hash.shrink_to_fit();
274
0
        self.blocks.shrink_to_fit();
275
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE13shrink_to_fitB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE13shrink_to_fitB6_
276
277
    /// Returns the value that was initially passed in [`Config::block_number_bytes`].
278
0
    pub fn block_number_bytes(&self) -> usize {
279
0
        self.block_number_bytes
280
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE18block_number_bytesB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE18block_number_bytesCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE18block_number_bytesB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE18block_number_bytesCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE18block_number_bytesCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE18block_number_bytesCsibGXYHQB8Ea_25json_rpc_general_requests
281
282
    /// Builds a [`chain_information::ChainInformationRef`] struct that might later be used to
283
    /// build a new [`NonFinalizedTree`].
284
0
    pub fn as_chain_information(&self) -> chain_information::ValidChainInformationRef {
285
0
        let attempt = chain_information::ChainInformationRef {
286
0
            finalized_block_header: header::decode(
287
0
                &self.finalized_block_header,
288
0
                self.block_number_bytes,
289
0
            )
290
0
            .unwrap(),
291
0
            consensus: match &self.finalized_consensus {
292
                FinalizedConsensus::Unknown => {
293
0
                    chain_information::ChainInformationConsensusRef::Unknown
294
                }
295
                FinalizedConsensus::Aura {
296
0
                    authorities_list,
297
0
                    slot_duration,
298
0
                } => chain_information::ChainInformationConsensusRef::Aura {
299
0
                    finalized_authorities_list: header::AuraAuthoritiesIter::from_slice(
300
0
                        authorities_list,
301
0
                    ),
302
0
                    slot_duration: *slot_duration,
303
0
                },
304
                FinalizedConsensus::Babe {
305
0
                    block_epoch_information,
306
0
                    next_epoch_transition,
307
0
                    slots_per_epoch,
308
0
                } => chain_information::ChainInformationConsensusRef::Babe {
309
0
                    slots_per_epoch: *slots_per_epoch,
310
0
                    finalized_block_epoch_information: block_epoch_information
311
0
                        .as_ref()
312
0
                        .map(|info| From::from(&**info)),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20as_chain_information0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE20as_chain_information0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20as_chain_information0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_information0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_information0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_information0CsibGXYHQB8Ea_25json_rpc_general_requests
313
0
                    finalized_next_epoch_transition: next_epoch_transition.as_ref().into(),
314
0
                },
315
            },
316
0
            finality: match &self.finality {
317
0
                Finality::Outsourced => chain_information::ChainInformationFinalityRef::Outsourced,
318
                Finality::Grandpa {
319
0
                    after_finalized_block_authorities_set_id,
320
0
                    finalized_triggered_authorities,
321
0
                    finalized_scheduled_change,
322
0
                } => chain_information::ChainInformationFinalityRef::Grandpa {
323
0
                    after_finalized_block_authorities_set_id:
324
0
                        *after_finalized_block_authorities_set_id,
325
0
                    finalized_scheduled_change: finalized_scheduled_change
326
0
                        .as_ref()
327
0
                        .map(|(n, l)| (*n, &l[..])),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20as_chain_informations_0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE20as_chain_informations_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20as_chain_informations_0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informations_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informations_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informations_0CsibGXYHQB8Ea_25json_rpc_general_requests
328
0
                    finalized_triggered_authorities,
329
0
                },
330
            },
331
        };
332
333
0
        chain_information::ValidChainInformationRef::try_from(attempt).unwrap()
334
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20as_chain_informationB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE20as_chain_informationCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20as_chain_informationB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informationCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informationCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20as_chain_informationCsibGXYHQB8Ea_25json_rpc_general_requests
335
336
    /// Returns the header of the latest finalized block.
337
0
    pub fn finalized_block_header(&self) -> &[u8] {
338
0
        &self.finalized_block_header
339
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE22finalized_block_headerB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE22finalized_block_headerCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE22finalized_block_headerB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_headerCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_headerCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_headerCsibGXYHQB8Ea_25json_rpc_general_requests
340
341
    /// Returns the hash of the latest finalized block.
342
0
    pub fn finalized_block_hash(&self) -> &[u8; 32] {
343
0
        &self.finalized_block_hash
344
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20finalized_block_hashB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE20finalized_block_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20finalized_block_hashB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20finalized_block_hashCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20finalized_block_hashCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE20finalized_block_hashCsibGXYHQB8Ea_25json_rpc_general_requests
345
346
    /// Returns the height of the latest finalized block.
347
21
    pub fn finalized_block_height(&self) -> u64 {
348
21
        self.finalized_block_number
349
21
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE22finalized_block_heightB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE22finalized_block_heightCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE22finalized_block_heightB6_
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_heightCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
347
2
    pub fn finalized_block_height(&self) -> u64 {
348
2
        self.finalized_block_number
349
2
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_heightCscDgN54JpMGG_6author
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE22finalized_block_heightCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
347
19
    pub fn finalized_block_height(&self) -> u64 {
348
19
        self.finalized_block_number
349
19
    }
350
351
    /// Returns the header of the best block.
352
0
    pub fn best_block_header(&self) -> &[u8] {
353
0
        if let Some((_, index)) = self.blocks_by_best_score.last_key_value() {
354
0
            &self.blocks.get(*index).unwrap().header
355
        } else {
356
0
            &self.finalized_block_header
357
        }
358
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE17best_block_headerB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE17best_block_headerB6_
359
360
    /// Returns the hash of the best block.
361
21
    pub fn best_block_hash(&self) -> &[u8; 32] {
362
21
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
363
0
            &self.blocks.get(*index).unwrap().hash
364
        } else {
365
21
            &self.finalized_block_hash
366
        }
367
21
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE15best_block_hashB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE15best_block_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE15best_block_hashB6_
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE15best_block_hashCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
361
2
    pub fn best_block_hash(&self) -> &[u8; 32] {
362
2
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
363
0
            &self.blocks.get(*index).unwrap().hash
364
        } else {
365
2
            &self.finalized_block_hash
366
        }
367
2
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE15best_block_hashCscDgN54JpMGG_6author
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE15best_block_hashCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
361
19
    pub fn best_block_hash(&self) -> &[u8; 32] {
362
19
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
363
0
            &self.blocks.get(*index).unwrap().hash
364
        } else {
365
19
            &self.finalized_block_hash
366
        }
367
19
    }
368
369
    /// Returns the height of the best block.
370
21
    pub fn best_block_height(&self) -> u64 {
371
21
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
372
0
            self.blocks.get(*index).unwrap().number
373
        } else {
374
21
            self.finalized_block_number
375
        }
376
21
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE17best_block_heightB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE17best_block_heightCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE17best_block_heightB6_
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE17best_block_heightCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
370
2
    pub fn best_block_height(&self) -> u64 {
371
2
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
372
0
            self.blocks.get(*index).unwrap().number
373
        } else {
374
2
            self.finalized_block_number
375
        }
376
2
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE17best_block_heightCscDgN54JpMGG_6author
_RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE17best_block_heightCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
370
19
    pub fn best_block_height(&self) -> u64 {
371
19
        if let Some((_, 
index0
)) = self.blocks_by_best_score.last_key_value() {
372
0
            self.blocks.get(*index).unwrap().number
373
        } else {
374
19
            self.finalized_block_number
375
        }
376
19
    }
377
378
    /// Returns consensus information about the current best block of the chain.
379
0
    pub fn best_block_consensus(&self) -> chain_information::ChainInformationConsensusRef {
380
0
        match (
381
0
            &self.finalized_consensus,
382
0
            self.blocks_by_best_score
383
0
                .last_key_value()
384
0
                .map(|(_, idx)| &self.blocks.get(*idx).unwrap().consensus),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensus0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensus0B8_
385
        ) {
386
            (FinalizedConsensus::Unknown, _) => {
387
0
                chain_information::ChainInformationConsensusRef::Unknown
388
            }
389
            (
390
                FinalizedConsensus::Aura {
391
0
                    authorities_list,
392
0
                    slot_duration,
393
                },
394
                None,
395
            )
396
            | (
397
0
                FinalizedConsensus::Aura { slot_duration, .. },
398
0
                Some(BlockConsensus::Aura { authorities_list }),
399
0
            ) => chain_information::ChainInformationConsensusRef::Aura {
400
0
                finalized_authorities_list: header::AuraAuthoritiesIter::from_slice(
401
0
                    authorities_list,
402
0
                ),
403
0
                slot_duration: *slot_duration,
404
0
            },
405
            (
406
                FinalizedConsensus::Babe {
407
0
                    block_epoch_information,
408
0
                    next_epoch_transition,
409
0
                    slots_per_epoch,
410
0
                },
411
0
                None,
412
0
            ) => chain_information::ChainInformationConsensusRef::Babe {
413
0
                slots_per_epoch: *slots_per_epoch,
414
0
                finalized_block_epoch_information: block_epoch_information
415
0
                    .as_ref()
416
0
                    .map(|info| From::from(&**info)),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensuss_0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensuss_0B8_
417
0
                finalized_next_epoch_transition: next_epoch_transition.as_ref().into(),
418
0
            },
419
            (
420
                FinalizedConsensus::Babe {
421
0
                    slots_per_epoch, ..
422
0
                },
423
0
                Some(BlockConsensus::Babe {
424
0
                    current_epoch,
425
0
                    next_epoch,
426
0
                }),
427
0
            ) => chain_information::ChainInformationConsensusRef::Babe {
428
0
                slots_per_epoch: *slots_per_epoch,
429
0
                finalized_block_epoch_information: current_epoch
430
0
                    .as_ref()
431
0
                    .map(|info| From::from(&**info)),
Unexecuted instantiation: _RNCNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensuss0_0B8_
Unexecuted instantiation: _RNCNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB4_16NonFinalizedTreepE20best_block_consensuss0_0B8_
432
0
                finalized_next_epoch_transition: next_epoch.as_ref().into(),
433
0
            },
434
435
            // Any mismatch of consensus engine between the finalized and best block is not
436
            // supported at the moment.
437
0
            _ => unreachable!(),
438
        }
439
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20best_block_consensusB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE20best_block_consensusB6_
440
441
    /// Returns true if the block with the given hash is in the [`NonFinalizedTree`].
442
0
    pub fn contains_non_finalized_block(&self, hash: &[u8; 32]) -> bool {
443
0
        self.blocks_by_hash.contains_key(hash)
444
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE28contains_non_finalized_blockB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE28contains_non_finalized_blockCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE28contains_non_finalized_blockB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE28contains_non_finalized_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE28contains_non_finalized_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE28contains_non_finalized_blockCsibGXYHQB8Ea_25json_rpc_general_requests
445
446
    /// Gives access to the user data of a block stored by the [`NonFinalizedTree`], identified
447
    /// by its hash.
448
    ///
449
    /// Returns `None` if the block can't be found.
450
0
    pub fn non_finalized_block_user_data(&self, hash: &[u8; 32]) -> Option<&T> {
451
0
        let node_index = *self.blocks_by_hash.get(hash)?;
452
0
        Some(&self.blocks.get(node_index).unwrap().user_data)
453
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE29non_finalized_block_user_dataB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE29non_finalized_block_user_dataB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE29non_finalized_block_user_dataCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE29non_finalized_block_user_dataCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE29non_finalized_block_user_dataCsibGXYHQB8Ea_25json_rpc_general_requests
454
455
    /// Gives access to the user data of a block stored by the [`NonFinalizedTree`], identified
456
    /// by its hash.
457
    ///
458
    /// Returns `None` if the block can't be found.
459
0
    pub fn non_finalized_block_user_data_mut(&mut self, hash: &[u8; 32]) -> Option<&mut T> {
460
0
        let node_index = *self.blocks_by_hash.get(hash)?;
461
0
        Some(&mut self.blocks.get_mut(node_index).unwrap().user_data)
462
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE33non_finalized_block_user_data_mutB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEE33non_finalized_block_user_data_mutCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE33non_finalized_block_user_data_mutB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE33non_finalized_block_user_data_mutCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE33non_finalized_block_user_data_mutCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEE33non_finalized_block_user_data_mutCsibGXYHQB8Ea_25json_rpc_general_requests
463
464
    /// Returns the SCALE-encoded header of a block stored by the [`NonFinalizedTree`], identified
465
    /// by its hash.
466
    ///
467
    /// Returns `None` if the block can't be found.
468
0
    pub fn non_finalized_block_header(&self, hash: &[u8; 32]) -> Option<&[u8]> {
469
0
        let node_index = *self.blocks_by_hash.get(hash)?;
470
0
        Some(&self.blocks.get(node_index).unwrap().header)
471
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE26non_finalized_block_headerB6_
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB2_16NonFinalizedTreepE26non_finalized_block_headerB6_
472
}
473
474
impl<T> fmt::Debug for NonFinalizedTree<T>
475
where
476
    T: fmt::Debug,
477
{
478
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
479
0
        struct Blocks<'a, T>(&'a NonFinalizedTree<T>);
480
0
        impl<'a, T> fmt::Debug for Blocks<'a, T>
481
0
        where
482
0
            T: fmt::Debug,
483
0
        {
484
0
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
485
0
                f.debug_map()
486
0
                    .entries(
487
0
                        self.0
488
0
                            .blocks
489
0
                            .iter_unordered()
490
0
                            .map(|(_, v)| (format!("0x{}", hex::encode(v.hash)), &v.user_data)),
Unexecuted instantiation: _RNCNvXININvXs_NtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtBc_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0pEINtB7_6BlockspEB1k_3fmt0Bg_
Unexecuted instantiation: _RNCNvXININvXs_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtBc_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0pEINtB7_6BlockspEB1l_3fmt0Bg_
491
0
                    )
492
0
                    .finish()
493
0
            }
Unexecuted instantiation: _RNvXININvXs_NtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeINtBa_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0pEINtB5_6BlockspEB1i_3fmtBe_
Unexecuted instantiation: _RNvXININvXs_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtBa_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0pEINtB5_6BlockspEB1j_3fmtBe_
494
0
        }
495
0
496
0
        f.debug_struct("NonFinalizedTree")
497
0
            .field(
498
0
                "finalized_block_hash",
499
0
                &format!(
500
0
                    "0x{}",
501
0
                    hex::encode(header::hash_from_scale_encoded_header(
502
0
                        &self.finalized_block_header
503
0
                    ))
504
0
                ),
505
0
            )
506
0
            .field("non_finalized_blocks", &Blocks(self))
507
0
            .finish()
508
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees_0pEINtB5_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees_0pEINtB5_16NonFinalizedTreepENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_
509
}
510
511
impl<'a, T> ops::Index<&'a [u8; 32]> for NonFinalizedTree<T> {
512
    type Output = T;
513
514
    #[track_caller]
515
0
    fn index(&self, block_hash: &'a [u8; 32]) -> &T {
516
0
        let node_index = self
517
0
            .blocks_by_hash
518
0
            .get(block_hash)
519
0
            .unwrap_or_else(|| panic!("invalid block hash"));
Unexecuted instantiation: _RNCNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees0_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5index0Bb_
Unexecuted instantiation: _RNCNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees0_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5index0Bb_
520
0
        &self
521
0
            .blocks
522
0
            .get(*node_index)
523
0
            .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees0_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5indexs_0Bb_
Unexecuted instantiation: _RNCNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees0_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5indexs_0Bb_
524
0
            .user_data
525
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees0_0pEINtB5_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5indexB9_
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees0_0pEINtB5_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexRAhj20_E5indexB9_
526
}
527
528
impl<'a, T> ops::IndexMut<&'a [u8; 32]> for NonFinalizedTree<T> {
529
    #[track_caller]
530
0
    fn index_mut(&mut self, block_hash: &'a [u8; 32]) -> &mut T {
531
0
        let node_index = self
532
0
            .blocks_by_hash
533
0
            .get(block_hash)
534
0
            .unwrap_or_else(|| panic!("invalid block hash"));
Unexecuted instantiation: _RNCNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees1_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_mut0Bb_
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_mut0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees1_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_mut0Bb_
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_mut0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_mut0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_mut0CsibGXYHQB8Ea_25json_rpc_general_requests
535
0
        &mut self
536
0
            .blocks
537
0
            .get_mut(*node_index)
538
0
            .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees1_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_muts_0Bb_
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_muts_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees1_0pEINtB7_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_muts_0Bb_
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_muts_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_muts_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB7_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1j_3ops5index8IndexMutRAhj20_E9index_muts_0CsibGXYHQB8Ea_25json_rpc_general_requests
539
0
            .user_data
540
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot5chain11blocks_trees1_0pEINtB5_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_mutB9_
Unexecuted instantiation: _RNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB5_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionuEEINtNtNtB1h_3ops5index8IndexMutRAhj20_E9index_mutCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot5chain11blocks_trees1_0pEINtB5_16NonFinalizedTreepEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutRAhj20_E9index_mutB9_
Unexecuted instantiation: _RNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB5_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1h_3ops5index8IndexMutRAhj20_E9index_mutCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB5_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1h_3ops5index8IndexMutRAhj20_E9index_mutCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvXs1_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeINtB5_16NonFinalizedTreeINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEINtNtNtB1h_3ops5index8IndexMutRAhj20_E9index_mutCsibGXYHQB8Ea_25json_rpc_general_requests
541
}
542
543
/// State of the consensus of the finalized block.
544
#[derive(Clone)]
545
enum FinalizedConsensus {
546
    Unknown,
547
    Aura {
548
        /// List of authorities that must sign the child of the finalized block.
549
        authorities_list: Arc<Vec<header::AuraAuthority>>,
550
551
        /// Duration, in milliseconds, of a slot.
552
        slot_duration: NonZeroU64,
553
    },
554
    Babe {
555
        /// See [`chain_information::ChainInformationConsensus::Babe::finalized_block_epoch_information`].
556
        block_epoch_information: Option<Arc<chain_information::BabeEpochInformation>>,
557
558
        /// See [`chain_information::ChainInformationConsensus::Babe::finalized_next_epoch_transition`].
559
        next_epoch_transition: Arc<chain_information::BabeEpochInformation>,
560
561
        /// See [`chain_information::ChainInformationConsensus::Babe::slots_per_epoch`].
562
        slots_per_epoch: NonZeroU64,
563
    },
564
}
565
566
/// State of the chain finality engine.
567
#[derive(Clone)]
568
enum Finality {
569
    Outsourced,
570
    Grandpa {
571
        /// Grandpa authorities set ID of the block right after the finalized block.
572
        after_finalized_block_authorities_set_id: u64,
573
574
        /// List of GrandPa authorities that need to finalize the block right after the finalized
575
        /// block.
576
        finalized_triggered_authorities: Arc<[header::GrandpaAuthority]>,
577
578
        /// Change in the GrandPa authorities list that has been scheduled by a block that is already
579
        /// finalized but not triggered yet. These changes will for sure happen. Contains the block
580
        /// number where the changes are to be triggered. The descendants of the block with that
581
        /// number need to be finalized with the new authorities.
582
        finalized_scheduled_change: Option<(u64, Arc<[header::GrandpaAuthority]>)>,
583
    },
584
}
585
586
struct Block<T> {
587
    /// Header of the block.
588
    ///
589
    /// Guaranteed to be valid.
590
    header: Vec<u8>,
591
    /// Cache of the hash of the block. Always equal to the hash of the header stored in this
592
    /// same struct.
593
    hash: [u8; 32],
594
    /// Number contained in [`Block::header`].
595
    number: u64,
596
    /// Changes to the consensus made by the block.
597
    consensus: BlockConsensus,
598
    /// Information about finality attached to each block.
599
    finality: BlockFinality,
600
    /// Score of the block when it comes to determining which block is the best in the chain.
601
    best_score: BestScore,
602
    /// Opaque data decided by the user.
603
    user_data: T,
604
}
605
606
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
607
struct BestScore {
608
    num_primary_slots: u64,
609
    num_secondary_slots: u64,
610
    insertion_counter: u128,
611
}
612
613
impl cmp::PartialOrd for BestScore {
614
4
    fn partial_cmp(&self, other: &BestScore) -> Option<cmp::Ordering> {
615
4
        Some(self.cmp(other))
616
4
    }
_RNvXs2_NtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeNtB5_9BestScoreNtNtCsaYZPK01V26L_4core3cmp10PartialOrd11partial_cmp
Line
Count
Source
614
4
    fn partial_cmp(&self, other: &BestScore) -> Option<cmp::Ordering> {
615
4
        Some(self.cmp(other))
616
4
    }
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeNtB5_9BestScoreNtNtCsaYZPK01V26L_4core3cmp10PartialOrd11partial_cmp
617
}
618
619
impl cmp::Ord for BestScore {
620
6
    fn cmp(&self, other: &Self) -> cmp::Ordering {
621
6
        match self.num_primary_slots.cmp(&other.num_primary_slots) {
622
            cmp::Ordering::Equal => {
623
3
                match self.num_secondary_slots.cmp(&other.num_secondary_slots) {
624
                    cmp::Ordering::Equal => {
625
                        // Note the inversion.
626
0
                        other.insertion_counter.cmp(&self.insertion_counter)
627
                    }
628
3
                    other => other,
629
                }
630
            }
631
3
            other => other,
632
        }
633
6
    }
_RNvXs3_NtNtCsN16ciHI6Qf_7smoldot5chain11blocks_treeNtB5_9BestScoreNtNtCsaYZPK01V26L_4core3cmp3Ord3cmp
Line
Count
Source
620
6
    fn cmp(&self, other: &Self) -> cmp::Ordering {
621
6
        match self.num_primary_slots.cmp(&other.num_primary_slots) {
622
            cmp::Ordering::Equal => {
623
3
                match self.num_secondary_slots.cmp(&other.num_secondary_slots) {
624
                    cmp::Ordering::Equal => {
625
                        // Note the inversion.
626
0
                        other.insertion_counter.cmp(&self.insertion_counter)
627
                    }
628
3
                    other => other,
629
                }
630
            }
631
3
            other => other,
632
        }
633
6
    }
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot5chain11blocks_treeNtB5_9BestScoreNtNtCsaYZPK01V26L_4core3cmp3Ord3cmp
634
}
635
636
/// Changes to the consensus made by a block.
637
#[derive(Clone)]
638
enum BlockConsensus {
639
    Aura {
640
        /// If `Some`, list of authorities that must verify the child of this block.
641
        /// This can be a clone of the value of the parent, a clone of
642
        /// [`FinalizedConsensus::Aura::authorities_list`], or a new value if the block modifies
643
        /// this list.
644
        authorities_list: Arc<Vec<header::AuraAuthority>>,
645
    },
646
    Babe {
647
        /// Information about the Babe epoch the block belongs to. `None` if the block belongs to
648
        /// epoch #0.
649
        current_epoch: Option<Arc<chain_information::BabeEpochInformation>>,
650
        /// Information about the Babe epoch the block belongs to.
651
        next_epoch: Arc<chain_information::BabeEpochInformation>,
652
    },
653
}
654
655
/// Information about finality attached to each block.
656
#[derive(Clone)]
657
enum BlockFinality {
658
    Outsourced,
659
    Grandpa {
660
        /// If a block A triggers a change in the list of Grandpa authorities, and a block B is
661
        /// a descendant of A, then B cannot be finalized before A is.
662
        /// This field contains the height of A, if it is known. Contains `None` if A is the
663
        /// current finalized block or below, and thus doesn't matter anyway.
664
        ///
665
        /// If `Some`, the value must always be strictly inferior to the attached block's number.
666
        prev_auth_change_trigger_number: Option<u64>,
667
668
        /// Authorities set id that must be used to finalize the blocks that descend from this
669
        /// one.
670
        ///
671
        /// If `triggers_change` is `false`, then this field must be equal to the parent block's.
672
        after_block_authorities_set_id: u64,
673
674
        /// `true` if this block triggers a change in the list of Grandpa authorities.
675
        triggers_change: bool,
676
677
        /// List of GrandPa authorities that need to finalize the block right after this block.
678
        ///
679
        /// If `triggers_change` is `false`, then this field must be equal to the parent block's.
680
        triggered_authorities: Arc<[header::GrandpaAuthority]>,
681
682
        /// A change in the GrandPa authorities list that has been scheduled for the block with the
683
        /// given number that descends from this one. The block with that number will trigger the
684
        /// new authorities, meaning that its descendants will need to be finalized with the new
685
        /// authorities.
686
        ///
687
        /// If `Some`, the value must always be strictly superior to the attached block's number.
688
        scheduled_change: Option<(u64, Arc<[header::GrandpaAuthority]>)>,
689
    },
690
}