/__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 | | } |