/__w/smoldot/smoldot/repo/lib/src/sync/all_forks/disjoint.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Substrate-lite |
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 | | //! Collection of "disjoint" blocks, in other words blocks whose existence is known but which |
19 | | //! can't be verified yet. |
20 | | //! |
21 | | //! > **Example**: The local node knows about block 5. A peer announces block 7. Since the local |
22 | | //! > node doesn't know block 6, it has to store block 7 for later, then download |
23 | | //! > block 6. The container in this module is where block 7 is temporarily stored. |
24 | | //! |
25 | | //! Each block stored in this collection has the following properties associated to it: |
26 | | //! |
27 | | //! - A height. |
28 | | //! - A hash. |
29 | | //! - An optional parent block hash. |
30 | | //! - Whether the block is known to be bad. |
31 | | //! - A opaque user data decided by the user of type `TBl`. |
32 | | //! |
33 | | //! This data structure is only able to link parent and children together if the heights are |
34 | | //! linearly increasing. For example, if block A is the parent of block B, then the height of |
35 | | //! block B must be equal to the height of block A plus one. Otherwise, this data structure will |
36 | | //! not be able to detect the parent-child relationship. |
37 | | //! |
38 | | //! If a block is marked as bad, all its children (i.e. other blocks in the collection whose |
39 | | //! parent hash is the bad block) are automatically marked as bad as well. This process is |
40 | | //! recursive, such that not only direct children but all descendants of a bad block are |
41 | | //! automatically marked as bad. |
42 | | //! |
43 | | |
44 | | #![allow(dead_code)] // TODO: remove this after `all.rs` implements full node; right now many methods here are useless because expected to be used only for full node code |
45 | | |
46 | | use alloc::collections::{btree_map::Entry, BTreeMap}; |
47 | | use core::{fmt, iter, mem}; |
48 | | |
49 | | /// Collection of pending blocks. |
50 | | pub struct DisjointBlocks<TBl> { |
51 | | /// All blocks in the collection. Keys are the block height and hash. |
52 | | blocks: BTreeMap<(u64, [u8; 32]), Block<TBl>>, |
53 | | } |
54 | | |
55 | | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
56 | | struct Block<TBl> { |
57 | | parent_hash: Option<[u8; 32]>, |
58 | | bad: bool, |
59 | | user_data: TBl, |
60 | | } |
61 | | |
62 | | impl<TBl> DisjointBlocks<TBl> { |
63 | | /// Initializes a new empty collection of blocks. |
64 | 5 | pub fn new() -> Self { |
65 | 5 | Self::with_capacity(0) |
66 | 5 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE3newB8_ Line | Count | Source | 64 | 5 | pub fn new() -> Self { | 65 | 5 | Self::with_capacity(0) | 66 | 5 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE3newB8_ |
67 | | |
68 | | /// Initializes a new collection of blocks with the given capacity. |
69 | 26 | pub fn with_capacity(_capacity: usize) -> Self { |
70 | 26 | DisjointBlocks { |
71 | 26 | blocks: BTreeMap::default(), |
72 | 26 | } |
73 | 26 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE13with_capacityB8_ Line | Count | Source | 69 | 5 | pub fn with_capacity(_capacity: usize) -> Self { | 70 | 5 | DisjointBlocks { | 71 | 5 | blocks: BTreeMap::default(), | 72 | 5 | } | 73 | 5 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13with_capacityCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13with_capacityB8_ _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13with_capacityCsiLzmwikkc22_14json_rpc_basic Line | Count | Source | 69 | 2 | pub fn with_capacity(_capacity: usize) -> Self { | 70 | 2 | DisjointBlocks { | 71 | 2 | blocks: BTreeMap::default(), | 72 | 2 | } | 73 | 2 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13with_capacityCscDgN54JpMGG_6author _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13with_capacityCsibGXYHQB8Ea_25json_rpc_general_requests Line | Count | Source | 69 | 19 | pub fn with_capacity(_capacity: usize) -> Self { | 70 | 19 | DisjointBlocks { | 71 | 19 | blocks: BTreeMap::default(), | 72 | 19 | } | 73 | 19 | } |
|
74 | | |
75 | | /// Returns `true` if this data structure doesn't contain any block. |
76 | 0 | pub fn is_empty(&self) -> bool { |
77 | 0 | self.blocks.is_empty() |
78 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8is_emptyB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8is_emptyB8_ |
79 | | |
80 | | /// Returns the number of blocks stored in the data structure. |
81 | 0 | pub fn len(&self) -> usize { |
82 | 0 | self.blocks.len() |
83 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE3lenB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE3lenCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE3lenB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE3lenCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE3lenCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE3lenCsibGXYHQB8Ea_25json_rpc_general_requests |
84 | | |
85 | | /// Returns the list of blocks in the collection. |
86 | 43 | pub fn iter(&'_ self) -> impl Iterator<Item = (u64, &[u8; 32], &'_ TBl)> + '_ { |
87 | 43 | self.blocks |
88 | 43 | .iter() |
89 | 43 | .map(|((he, ha), bl)| (*he, ha, &bl.user_data)0 ) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE4iter0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE4iter0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE4iter0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iter0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iter0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iter0CsibGXYHQB8Ea_25json_rpc_general_requests |
90 | 43 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE4iterB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE4iterCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE4iterB8_ _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iterCsiLzmwikkc22_14json_rpc_basic Line | Count | Source | 86 | 4 | pub fn iter(&'_ self) -> impl Iterator<Item = (u64, &[u8; 32], &'_ TBl)> + '_ { | 87 | 4 | self.blocks | 88 | 4 | .iter() | 89 | 4 | .map(|((he, ha), bl)| (*he, ha, &bl.user_data)) | 90 | 4 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iterCscDgN54JpMGG_6author _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE4iterCsibGXYHQB8Ea_25json_rpc_general_requests Line | Count | Source | 86 | 39 | pub fn iter(&'_ self) -> impl Iterator<Item = (u64, &[u8; 32], &'_ TBl)> + '_ { | 87 | 39 | self.blocks | 88 | 39 | .iter() | 89 | 39 | .map(|((he, ha), bl)| (*he, ha, &bl.user_data)) | 90 | 39 | } |
|
91 | | |
92 | | /// Returns `true` if the block with the given height and hash is in the collection. |
93 | 0 | pub fn contains(&self, height: u64, hash: &[u8; 32]) -> bool { |
94 | 0 | self.blocks.contains_key(&(height, *hash)) |
95 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8containsB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE8containsCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8containsB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE8containsCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE8containsCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE8containsCsibGXYHQB8Ea_25json_rpc_general_requests |
96 | | |
97 | | /// Inserts the block in the collection, passing a user data. |
98 | | /// |
99 | | /// If a `parent_hash` is passed, and the parent is known to be bad, the newly-inserted block |
100 | | /// is immediately marked as bad as well. |
101 | | /// |
102 | | /// Returns the previous user data associated to this block, if any. |
103 | | /// |
104 | | /// # Panic |
105 | | /// |
106 | | /// Panics if the block was already in the collection but with a different `parent_hash` than |
107 | | /// provided. |
108 | | /// |
109 | 15 | pub fn insert( |
110 | 15 | &mut self, |
111 | 15 | height: u64, |
112 | 15 | hash: [u8; 32], |
113 | 15 | parent_hash: Option<[u8; 32]>, |
114 | 15 | user_data: TBl, |
115 | 15 | ) -> Option<TBl> { |
116 | 15 | let previous_user_data = match self.blocks.entry((height, hash)) { |
117 | 2 | Entry::Occupied(entry) => { |
118 | 2 | let entry = entry.into_mut(); |
119 | 2 | |
120 | 2 | match (parent_hash, &mut entry.parent_hash) { |
121 | 1 | (Some(parent_hash), &mut Some(ph0 )) if ph != parent_hash => panic!()0 , |
122 | 2 | _ => {} |
123 | 2 | } |
124 | 2 | |
125 | 2 | Some(mem::replace(&mut entry.user_data, user_data)) |
126 | | } |
127 | 13 | Entry::Vacant(entry) => { |
128 | 13 | entry.insert(Block { |
129 | 13 | parent_hash: None, |
130 | 13 | bad: false, |
131 | 13 | user_data, |
132 | 13 | }); |
133 | 13 | |
134 | 13 | None |
135 | | } |
136 | | }; |
137 | | |
138 | 15 | if let Some(parent_hash13 ) = parent_hash { |
139 | 13 | self.set_parent_hash(height, &hash, parent_hash); |
140 | 13 | }2 |
141 | | |
142 | 15 | previous_user_data |
143 | 15 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE6insertB8_ Line | Count | Source | 109 | 15 | pub fn insert( | 110 | 15 | &mut self, | 111 | 15 | height: u64, | 112 | 15 | hash: [u8; 32], | 113 | 15 | parent_hash: Option<[u8; 32]>, | 114 | 15 | user_data: TBl, | 115 | 15 | ) -> Option<TBl> { | 116 | 15 | let previous_user_data = match self.blocks.entry((height, hash)) { | 117 | 2 | Entry::Occupied(entry) => { | 118 | 2 | let entry = entry.into_mut(); | 119 | 2 | | 120 | 2 | match (parent_hash, &mut entry.parent_hash) { | 121 | 1 | (Some(parent_hash), &mut Some(ph0 )) if ph != parent_hash => panic!()0 , | 122 | 2 | _ => {} | 123 | 2 | } | 124 | 2 | | 125 | 2 | Some(mem::replace(&mut entry.user_data, user_data)) | 126 | | } | 127 | 13 | Entry::Vacant(entry) => { | 128 | 13 | entry.insert(Block { | 129 | 13 | parent_hash: None, | 130 | 13 | bad: false, | 131 | 13 | user_data, | 132 | 13 | }); | 133 | 13 | | 134 | 13 | None | 135 | | } | 136 | | }; | 137 | | | 138 | 15 | if let Some(parent_hash13 ) = parent_hash { | 139 | 13 | self.set_parent_hash(height, &hash, parent_hash); | 140 | 13 | }2 | 141 | | | 142 | 15 | previous_user_data | 143 | 15 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE6insertCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE6insertB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6insertCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6insertCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6insertCsibGXYHQB8Ea_25json_rpc_general_requests |
144 | | |
145 | | /// Removes the block from the collection. |
146 | | /// |
147 | | /// # Panic |
148 | | /// |
149 | | /// Panics if the block with the given height and hash hasn't been inserted before. |
150 | | /// |
151 | | #[track_caller] |
152 | 0 | pub fn remove(&mut self, height: u64, hash: &[u8; 32]) -> TBl { |
153 | 0 | self.blocks.remove(&(height, *hash)).unwrap().user_data |
154 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE6removeB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE6removeCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE6removeB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6removeCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6removeCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6removeCsibGXYHQB8Ea_25json_rpc_general_requests |
155 | | |
156 | | /// Removes from the collection the blocks whose height is strictly inferior to the given |
157 | | /// value, and returns them. |
158 | 0 | pub fn remove_below_height( |
159 | 0 | &mut self, |
160 | 0 | threshold: u64, |
161 | 0 | ) -> impl ExactSizeIterator<Item = (u64, [u8; 32], TBl)> { |
162 | 0 | let above_threshold = self.blocks.split_off(&(threshold, [0; 32])); |
163 | 0 | let below_threshold = mem::replace(&mut self.blocks, above_threshold); |
164 | 0 | below_threshold |
165 | 0 | .into_iter() |
166 | 0 | .map(|((he, ha), v)| (he, ha, v.user_data)) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE19remove_below_height0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE19remove_below_height0Ba_ |
167 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE19remove_below_heightB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE19remove_below_heightCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE19remove_below_heightB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE19remove_below_heightCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE19remove_below_heightCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE19remove_below_heightCsibGXYHQB8Ea_25json_rpc_general_requests |
168 | | |
169 | | /// Returns the user data associated to the block. This is the value originally passed |
170 | | /// through [`DisjointBlocks::insert`]. |
171 | | /// |
172 | | /// Returns `None` if the block hasn't been inserted before. |
173 | 0 | pub fn user_data(&self, height: u64, hash: &[u8; 32]) -> Option<&TBl> { |
174 | 0 | Some(&self.blocks.get(&(height, *hash))?.user_data) |
175 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE9user_dataB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE9user_dataCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE9user_dataB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE9user_dataCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE9user_dataCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE9user_dataCsibGXYHQB8Ea_25json_rpc_general_requests |
176 | | |
177 | | /// Returns the user data associated to the block. This is the value originally passed |
178 | | /// through [`DisjointBlocks::insert`]. |
179 | | /// |
180 | | /// Returns `None` if the block hasn't been inserted before. |
181 | 0 | pub fn user_data_mut(&mut self, height: u64, hash: &[u8; 32]) -> Option<&mut TBl> { |
182 | 0 | Some(&mut self.blocks.get_mut(&(height, *hash))?.user_data) |
183 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13user_data_mutB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13user_data_mutCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13user_data_mutB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13user_data_mutCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13user_data_mutCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13user_data_mutCsibGXYHQB8Ea_25json_rpc_general_requests |
184 | | |
185 | | /// Returns the parent hash of the given block. |
186 | | /// |
187 | | /// Returns `None` if either the block or its parent isn't known. |
188 | 0 | pub fn parent_hash(&self, height: u64, hash: &[u8; 32]) -> Option<&[u8; 32]> { |
189 | 0 | self.blocks |
190 | 0 | .get(&(height, *hash)) |
191 | 0 | .and_then(|b| b.parent_hash.as_ref()) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE11parent_hash0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE11parent_hash0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE11parent_hash0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hash0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hash0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hash0CsibGXYHQB8Ea_25json_rpc_general_requests |
192 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE11parent_hashB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE11parent_hashCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE11parent_hashB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hashCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hashCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE11parent_hashCsibGXYHQB8Ea_25json_rpc_general_requests |
193 | | |
194 | | /// Returns the list of blocks whose height is `height + 1` and whose parent hash is the |
195 | | /// given block. |
196 | 0 | pub fn children( |
197 | 0 | &'_ self, |
198 | 0 | height: u64, |
199 | 0 | hash: &[u8; 32], |
200 | 0 | ) -> impl Iterator<Item = (u64, &[u8; 32], &'_ TBl)> + '_ { |
201 | 0 | let hash = *hash; |
202 | 0 | self.blocks |
203 | 0 | .range((height + 1, [0; 32])..=(height + 1, [0xff; 32])) |
204 | 0 | .filter(move |((_maybe_child_height, _), maybe_child)| { |
205 | 0 | debug_assert_eq!(*_maybe_child_height, height + 1); |
206 | 0 | maybe_child.parent_hash.as_ref() == Some(&hash) |
207 | 0 | }) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE8children0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE8children0Ba_ |
208 | 0 | .map(|((he, ha), bl)| (*he, ha, &bl.user_data)) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE8childrens_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE8childrens_0Ba_ |
209 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8childrenB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE8childrenB8_ |
210 | | |
211 | | /// Sets the parent hash of the given block. |
212 | | /// |
213 | | /// If the parent is in the collection and known to be bad, the block is marked as bad as |
214 | | /// well. |
215 | | /// |
216 | | /// # Panic |
217 | | /// |
218 | | /// Panics if the block with the given height and hash hasn't been inserted before. |
219 | | /// Panics if the parent hash of that block was already known, and is different from the one |
220 | | /// passed as parameter. |
221 | | /// |
222 | | #[track_caller] |
223 | 14 | pub fn set_parent_hash(&mut self, height: u64, hash: &[u8; 32], parent_hash: [u8; 32]) { |
224 | 14 | let parent_is_bad = match height.checked_sub(1) { |
225 | 14 | Some(parent_height) => self |
226 | 14 | .blocks |
227 | 14 | .get(&(parent_height, parent_hash)) |
228 | 14 | .map_or(false, |b| b.bad6 ), _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE15set_parent_hash0Ba_ Line | Count | Source | 228 | 6 | .map_or(false, |b| b.bad), |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE15set_parent_hash0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE15set_parent_hash0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hash0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hash0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hash0CsibGXYHQB8Ea_25json_rpc_general_requests |
229 | 0 | None => false, |
230 | | }; |
231 | | |
232 | 14 | let block = self.blocks.get_mut(&(height, *hash)).unwrap(); |
233 | 14 | |
234 | 14 | match &mut block.parent_hash { |
235 | 1 | &mut Some(ph) => assert_eq!(ph, parent_hash), |
236 | 13 | ph @ &mut None => *ph = Some(parent_hash), |
237 | | } |
238 | | |
239 | 14 | if parent_is_bad { |
240 | 3 | self.set_block_bad(height, hash); |
241 | 11 | } |
242 | 14 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE15set_parent_hashB8_ Line | Count | Source | 223 | 14 | pub fn set_parent_hash(&mut self, height: u64, hash: &[u8; 32], parent_hash: [u8; 32]) { | 224 | 14 | let parent_is_bad = match height.checked_sub(1) { | 225 | 14 | Some(parent_height) => self | 226 | 14 | .blocks | 227 | 14 | .get(&(parent_height, parent_hash)) | 228 | 14 | .map_or(false, |b| b.bad), | 229 | 0 | None => false, | 230 | | }; | 231 | | | 232 | 14 | let block = self.blocks.get_mut(&(height, *hash)).unwrap(); | 233 | 14 | | 234 | 14 | match &mut block.parent_hash { | 235 | 1 | &mut Some(ph) => assert_eq!(ph, parent_hash), | 236 | 13 | ph @ &mut None => *ph = Some(parent_hash), | 237 | | } | 238 | | | 239 | 14 | if parent_is_bad { | 240 | 3 | self.set_block_bad(height, hash); | 241 | 11 | } | 242 | 14 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE15set_parent_hashCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE15set_parent_hashB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hashCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hashCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15set_parent_hashCsibGXYHQB8Ea_25json_rpc_general_requests |
243 | | |
244 | | /// Marks the given block and all its known children as "bad". |
245 | | /// |
246 | | /// If a child of this block is later added to the collection, it is also automatically |
247 | | /// marked as bad. |
248 | | /// |
249 | | /// # Panic |
250 | | /// |
251 | | /// Panics if the block with the given height and hash hasn't been inserted before. |
252 | | /// |
253 | | #[track_caller] |
254 | 7 | pub fn set_block_bad(&mut self, mut height: u64, hash: &[u8; 32]) { |
255 | 7 | // Initially contains the concerned block, then will contain the children of the concerned |
256 | 7 | // block, then the grand-children, then the grand-grand-children, and so on. |
257 | 7 | let mut blocks = |
258 | 7 | hashbrown::HashSet::with_capacity_and_hasher(1, fnv::FnvBuildHasher::default()); |
259 | 7 | blocks.insert(*hash); |
260 | | |
261 | 17 | while !blocks.is_empty() { |
262 | 10 | let mut children = hashbrown::HashSet::with_capacity_and_hasher( |
263 | 10 | blocks.len() * 4, |
264 | 10 | fnv::FnvBuildHasher::default(), |
265 | 10 | ); |
266 | | |
267 | | // Iterate over all blocks whose height is `height + 1` to try find children. |
268 | 10 | for ((_maybe_child_height, maybe_child_hash), maybe_child4 ) in self |
269 | 10 | .blocks |
270 | 10 | .range((height + 1, [0; 32])..=(height + 1, [0xff; 32])) |
271 | | { |
272 | 4 | debug_assert_eq!(*_maybe_child_height, height + 1); |
273 | 4 | if maybe_child |
274 | 4 | .parent_hash |
275 | 4 | .as_ref() |
276 | 4 | .map_or(false, |p| blocks.contains(p)) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE13set_block_bad0Ba_ Line | Count | Source | 276 | 4 | .map_or(false, |p| blocks.contains(p)) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13set_block_bad0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE13set_block_bad0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_bad0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_bad0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_bad0CsibGXYHQB8Ea_25json_rpc_general_requests |
277 | 4 | { |
278 | 4 | children.insert(*maybe_child_hash); |
279 | 4 | }0 |
280 | | } |
281 | | |
282 | 21 | for hash11 in blocks { |
283 | 11 | self.blocks.get_mut(&(height, hash)).unwrap().bad = true; |
284 | 11 | } |
285 | | |
286 | 10 | blocks = children; |
287 | 10 | height += 1; |
288 | | } |
289 | 7 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE13set_block_badB8_ Line | Count | Source | 254 | 7 | pub fn set_block_bad(&mut self, mut height: u64, hash: &[u8; 32]) { | 255 | 7 | // Initially contains the concerned block, then will contain the children of the concerned | 256 | 7 | // block, then the grand-children, then the grand-grand-children, and so on. | 257 | 7 | let mut blocks = | 258 | 7 | hashbrown::HashSet::with_capacity_and_hasher(1, fnv::FnvBuildHasher::default()); | 259 | 7 | blocks.insert(*hash); | 260 | | | 261 | 17 | while !blocks.is_empty() { | 262 | 10 | let mut children = hashbrown::HashSet::with_capacity_and_hasher( | 263 | 10 | blocks.len() * 4, | 264 | 10 | fnv::FnvBuildHasher::default(), | 265 | 10 | ); | 266 | | | 267 | | // Iterate over all blocks whose height is `height + 1` to try find children. | 268 | 10 | for ((_maybe_child_height, maybe_child_hash), maybe_child4 ) in self | 269 | 10 | .blocks | 270 | 10 | .range((height + 1, [0; 32])..=(height + 1, [0xff; 32])) | 271 | | { | 272 | 4 | debug_assert_eq!(*_maybe_child_height, height + 1); | 273 | 4 | if maybe_child | 274 | 4 | .parent_hash | 275 | 4 | .as_ref() | 276 | 4 | .map_or(false, |p| blocks.contains(p)) | 277 | 4 | { | 278 | 4 | children.insert(*maybe_child_hash); | 279 | 4 | }0 | 280 | | } | 281 | | | 282 | 21 | for hash11 in blocks { | 283 | 11 | self.blocks.get_mut(&(height, hash)).unwrap().bad = true; | 284 | 11 | } | 285 | | | 286 | 10 | blocks = children; | 287 | 10 | height += 1; | 288 | | } | 289 | 7 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13set_block_badCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13set_block_badB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_badCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_badCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13set_block_badCsibGXYHQB8Ea_25json_rpc_general_requests |
290 | | |
291 | | /// Returns the list of blocks whose parent hash is known but the parent itself is absent from |
292 | | /// the list of disjoint blocks. These blocks can potentially be verified. |
293 | 21 | pub fn good_tree_roots(&'_ self) -> impl Iterator<Item = TreeRoot> + '_ { |
294 | 21 | self.blocks |
295 | 21 | .iter() |
296 | 21 | .filter(|(_, block)| !block.bad0 ) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE15good_tree_roots0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE15good_tree_roots0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE15good_tree_roots0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_roots0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_roots0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_roots0CsibGXYHQB8Ea_25json_rpc_general_requests |
297 | 21 | .filter_map(move |((height, hash), block)| {0 |
298 | 0 | let parent_hash = block.parent_hash.as_ref()?; |
299 | | |
300 | | // Return `None` if parent is in the list of blocks. |
301 | 0 | if self.blocks.contains_key(&(*height - 1, *parent_hash)) { |
302 | 0 | return None; |
303 | 0 | } |
304 | 0 |
|
305 | 0 | Some(TreeRoot { |
306 | 0 | block_hash: *hash, |
307 | 0 | block_number: *height, |
308 | 0 | parent_block_hash: *parent_hash, |
309 | 0 | }) |
310 | 21 | }0 ) Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE15good_tree_rootss_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE15good_tree_rootss_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE15good_tree_rootss_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootss_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootss_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootss_0CsibGXYHQB8Ea_25json_rpc_general_requests |
311 | 21 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE15good_tree_rootsB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE15good_tree_rootsCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE15good_tree_rootsB8_ _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootsCsiLzmwikkc22_14json_rpc_basic Line | Count | Source | 293 | 2 | pub fn good_tree_roots(&'_ self) -> impl Iterator<Item = TreeRoot> + '_ { | 294 | 2 | self.blocks | 295 | 2 | .iter() | 296 | 2 | .filter(|(_, block)| !block.bad) | 297 | 2 | .filter_map(move |((height, hash), block)| { | 298 | | let parent_hash = block.parent_hash.as_ref()?; | 299 | | | 300 | | // Return `None` if parent is in the list of blocks. | 301 | | if self.blocks.contains_key(&(*height - 1, *parent_hash)) { | 302 | | return None; | 303 | | } | 304 | | | 305 | | Some(TreeRoot { | 306 | | block_hash: *hash, | 307 | | block_number: *height, | 308 | | parent_block_hash: *parent_hash, | 309 | | }) | 310 | 2 | }) | 311 | 2 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootsCscDgN54JpMGG_6author _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE15good_tree_rootsCsibGXYHQB8Ea_25json_rpc_general_requests Line | Count | Source | 293 | 19 | pub fn good_tree_roots(&'_ self) -> impl Iterator<Item = TreeRoot> + '_ { | 294 | 19 | self.blocks | 295 | 19 | .iter() | 296 | 19 | .filter(|(_, block)| !block.bad) | 297 | 19 | .filter_map(move |((height, hash), block)| { | 298 | | let parent_hash = block.parent_hash.as_ref()?; | 299 | | | 300 | | // Return `None` if parent is in the list of blocks. | 301 | | if self.blocks.contains_key(&(*height - 1, *parent_hash)) { | 302 | | return None; | 303 | | } | 304 | | | 305 | | Some(TreeRoot { | 306 | | block_hash: *hash, | 307 | | block_number: *height, | 308 | | parent_block_hash: *parent_hash, | 309 | | }) | 310 | 19 | }) | 311 | 19 | } |
|
312 | | |
313 | | /// Returns an iterator yielding blocks that are known to exist but which either haven't been |
314 | | /// inserted, or whose parent hash isn't known. |
315 | | /// |
316 | | /// More precisely, the iterator returns: |
317 | | /// |
318 | | /// - Blocks that have been inserted in this data structure but whose parent hash is unknown. |
319 | | /// - Parents of blocks that have been inserted in this data structure and whose parent hash |
320 | | /// is known and whose parent is missing from the data structure. |
321 | | /// |
322 | | /// > **Note**: Blocks in the second category might include blocks that are already known by |
323 | | /// > the user of this data structure. To avoid this, you are encouraged to remove |
324 | | /// > from the [`DisjointBlocks`] any block that can be verified prior to calling |
325 | | /// > this method. |
326 | | /// |
327 | | /// The blocks yielded by the iterator are always ordered by ascending height. |
328 | 55 | pub fn unknown_blocks(&'_ self) -> impl Iterator<Item = (u64, &'_ [u8; 32])> + '_ { |
329 | 55 | // Blocks whose parent hash isn't known. |
330 | 55 | let mut iter1 = self |
331 | 55 | .blocks |
332 | 55 | .iter() |
333 | 55 | .filter(|(_, s)| !s.bad23 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blocks0Ba_ Line | Count | Source | 333 | 23 | .filter(|(_, s)| !s.bad) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blocks0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blocks0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocks0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocks0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocks0CsibGXYHQB8Ea_25json_rpc_general_requests |
334 | 55 | .filter(|(_, s)| s.parent_hash.is_none()9 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss_0Ba_ Line | Count | Source | 334 | 9 | .filter(|(_, s)| s.parent_hash.is_none()) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss_0CsibGXYHQB8Ea_25json_rpc_general_requests |
335 | 55 | .map(|((n, h), _)| (*n, h)1 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss0_0Ba_ Line | Count | Source | 335 | 1 | .map(|((n, h), _)| (*n, h)) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss0_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss0_0CsibGXYHQB8Ea_25json_rpc_general_requests |
336 | 55 | .peekable(); |
337 | 55 | |
338 | 55 | // Blocks whose hash is referenced as the parent of a block, but are missing from the |
339 | 55 | // collection. |
340 | 55 | let mut iter2 = self |
341 | 55 | .blocks |
342 | 55 | .iter() |
343 | 55 | .filter(|(_, s)| !s.bad23 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss1_0Ba_ Line | Count | Source | 343 | 23 | .filter(|(_, s)| !s.bad) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss1_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss1_0CsibGXYHQB8Ea_25json_rpc_general_requests |
344 | 55 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(9 |h| (n - 1, h)8 )9 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss2_0Ba_ Line | Count | Source | 344 | 9 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(|h| (n - 1, h))) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss2_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_0CsibGXYHQB8Ea_25json_rpc_general_requests _RNCNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlocksuE14unknown_blockss2_00Bc_ Line | Count | Source | 344 | 8 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(|h| (n - 1, h))) |
Unexecuted instantiation: _RNCNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlocksINtNtB8_14pending_blocks15UnverifiedBlockINtB8_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss2_00CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlockspE14unknown_blockss2_00Bc_ Unexecuted instantiation: _RNCNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlocksINtNtB8_14pending_blocks15UnverifiedBlockINtB8_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_00CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlocksINtNtB8_14pending_blocks15UnverifiedBlockINtB8_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_00CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB6_14DisjointBlocksINtNtB8_14pending_blocks15UnverifiedBlockINtB8_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss2_00CsibGXYHQB8Ea_25json_rpc_general_requests |
345 | 55 | .filter(move |(n, h)| !self.blocks.contains_key(&(*n, **h))8 ) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss3_0Ba_ Line | Count | Source | 345 | 8 | .filter(move |(n, h)| !self.blocks.contains_key(&(*n, **h))) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss3_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss3_0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss3_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss3_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss3_0CsibGXYHQB8Ea_25json_rpc_general_requests |
346 | 55 | .peekable(); |
347 | 55 | |
348 | 55 | // A custom combinator is used in order to order elements between `iter1` and `iter2` |
349 | 55 | // by ascending block height. |
350 | 61 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { |
351 | 0 | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), |
352 | 0 | (Some(_), Some(_)) => iter1.next(), |
353 | 1 | (Some(_), None) => iter1.next(), |
354 | 5 | (None, Some(_)) => iter2.next(), |
355 | 55 | (None, None) => None, |
356 | 61 | }) _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksuE14unknown_blockss4_0Ba_ Line | Count | Source | 350 | 18 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | 0 | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | 0 | (Some(_), Some(_)) => iter1.next(), | 353 | 1 | (Some(_), None) => iter1.next(), | 354 | 5 | (None, Some(_)) => iter2.next(), | 355 | 12 | (None, None) => None, | 356 | 18 | }) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blockss4_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE14unknown_blockss4_0Ba_ _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss4_0CsiLzmwikkc22_14json_rpc_basic Line | Count | Source | 350 | 4 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | 0 | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | 0 | (Some(_), Some(_)) => iter1.next(), | 353 | 0 | (Some(_), None) => iter1.next(), | 354 | 0 | (None, Some(_)) => iter2.next(), | 355 | 4 | (None, None) => None, | 356 | 4 | }) |
Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss4_0CscDgN54JpMGG_6author _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blockss4_0CsibGXYHQB8Ea_25json_rpc_general_requests Line | Count | Source | 350 | 39 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | 0 | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | 0 | (Some(_), Some(_)) => iter1.next(), | 353 | 0 | (Some(_), None) => iter1.next(), | 354 | 0 | (None, Some(_)) => iter2.next(), | 355 | 39 | (None, None) => None, | 356 | 39 | }) |
|
357 | 55 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE14unknown_blocksB8_ Line | Count | Source | 328 | 12 | pub fn unknown_blocks(&'_ self) -> impl Iterator<Item = (u64, &'_ [u8; 32])> + '_ { | 329 | 12 | // Blocks whose parent hash isn't known. | 330 | 12 | let mut iter1 = self | 331 | 12 | .blocks | 332 | 12 | .iter() | 333 | 12 | .filter(|(_, s)| !s.bad) | 334 | 12 | .filter(|(_, s)| s.parent_hash.is_none()) | 335 | 12 | .map(|((n, h), _)| (*n, h)) | 336 | 12 | .peekable(); | 337 | 12 | | 338 | 12 | // Blocks whose hash is referenced as the parent of a block, but are missing from the | 339 | 12 | // collection. | 340 | 12 | let mut iter2 = self | 341 | 12 | .blocks | 342 | 12 | .iter() | 343 | 12 | .filter(|(_, s)| !s.bad) | 344 | 12 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(|h| (n - 1, h))) | 345 | 12 | .filter(move |(n, h)| !self.blocks.contains_key(&(*n, **h))) | 346 | 12 | .peekable(); | 347 | 12 | | 348 | 12 | // A custom combinator is used in order to order elements between `iter1` and `iter2` | 349 | 12 | // by ascending block height. | 350 | 12 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | | (Some(_), Some(_)) => iter1.next(), | 353 | | (Some(_), None) => iter1.next(), | 354 | | (None, Some(_)) => iter2.next(), | 355 | | (None, None) => None, | 356 | 12 | }) | 357 | 12 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE14unknown_blocksCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE14unknown_blocksB8_ _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocksCsiLzmwikkc22_14json_rpc_basic Line | Count | Source | 328 | 4 | pub fn unknown_blocks(&'_ self) -> impl Iterator<Item = (u64, &'_ [u8; 32])> + '_ { | 329 | 4 | // Blocks whose parent hash isn't known. | 330 | 4 | let mut iter1 = self | 331 | 4 | .blocks | 332 | 4 | .iter() | 333 | 4 | .filter(|(_, s)| !s.bad) | 334 | 4 | .filter(|(_, s)| s.parent_hash.is_none()) | 335 | 4 | .map(|((n, h), _)| (*n, h)) | 336 | 4 | .peekable(); | 337 | 4 | | 338 | 4 | // Blocks whose hash is referenced as the parent of a block, but are missing from the | 339 | 4 | // collection. | 340 | 4 | let mut iter2 = self | 341 | 4 | .blocks | 342 | 4 | .iter() | 343 | 4 | .filter(|(_, s)| !s.bad) | 344 | 4 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(|h| (n - 1, h))) | 345 | 4 | .filter(move |(n, h)| !self.blocks.contains_key(&(*n, **h))) | 346 | 4 | .peekable(); | 347 | 4 | | 348 | 4 | // A custom combinator is used in order to order elements between `iter1` and `iter2` | 349 | 4 | // by ascending block height. | 350 | 4 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | | (Some(_), Some(_)) => iter1.next(), | 353 | | (Some(_), None) => iter1.next(), | 354 | | (None, Some(_)) => iter2.next(), | 355 | | (None, None) => None, | 356 | 4 | }) | 357 | 4 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocksCscDgN54JpMGG_6author _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE14unknown_blocksCsibGXYHQB8Ea_25json_rpc_general_requests Line | Count | Source | 328 | 39 | pub fn unknown_blocks(&'_ self) -> impl Iterator<Item = (u64, &'_ [u8; 32])> + '_ { | 329 | 39 | // Blocks whose parent hash isn't known. | 330 | 39 | let mut iter1 = self | 331 | 39 | .blocks | 332 | 39 | .iter() | 333 | 39 | .filter(|(_, s)| !s.bad) | 334 | 39 | .filter(|(_, s)| s.parent_hash.is_none()) | 335 | 39 | .map(|((n, h), _)| (*n, h)) | 336 | 39 | .peekable(); | 337 | 39 | | 338 | 39 | // Blocks whose hash is referenced as the parent of a block, but are missing from the | 339 | 39 | // collection. | 340 | 39 | let mut iter2 = self | 341 | 39 | .blocks | 342 | 39 | .iter() | 343 | 39 | .filter(|(_, s)| !s.bad) | 344 | 39 | .filter_map(|((n, _), s)| s.parent_hash.as_ref().map(|h| (n - 1, h))) | 345 | 39 | .filter(move |(n, h)| !self.blocks.contains_key(&(*n, **h))) | 346 | 39 | .peekable(); | 347 | 39 | | 348 | 39 | // A custom combinator is used in order to order elements between `iter1` and `iter2` | 349 | 39 | // by ascending block height. | 350 | 39 | iter::from_fn(move || match (iter1.peek(), iter2.peek()) { | 351 | | (Some((b1, _)), Some((b2, _))) if b1 > b2 => iter2.next(), | 352 | | (Some(_), Some(_)) => iter1.next(), | 353 | | (Some(_), None) => iter1.next(), | 354 | | (None, Some(_)) => iter2.next(), | 355 | | (None, None) => None, | 356 | 39 | }) | 357 | 39 | } |
|
358 | | |
359 | | /// Returns whether a block is marked as bad. |
360 | | /// |
361 | | /// Returns `None` if the block isn't known. |
362 | 12 | pub fn is_bad(&self, height: u64, hash: &[u8; 32]) -> Option<bool> { |
363 | 12 | Some(self.blocks.get(&(height, *hash))?0 .bad) |
364 | 12 | } _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksuE6is_badB8_ Line | Count | Source | 362 | 12 | pub fn is_bad(&self, height: u64, hash: &[u8; 32]) -> Option<bool> { | 363 | 12 | Some(self.blocks.get(&(height, *hash))?0 .bad) | 364 | 12 | } |
Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE6is_badCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE6is_badB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6is_badCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6is_badCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE6is_badCsibGXYHQB8Ea_25json_rpc_general_requests |
365 | | |
366 | | /// Returns whether the parent of a block is bad. |
367 | | /// |
368 | | /// Returns `None` if either the block or its parent isn't known. |
369 | 0 | pub fn is_parent_bad(&self, height: u64, hash: &[u8; 32]) -> Option<bool> { |
370 | 0 | let parent_hash = self.blocks.get(&(height, *hash))?.parent_hash?; |
371 | 0 | let parent_height = match height.checked_sub(1) { |
372 | 0 | Some(h) => h, |
373 | 0 | None => return Some(false), // Parent is known and isn't present in the data structure. |
374 | | }; |
375 | 0 | Some( |
376 | 0 | self.blocks |
377 | 0 | .get(&(parent_height, parent_hash)) |
378 | 0 | .map_or(false, |parent| parent.bad), Unexecuted instantiation: _RNCNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE13is_parent_bad0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13is_parent_bad0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlockspE13is_parent_bad0Ba_ Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_bad0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_bad0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB4_14DisjointBlocksINtNtB6_14pending_blocks15UnverifiedBlockINtB6_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_bad0CsibGXYHQB8Ea_25json_rpc_general_requests |
379 | 0 | ) |
380 | 0 | } Unexecuted instantiation: _RNvMNtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13is_parent_badB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionuEEEE13is_parent_badCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlockspE13is_parent_badB8_ Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_badCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_badCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMNtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjointINtB2_14DisjointBlocksINtNtB4_14pending_blocks15UnverifiedBlockINtB4_12PendingBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockEEEE13is_parent_badCsibGXYHQB8Ea_25json_rpc_general_requests |
381 | | } |
382 | | |
383 | | impl<TBl: fmt::Debug> fmt::Debug for DisjointBlocks<TBl> { |
384 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
385 | 0 | fmt::Debug::fmt(&self.blocks, f) |
386 | 0 | } Unexecuted instantiation: _RNvXININtNtNtCsN16ciHI6Qf_7smoldot4sync9all_forks8disjoints_0pEINtB5_14DisjointBlockspENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtBb_ Unexecuted instantiation: _RNvXININtNtNtCseuYC0Zibziv_7smoldot4sync9all_forks8disjoints_0pEINtB5_14DisjointBlockspENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtBb_ |
387 | | } |
388 | | |
389 | | /// See [`DisjointBlocks::good_tree_roots`]. |
390 | | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] |
391 | | pub struct TreeRoot { |
392 | | /// Hash of the block that is a tree root. |
393 | | pub block_hash: [u8; 32], |
394 | | /// Height of the block that is a tree root. |
395 | | pub block_number: u64, |
396 | | /// Hash of the parent of the block. |
397 | | pub parent_block_hash: [u8; 32], |
398 | | } |
399 | | |
400 | | #[cfg(test)] |
401 | | mod tests { |
402 | | #[test] |
403 | 1 | fn insert_doesnt_override_bad() { |
404 | 1 | // Calling `insert` with a block that already exists doesn't reset its "bad" state. |
405 | 1 | |
406 | 1 | let mut collection = super::DisjointBlocks::new(); |
407 | 1 | |
408 | 1 | assert!(collection.insert(1, [1; 32], Some([0; 32]), ()).is_none()); |
409 | 1 | assert_eq!(collection.unknown_blocks().count(), 1); |
410 | | |
411 | 1 | collection.set_block_bad(1, &[1; 32]); |
412 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
413 | | |
414 | 1 | assert!(collection.insert(1, [1; 32], Some([0; 32]), ()).is_some()); |
415 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
416 | 1 | } |
417 | | |
418 | | #[test] |
419 | 1 | fn insert_doesnt_override_parent() { |
420 | 1 | // Calling `insert` with a block that already exists doesn't reset its parent. |
421 | 1 | |
422 | 1 | let mut collection = super::DisjointBlocks::new(); |
423 | 1 | |
424 | 1 | assert!(collection.insert(1, [1; 32], Some([0; 32]), ()).is_none()); |
425 | 1 | assert_eq!( |
426 | 1 | collection.unknown_blocks().collect::<Vec<_>>(), |
427 | 1 | vec![(0, &[0; 32])] |
428 | 1 | ); |
429 | | |
430 | 1 | assert!(collection.insert(1, [1; 32], None, ()).is_some()); |
431 | 1 | assert_eq!( |
432 | 1 | collection.unknown_blocks().collect::<Vec<_>>(), |
433 | 1 | vec![(0, &[0; 32])] |
434 | 1 | ); |
435 | 1 | } |
436 | | |
437 | | #[test] |
438 | 1 | fn set_parent_hash_updates_bad() { |
439 | 1 | // Calling `set_parent_hash` where the parent is a known a bad block marks the block and |
440 | 1 | // its children as bad as well. |
441 | 1 | |
442 | 1 | let mut collection = super::DisjointBlocks::new(); |
443 | 1 | |
444 | 1 | collection.insert(1, [1; 32], Some([0; 32]), ()); |
445 | 1 | assert_eq!(collection.unknown_blocks().count(), 1); |
446 | 1 | collection.set_block_bad(1, &[1; 32]); |
447 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
448 | | |
449 | 1 | collection.insert(2, [2; 32], None, ()); |
450 | 1 | assert!(!collection.is_bad(2, &[2; 32]).unwrap()); |
451 | 1 | collection.insert(3, [3; 32], Some([2; 32]), ()); |
452 | 1 | assert!(!collection.is_bad(3, &[3; 32]).unwrap()); |
453 | 1 | collection.insert(3, [31; 32], Some([2; 32]), ()); |
454 | 1 | assert!(!collection.is_bad(3, &[31; 32]).unwrap()); |
455 | 1 | collection.insert(4, [4; 32], Some([3; 32]), ()); |
456 | 1 | assert!(!collection.is_bad(4, &[4; 32]).unwrap()); |
457 | 1 | assert_eq!(collection.unknown_blocks().count(), 1); |
458 | | |
459 | 1 | collection.set_parent_hash(2, &[2; 32], [1; 32]); |
460 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
461 | 1 | assert!(collection.is_bad(2, &[2; 32]).unwrap()); |
462 | 1 | assert!(collection.is_bad(3, &[3; 32]).unwrap()); |
463 | 1 | assert!(collection.is_bad(3, &[31; 32]).unwrap()); |
464 | 1 | assert!(collection.is_bad(4, &[4; 32]).unwrap()); |
465 | 1 | } |
466 | | |
467 | | #[test] |
468 | 1 | fn insert_updates_bad() { |
469 | 1 | // Calling `insert` where the parent is a known a bad block marks the block as |
470 | 1 | // bad as well. |
471 | 1 | |
472 | 1 | let mut collection = super::DisjointBlocks::new(); |
473 | 1 | |
474 | 1 | collection.insert(1, [1; 32], Some([0; 32]), ()); |
475 | 1 | collection.set_block_bad(1, &[1; 32]); |
476 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
477 | | |
478 | 1 | collection.insert(2, [2; 32], Some([1; 32]), ()); |
479 | 1 | assert_eq!(collection.unknown_blocks().count(), 0); |
480 | | |
481 | | // Control sample. |
482 | 1 | collection.insert(1, [0x80; 32], Some([0; 32]), ()); |
483 | 1 | assert_eq!(collection.unknown_blocks().count(), 1); |
484 | 1 | } |
485 | | |
486 | | #[test] |
487 | 1 | fn insert_filling_gap_updates_bad() { |
488 | 1 | // Block 1 is known bad. Block 2 is unknown. Block 3 is known. Inserting block 2 should |
489 | 1 | // mark block 3 as bad. |
490 | 1 | |
491 | 1 | let mut collection = super::DisjointBlocks::new(); |
492 | 1 | |
493 | 1 | collection.insert(1, [1; 32], Some([0; 32]), ()); |
494 | 1 | collection.set_block_bad(1, &[1; 32]); |
495 | 1 | assert!(collection.is_bad(1, &[1; 32]).unwrap()); |
496 | | |
497 | 1 | collection.insert(3, [3; 32], Some([2; 32]), ()); |
498 | 1 | assert!(!collection.is_bad(3, &[3; 32]).unwrap()); |
499 | | |
500 | 1 | collection.insert(2, [2; 32], Some([1; 32]), ()); |
501 | 1 | assert!(collection.is_bad(2, &[2; 32]).unwrap()); |
502 | 1 | assert!(collection.is_bad(3, &[3; 32]).unwrap()); |
503 | 1 | } |
504 | | } |