Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/trie/branch_search.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2023  Pierre Krieger
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
//! Allows searching for the closest branch node in a trie when only the storage trie nodes are
19
//! known.
20
//!
21
//! This module can be used in situations where only the list of trie nodes with a storage value
22
//! is known, such as in the form of a `BTreeMap`, and allows finding the list of branch nodes.
23
24
use core::iter;
25
26
use crate::trie;
27
use alloc::vec::{IntoIter, Vec};
28
29
pub use crate::trie::Nibble;
30
31
mod tests;
32
33
/// Configuration for [`start_branch_search`].
34
#[derive(Debug, Clone)]
35
pub struct Config<K, P> {
36
    /// The search will try to find the closest node whose key is strictly superior or superior
37
    /// or equal (see [`Config::or_equal`]) to the value in this field.
38
    pub key_before: K,
39
40
    /// If `true`, also include the node whose key is equal to [`Config::key_before`] (if any).
41
    /// If `false`, only nodes whose key is strictly superior will be searched.
42
    pub or_equal: bool,
43
44
    /// Only search nodes whose key starts with the list of nibbles given in this field.
45
    pub prefix: P,
46
47
    /// If `true`, only return nodes that have a storage value associated to them.
48
    ///
49
    /// > **Note**: This option is provided as a convenience. The entire point of this search
50
    /// >           is to find branch nodes when only storage nodes are known.
51
    pub no_branch_search: bool,
52
}
53
54
/// Start the search algorithm.
55
// TODO: maybe rename things a bit? it's weird that `NextKey` is returned
56
551k
pub fn start_branch_search(
57
551k
    config: Config<impl Iterator<Item = Nibble>, impl Iterator<Item = Nibble>>,
58
551k
) -> NextKey {
59
551k
    NextKey {
60
551k
        prefix: config.prefix.collect(),
61
551k
        key_before: config.key_before.collect(),
62
551k
        or_equal: config.or_equal,
63
551k
        inner: NextKeyInner::FirstFound {
64
551k
            no_branch_search: config.no_branch_search,
65
551k
        },
66
551k
    }
67
551k
}
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie13branch_search19start_branch_searchINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterNtNtB4_6nibble6NibbleEB16_EB6_
Line
Count
Source
56
8.25k
pub fn start_branch_search(
57
8.25k
    config: Config<impl Iterator<Item = Nibble>, impl Iterator<Item = Nibble>>,
58
8.25k
) -> NextKey {
59
8.25k
    NextKey {
60
8.25k
        prefix: config.prefix.collect(),
61
8.25k
        key_before: config.key_before.collect(),
62
8.25k
        or_equal: config.or_equal,
63
8.25k
        inner: NextKeyInner::FirstFound {
64
8.25k
            no_branch_search: config.no_branch_search,
65
8.25k
        },
66
8.25k
    }
67
8.25k
}
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie13branch_search19start_branch_searchINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1f_5slice4iter4IterNtNtB4_6nibble6NibbleEEB16_EB6_
Line
Count
Source
56
524k
pub fn start_branch_search(
57
524k
    config: Config<impl Iterator<Item = Nibble>, impl Iterator<Item = Nibble>>,
58
524k
) -> NextKey {
59
524k
    NextKey {
60
524k
        prefix: config.prefix.collect(),
61
524k
        key_before: config.key_before.collect(),
62
524k
        or_equal: config.or_equal,
63
524k
        inner: NextKeyInner::FirstFound {
64
524k
            no_branch_search: config.no_branch_search,
65
524k
        },
66
524k
    }
67
524k
}
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie13branch_search19start_branch_searchINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapINtNtNtB1f_5slice4iter4IterNtNtB4_14calculate_root4NodeEINtNtB1b_5chain5ChainINtNtB1b_6copied6CopiedIB23_NtNtB4_6nibble6NibbleEEINtNtB1f_6option8IntoIterB3J_EENCNvMB2v_NtB2v_9CalcInner26current_iter_node_full_key0EB16_EB6_
Line
Count
Source
56
2.48k
pub fn start_branch_search(
57
2.48k
    config: Config<impl Iterator<Item = Nibble>, impl Iterator<Item = Nibble>>,
58
2.48k
) -> NextKey {
59
2.48k
    NextKey {
60
2.48k
        prefix: config.prefix.collect(),
61
2.48k
        key_before: config.key_before.collect(),
62
2.48k
        or_equal: config.or_equal,
63
2.48k
        inner: NextKeyInner::FirstFound {
64
2.48k
            no_branch_search: config.no_branch_search,
65
2.48k
        },
66
2.48k
    }
67
2.48k
}
_RINvNtNtCseuYC0Zibziv_7smoldot4trie13branch_search19start_branch_searchINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapINtNtNtB1g_5slice4iter4IterNtNtB4_14calculate_root4NodeEINtNtB1c_5chain5ChainINtNtB1c_6copied6CopiedIB24_NtNtB4_6nibble6NibbleEEINtNtB1g_6option8IntoIterB3K_EENCNvMB2w_NtB2w_9CalcInner26current_iter_node_full_key0EB17_EB6_
Line
Count
Source
56
16.1k
pub fn start_branch_search(
57
16.1k
    config: Config<impl Iterator<Item = Nibble>, impl Iterator<Item = Nibble>>,
58
16.1k
) -> NextKey {
59
16.1k
    NextKey {
60
16.1k
        prefix: config.prefix.collect(),
61
16.1k
        key_before: config.key_before.collect(),
62
16.1k
        or_equal: config.or_equal,
63
16.1k
        inner: NextKeyInner::FirstFound {
64
16.1k
            no_branch_search: config.no_branch_search,
65
16.1k
        },
66
16.1k
    }
67
16.1k
}
68
69
/// Progress in the search algorithm.
70
pub enum BranchSearch {
71
    /// In order to continue, the API user must indicate the trie node with a storage value that
72
    /// immediately follows a given one.
73
    NextKey(NextKey),
74
    /// Search has finished successfully.
75
    Found {
76
        /// Result of the search. `None` if there is no branch/storage node after
77
        /// [`Config::key_before`] in the trie.
78
        branch_trie_node_key: Option<BranchTrieNodeKeyIter>,
79
    },
80
}
81
82
/// Implementation of `Iterator<Item = Nibble>`. See [`BranchSearch::Found::branch_trie_node_key`].
83
pub struct BranchTrieNodeKeyIter {
84
    inner: IntoIter<Nibble>,
85
}
86
87
impl Iterator for BranchTrieNodeKeyIter {
88
    type Item = Nibble;
89
90
603k
    fn next(&mut self) -> Option<Self::Item> {
91
603k
        self.inner.next()
92
603k
    }
_RNvXNtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB2_21BranchTrieNodeKeyIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
90
524k
    fn next(&mut self) -> Option<Self::Item> {
91
524k
        self.inner.next()
92
524k
    }
_RNvXNtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB2_21BranchTrieNodeKeyIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
90
79.3k
    fn next(&mut self) -> Option<Self::Item> {
91
79.3k
        self.inner.next()
92
79.3k
    }
93
94
92.1k
    fn size_hint(&self) -> (usize, Option<usize>) {
95
92.1k
        self.inner.size_hint()
96
92.1k
    }
_RNvXNtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB2_21BranchTrieNodeKeyIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint
Line
Count
Source
94
91.2k
    fn size_hint(&self) -> (usize, Option<usize>) {
95
91.2k
        self.inner.size_hint()
96
91.2k
    }
_RNvXNtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB2_21BranchTrieNodeKeyIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint
Line
Count
Source
94
882
    fn size_hint(&self) -> (usize, Option<usize>) {
95
882
        self.inner.size_hint()
96
882
    }
97
}
98
99
impl ExactSizeIterator for BranchTrieNodeKeyIter {}
100
101
/// In order to continue, the API user must indicate the trie node with a storage value that
102
/// immediately follows a given one.
103
pub struct NextKey {
104
    inner: NextKeyInner,
105
    /// Value passed as [`Config::key_before`].
106
    key_before: Vec<Nibble>,
107
    /// Value passed as [`Config::prefix`].
108
    prefix: Vec<Nibble>,
109
    /// Value passed as [`Config::or_equal`].
110
    or_equal: bool,
111
}
112
113
enum NextKeyInner {
114
    FirstFound {
115
        /// Value passed as [`Config::no_branch_search`].
116
        no_branch_search: bool,
117
    },
118
    FurtherRound {
119
        /// Must never be empty and must never contain only `f` nibbles.
120
        current_found_branch: Vec<Nibble>,
121
    },
122
}
123
124
impl NextKey {
125
    /// The API user must provide the trie node with a storage value whose key is the first one
126
    /// that is strictly superior or superior or equal to the key returned by this function.
127
2.04M
    pub fn key_before(&'_ self) -> impl Iterator<Item = u8> + '_ {
128
2.04M
        trie::nibbles_to_bytes_suffix_extend(match &self.inner {
129
1.85M
            NextKeyInner::FirstFound { .. } => either::Left(self.key_before.iter().copied()),
130
            NextKeyInner::FurtherRound {
131
190k
                current_found_branch,
132
190k
            } => {
133
190k
                let num_f_nibbles_to_pop = current_found_branch
134
190k
                    .iter()
135
190k
                    .rev()
136
202k
                    .take_while(|n| **n == Nibble::max())
_RNCNvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB7_7NextKey10key_before0Bb_
Line
Count
Source
136
201k
                    .take_while(|n| **n == Nibble::max())
_RNCNvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB7_7NextKey10key_before0Bb_
Line
Count
Source
136
1.34k
                    .take_while(|n| **n == Nibble::max())
137
190k
                    .count();
138
190k
                debug_assert!(num_f_nibbles_to_pop < current_found_branch.len());
139
140
190k
                let len = current_found_branch.len();
141
190k
                let extra_nibble = current_found_branch[len - num_f_nibbles_to_pop - 1]
142
190k
                    .checked_add(1)
143
190k
                    .unwrap_or_else(|| 
unreachable!()0
);
Unexecuted instantiation: _RNCNvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB7_7NextKey10key_befores_0Bb_
Unexecuted instantiation: _RNCNvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB7_7NextKey10key_befores_0Bb_
144
190k
145
190k
                either::Right(
146
190k
                    current_found_branch
147
190k
                        .iter()
148
190k
                        .take(len - num_f_nibbles_to_pop - 1)
149
190k
                        .copied()
150
190k
                        .chain(iter::once(extra_nibble)),
151
190k
                )
152
            }
153
        })
154
2.04M
    }
_RNvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB5_7NextKey10key_before
Line
Count
Source
127
2.02M
    pub fn key_before(&'_ self) -> impl Iterator<Item = u8> + '_ {
128
2.02M
        trie::nibbles_to_bytes_suffix_extend(match &self.inner {
129
1.83M
            NextKeyInner::FirstFound { .. } => either::Left(self.key_before.iter().copied()),
130
            NextKeyInner::FurtherRound {
131
189k
                current_found_branch,
132
189k
            } => {
133
189k
                let num_f_nibbles_to_pop = current_found_branch
134
189k
                    .iter()
135
189k
                    .rev()
136
189k
                    .take_while(|n| **n == Nibble::max())
137
189k
                    .count();
138
189k
                debug_assert!(num_f_nibbles_to_pop < current_found_branch.len());
139
140
189k
                let len = current_found_branch.len();
141
189k
                let extra_nibble = current_found_branch[len - num_f_nibbles_to_pop - 1]
142
189k
                    .checked_add(1)
143
189k
                    .unwrap_or_else(|| unreachable!());
144
189k
145
189k
                either::Right(
146
189k
                    current_found_branch
147
189k
                        .iter()
148
189k
                        .take(len - num_f_nibbles_to_pop - 1)
149
189k
                        .copied()
150
189k
                        .chain(iter::once(extra_nibble)),
151
189k
                )
152
            }
153
        })
154
2.02M
    }
_RNvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB5_7NextKey10key_before
Line
Count
Source
127
17.4k
    pub fn key_before(&'_ self) -> impl Iterator<Item = u8> + '_ {
128
17.4k
        trie::nibbles_to_bytes_suffix_extend(match &self.inner {
129
16.1k
            NextKeyInner::FirstFound { .. } => either::Left(self.key_before.iter().copied()),
130
            NextKeyInner::FurtherRound {
131
1.30k
                current_found_branch,
132
1.30k
            } => {
133
1.30k
                let num_f_nibbles_to_pop = current_found_branch
134
1.30k
                    .iter()
135
1.30k
                    .rev()
136
1.30k
                    .take_while(|n| **n == Nibble::max())
137
1.30k
                    .count();
138
1.30k
                debug_assert!(num_f_nibbles_to_pop < current_found_branch.len());
139
140
1.30k
                let len = current_found_branch.len();
141
1.30k
                let extra_nibble = current_found_branch[len - num_f_nibbles_to_pop - 1]
142
1.30k
                    .checked_add(1)
143
1.30k
                    .unwrap_or_else(|| unreachable!());
144
1.30k
145
1.30k
                either::Right(
146
1.30k
                    current_found_branch
147
1.30k
                        .iter()
148
1.30k
                        .take(len - num_f_nibbles_to_pop - 1)
149
1.30k
                        .copied()
150
1.30k
                        .chain(iter::once(extra_nibble)),
151
1.30k
                )
152
            }
153
        })
154
17.4k
    }
155
156
    /// If `true`, if the key returned by [`NextKey::key_before`] corresponds to a trie node with
157
    /// a storage value, then the API user must indicate it. If `false`, it must indicate the key
158
    /// strictly superior.
159
85.4k
    pub fn or_equal(&self) -> bool {
160
85.4k
        match self.inner {
161
            NextKeyInner::FirstFound { .. } => {
162
                // If `key_before` is for example `0xa`, `key_before()` will return `0xa0` due to
163
                // the usage of `nibbles_to_bytes_suffix_extend`. For this reason, we have to
164
                // always return `true` if the number of nibbles in `key_before` is uneven.
165
83.3k
                self.or_equal || 
(self.key_before.len() % 2 != 0)29.2k
166
            }
167
2.08k
            NextKeyInner::FurtherRound { .. } => true,
168
        }
169
85.4k
    }
_RNvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB5_7NextKey8or_equal
Line
Count
Source
159
68.0k
    pub fn or_equal(&self) -> bool {
160
68.0k
        match self.inner {
161
            NextKeyInner::FirstFound { .. } => {
162
                // If `key_before` is for example `0xa`, `key_before()` will return `0xa0` due to
163
                // the usage of `nibbles_to_bytes_suffix_extend`. For this reason, we have to
164
                // always return `true` if the number of nibbles in `key_before` is uneven.
165
67.2k
                self.or_equal || 
(self.key_before.len() % 2 != 0)29.2k
166
            }
167
787
            NextKeyInner::FurtherRound { .. } => true,
168
        }
169
68.0k
    }
_RNvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB5_7NextKey8or_equal
Line
Count
Source
159
17.4k
    pub fn or_equal(&self) -> bool {
160
17.4k
        match self.inner {
161
            NextKeyInner::FirstFound { .. } => {
162
                // If `key_before` is for example `0xa`, `key_before()` will return `0xa0` due to
163
                // the usage of `nibbles_to_bytes_suffix_extend`. For this reason, we have to
164
                // always return `true` if the number of nibbles in `key_before` is uneven.
165
16.1k
                self.or_equal || 
(self.key_before.len() % 2 != 0)0
166
            }
167
1.30k
            NextKeyInner::FurtherRound { .. } => true,
168
        }
169
17.4k
    }
170
171
    /// The API user must indicate a key that starts with the bytes returned by this function.
172
    /// If the first key doesn't start with these bytes, then the API user must indicate `None`.
173
482k
    pub fn prefix(&'_ self) -> impl Iterator<Item = u8> + '_ {
174
482k
        trie::nibbles_to_bytes_truncate(self.prefix.iter().copied())
175
482k
    }
_RNvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB5_7NextKey6prefix
Line
Count
Source
173
465k
    pub fn prefix(&'_ self) -> impl Iterator<Item = u8> + '_ {
174
465k
        trie::nibbles_to_bytes_truncate(self.prefix.iter().copied())
175
465k
    }
_RNvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB5_7NextKey6prefix
Line
Count
Source
173
17.4k
    pub fn prefix(&'_ self) -> impl Iterator<Item = u8> + '_ {
174
17.4k
        trie::nibbles_to_bytes_truncate(self.prefix.iter().copied())
175
17.4k
    }
176
177
    /// Indicate the key. `None` must be passed if [`NextKey::key_before`] is the last key of
178
    /// the sub-trie that starts with [`NextKey::prefix`].
179
600k
    pub fn inject(
180
600k
        mut self,
181
600k
        storage_trie_node_key: Option<impl Iterator<Item = u8>>,
182
600k
    ) -> BranchSearch {
183
600k
        match (self.inner, storage_trie_node_key) {
184
            // No matter what, if we're at the first round and the user injected `None`, that
185
            // means `key_before` is equal or superior to the last key of the trie and thus there
186
            // can't be any branch node after it.
187
353k
            (NextKeyInner::FirstFound { .. }, None) => BranchSearch::Found {
188
353k
                branch_trie_node_key: None,
189
353k
            },
190
191
            // If `no_branch_search` is `true`, simply immediately return the value provided by
192
            // the user.
193
            (
194
                NextKeyInner::FirstFound {
195
                    no_branch_search: true,
196
                    ..
197
                },
198
96.9k
                Some(storage_trie_node_key),
199
96.9k
            ) => {
200
96.9k
                let storage_trie_node_key =
201
96.9k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
202
96.9k
                debug_assert!(storage_trie_node_key >= self.key_before);
203
204
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
205
                // whether the value provided by the user is still within the prefix.
206
96.9k
                if !storage_trie_node_key.starts_with(&self.prefix) {
207
37.3k
                    return BranchSearch::Found {
208
37.3k
                        branch_trie_node_key: None,
209
37.3k
                    };
210
59.6k
                }
211
59.6k
212
59.6k
                BranchSearch::Found {
213
59.6k
                    branch_trie_node_key: Some(BranchTrieNodeKeyIter {
214
59.6k
                        inner: storage_trie_node_key.into_iter(),
215
59.6k
                    }),
216
59.6k
                }
217
            }
218
219
            (
220
                NextKeyInner::FirstFound {
221
                    no_branch_search: false,
222
                    ..
223
                },
224
100k
                Some(storage_trie_node_key),
225
100k
            ) => {
226
100k
                let storage_trie_node_key =
227
100k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
228
100k
                debug_assert!(storage_trie_node_key >= self.key_before);
229
230
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
231
                // whether the value provided by the user is still within the prefix.
232
100k
                if !storage_trie_node_key.starts_with(&self.prefix) {
233
39.0k
                    return BranchSearch::Found {
234
39.0k
                        branch_trie_node_key: None,
235
39.0k
                    };
236
61.9k
                }
237
61.9k
238
61.9k
                if storage_trie_node_key.is_empty()
239
50.8k
                    || 
storage_trie_node_key.iter().all(47.3k
|n| *n == Nibble::max()
)47.3k
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0Bc_
Line
Count
Source
239
123
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1k_5slice4iter4IterhEEE0Bc_
Line
Count
Source
239
508
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNvNtBa_6nibble30nibbles_to_bytes_suffix_extend4IterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterNtB1g_6NibbleEEE0Bc_
Line
Count
Source
239
49.2k
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEE0CsDDUKWWCHAU_18smoldot_light_wasm
_RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0Bc_
Line
Count
Source
239
1.02k
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEE0Bc_
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEE0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEE0CsibGXYHQB8Ea_25json_rpc_general_requests
240
                {
241
14.5k
                    return BranchSearch::Found {
242
14.5k
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
243
14.5k
                            inner: storage_trie_node_key.into_iter(),
244
14.5k
                        }),
245
14.5k
                    };
246
47.3k
                }
247
47.3k
248
47.3k
                self.inner = NextKeyInner::FurtherRound {
249
47.3k
                    current_found_branch: storage_trie_node_key,
250
47.3k
                };
251
47.3k
                BranchSearch::NextKey(self)
252
            }
253
254
            (
255
                NextKeyInner::FurtherRound {
256
25.3k
                    mut current_found_branch,
257
25.3k
                },
258
25.3k
                Some(storage_trie_node_key),
259
25.3k
            ) => {
260
25.3k
                let storage_trie_node_key = trie::bytes_to_nibbles(storage_trie_node_key);
261
25.3k
262
25.3k
                let num_common = storage_trie_node_key
263
25.3k
                    .zip(current_found_branch.iter())
264
75.2k
                    .take_while(|(a, b)| a == *b)
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0Bc_
Line
Count
Source
264
4.06k
                    .take_while(|(a, b)| a == *b)
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1k_5slice4iter4IterhEEEs_0Bc_
Line
Count
Source
264
15.5k
                    .take_while(|(a, b)| a == *b)
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNvNtBa_6nibble30nibbles_to_bytes_suffix_extend4IterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterNtB1g_6NibbleEEEs_0Bc_
Line
Count
Source
264
26.2k
                    .take_while(|(a, b)| a == *b)
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm
_RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0Bc_
Line
Count
Source
264
29.3k
                    .take_while(|(a, b)| a == *b)
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs_0Bc_
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests
265
25.3k
                    .count();
266
25.3k
267
25.3k
                // Check against infinite loops.
268
25.3k
                debug_assert!(num_common < current_found_branch.len());
269
270
25.3k
                if !current_found_branch[..num_common].starts_with(&self.prefix)
271
21.7k
                    || &current_found_branch[..num_common] < &self.key_before
272
9.56k
                    || (!self.or_equal && 
current_found_branch[..num_common] == self.key_before8.21k
)
273
                {
274
22.7k
                    return BranchSearch::Found {
275
22.7k
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
276
22.7k
                            inner: current_found_branch.into_iter(),
277
22.7k
                        }),
278
22.7k
                    };
279
2.55k
                }
280
2.55k
281
2.55k
                current_found_branch.truncate(num_common);
282
2.55k
283
2.55k
                if current_found_branch.is_empty()
284
2.53k
                    || 
current_found_branch.iter().all(2.52k
|n| *n == Nibble::max()
)2.52k
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0Bc_
Line
Count
Source
284
37
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1k_5slice4iter4IterhEEEs0_0Bc_
Line
Count
Source
284
183
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
_RNCINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNvNtBa_6nibble30nibbles_to_bytes_suffix_extend4IterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterNtB1g_6NibbleEEEs0_0Bc_
Line
Count
Source
284
2.02k
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm
_RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0Bc_
Line
Count
Source
284
294
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs0_0Bc_
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB8_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1l_5slice4iter4IterhEEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests
285
                {
286
225
                    return BranchSearch::Found {
287
225
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
288
225
                            inner: current_found_branch.into_iter(),
289
225
                        }),
290
225
                    };
291
2.33k
                }
292
2.33k
293
2.33k
                self.inner = NextKeyInner::FurtherRound {
294
2.33k
                    current_found_branch,
295
2.33k
                };
296
2.33k
                BranchSearch::NextKey(self)
297
            }
298
299
            // If `current_found_branch` doesn't have any sibling or uncle after it, then we know
300
            // that there can't be any more branch node and the search is over.
301
            (
302
                NextKeyInner::FurtherRound {
303
24.3k
                    current_found_branch,
304
24.3k
                },
305
24.3k
                None,
306
24.3k
            ) => BranchSearch::Found {
307
24.3k
                branch_trie_node_key: Some(BranchTrieNodeKeyIter {
308
24.3k
                    inner: current_found_branch.into_iter(),
309
24.3k
                }),
310
24.3k
            },
311
        }
312
600k
    }
_RINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEBa_
Line
Count
Source
179
2.04k
    pub fn inject(
180
2.04k
        mut self,
181
2.04k
        storage_trie_node_key: Option<impl Iterator<Item = u8>>,
182
2.04k
    ) -> BranchSearch {
183
2.04k
        match (self.inner, storage_trie_node_key) {
184
            // No matter what, if we're at the first round and the user injected `None`, that
185
            // means `key_before` is equal or superior to the last key of the trie and thus there
186
            // can't be any branch node after it.
187
1.63k
            (NextKeyInner::FirstFound { .. }, None) => BranchSearch::Found {
188
1.63k
                branch_trie_node_key: None,
189
1.63k
            },
190
191
            // If `no_branch_search` is `true`, simply immediately return the value provided by
192
            // the user.
193
            (
194
                NextKeyInner::FirstFound {
195
                    no_branch_search: true,
196
                    ..
197
                },
198
0
                Some(storage_trie_node_key),
199
0
            ) => {
200
0
                let storage_trie_node_key =
201
0
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
202
0
                debug_assert!(storage_trie_node_key >= self.key_before);
203
204
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
205
                // whether the value provided by the user is still within the prefix.
206
0
                if !storage_trie_node_key.starts_with(&self.prefix) {
207
0
                    return BranchSearch::Found {
208
0
                        branch_trie_node_key: None,
209
0
                    };
210
0
                }
211
0
212
0
                BranchSearch::Found {
213
0
                    branch_trie_node_key: Some(BranchTrieNodeKeyIter {
214
0
                        inner: storage_trie_node_key.into_iter(),
215
0
                    }),
216
0
                }
217
            }
218
219
            (
220
                NextKeyInner::FirstFound {
221
                    no_branch_search: false,
222
                    ..
223
                },
224
250
                Some(storage_trie_node_key),
225
250
            ) => {
226
250
                let storage_trie_node_key =
227
250
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
228
250
                debug_assert!(storage_trie_node_key >= self.key_before);
229
230
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
231
                // whether the value provided by the user is still within the prefix.
232
250
                if !storage_trie_node_key.starts_with(&self.prefix) {
233
132
                    return BranchSearch::Found {
234
132
                        branch_trie_node_key: None,
235
132
                    };
236
118
                }
237
118
238
118
                if storage_trie_node_key.is_empty()
239
118
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
240
                {
241
0
                    return BranchSearch::Found {
242
0
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
243
0
                            inner: storage_trie_node_key.into_iter(),
244
0
                        }),
245
0
                    };
246
118
                }
247
118
248
118
                self.inner = NextKeyInner::FurtherRound {
249
118
                    current_found_branch: storage_trie_node_key,
250
118
                };
251
118
                BranchSearch::NextKey(self)
252
            }
253
254
            (
255
                NextKeyInner::FurtherRound {
256
104
                    mut current_found_branch,
257
104
                },
258
104
                Some(storage_trie_node_key),
259
104
            ) => {
260
104
                let storage_trie_node_key = trie::bytes_to_nibbles(storage_trie_node_key);
261
104
262
104
                let num_common = storage_trie_node_key
263
104
                    .zip(current_found_branch.iter())
264
104
                    .take_while(|(a, b)| a == *b)
265
104
                    .count();
266
104
267
104
                // Check against infinite loops.
268
104
                debug_assert!(num_common < current_found_branch.len());
269
270
104
                if !current_found_branch[..num_common].starts_with(&self.prefix)
271
37
                    || &current_found_branch[..num_common] < &self.key_before
272
37
                    || (!self.or_equal && 
current_found_branch[..num_common] == self.key_before0
)
273
                {
274
67
                    return BranchSearch::Found {
275
67
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
276
67
                            inner: current_found_branch.into_iter(),
277
67
                        }),
278
67
                    };
279
37
                }
