Skip to main content

forest/chain_sync/
bad_block_cache.rs

1// Copyright 2019-2026 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4use std::num::NonZeroUsize;
5
6use cid::Cid;
7use nonzero_ext::nonzero;
8
9use crate::utils::{cache::SizeTrackingLruCache, get_size};
10
11/// Thread-safe cache for tracking bad blocks.
12/// This cache is checked before validating a block, to ensure no duplicate
13/// work.
14#[derive(Debug)]
15pub struct BadBlockCache {
16    cache: SizeTrackingLruCache<get_size::CidWrapper, ()>,
17}
18
19impl Default for BadBlockCache {
20    fn default() -> Self {
21        Self::new(nonzero!(1usize << 15))
22    }
23}
24
25impl BadBlockCache {
26    pub fn new(cap: NonZeroUsize) -> Self {
27        Self {
28            cache: SizeTrackingLruCache::new_with_metrics("bad_block".into(), cap),
29        }
30    }
31
32    pub fn push(&self, c: Cid) {
33        self.cache.push(c.into(), ());
34        tracing::warn!("Marked bad block: {c}");
35    }
36
37    /// Returns `Some` if the block CID is in bad block cache.
38    /// This function does not update the head position of the `Cid` key.
39    pub fn peek(&self, c: &Cid) -> Option<()> {
40        self.cache.peek_cloned(&(*c).into())
41    }
42}