use crate::{Header, SealedHeader, TransactionSigned, H256}; use reth_rlp::{Decodable, DecodeError, Encodable, RlpDecodable, RlpEncodable}; 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, /// Ommers/uncles header pub ommers: Vec, } 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 BlockLocked { /// Locked block header. pub header: SealedHeader, /// Transactions with signatures. pub body: Vec, /// Ommer/uncle headers pub ommers: Vec, } impl BlockLocked { /// Header hash. pub fn hash(&self) -> H256 { self.header.hash() } } impl Deref for BlockLocked { type Target = Header; fn deref(&self) -> &Self::Target { self.header.as_ref() } } /// Either a block hash _or_ a block number #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum BlockHashOrNumber { /// A block hash Hash(H256), /// A block number Number(u64), } impl From for BlockHashOrNumber { fn from(value: H256) -> Self { BlockHashOrNumber::Hash(value) } } impl From 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 length(&self) -> usize { match self { Self::Hash(block_hash) => block_hash.length(), Self::Number(block_number) => block_number.length(), } } 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), } } } /// Allows for RLP decoding of a block hash or block number impl Decodable for BlockHashOrNumber { fn decode(buf: &mut &[u8]) -> Result { 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)?)) } } }