alloy_eips/eip4844/
utils.rsuse crate::eip4844::USABLE_BITS_PER_FIELD_ELEMENT;
pub const fn fits_in_fe(data: &[u8]) -> bool {
match data.len() {
33.. => false,
32 => data[0] & 0b1100_0000 == 0, _ => true,
}
}
pub const fn minimum_fe_for_bytes(bytes: usize) -> usize {
(bytes * 8).div_ceil(USABLE_BITS_PER_FIELD_ELEMENT)
}
pub const fn minimum_fe(data: &[u8]) -> usize {
minimum_fe_for_bytes(data.len())
}
#[derive(Clone, Copy, Debug)]
pub struct WholeFe<'a>(&'a [u8]);
impl<'a> WholeFe<'a> {
const fn new_unchecked(data: &'a [u8]) -> Self {
Self(data)
}
pub const fn new(data: &'a [u8]) -> Option<Self> {
if data.len() == 32 && fits_in_fe(data) {
Some(Self::new_unchecked(data))
} else {
None
}
}
}
impl AsRef<[u8]> for WholeFe<'_> {
fn as_ref(&self) -> &[u8] {
self.0
}
}
#[cfg(test)]
mod test {
use crate::eip4844::{FIELD_ELEMENTS_PER_BLOB, USABLE_BYTES_PER_BLOB};
use super::*;
#[test]
fn calc_required_fe() {
assert_eq!(minimum_fe(&[0u8; 32]), 2);
assert_eq!(minimum_fe(&[0u8; 31]), 1);
assert_eq!(minimum_fe(&[0u8; 33]), 2);
assert_eq!(minimum_fe(&[0u8; 64]), 3);
assert_eq!(minimum_fe(&[0u8; 65]), 3);
assert_eq!(minimum_fe_for_bytes(USABLE_BYTES_PER_BLOB), FIELD_ELEMENTS_PER_BLOB as usize);
}
#[test]
fn calc_is_valid_field_element() {
assert!(fits_in_fe(&[0u8; 32]));
assert!(!fits_in_fe(&[0u8; 33]));
assert!(WholeFe::new(&[0u8; 32]).is_some());
assert!(WholeFe::new(&[0u8; 33]).is_none());
assert!(WholeFe::new(&[0u8; 31]).is_none());
}
}