1use crate::Nibbles;
2use alloc::{sync::Arc, vec::Vec};
3use alloy_primitives::{
4 map::{B256Map, B256Set},
5 B256,
6};
7use core::ops::Range;
8
9#[derive(Clone, Default, Debug, PartialEq, Eq)]
11pub struct TriePrefixSetsMut {
12 pub account_prefix_set: PrefixSetMut,
14 pub storage_prefix_sets: B256Map<PrefixSetMut>,
17 pub destroyed_accounts: B256Set,
19}
20
21impl TriePrefixSetsMut {
22 pub fn is_empty(&self) -> bool {
24 self.account_prefix_set.is_empty() &&
25 self.storage_prefix_sets.is_empty() &&
26 self.destroyed_accounts.is_empty()
27 }
28
29 pub fn extend(&mut self, other: Self) {
31 self.account_prefix_set.extend(other.account_prefix_set);
32 for (hashed_address, prefix_set) in other.storage_prefix_sets {
33 self.storage_prefix_sets.entry(hashed_address).or_default().extend(prefix_set);
34 }
35 self.destroyed_accounts.extend(other.destroyed_accounts);
36 }
37
38 pub fn extend_ref(&mut self, other: &Self) {
40 self.account_prefix_set.extend_ref(&other.account_prefix_set);
41 for (hashed_address, prefix_set) in &other.storage_prefix_sets {
42 self.storage_prefix_sets.entry(*hashed_address).or_default().extend_ref(prefix_set);
43 }
44 self.destroyed_accounts.extend(other.destroyed_accounts.iter().copied());
45 }
46
47 pub fn freeze(self) -> TriePrefixSets {
51 TriePrefixSets {
52 account_prefix_set: self.account_prefix_set.freeze(),
53 storage_prefix_sets: self
54 .storage_prefix_sets
55 .into_iter()
56 .map(|(hashed_address, prefix_set)| (hashed_address, prefix_set.freeze()))
57 .collect(),
58 destroyed_accounts: self.destroyed_accounts,
59 }
60 }
61
62 pub fn clear(&mut self) {
64 self.destroyed_accounts.clear();
65 self.storage_prefix_sets.clear();
66 self.account_prefix_set.clear();
67 }
68}
69
70#[derive(Default, Debug, Clone)]
72pub struct TriePrefixSets {
73 pub account_prefix_set: PrefixSet,
75 pub storage_prefix_sets: B256Map<PrefixSet>,
78 pub destroyed_accounts: B256Set,
80}
81
82#[derive(PartialEq, Eq, Clone, Default, Debug)]
112pub struct PrefixSetMut {
113 all: bool,
116 keys: Vec<Nibbles>,
117}
118
119impl<I> From<I> for PrefixSetMut
120where
121 I: IntoIterator<Item = Nibbles>,
122{
123 fn from(value: I) -> Self {
124 Self { all: false, keys: value.into_iter().collect() }
125 }
126}
127
128impl PrefixSetMut {
129 pub fn with_capacity(capacity: usize) -> Self {
131 Self { all: false, keys: Vec::with_capacity(capacity) }
132 }
133
134 pub const fn all() -> Self {
136 Self { all: true, keys: Vec::new() }
137 }
138
139 pub fn insert(&mut self, nibbles: Nibbles) {
141 self.keys.push(nibbles);
142 }
143
144 pub fn extend(&mut self, other: Self) {
146 self.all |= other.all;
147 self.keys.extend(other.keys);
148 }
149
150 pub fn extend_ref(&mut self, other: &Self) {
152 self.all |= other.all;
153 self.keys.extend(other.keys.iter().copied());
154 }
155
156 pub fn append(&mut self, other: &mut Self) {
158 self.all |= other.all;
159 other.all = false;
160 self.keys.append(&mut other.keys);
161 }
162
163 pub fn extend_keys<I>(&mut self, keys: I)
165 where
166 I: IntoIterator<Item = Nibbles>,
167 {
168 self.keys.extend(keys);
169 }
170
171 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
173 self.keys.iter()
174 }
175
176 pub const fn len(&self) -> usize {
178 self.keys.len()
179 }
180
181 pub const fn is_empty(&self) -> bool {
183 !self.all && self.keys.is_empty()
184 }
185
186 pub fn clear(&mut self) {
188 self.all = false;
189 self.keys.clear();
190 }
191
192 pub fn freeze(mut self) -> PrefixSet {
196 if self.all {
197 PrefixSet { index: 0, all: true, keys: Arc::new(Vec::new()) }
198 } else {
199 self.keys.sort_unstable();
200 self.keys.dedup();
201 self.keys.shrink_to_fit();
203 PrefixSet { index: 0, all: false, keys: Arc::new(self.keys) }
204 }
205 }
206}
207
208impl<'a> IntoIterator for &'a PrefixSetMut {
209 type Item = &'a Nibbles;
210 type IntoIter = core::slice::Iter<'a, Nibbles>;
211 fn into_iter(self) -> Self::IntoIter {
212 self.iter()
213 }
214}
215
216#[derive(Debug, Default, Clone)]
220pub struct PrefixSet {
221 all: bool,
223 index: usize,
224 keys: Arc<Vec<Nibbles>>,
225}
226
227impl<I> From<I> for PrefixSet
228where
229 I: Iterator<Item = B256>,
230{
231 fn from(keys: I) -> Self {
232 let (lower_bound, upper_bound) = keys.size_hint();
233 let mut unpacked = Vec::with_capacity(upper_bound.unwrap_or(lower_bound));
234 let mut previous = None;
235
236 for key in keys {
237 debug_assert!(
238 previous.is_none_or(|previous| previous <= key),
239 "prefix set keys must be sorted"
240 );
241 if previous != Some(key) {
242 unpacked.push(Nibbles::unpack(key));
243 }
244 previous = Some(key);
245 }
246
247 Self { index: 0, all: false, keys: Arc::new(unpacked) }
248 }
249}
250
251impl PrefixSet {
252 pub fn all_paths() -> Self {
254 Self { index: 0, all: true, keys: Arc::new(Vec::new()) }
255 }
256
257 #[inline]
272 pub fn contains(&mut self, prefix: &Nibbles) -> bool {
273 if self.all {
274 return true
275 }
276
277 while self.index > 0 && &self.keys[self.index] > prefix {
278 self.index -= 1;
279 }
280
281 for (idx, key) in self.keys[self.index..].iter().enumerate() {
282 if key.starts_with(prefix) {
283 self.index += idx;
284 return true
285 }
286
287 if key > prefix {
288 self.index += idx;
289 return false
290 }
291 }
292
293 false
294 }
295
296 #[inline]
302 pub fn contains_range(&mut self, range: Range<&Nibbles>) -> bool {
303 if self.all {
304 return true
305 }
306
307 while self.index > 0 && &self.keys[self.index] >= range.end {
308 self.index -= 1;
309 }
310
311 for (idx, key) in self.keys[self.index..].iter().enumerate() {
312 if key >= range.start && key < range.end {
313 self.index += idx;
314 return true
315 }
316
317 if key >= range.end {
318 self.index += idx;
319 return false
320 }
321 }
322
323 false
324 }
325
326 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
328 self.keys.iter()
329 }
330
331 pub fn slice(&self) -> &[Nibbles] {
333 self.keys.as_slice()
334 }
335
336 pub const fn all(&self) -> bool {
338 self.all
339 }
340
341 pub fn len(&self) -> usize {
343 self.keys.len()
344 }
345
346 pub fn is_empty(&self) -> bool {
348 !self.all && self.keys.is_empty()
349 }
350}
351
352impl<'a> IntoIterator for &'a PrefixSet {
353 type Item = &'a Nibbles;
354 type IntoIter = core::slice::Iter<'a, Nibbles>;
355 fn into_iter(self) -> Self::IntoIter {
356 self.iter()
357 }
358}
359
360#[cfg(test)]
361mod tests {
362 use super::*;
363 use alloy_primitives::B256;
364
365 #[test]
366 fn test_contains_with_multiple_inserts_and_duplicates() {
367 let mut prefix_set_mut = PrefixSetMut::default();
368 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
369 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
370 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
371 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); let mut prefix_set = prefix_set_mut.freeze();
374 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
375 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
376 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
377 assert_eq!(prefix_set.len(), 3); }
379
380 #[test]
381 fn test_from_sorted_b256_iterator() {
382 let first = B256::with_last_byte(1);
383 let second = B256::with_last_byte(2);
384 let prefix_set = PrefixSet::from([first, second].into_iter());
385
386 assert_eq!(prefix_set.slice(), &[Nibbles::unpack(first), Nibbles::unpack(second)]);
387 }
388
389 #[test]
390 fn test_from_sorted_b256_iterator_with_duplicates() {
391 let first = B256::with_last_byte(1);
392 let second = B256::with_last_byte(2);
393 let prefix_set = PrefixSet::from([first, first, second].into_iter());
394
395 assert_eq!(prefix_set.slice(), &[Nibbles::unpack(first), Nibbles::unpack(second)]);
396 }
397
398 #[cfg(debug_assertions)]
399 #[test]
400 #[should_panic(expected = "prefix set keys must be sorted")]
401 fn test_from_unsorted_b256_iterator() {
402 let _: PrefixSet = [B256::with_last_byte(2), B256::with_last_byte(1)].into_iter().into();
403 }
404
405 #[test]
406 fn test_freeze_shrinks_capacity() {
407 let mut prefix_set_mut = PrefixSetMut::default();
408 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
409 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
410 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
411 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); assert_eq!(prefix_set_mut.keys.len(), 4); assert_eq!(prefix_set_mut.keys.capacity(), 4); let mut prefix_set = prefix_set_mut.freeze();
417 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
418 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
419 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
420 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
423
424 #[test]
425 fn test_freeze_shrinks_existing_capacity() {
426 let mut prefix_set_mut = PrefixSetMut::with_capacity(101);
428 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
429 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
430 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
431 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); assert_eq!(prefix_set_mut.keys.len(), 4); assert_eq!(prefix_set_mut.keys.capacity(), 101); let mut prefix_set = prefix_set_mut.freeze();
437 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
438 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
439 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
440 assert_eq!(prefix_set.keys.len(), 3); assert_eq!(prefix_set.keys.capacity(), 3); }
443
444 #[test]
445 fn test_prefix_set_all_extend() {
446 let mut prefix_set_mut = PrefixSetMut::default();
447 prefix_set_mut.extend(PrefixSetMut::all());
448 assert!(prefix_set_mut.all);
449 }
450
451 #[test]
452 fn test_prefix_set_slice_returns_frozen_keys() {
453 let path_a = Nibbles::from_nibbles([1, 2, 3]);
454 let path_b = Nibbles::from_nibbles([4, 5, 6]);
455 let mut prefix_set_mut = PrefixSetMut::default();
456 prefix_set_mut.insert(path_b);
457 prefix_set_mut.insert(path_a);
458 prefix_set_mut.insert(path_b);
459
460 let prefix_set = prefix_set_mut.freeze();
461 assert_eq!(prefix_set.slice(), &[path_a, path_b]);
462 }
463
464 #[test]
465 fn test_trie_prefix_sets_mut_extend_ref() {
466 let account_path = Nibbles::from_nibbles([1, 2]);
467 let storage_path = Nibbles::from_nibbles([3, 4]);
468 let storage_account = B256::with_last_byte(1);
469 let destroyed_account = B256::with_last_byte(2);
470 let other = TriePrefixSetsMut {
471 account_prefix_set: PrefixSetMut::from([account_path]),
472 storage_prefix_sets: B256Map::from_iter([(
473 storage_account,
474 PrefixSetMut::from([storage_path]),
475 )]),
476 destroyed_accounts: B256Set::from_iter([destroyed_account]),
477 };
478
479 let mut prefix_sets = TriePrefixSetsMut::default();
480 prefix_sets.extend_ref(&other);
481
482 let frozen = prefix_sets.freeze();
483 assert_eq!(frozen.account_prefix_set.slice(), &[account_path]);
484 assert_eq!(frozen.storage_prefix_sets[&storage_account].slice(), &[storage_path]);
485 assert!(frozen.destroyed_accounts.contains(&destroyed_account));
486 assert_eq!(other.account_prefix_set.len(), 1);
487 }
488}