Coverage Report

Created: 2024-05-16 12:16

/__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_has
h => 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_has
h => 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
}