280
37
281
37
                current_found_branch.truncate(num_common);
282
37
283
37
                if current_found_branch.is_empty()
284
36
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
285
                {
286
1
                    return BranchSearch::Found {
287
1
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
288
1
                            inner: current_found_branch.into_iter(),
289
1
                        }),
290
1
                    };
291
36
                }
292
36
293
36
                self.inner = NextKeyInner::FurtherRound {
294
36
                    current_found_branch,
295
36
                };
296
36
                BranchSearch::NextKey(self)
297
            }
298
299
            // If `current_found_branch` doesn't have any sibling or uncle after it, then we know
300
            // that there can't be any more branch node and the search is over.
301
            (
302
                NextKeyInner::FurtherRound {
303
50
                    current_found_branch,
304
50
                },
305
50
                None,
306
50
            ) => BranchSearch::Found {
307
50
                branch_trie_node_key: Some(BranchTrieNodeKeyIter {
308
50
                    inner: current_found_branch.into_iter(),
309
50
                }),
310
50
            },
311
        }
312
2.04k
    }
_RINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1i_5slice4iter4IterhEEEBa_
Line
Count
Source
179
9.51k
    pub fn inject(
180
9.51k
        mut self,
181
9.51k
        storage_trie_node_key: Option<impl Iterator<Item = u8>>,
182
9.51k
    ) -> BranchSearch {
183
9.51k
        match (self.inner, storage_trie_node_key) {
184
            // No matter what, if we're at the first round and the user injected `None`, that
185
            // means `key_before` is equal or superior to the last key of the trie and thus there
186
            // can't be any branch node after it.
187
7.83k
            (NextKeyInner::FirstFound { .. }, None) => BranchSearch::Found {
188
7.83k
                branch_trie_node_key: None,
189
7.83k
            },
190
191
            // If `no_branch_search` is `true`, simply immediately return the value provided by
192
            // the user.
193
            (
194
                NextKeyInner::FirstFound {
195
                    no_branch_search: true,
196
                    ..
197
                },
198
10
                Some(storage_trie_node_key),
199
10
            ) => {
200
10
                let storage_trie_node_key =
201
10
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
202
10
                debug_assert!(storage_trie_node_key >= self.key_before);
203
204
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
205
                // whether the value provided by the user is still within the prefix.
206
10
                if !storage_trie_node_key.starts_with(&self.prefix) {
207
0
                    return BranchSearch::Found {
208
0
                        branch_trie_node_key: None,
209
0
                    };
210
10
                }
211
10
212
10
                BranchSearch::Found {
213
10
                    branch_trie_node_key: Some(BranchTrieNodeKeyIter {
214
10
                        inner: storage_trie_node_key.into_iter(),
215
10
                    }),
216
10
                }
217
            }
218
219
            (
220
                NextKeyInner::FirstFound {
221
                    no_branch_search: false,
222
                    ..
223
                },
224
1.00k
                Some(storage_trie_node_key),
225
1.00k
            ) => {
226
1.00k
                let storage_trie_node_key =
227
1.00k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
228
1.00k
                debug_assert!(storage_trie_node_key >= self.key_before);
229
230
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
231
                // whether the value provided by the user is still within the prefix.
232
1.00k
                if !storage_trie_node_key.starts_with(&self.prefix) {
233
513
                    return BranchSearch::Found {
234
513
                        branch_trie_node_key: None,
235
513
                    };
236
491
                }
237
491
238
491
                if storage_trie_node_key.is_empty()
239
491
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
240
                {
241
0
                    return BranchSearch::Found {
242
0
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
243
0
                            inner: storage_trie_node_key.into_iter(),
244
0
                        }),
245
0
                    };
246
491
                }
247
491
248
491
                self.inner = NextKeyInner::FurtherRound {
249
491
                    current_found_branch: storage_trie_node_key,
250
491
                };
251
491
                BranchSearch::NextKey(self)
252
            }
