mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-17 02:12:02 -05:00
* feat(engine): new payload execution * address PR comments * rm unused dev deps * add comment about lru * remove par_iter
121 lines
3.6 KiB
Rust
121 lines
3.6 KiB
Rust
use crate::{Header, SealedHeader, TransactionSigned, H256};
|
|
use reth_rlp::{Decodable, DecodeError, Encodable, RlpDecodable, RlpEncodable};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::ops::Deref;
|
|
|
|
/// Ethereum full block.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Default, RlpEncodable, RlpDecodable)]
|
|
pub struct Block {
|
|
/// Block header.
|
|
pub header: Header,
|
|
/// Transactions in this block.
|
|
pub body: Vec<TransactionSigned>,
|
|
/// Ommers/uncles header
|
|
pub ommers: Vec<Header>,
|
|
}
|
|
|
|
impl Deref for Block {
|
|
type Target = Header;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.header
|
|
}
|
|
}
|
|
|
|
/// Sealed Ethereum full block.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Default, RlpEncodable, RlpDecodable)]
|
|
pub struct SealedBlock {
|
|
/// Locked block header.
|
|
pub header: SealedHeader,
|
|
/// Transactions with signatures.
|
|
pub body: Vec<TransactionSigned>,
|
|
/// Ommer/uncle headers
|
|
pub ommers: Vec<SealedHeader>,
|
|
}
|
|
|
|
impl SealedBlock {
|
|
/// Header hash.
|
|
pub fn hash(&self) -> H256 {
|
|
self.header.hash()
|
|
}
|
|
|
|
/// Splits the sealed block into underlying components
|
|
pub fn split(self) -> (SealedHeader, Vec<TransactionSigned>, Vec<SealedHeader>) {
|
|
(self.header, self.body, self.ommers)
|
|
}
|
|
|
|
/// Unseal the block
|
|
pub fn unseal(self) -> Block {
|
|
Block {
|
|
header: self.header.unseal(),
|
|
body: self.body,
|
|
ommers: self.ommers.into_iter().map(|o| o.unseal()).collect(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Deref for SealedBlock {
|
|
type Target = SealedHeader;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.header
|
|
}
|
|
}
|
|
|
|
/// Either a block hash _or_ a block number
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
pub enum BlockHashOrNumber {
|
|
/// A block hash
|
|
Hash(H256),
|
|
/// A block number
|
|
Number(u64),
|
|
}
|
|
|
|
impl From<H256> for BlockHashOrNumber {
|
|
fn from(value: H256) -> Self {
|
|
BlockHashOrNumber::Hash(value)
|
|
}
|
|
}
|
|
|
|
impl From<u64> for BlockHashOrNumber {
|
|
fn from(value: u64) -> Self {
|
|
BlockHashOrNumber::Number(value)
|
|
}
|
|
}
|
|
|
|
/// Allows for RLP encoding of either a block hash or block number
|
|
impl Encodable for BlockHashOrNumber {
|
|
fn encode(&self, out: &mut dyn bytes::BufMut) {
|
|
match self {
|
|
Self::Hash(block_hash) => block_hash.encode(out),
|
|
Self::Number(block_number) => block_number.encode(out),
|
|
}
|
|
}
|
|
fn length(&self) -> usize {
|
|
match self {
|
|
Self::Hash(block_hash) => block_hash.length(),
|
|
Self::Number(block_number) => block_number.length(),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Allows for RLP decoding of a block hash or block number
|
|
impl Decodable for BlockHashOrNumber {
|
|
fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
|
|
let header: u8 = *buf.first().ok_or(DecodeError::InputTooShort)?;
|
|
// if the byte string is exactly 32 bytes, decode it into a Hash
|
|
// 0xa0 = 0x80 (start of string) + 0x20 (32, length of string)
|
|
if header == 0xa0 {
|
|
// strip the first byte, parsing the rest of the string.
|
|
// If the rest of the string fails to decode into 32 bytes, we'll bubble up the
|
|
// decoding error.
|
|
let hash = H256::decode(buf)?;
|
|
Ok(Self::Hash(hash))
|
|
} else {
|
|
// a block number when encoded as bytes ranges from 0 to any number of bytes - we're
|
|
// going to accept numbers which fit in less than 64 bytes.
|
|
// Any data larger than this which is not caught by the Hash decoding should error and
|
|
// is considered an invalid block number.
|
|
Ok(Self::Number(u64::decode(buf)?))
|
|
}
|
|
}
|
|
}
|