use crate::Header;
use alloc::vec::Vec;
use alloy_eips::eip4895::Withdrawals;
use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Block<T> {
pub header: Header,
pub body: BlockBody<T>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default, RlpEncodable, RlpDecodable)]
#[rlp(trailing)]
pub struct BlockBody<T> {
pub transactions: Vec<T>,
pub ommers: Vec<Header>,
pub withdrawals: Option<Withdrawals>,
}
mod block_rlp {
use super::*;
#[derive(RlpDecodable)]
#[rlp(trailing)]
struct Helper<T> {
header: Header,
transactions: Vec<T>,
ommers: Vec<Header>,
withdrawals: Option<Withdrawals>,
}
#[derive(RlpEncodable)]
#[rlp(trailing)]
struct HelperRef<'a, T> {
header: &'a Header,
transactions: &'a Vec<T>,
ommers: &'a Vec<Header>,
withdrawals: Option<&'a Withdrawals>,
}
impl<'a, T> From<&'a Block<T>> for HelperRef<'a, T> {
fn from(block: &'a Block<T>) -> Self {
let Block { header, body: BlockBody { transactions, ommers, withdrawals } } = block;
Self { header, transactions, ommers, withdrawals: withdrawals.as_ref() }
}
}
impl<T: Encodable> Encodable for Block<T> {
fn encode(&self, out: &mut dyn alloy_rlp::bytes::BufMut) {
let helper: HelperRef<'_, T> = self.into();
helper.encode(out)
}
fn length(&self) -> usize {
let helper: HelperRef<'_, T> = self.into();
helper.length()
}
}
impl<T: Decodable> Decodable for Block<T> {
fn decode(b: &mut &[u8]) -> alloy_rlp::Result<Self> {
let Helper { header, transactions, ommers, withdrawals } = Helper::decode(b)?;
Ok(Self { header, body: BlockBody { transactions, ommers, withdrawals } })
}
}
}