reth_static_file_types/
lib.rs1#![doc(
4 html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
5 html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
6 issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
7)]
8#![cfg_attr(not(test), warn(unused_crate_dependencies))]
9#![cfg_attr(docsrs, feature(doc_cfg))]
10#![cfg_attr(not(feature = "std"), no_std)]
11
12extern crate alloc;
13
14mod compression;
15mod event;
16mod segment;
17
18use alloy_primitives::BlockNumber;
19pub use compression::Compression;
20use core::ops::RangeInclusive;
21pub use event::StaticFileProducerEvent;
22pub use segment::{SegmentConfig, SegmentHeader, SegmentRangeInclusive, StaticFileSegment};
23
24pub type StaticFileMap<T> = alloc::boxed::Box<fixed_map::Map<StaticFileSegment, T>>;
26
27pub const DEFAULT_BLOCKS_PER_STATIC_FILE: u64 = 500_000;
29
30#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
32pub struct HighestStaticFiles {
33 pub receipts: Option<BlockNumber>,
36}
37
38impl HighestStaticFiles {
39 fn iter(&self) -> impl Iterator<Item = Option<BlockNumber>> {
41 [self.receipts].into_iter()
42 }
43
44 pub fn min_block_num(&self) -> Option<u64> {
46 self.iter().flatten().min()
47 }
48
49 pub fn max_block_num(&self) -> Option<u64> {
51 self.iter().flatten().max()
52 }
53}
54
55#[derive(Debug, Clone, Eq, PartialEq)]
57pub struct StaticFileTargets {
58 pub receipts: Option<RangeInclusive<BlockNumber>>,
60}
61
62impl StaticFileTargets {
63 pub const fn any(&self) -> bool {
65 self.receipts.is_some()
66 }
67
68 pub fn is_contiguous_to_highest_static_files(&self, static_files: HighestStaticFiles) -> bool {
71 core::iter::once(&(self.receipts.as_ref(), static_files.receipts)).all(
72 |(target_block_range, highest_static_file_block)| {
73 target_block_range.is_none_or(|target_block_range| {
74 *target_block_range.start() ==
75 highest_static_file_block
76 .map_or(0, |highest_static_file_block| highest_static_file_block + 1)
77 })
78 },
79 )
80 }
81}
82
83pub const fn find_fixed_range(
86 block: BlockNumber,
87 blocks_per_static_file: u64,
88) -> SegmentRangeInclusive {
89 let start = (block / blocks_per_static_file) * blocks_per_static_file;
90 SegmentRangeInclusive::new(start, start + blocks_per_static_file - 1)
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_highest_static_files_min() {
99 let files = HighestStaticFiles { receipts: Some(100) };
100
101 assert_eq!(files.min_block_num(), Some(100));
103
104 let empty_files = HighestStaticFiles::default();
105 assert_eq!(empty_files.min_block_num(), None);
107 }
108
109 #[test]
110 fn test_highest_static_files_max() {
111 let files = HighestStaticFiles { receipts: Some(100) };
112
113 assert_eq!(files.max_block_num(), Some(100));
115
116 let empty_files = HighestStaticFiles::default();
117 assert_eq!(empty_files.max_block_num(), None);
119 }
120
121 #[test]
122 fn test_find_fixed_range() {
123 let block: BlockNumber = 600_000;
125 let range = find_fixed_range(block, DEFAULT_BLOCKS_PER_STATIC_FILE);
126 assert_eq!(range.start(), 500_000);
127 assert_eq!(range.end(), 999_999);
128
129 let block: BlockNumber = 1_200_000;
131 let range = find_fixed_range(block, 1_000_000);
132 assert_eq!(range.start(), 1_000_000);
133 assert_eq!(range.end(), 1_999_999);
134 }
135}