reth_static_file_types/
lib.rs#![doc(
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
mod compression;
mod event;
mod segment;
use alloy_primitives::BlockNumber;
pub use compression::Compression;
pub use event::StaticFileProducerEvent;
pub use segment::{SegmentConfig, SegmentHeader, SegmentRangeInclusive, StaticFileSegment};
use std::ops::RangeInclusive;
pub const DEFAULT_BLOCKS_PER_STATIC_FILE: u64 = 500_000;
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
pub struct HighestStaticFiles {
pub headers: Option<BlockNumber>,
pub receipts: Option<BlockNumber>,
pub transactions: Option<BlockNumber>,
}
impl HighestStaticFiles {
pub const fn highest(&self, segment: StaticFileSegment) -> Option<BlockNumber> {
match segment {
StaticFileSegment::Headers => self.headers,
StaticFileSegment::Transactions => self.transactions,
StaticFileSegment::Receipts => self.receipts,
}
}
pub fn as_mut(&mut self, segment: StaticFileSegment) -> &mut Option<BlockNumber> {
match segment {
StaticFileSegment::Headers => &mut self.headers,
StaticFileSegment::Transactions => &mut self.transactions,
StaticFileSegment::Receipts => &mut self.receipts,
}
}
pub fn min(&self) -> Option<u64> {
[self.headers, self.transactions, self.receipts].iter().filter_map(|&option| option).min()
}
pub fn max(&self) -> Option<u64> {
[self.headers, self.transactions, self.receipts].iter().filter_map(|&option| option).max()
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct StaticFileTargets {
pub headers: Option<RangeInclusive<BlockNumber>>,
pub receipts: Option<RangeInclusive<BlockNumber>>,
pub transactions: Option<RangeInclusive<BlockNumber>>,
}
impl StaticFileTargets {
pub const fn any(&self) -> bool {
self.headers.is_some() || self.receipts.is_some() || self.transactions.is_some()
}
pub fn is_contiguous_to_highest_static_files(&self, static_files: HighestStaticFiles) -> bool {
[
(self.headers.as_ref(), static_files.headers),
(self.receipts.as_ref(), static_files.receipts),
(self.transactions.as_ref(), static_files.transactions),
]
.iter()
.all(|(target_block_range, highest_static_fileted_block)| {
target_block_range.map_or(true, |target_block_range| {
*target_block_range.start() ==
highest_static_fileted_block.map_or(0, |highest_static_fileted_block| {
highest_static_fileted_block + 1
})
})
})
}
}
pub const fn find_fixed_range(
block: BlockNumber,
blocks_per_static_file: u64,
) -> SegmentRangeInclusive {
let start = (block / blocks_per_static_file) * blocks_per_static_file;
SegmentRangeInclusive::new(start, start + blocks_per_static_file - 1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_highest_static_files_highest() {
let files =
HighestStaticFiles { headers: Some(100), receipts: Some(200), transactions: None };
assert_eq!(files.highest(StaticFileSegment::Headers), Some(100));
assert_eq!(files.highest(StaticFileSegment::Receipts), Some(200));
assert_eq!(files.highest(StaticFileSegment::Transactions), None);
}
#[test]
fn test_highest_static_files_as_mut() {
let mut files = HighestStaticFiles::default();
*files.as_mut(StaticFileSegment::Headers) = Some(150);
assert_eq!(files.headers, Some(150));
*files.as_mut(StaticFileSegment::Receipts) = Some(250);
assert_eq!(files.receipts, Some(250));
*files.as_mut(StaticFileSegment::Transactions) = Some(350);
assert_eq!(files.transactions, Some(350));
}
#[test]
fn test_highest_static_files_min() {
let files =
HighestStaticFiles { headers: Some(300), receipts: Some(100), transactions: None };
assert_eq!(files.min(), Some(100));
let empty_files = HighestStaticFiles::default();
assert_eq!(empty_files.min(), None);
}
#[test]
fn test_highest_static_files_max() {
let files =
HighestStaticFiles { headers: Some(300), receipts: Some(100), transactions: Some(500) };
assert_eq!(files.max(), Some(500));
let empty_files = HighestStaticFiles::default();
assert_eq!(empty_files.max(), None);
}
#[test]
fn test_find_fixed_range() {
let block: BlockNumber = 600_000;
let range = find_fixed_range(block, DEFAULT_BLOCKS_PER_STATIC_FILE);
assert_eq!(range.start(), 500_000);
assert_eq!(range.end(), 999_999);
let block: BlockNumber = 1_200_000;
let range = find_fixed_range(block, 1_000_000);
assert_eq!(range.start(), 1_000_000);
assert_eq!(range.end(), 1_999_999);
}
}