253
254
            (
255
                NextKeyInner::FurtherRound {
256
416
                    mut current_found_branch,
257
416
                },
258
416
                Some(storage_trie_node_key),
259
416
            ) => {
260
416
                let storage_trie_node_key = trie::bytes_to_nibbles(storage_trie_node_key);
261
416
262
416
                let num_common = storage_trie_node_key
263
416
                    .zip(current_found_branch.iter())
264
416
                    .take_while(|(a, b)| a == *b)
265
416
                    .count();
266
416
267
416
                // Check against infinite loops.
268
416
                debug_assert!(num_common < current_found_branch.len());
269
270
416
                if !current_found_branch[..num_common].starts_with(&self.prefix)
271
185
                    || &current_found_branch[..num_common] < &self.key_before
272
185
                    || (!self.or_equal && 
current_found_branch[..num_common] == self.key_before0
)
273
                {
274
231
                    return BranchSearch::Found {
275
231
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
276
231
                            inner: current_found_branch.into_iter(),
277
231
                        }),
278
231
                    };
279
185
                }
280
185
281
185
                current_found_branch.truncate(num_common);
282
185
283
185
                if current_found_branch.is_empty()
284
178
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
285
                {
286
7
                    return BranchSearch::Found {
287
7
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
288
7
                            inner: current_found_branch.into_iter(),
289
7
                        }),
