diff --git a/crates/interfaces/src/p2p/headers/client.rs b/crates/interfaces/src/p2p/headers/client.rs index 3416006035..5ff872887c 100644 --- a/crates/interfaces/src/p2p/headers/client.rs +++ b/crates/interfaces/src/p2p/headers/client.rs @@ -1,8 +1,9 @@ use crate::p2p::MessageStream; -use reth_primitives::{rpc::BlockId, Header, H256, H512}; +use reth_primitives::{Header, H256, H512}; use async_trait::async_trait; +use reth_primitives::BlockHashOrNumber; use std::{collections::HashSet, fmt::Debug}; /// Each peer returns a list of headers and the request id corresponding @@ -31,7 +32,7 @@ impl From<(u64, Vec
)> for HeadersResponse { #[derive(Clone, Debug)] pub struct HeadersRequest { /// The starting block - pub start: BlockId, + pub start: BlockHashOrNumber, /// The response max size pub limit: u64, /// Flag indicating whether the blocks should diff --git a/crates/interfaces/src/p2p/headers/downloader.rs b/crates/interfaces/src/p2p/headers/downloader.rs index 2657b37be7..97fbe9c5b2 100644 --- a/crates/interfaces/src/p2p/headers/downloader.rs +++ b/crates/interfaces/src/p2p/headers/downloader.rs @@ -1,9 +1,7 @@ use super::client::{HeadersClient, HeadersRequest, HeadersStream}; -use crate::consensus::Consensus; - -use crate::p2p::headers::error::DownloadError; +use crate::{consensus::Consensus, p2p::headers::error::DownloadError}; use async_trait::async_trait; -use reth_primitives::{rpc::BlockId, Header, SealedHeader}; +use reth_primitives::{BlockHashOrNumber, Header, SealedHeader}; use reth_rpc_types::engine::ForkchoiceState; use std::time::Duration; use tokio_stream::StreamExt; @@ -46,7 +44,7 @@ pub trait HeaderDownloader: Sync + Send { async fn download_headers( &self, stream: &mut HeadersStream, - start: BlockId, + start: BlockHashOrNumber, limit: u64, ) -> Result, DownloadError> { let request_id = rand::random(); diff --git a/crates/net/eth-wire/src/types/blocks.rs b/crates/net/eth-wire/src/types/blocks.rs index 7f90bf6c90..b5b00a6cc2 100644 --- a/crates/net/eth-wire/src/types/blocks.rs +++ b/crates/net/eth-wire/src/types/blocks.rs @@ -1,59 +1,8 @@ //! Implements the `GetBlockHeaders`, `GetBlockBodies`, `BlockHeaders`, and `BlockBodies` message //! types. -use reth_primitives::{Header, TransactionSigned, H256}; -use reth_rlp::{ - Decodable, DecodeError, Encodable, RlpDecodable, RlpDecodableWrapper, RlpEncodable, - RlpEncodableWrapper, -}; - use super::RawBlockBody; - -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -/// Either a block hash _or_ a block number -pub enum BlockHashOrNumber { - /// A block hash - Hash(H256), - /// A block number - Number(u64), -} - -/// 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)?)) - } - } -} +use reth_primitives::{BlockHashOrNumber, Header, TransactionSigned, H256}; +use reth_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; /// A request for a peer to return block headers starting at the requested block. /// The peer must return at most [`limit`](#structfield.limit) headers. @@ -152,11 +101,11 @@ mod test { }; use hex_literal::hex; use reth_primitives::{ - Header, Signature, Transaction, TransactionKind, TransactionSigned, U256, + BlockHashOrNumber, Header, Signature, Transaction, TransactionKind, TransactionSigned, U256, }; use reth_rlp::{Decodable, Encodable}; - use super::{BlockBody, BlockHashOrNumber}; + use super::BlockBody; #[test] fn decode_hash() { diff --git a/crates/net/headers-downloaders/src/linear.rs b/crates/net/headers-downloaders/src/linear.rs index b52718d0ed..b2a2d34ca0 100644 --- a/crates/net/headers-downloaders/src/linear.rs +++ b/crates/net/headers-downloaders/src/linear.rs @@ -9,7 +9,7 @@ use reth_interfaces::{ error::DownloadError, }, }; -use reth_primitives::{rpc::BlockId, SealedHeader}; +use reth_primitives::SealedHeader; use reth_rpc_types::engine::ForkchoiceState; /// Download headers in batches @@ -101,8 +101,7 @@ impl LinearDownloader { ) -> Result { // Request headers starting from tip or earliest cached let start = earliest.map_or(forkchoice.head_block_hash, |h| h.parent_hash); - let mut headers = - self.download_headers(stream, BlockId::Hash(start), self.batch_size).await?; + let mut headers = self.download_headers(stream, start.into(), self.batch_size).await?; headers.sort_unstable_by_key(|h| h.number); let mut out = Vec::with_capacity(headers.len()); @@ -207,7 +206,7 @@ mod tests { TestConsensus, TestHeadersClient, }, }; - use reth_primitives::{rpc::BlockId, SealedHeader}; + use reth_primitives::{BlockHashOrNumber, SealedHeader}; use assert_matches::assert_matches; use once_cell::sync::Lazy; @@ -301,7 +300,7 @@ mod tests { assert_matches!( request, Some((_, HeadersRequest { start, .. })) - if matches!(start, BlockId::Hash(hash) if *hash == tip_hash) + if matches!(start, BlockHashOrNumber::Hash(hash) if *hash == tip_hash) ); let request = request.unwrap(); diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index f826880fac..a48fc12cf8 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,4 +1,5 @@ use crate::{Header, Receipt, SealedHeader, Transaction, TransactionSigned, H256}; +use reth_rlp::{Decodable, DecodeError, Encodable}; use std::ops::Deref; /// Ethereum full block. @@ -47,3 +48,62 @@ impl Deref for BlockLocked { 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)?)) + } + } +} diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index aaff276389..e810143dc1 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -29,7 +29,7 @@ mod transaction; pub mod proofs; pub use account::Account; -pub use block::{Block, BlockLocked}; +pub use block::{Block, BlockHashOrNumber, BlockLocked}; pub use chain::Chain; pub use constants::MAINNET_GENESIS; pub use forkid::{ForkFilter, ForkHash, ForkId, ValidationError};