use crate::{segments::SegmentSet, Pruner};
use alloy_eips::eip2718::Encodable2718;
use reth_chainspec::MAINNET;
use reth_config::PruneConfig;
use reth_db::{table::Value, transaction::DbTxMut};
use reth_exex_types::FinishedExExHeight;
use reth_primitives_traits::NodePrimitives;
use reth_provider::{
providers::StaticFileProvider, BlockReader, DBProvider, DatabaseProviderFactory,
NodePrimitivesProvider, PruneCheckpointWriter, StaticFileProviderFactory,
};
use reth_prune_types::PruneModes;
use std::time::Duration;
use tokio::sync::watch;
#[derive(Debug, Clone)]
pub struct PrunerBuilder {
block_interval: usize,
segments: PruneModes,
delete_limit: usize,
timeout: Option<Duration>,
finished_exex_height: watch::Receiver<FinishedExExHeight>,
}
impl PrunerBuilder {
pub const DEFAULT_TIMEOUT: Duration = Duration::from_millis(100);
pub fn new(pruner_config: PruneConfig) -> Self {
Self::default()
.block_interval(pruner_config.block_interval)
.segments(pruner_config.segments)
}
pub const fn block_interval(mut self, block_interval: usize) -> Self {
self.block_interval = block_interval;
self
}
pub fn segments(mut self, segments: PruneModes) -> Self {
self.segments = segments;
self
}
pub const fn delete_limit(mut self, prune_delete_limit: usize) -> Self {
self.delete_limit = prune_delete_limit;
self
}
pub const fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn finished_exex_height(
mut self,
finished_exex_height: watch::Receiver<FinishedExExHeight>,
) -> Self {
self.finished_exex_height = finished_exex_height;
self
}
pub fn build_with_provider_factory<PF>(self, provider_factory: PF) -> Pruner<PF::ProviderRW, PF>
where
PF: DatabaseProviderFactory<
ProviderRW: PruneCheckpointWriter
+ BlockReader<Transaction: Encodable2718>
+ StaticFileProviderFactory<
Primitives: NodePrimitives<SignedTx: Value, Receipt: Value>,
>,
> + StaticFileProviderFactory<
Primitives = <PF::ProviderRW as NodePrimitivesProvider>::Primitives,
>,
{
let segments =
SegmentSet::from_components(provider_factory.static_file_provider(), self.segments);
Pruner::new_with_factory(
provider_factory,
segments.into_vec(),
self.block_interval,
self.delete_limit,
self.timeout,
self.finished_exex_height,
)
}
pub fn build<Provider>(
self,
static_file_provider: StaticFileProvider<Provider::Primitives>,
) -> Pruner<Provider, ()>
where
Provider: StaticFileProviderFactory<Primitives: NodePrimitives<SignedTx: Value, Receipt: Value>>
+ DBProvider<Tx: DbTxMut>
+ BlockReader<Transaction: Encodable2718>
+ PruneCheckpointWriter,
{
let segments = SegmentSet::<Provider>::from_components(static_file_provider, self.segments);
Pruner::new(
segments.into_vec(),
self.block_interval,
self.delete_limit,
self.timeout,
self.finished_exex_height,
)
}
}
impl Default for PrunerBuilder {
fn default() -> Self {
Self {
block_interval: 5,
segments: PruneModes::none(),
delete_limit: MAINNET.prune_delete_limit,
timeout: None,
finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1,
}
}
}