290
7
                    };
291
178
                }
292
178
293
178
                self.inner = NextKeyInner::FurtherRound {
294
178
                    current_found_branch,
295
178
                };
296
178
                BranchSearch::NextKey(self)
297
            }
298
299
            // If `current_found_branch` doesn't have any sibling or uncle after it, then we know
300
            // that there can't be any more branch node and the search is over.
301
            (
302
                NextKeyInner::FurtherRound {
303
253
                    current_found_branch,
304
253
                },
305
253
                None,
306
253
            ) => BranchSearch::Found {
307
253
                branch_trie_node_key: Some(BranchTrieNodeKeyIter {
308
253
                    inner: current_found_branch.into_iter(),
309
253
                }),
310
253
            },
311
        }
312
9.51k
    }
_RINvMs0_NtNtCsN16ciHI6Qf_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNvNtB8_6nibble30nibbles_to_bytes_suffix_extend4IterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterNtB1e_6NibbleEEEBa_
Line
Count
Source
179
571k
    pub fn inject(
180
571k
        mut self,
181
571k
        storage_trie_node_key: Option<impl Iterator<Item = u8>>,
182
571k
    ) -> BranchSearch {
183
571k
        match (self.inner, storage_trie_node_key) {
184
            // No matter what, if we're at the first round and the user injected `None`, that
185
            // means `key_before` is equal or superior to the last key of the trie and thus there
186
            // can't be any branch node after it.
187
329k
            (NextKeyInner::FirstFound { .. }, None) => BranchSearch::Found {
188
329k
                branch_trie_node_key: None,
189
329k
            },
190
191
            // If `no_branch_search` is `true`, simply immediately return the value provided by
192
            // the user.
193
            (
194
                NextKeyInner::FirstFound {
195
                    no_branch_search: true,
196
                    ..
197
                },
198
96.9k
                Some(storage_trie_node_key),
199
96.9k
            ) => {
200
96.9k
                let storage_trie_node_key =
201
96.9k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
202
96.9k
                debug_assert!(storage_trie_node_key >= self.key_before);
203
204
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
205
                // whether the value provided by the user is still within the prefix.
206
96.9k
                if !storage_trie_node_key.starts_with(&self.prefix) {
207
37.3k
                    return BranchSearch::Found {
208
37.3k
                        branch_trie_node_key: None,
209
37.3k
                    };
210
59.6k
                }
211
59.6k
212
59.6k
                BranchSearch::Found {
213
59.6k
                    branch_trie_node_key: Some(BranchTrieNodeKeyIter {
214
59.6k
                        inner: storage_trie_node_key.into_iter(),
215
59.6k
                    }),
216
59.6k
                }
217
            }
218
219
            (
220
                NextKeyInner::FirstFound {
221
                    no_branch_search: false,
222
                    ..
223
                },
224
97.7k
                Some(storage_trie_node_key),
225
97.7k
            ) => {
226
97.7k
                let storage_trie_node_key =
227
97.7k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
228
97.7k
                debug_assert!(storage_trie_node_key >= self.key_before);
229
230
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
231
                // whether the value provided by the user is still within the prefix.
232
97.7k
                if !storage_trie_node_key.starts_with(&self.prefix) {
233
37.4k
                    return BranchSearch::Found {
234
37.4k
                        branch_trie_node_key: None,
235
37.4k
                    };
236
60.2k
                }
237
60.2k
238
60.2k
                if storage_trie_node_key.is_empty()
239
45.7k
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
240
                {
241
14.5k
                    return BranchSearch::Found {
242
14.5k
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
243
14.5k
                            inner: storage_trie_node_key.into_iter(),
244
14.5k
                        }),
245
14.5k
                    };
246
45.7k
                }
247
45.7k
248
45.7k
                self.inner = NextKeyInner::FurtherRound {
249
45.7k
                    current_found_branch: storage_trie_node_key,
250
45.7k
                };
251
45.7k
                BranchSearch::NextKey(self)
252
            }
