mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(pruner): prune receipts based on log emitters during live sync (#4140)
This commit is contained in:
@ -24,24 +24,61 @@ impl ContractLogsPruneConfig {
|
||||
/// Given the `tip` block number, consolidates the structure so it can easily be queried for
|
||||
/// filtering across a range of blocks.
|
||||
///
|
||||
/// The [`BlockNumber`] key of the map should be viewed as `PruneMode::Before(block)`.
|
||||
/// Example:
|
||||
///
|
||||
/// `{ addrA: Before(872), addrB: Before(500), addrC: Distance(128) }`
|
||||
///
|
||||
/// for `tip: 1000`, gets transformed to a map such as:
|
||||
///
|
||||
/// `{ 500: [addrB], 872: [addrA, addrC] }`
|
||||
///
|
||||
/// The [`BlockNumber`] key of the new map should be viewed as `PruneMode::Before(block)`, which
|
||||
/// makes the previous result equivalent to
|
||||
///
|
||||
/// `{ Before(500): [addrB], Before(872): [addrA, addrC] }`
|
||||
pub fn group_by_block(
|
||||
&self,
|
||||
tip: BlockNumber,
|
||||
pruned_block: Option<BlockNumber>,
|
||||
) -> Result<BTreeMap<BlockNumber, Vec<&Address>>, PrunePartError> {
|
||||
let mut map = BTreeMap::new();
|
||||
let pruned_block = pruned_block.unwrap_or_default();
|
||||
|
||||
for (address, mode) in self.0.iter() {
|
||||
// Getting `None`, means that there is nothing to prune yet, so we need it to include in
|
||||
// the BTreeMap (block = 0), otherwise it will be excluded.
|
||||
// Reminder that this BTreeMap works as an inclusion list that excludes (prunes) all
|
||||
// other receipts.
|
||||
let block = mode
|
||||
.prune_target_block(tip, MINIMUM_PRUNING_DISTANCE, PrunePart::ContractLogs)?
|
||||
.map(|(block, _)| block)
|
||||
.unwrap_or_default();
|
||||
let block = (pruned_block + 1).max(
|
||||
mode.prune_target_block(tip, MINIMUM_PRUNING_DISTANCE, PrunePart::ContractLogs)?
|
||||
.map(|(block, _)| block)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
map.entry(block).or_insert_with(Vec::new).push(address)
|
||||
}
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
/// Returns the lowest block where we start filtering logs which use `PruneMode::Distance(_)`.
|
||||
pub fn lowest_block_with_distance(
|
||||
&self,
|
||||
tip: BlockNumber,
|
||||
pruned_block: Option<BlockNumber>,
|
||||
) -> Result<Option<BlockNumber>, PrunePartError> {
|
||||
let pruned_block = pruned_block.unwrap_or_default();
|
||||
let mut lowest = None;
|
||||
|
||||
for (_, mode) in self.0.iter() {
|
||||
if let PruneMode::Distance(_) = mode {
|
||||
if let Some((block, _)) =
|
||||
mode.prune_target_block(tip, MINIMUM_PRUNING_DISTANCE, PrunePart::ContractLogs)?
|
||||
{
|
||||
lowest = Some(lowest.unwrap_or(u64::MAX).min(block));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(lowest.map(|lowest| lowest.max(pruned_block)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user