use alloy::{
eips::{BlockId, BlockNumberOrTag},
network::Network,
};
use crate::{
BlockRangeScannerBuilder, DEFAULT_BLOCK_CONFIRMATIONS, EventScanner, RingBufferCapacity,
ScannerError,
};
use robust_provider::IntoRobustProvider;
pub const DEFAULT_MAX_CONCURRENT_FETCHES: usize = 24;
#[derive(Default, Debug)]
pub struct Unspecified;
#[derive(Debug)]
pub struct Historic {
pub(crate) from_block: BlockId,
pub(crate) to_block: BlockId,
pub(crate) max_concurrent_fetches: usize,
}
#[derive(Debug)]
pub struct Live {
pub(crate) block_confirmations: u64,
pub(crate) max_concurrent_fetches: usize,
}
#[derive(Debug)]
pub struct LatestEvents {
pub(crate) count: usize,
pub(crate) from_block: BlockId,
pub(crate) to_block: BlockId,
pub(crate) block_confirmations: u64,
pub(crate) max_concurrent_fetches: usize,
}
#[derive(Default, Debug)]
pub struct Synchronize;
#[derive(Debug)]
pub struct SyncFromLatestEvents {
pub(crate) count: usize,
pub(crate) block_confirmations: u64,
pub(crate) max_concurrent_fetches: usize,
}
#[derive(Debug)]
pub struct SyncFromBlock {
pub(crate) from_block: BlockId,
pub(crate) block_confirmations: u64,
pub(crate) max_concurrent_fetches: usize,
}
impl Default for Historic {
fn default() -> Self {
Self {
from_block: BlockNumberOrTag::Earliest.into(),
to_block: BlockNumberOrTag::Latest.into(),
max_concurrent_fetches: DEFAULT_MAX_CONCURRENT_FETCHES,
}
}
}
impl Default for Live {
fn default() -> Self {
Self {
block_confirmations: DEFAULT_BLOCK_CONFIRMATIONS,
max_concurrent_fetches: DEFAULT_MAX_CONCURRENT_FETCHES,
}
}
}
#[derive(Default, Debug)]
pub struct EventScannerBuilder<Mode> {
pub(crate) config: Mode,
pub(crate) block_range_scanner: BlockRangeScannerBuilder,
}
impl EventScannerBuilder<Unspecified> {
#[must_use]
pub fn historic() -> EventScannerBuilder<Historic> {
EventScannerBuilder::default()
}
#[must_use]
pub fn live() -> EventScannerBuilder<Live> {
EventScannerBuilder::default()
}
#[must_use]
pub fn sync() -> EventScannerBuilder<Synchronize> {
EventScannerBuilder::default()
}
#[must_use]
pub fn latest(count: usize) -> EventScannerBuilder<LatestEvents> {
EventScannerBuilder::<LatestEvents>::new(count)
}
}
impl EventScannerBuilder<LatestEvents> {
#[must_use]
pub fn new(count: usize) -> Self {
Self {
config: LatestEvents {
count,
from_block: BlockNumberOrTag::Latest.into(),
to_block: BlockNumberOrTag::Earliest.into(),
block_confirmations: DEFAULT_BLOCK_CONFIRMATIONS,
max_concurrent_fetches: DEFAULT_MAX_CONCURRENT_FETCHES,
},
block_range_scanner: BlockRangeScannerBuilder::default(),
}
}
}
impl EventScannerBuilder<SyncFromLatestEvents> {
#[must_use]
pub fn new(count: usize) -> Self {
Self {
config: SyncFromLatestEvents {
count,
block_confirmations: DEFAULT_BLOCK_CONFIRMATIONS,
max_concurrent_fetches: DEFAULT_MAX_CONCURRENT_FETCHES,
},
block_range_scanner: BlockRangeScannerBuilder::default(),
}
}
}
impl EventScannerBuilder<SyncFromBlock> {
#[must_use]
pub fn new(from_block: impl Into<BlockId>) -> Self {
Self {
config: SyncFromBlock {
from_block: from_block.into(),
block_confirmations: DEFAULT_BLOCK_CONFIRMATIONS,
max_concurrent_fetches: DEFAULT_MAX_CONCURRENT_FETCHES,
},
block_range_scanner: BlockRangeScannerBuilder::default(),
}
}
}
impl<Mode> EventScannerBuilder<Mode> {
#[must_use]
pub fn max_block_range(mut self, max_block_range: u64) -> Self {
self.block_range_scanner.max_block_range = max_block_range;
self
}
#[must_use]
pub fn past_blocks_storage_capacity(
mut self,
past_blocks_storage_capacity: RingBufferCapacity,
) -> Self {
self.block_range_scanner.past_blocks_storage_capacity = past_blocks_storage_capacity;
self
}
#[must_use]
pub fn buffer_capacity(mut self, buffer_capacity: usize) -> Self {
self.block_range_scanner.buffer_capacity = buffer_capacity;
self
}
pub(crate) async fn build<N: Network>(
self,
provider: impl IntoRobustProvider<N>,
) -> Result<EventScanner<Mode, N>, ScannerError> {
let block_range_scanner = self.block_range_scanner.connect::<N>(provider).await?;
Ok(EventScanner::new(self.config, block_range_scanner))
}
}
#[cfg(test)]
mod tests {
use crate::block_range_scanner::DEFAULT_STREAM_BUFFER_CAPACITY;
use super::*;
#[test]
fn test_historic_scanner_config_defaults() {
let builder = EventScannerBuilder::<Historic>::default();
assert_eq!(builder.config.from_block, BlockNumberOrTag::Earliest.into());
assert_eq!(builder.config.to_block, BlockNumberOrTag::Latest.into());
assert_eq!(builder.block_range_scanner.buffer_capacity, DEFAULT_STREAM_BUFFER_CAPACITY);
}
#[test]
fn test_live_scanner_config_defaults() {
let builder = EventScannerBuilder::<Live>::default();
assert_eq!(builder.config.block_confirmations, DEFAULT_BLOCK_CONFIRMATIONS);
assert_eq!(builder.block_range_scanner.buffer_capacity, DEFAULT_STREAM_BUFFER_CAPACITY);
}
#[test]
fn test_latest_scanner_config_defaults() {
let builder = EventScannerBuilder::<LatestEvents>::new(10);
assert_eq!(builder.config.count, 10);
assert_eq!(builder.config.from_block, BlockNumberOrTag::Latest.into());
assert_eq!(builder.config.to_block, BlockNumberOrTag::Earliest.into());
assert_eq!(builder.config.block_confirmations, DEFAULT_BLOCK_CONFIRMATIONS);
assert_eq!(builder.block_range_scanner.buffer_capacity, DEFAULT_STREAM_BUFFER_CAPACITY);
}
#[test]
fn sync_scanner_config_defaults() {
let builder = EventScannerBuilder::<SyncFromBlock>::new(BlockNumberOrTag::Earliest);
assert_eq!(builder.config.from_block, BlockNumberOrTag::Earliest.into());
assert_eq!(builder.config.block_confirmations, DEFAULT_BLOCK_CONFIRMATIONS);
assert_eq!(builder.block_range_scanner.buffer_capacity, DEFAULT_STREAM_BUFFER_CAPACITY);
}
}