Files
reth/crates/primitives/src/block.rs
Roman Krasiuk 565a0aa90b feat(engine): new payload execution (#631)
* feat(engine): new payload execution

* address PR comments

* rm unused dev deps

* add comment about lru

* remove par_iter
2022-12-29 02:36:56 -08:00

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)?))
}
}
}