Skip to main content

reth_network_api/
custody.rs

1//! Shared blob cell custody state.
2
3use alloy_primitives::B128;
4use std::sync::{
5    atomic::{AtomicU64, AtomicU8, Ordering},
6    Arc,
7};
8
9/// Shared blob cell custody bitmap for [EIP-8070] sparse blobpool sampling.
10///
11/// This stores the latest `custodyColumns` value received from
12/// `engine_forkchoiceUpdatedV4`, so network components can align blob cell sampling with the
13/// consensus client's custody set. The value is a lightweight hint for sampling decisions, not a
14/// consensus-critical guard.
15///
16/// [EIP-8070]: https://eips.ethereum.org/EIPS/eip-8070
17#[derive(Debug, Clone, Default)]
18pub struct CellCustody {
19    inner: Arc<CellCustodyInner>,
20}
21
22impl CellCustody {
23    /// Returns the currently configured blob cell custody bitmap.
24    ///
25    /// Reads are intentionally cheap and eventually consistent. Concurrent custom-to-custom
26    /// updates may briefly expose an in-flight bitmap, which is acceptable because custody is only
27    /// used to steer future sampling requests.
28    pub fn get(&self) -> B128 {
29        match self.inner.state.load(Ordering::Relaxed) {
30            CELL_CUSTODY_NONE => B128::from(0u128),
31            CELL_CUSTODY_FULL => B128::from(u128::MAX),
32            _ => {
33                let high = self.inner.high.load(Ordering::Relaxed) as u128;
34                let low = self.inner.low.load(Ordering::Relaxed) as u128;
35
36                B128::from((high << 64) | low)
37            }
38        }
39    }
40
41    /// Updates the blob cell custody bitmap.
42    pub fn set(&self, custody_columns: B128) {
43        let custody_columns = u128::from(custody_columns);
44        match custody_columns {
45            0 => self.inner.state.store(CELL_CUSTODY_NONE, Ordering::Relaxed),
46            u128::MAX => self.inner.state.store(CELL_CUSTODY_FULL, Ordering::Relaxed),
47            _ => {
48                self.inner.high.store((custody_columns >> 64) as u64, Ordering::Relaxed);
49                self.inner.low.store(custody_columns as u64, Ordering::Relaxed);
50                self.inner.state.store(CELL_CUSTODY_CUSTOM, Ordering::Relaxed);
51            }
52        }
53    }
54}
55
56const CELL_CUSTODY_NONE: u8 = 0;
57const CELL_CUSTODY_FULL: u8 = 1;
58const CELL_CUSTODY_CUSTOM: u8 = 2;
59
60#[derive(Debug, Default)]
61struct CellCustodyInner {
62    state: AtomicU8,
63    high: AtomicU64,
64    low: AtomicU64,
65}