253
254
            (
255
                NextKeyInner::FurtherRound {
256
23.9k
                    mut current_found_branch,
257
23.9k
                },
258
23.9k
                Some(storage_trie_node_key),
259
23.9k
            ) => {
260
23.9k
                let storage_trie_node_key = trie::bytes_to_nibbles(storage_trie_node_key);
261
23.9k
262
23.9k
                let num_common = storage_trie_node_key
263
23.9k
                    .zip(current_found_branch.iter())
264
23.9k
                    .take_while(|(a, b)| a == *b)
265
23.9k
                    .count();
266
23.9k
267
23.9k
                // Check against infinite loops.
268
23.9k
                debug_assert!(num_common < current_found_branch.len());
269
270
23.9k
                if !current_found_branch[..num_common].starts_with(&self.prefix)
271
21.2k
                    || &current_found_branch[..num_common] < &self.key_before
272
9.02k
                    || (!self.or_equal && 
current_found_branch[..num_common] == self.key_before8.21k
)
273
                {
274
21.9k
                    return BranchSearch::Found {
275
21.9k
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
276
21.9k
                            inner: current_found_branch.into_iter(),
277
21.9k
                        }),
278
21.9k
                    };
279
2.02k
                }
280
2.02k
281
2.02k
                current_found_branch.truncate(num_common);
