mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: move BlockHashOrNumber to primitives (#203)
This commit is contained in:
@ -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<Header>)> 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
|
||||
|
||||
@ -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<Vec<Header>, DownloadError> {
|
||||
let request_id = rand::random();
|
||||
|
||||
@ -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<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)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
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() {
|
||||
|
||||
@ -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<C: Consensus, H: HeadersClient> LinearDownloader<C, H> {
|
||||
) -> Result<LinearDownloadResult, DownloadError> {
|
||||
// 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();
|
||||
|
||||
@ -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<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 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<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)?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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};
|
||||
|
||||
Reference in New Issue
Block a user