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 self.keys.sort_unstable();
198 self.keys.dedup();
199 self.keys.shrink_to_fit();
201 }
202 PrefixSet::new(self.all, self.keys)
203 }
204}
205
206impl<'a> IntoIterator for &'a PrefixSetMut {
207 type Item = &'a Nibbles;
208 type IntoIter = core::slice::Iter<'a, Nibbles>;
209 fn into_iter(self) -> Self::IntoIter {
210 self.iter()
211 }
212}
213
214#[derive(Debug, Clone)]
218pub struct PrefixSet {
219 all: bool,
221 index: usize,
222 keys: Option<Arc<Vec<Nibbles>>>,
224}
225
226impl Default for PrefixSet {
227 fn default() -> Self {
228 Self::new(false, Vec::new())
229 }
230}
231
232impl<I> From<I> for PrefixSet
233where
234 I: Iterator<Item = B256>,
235{
236 fn from(keys: I) -> Self {
237 let (lower_bound, upper_bound) = keys.size_hint();
238 let mut unpacked = Vec::with_capacity(upper_bound.unwrap_or(lower_bound));
239 let mut previous = None;
240
241 for key in keys {
242 debug_assert!(
243 previous.is_none_or(|previous| previous <= key),
244 "prefix set keys must be sorted"
245 );
246 if previous != Some(key) {
247 unpacked.push(Nibbles::unpack(key));
248 }
249 previous = Some(key);
250 }
251
252 Self::new(false, unpacked)
253 }
254}
255
256impl PrefixSet {
257 fn new(all: bool, keys: Vec<Nibbles>) -> Self {
258 Self { index: 0, all, keys: (!all && !keys.is_empty()).then(|| Arc::new(keys)) }
259 }
260
261 pub fn all_paths() -> Self {
263 Self::new(true, Vec::new())
264 }
265
266 #[inline]
281 pub fn contains(&mut self, prefix: &Nibbles) -> bool {
282 if self.all {
283 return true
284 }
285
286 let keys = self.keys.as_deref().map(Vec::as_slice).unwrap_or_default();
287 while self.index > 0 && &keys[self.index] > prefix {
288 self.index -= 1;
289 }
290
291 for (idx, key) in keys[self.index..].iter().enumerate() {
292 if key.starts_with(prefix) {
293 self.index += idx;
294 return true
295 }
296
297 if key > prefix {
298 self.index += idx;
299 return false
300 }
301 }
302
303 false
304 }
305
306 #[inline]
312 pub fn contains_range(&mut self, range: Range<&Nibbles>) -> bool {
313 if self.all {
314 return true
315 }
316
317 let keys = self.keys.as_deref().map(Vec::as_slice).unwrap_or_default();
318 while self.index > 0 && &keys[self.index] >= range.end {
319 self.index -= 1;
320 }
321
322 for (idx, key) in keys[self.index..].iter().enumerate() {
323 if key >= range.start && key < range.end {
324 self.index += idx;
325 return true
326 }
327
328 if key >= range.end {
329 self.index += idx;
330 return false
331 }
332 }
333
334 false
335 }
336
337 #[inline]
339 pub fn contains_from(&mut self, start: &Nibbles) -> bool {
340 if self.all {
341 return true
342 }
343
344 let keys = self.keys.as_deref().map(Vec::as_slice).unwrap_or_default();
345 while self.index > 0 && &keys[self.index] > start {
346 self.index -= 1;
347 }
348
349 for (idx, key) in keys[self.index..].iter().enumerate() {
350 if key >= start {
351 self.index += idx;
352 return true
353 }
354 }
355
356 false
357 }
358
359 pub fn iter(&self) -> core::slice::Iter<'_, Nibbles> {
361 self.slice().iter()
362 }
363
364 pub fn slice(&self) -> &[Nibbles] {
366 self.keys.as_deref().map(Vec::as_slice).unwrap_or_default()
367 }
368
369 pub const fn all(&self) -> bool {
371 self.all
372 }
373
374 pub fn len(&self) -> usize {
376 self.slice().len()
377 }
378
379 pub const fn is_empty(&self) -> bool {
381 !self.all && self.keys.is_none()
382 }
383}
384
385impl<'a> IntoIterator for &'a PrefixSet {
386 type Item = &'a Nibbles;
387 type IntoIter = core::slice::Iter<'a, Nibbles>;
388 fn into_iter(self) -> Self::IntoIter {
389 self.iter()
390 }
391}
392
393#[cfg(test)]
394mod tests {
395 use super::*;
396 use alloy_primitives::B256;
397
398 #[test]
399 fn test_contains_with_multiple_inserts_and_duplicates() {
400 let mut prefix_set_mut = PrefixSetMut::default();
401 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
402 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
403 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
404 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3])); let mut prefix_set = prefix_set_mut.freeze();
407 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
408 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
409 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
410 assert_eq!(prefix_set.len(), 3); }
412
413 #[test]
414 fn test_contains_from() {
415 let first = Nibbles::from_nibbles([1, 2, 3]);
416 let middle = Nibbles::from_nibbles([1, 2, 4]);
417 let last = Nibbles::from_nibbles([4, 5, 6]);
418 let mut prefix_set = PrefixSetMut::from([first, middle, last]).freeze();
419
420 assert!(prefix_set.contains_range(&first..&middle));
421 assert!(prefix_set.contains_from(&middle));
422 assert!(prefix_set.contains_from(&last));
423 assert!(!prefix_set.contains_from(&Nibbles::from_nibbles([5])));
424 }
425
426 #[test]
427 fn test_from_sorted_b256_iterator() {
428 let first = B256::with_last_byte(1);
429 let second = B256::with_last_byte(2);
430 let prefix_set = PrefixSet::from([first, second].into_iter());
431
432 assert_eq!(prefix_set.slice(), &[Nibbles::unpack(first), Nibbles::unpack(second)]);
433 }
434
435 #[test]
436 fn test_from_sorted_b256_iterator_with_duplicates() {
437 let first = B256::with_last_byte(1);
438 let second = B256::with_last_byte(2);
439 let prefix_set = PrefixSet::from([first, first, second].into_iter());
440
441 assert_eq!(prefix_set.slice(), &[Nibbles::unpack(first), Nibbles::unpack(second)]);
442 }
443
444 #[cfg(debug_assertions)]
445 #[test]
446 #[should_panic(expected = "prefix set keys must be sorted")]
447 fn test_from_unsorted_b256_iterator() {
448 let _: PrefixSet = [B256::with_last_byte(2), B256::with_last_byte(1)].into_iter().into();
449 }
450
451 #[test]
452 fn test_freeze_shrinks_capacity() {
453 let mut prefix_set_mut = PrefixSetMut::default();
454 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
455 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
456 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
457 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();
463 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
464 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
465 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
466 assert_eq!(prefix_set.slice().len(), 3); assert_eq!(prefix_set.keys.as_ref().unwrap().capacity(), 3); }
469
470 #[test]
471 fn test_freeze_shrinks_existing_capacity() {
472 let mut prefix_set_mut = PrefixSetMut::with_capacity(101);
474 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 3]));
475 prefix_set_mut.insert(Nibbles::from_nibbles([1, 2, 4]));
476 prefix_set_mut.insert(Nibbles::from_nibbles([4, 5, 6]));
477 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();
483 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([1, 2])));
484 assert!(prefix_set.contains(&Nibbles::from_nibbles_unchecked([4, 5])));
485 assert!(!prefix_set.contains(&Nibbles::from_nibbles_unchecked([7, 8])));
486 assert_eq!(prefix_set.slice().len(), 3); assert_eq!(prefix_set.keys.as_ref().unwrap().capacity(), 3); }
489
490 #[test]
491 fn test_empty_prefix_sets_do_not_allocate() {
492 assert!(PrefixSet::default().keys.is_none());
493 assert!(PrefixSetMut::default().freeze().keys.is_none());
494 assert!(PrefixSet::from(core::iter::empty()).keys.is_none());
495 assert!(PrefixSet::all_paths().keys.is_none());
496 }
497
498 #[test]
499 fn test_prefix_set_all_extend() {
500 let mut prefix_set_mut = PrefixSetMut::default();
501 prefix_set_mut.extend(PrefixSetMut::all());
502 assert!(prefix_set_mut.all);
503 }
504
505 #[test]
506 fn test_prefix_set_slice_returns_frozen_keys() {
507 let path_a = Nibbles::from_nibbles([1, 2, 3]);
508 let path_b = Nibbles::from_nibbles([4, 5, 6]);
509 let mut prefix_set_mut = PrefixSetMut::default();
510 prefix_set_mut.insert(path_b);
511 prefix_set_mut.insert(path_a);
512 prefix_set_mut.insert(path_b);
513
514 let prefix_set = prefix_set_mut.freeze();
515 assert_eq!(prefix_set.slice(), &[path_a, path_b]);
516 }
517
518 #[test]
519 fn test_trie_prefix_sets_mut_extend_ref() {
520 let account_path = Nibbles::from_nibbles([1, 2]);
521 let storage_path = Nibbles::from_nibbles([3, 4]);
522 let storage_account = B256::with_last_byte(1);
523 let destroyed_account = B256::with_last_byte(2);
524 let other = TriePrefixSetsMut {
525 account_prefix_set: PrefixSetMut::from([account_path]),
526 storage_prefix_sets: B256Map::from_iter([(
527 storage_account,
528 PrefixSetMut::from([storage_path]),
529 )]),
530 destroyed_accounts: B256Set::from_iter([destroyed_account]),
531 };
532
533 let mut prefix_sets = TriePrefixSetsMut::default();
534 prefix_sets.extend_ref(&other);
535
536 let frozen = prefix_sets.freeze();
537 assert_eq!(frozen.account_prefix_set.slice(), &[account_path]);
538 assert_eq!(frozen.storage_prefix_sets[&storage_account].slice(), &[storage_path]);
539 assert!(frozen.destroyed_accounts.contains(&destroyed_account));
540 assert_eq!(other.account_prefix_set.len(), 1);
541 }
542}