282
2.02k
283
2.02k
                if current_found_branch.is_empty()
284
2.02k
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
285
                {
286
196
                    return BranchSearch::Found {
287
196
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
288
196
                            inner: current_found_branch.into_iter(),
289
196
                        }),
290
196
                    };
291
1.82k
                }
292
1.82k
293
1.82k
                self.inner = NextKeyInner::FurtherRound {
294
1.82k
                    current_found_branch,
295
1.82k
                };
296
1.82k
                BranchSearch::NextKey(self)
297
            }
298
299
            // If `current_found_branch` doesn't have any sibling or uncle after it, then we know
300
            // that there can't be any more branch node and the search is over.
301
            (
302
                NextKeyInner::FurtherRound {
303
23.5k
                    current_found_branch,
304
23.5k
                },
305
23.5k
                None,
306
23.5k
            ) => BranchSearch::Found {
307
23.5k
                branch_trie_node_key: Some(BranchTrieNodeKeyIter {
308
23.5k
                    inner: current_found_branch.into_iter(),
309
23.5k
                }),
310
23.5k
            },
311
        }
312
571k
    }
Unexecuted instantiation: _RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1j_5slice4iter4IterhEEECsDDUKWWCHAU_18smoldot_light_wasm
_RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEBa_
Line
Count
Source
179
17.4k
    pub fn inject(
180
17.4k
        mut self,
181
17.4k
        storage_trie_node_key: Option<impl Iterator<Item = u8>>,
182
17.4k
    ) -> BranchSearch {
183
17.4k
        match (self.inner, storage_trie_node_key) {
184
            // No matter what, if we're at the first round and the user injected `None`, that
185
            // means `key_before` is equal or superior to the last key of the trie and thus there
186
            // can't be any branch node after it.
187
14.1k
            (NextKeyInner::FirstFound { .. }, None) => BranchSearch::Found {
188
14.1k
                branch_trie_node_key: None,
189
14.1k
            },
190
191
            // If `no_branch_search` is `true`, simply immediately return the value provided by
192
            // the user.
193
            (
194
                NextKeyInner::FirstFound {
195
                    no_branch_search: true,
196
                    ..
197
                },
198
0
                Some(storage_trie_node_key),
199
0
            ) => {
200
0
                let storage_trie_node_key =
201
0
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
202
0
                debug_assert!(storage_trie_node_key >= self.key_before);
203
204
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
205
                // whether the value provided by the user is still within the prefix.
206
0
                if !storage_trie_node_key.starts_with(&self.prefix) {
207
0
                    return BranchSearch::Found {
208
0
                        branch_trie_node_key: None,
209
0
                    };
210
0
                }
211
0
212
0
                BranchSearch::Found {
213
0
                    branch_trie_node_key: Some(BranchTrieNodeKeyIter {
214
0
                        inner: storage_trie_node_key.into_iter(),
215
0
                    }),
216
0
                }
217
            }
218
219
            (
220
                NextKeyInner::FirstFound {
221
                    no_branch_search: false,
222
                    ..
223
                },
224
1.99k
                Some(storage_trie_node_key),
225
1.99k
            ) => {
226
1.99k
                let storage_trie_node_key =
227
1.99k
                    trie::bytes_to_nibbles(storage_trie_node_key).collect::<Vec<_>>();
228
1.99k
                debug_assert!(storage_trie_node_key >= self.key_before);
229
230
                // Due to our usage of `nibbles_to_bytes_truncate` in `prefix()`, we must check
231
                // whether the value provided by the user is still within the prefix.
232
1.99k
                if !storage_trie_node_key.starts_with(&self.prefix) {
233
987
                    return BranchSearch::Found {
234
987
                        branch_trie_node_key: None,
235
987
                    };
236
1.00k
                }
237
1.00k
238
1.00k
                if storage_trie_node_key.is_empty()
239
1.00k
                    || storage_trie_node_key.iter().all(|n| *n == Nibble::max())
240
                {
241
0
                    return BranchSearch::Found {
242
0
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
243
0
                            inner: storage_trie_node_key.into_iter(),
244
0
                        }),
245
0
                    };
246
1.00k
                }
247
1.00k
248
1.00k
                self.inner = NextKeyInner::FurtherRound {
249
1.00k
                    current_found_branch: storage_trie_node_key,
250
1.00k
                };
251
1.00k
                BranchSearch::NextKey(self)
252
            }
