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