253
254
            (
255
                NextKeyInner::FurtherRound {
256
861
                    mut current_found_branch,
257
861
                },
258
861
                Some(storage_trie_node_key),
259
861
            ) => {
260
861
                let storage_trie_node_key = trie::bytes_to_nibbles(storage_trie_node_key);
261
861
262
861
                let num_common = storage_trie_node_key
263
861
                    .zip(current_found_branch.iter())
264
861
                    .take_while(|(a, b)| a == *b)
265
861
                    .count();
266
861
267
861
                // Check against infinite loops.
268
861
                debug_assert!(num_common < current_found_branch.len());
269
270
861
                if !current_found_branch[..num_common].starts_with(&self.prefix)
271
315
                    || &current_found_branch[..num_common] < &self.key_before
272
315
                    || (!self.or_equal && 
current_found_branch[..num_common] == self.key_before0
)
273
                {
274
546
                    return BranchSearch::Found {
275
546
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
276
546
                            inner: current_found_branch.into_iter(),
277
546
                        }),
278
546
                    };
279
315
                }
280
315
281
315
                current_found_branch.truncate(num_common);
282
315
283
315
                if current_found_branch.is_empty()
284
294
                    || current_found_branch.iter().all(|n| *n == Nibble::max())
285
                {
286
21
                    return BranchSearch::Found {
287
21
                        branch_trie_node_key: Some(BranchTrieNodeKeyIter {
288
21
                            inner: current_found_branch.into_iter(),
289
21
                        }),
290
21
                    };
291
294
                }
292
294
293
294
                self.inner = NextKeyInner::FurtherRound {
294
294
                    current_found_branch,
295
294
                };
296
294
                BranchSearch::NextKey(self)
297
            }
298
299
            // If `current_found_branch` doesn't have any sibling or uncle after it, then we know
300
            // that there can't be any more branch node and the search is over.
301
            (
302
                NextKeyInner::FurtherRound {
303
441
                    current_found_branch,
304
441
                },
305
441
                None,
306
441
            ) => BranchSearch::Found {
307
441
                branch_trie_node_key: Some(BranchTrieNodeKeyIter {
308
441
                    inner: current_found_branch.into_iter(),
309
441
                }),
310
441
            },
311
        }
312
17.4k
    }
Unexecuted instantiation: _RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1j_5slice4iter4IterhEEEBa_
Unexecuted instantiation: _RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1j_5slice4iter4IterhEEECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1j_5slice4iter4IterhEEECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs0_NtNtCseuYC0Zibziv_7smoldot4trie13branch_searchNtB6_7NextKey6injectINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1j_5slice4iter4IterhEEECsibGXYHQB8Ea_25json_rpc_general_requests
313
}