From b8c9c0b8203be42674f14a73d25dc94c72223842 Mon Sep 17 00:00:00 2001 From: lakshya-sky <8559992+lakshya-sky@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:07:21 -0400 Subject: [PATCH 1/4] Move block hash types to alloy-eips --- crates/eips/Cargo.toml | 3 +- crates/eips/src/eip1898.rs | 177 +++++++++++++++++++++++++++++- crates/eips/src/lib.rs | 4 +- crates/rpc-types/src/eth/block.rs | 176 +---------------------------- 4 files changed, 185 insertions(+), 175 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index cb186d0fb36..92b65585727 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -16,8 +16,9 @@ alloy-primitives = { workspace = true, features = ["rlp"], default-features = fa alloy-rlp = { workspace = true, features = ["derive"], default-features = false } alloy-serde.workspace = true -# serde +# misc serde = { workspace = true, default-features = false, optional = true } +thiserror.workspace = true # kzg derive_more = { workspace = true, optional = true } diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 0b417658f4b..44b938b749b 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -1,6 +1,7 @@ //! [EIP-1898]: https://eips.ethereum.org/EIPS/eip-1898 -use alloy_primitives::{hex::FromHexError, ruint::ParseError, B256, U64}; +use alloy_primitives::{hex::FromHexError, ruint::ParseError, BlockHash, BlockNumber, B256, U64}; +use alloy_rlp::{bytes, Decodable, Encodable, Error as RlpError}; use core::{ fmt::{self, Debug, Display, Formatter}, num::ParseIntError, @@ -556,6 +557,180 @@ impl FromStr for BlockId { } } +/// Block number and hash. +#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] +pub struct BlockNumHash { + /// Block number + pub number: BlockNumber, + /// Block hash + pub hash: BlockHash, +} + +/// Block number and hash of the forked block. +pub type ForkBlock = BlockNumHash; + +impl fmt::Debug for BlockNumHash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("").field(&self.number).field(&self.hash).finish() + } +} + +impl fmt::Display for BlockNumHash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "BlockNumHash{{ number: {}, hash: {} }}", self.number, self.hash) + } +} + +impl BlockNumHash { + /// Creates a new `BlockNumHash` from a block number and hash. + pub const fn new(number: BlockNumber, hash: BlockHash) -> Self { + Self { number, hash } + } + + /// Consumes `Self` and returns [`BlockNumber`], [`BlockHash`] + pub const fn into_components(self) -> (BlockNumber, BlockHash) { + (self.number, self.hash) + } + + /// Returns whether or not the block matches the given [BlockHashOrNumber]. + pub fn matches_block_or_num(&self, block: &BlockHashOrNumber) -> bool { + match block { + BlockHashOrNumber::Hash(hash) => self.hash == *hash, + BlockHashOrNumber::Number(number) => self.number == *number, + } + } +} + +impl From<(BlockNumber, BlockHash)> for BlockNumHash { + fn from(val: (BlockNumber, BlockHash)) -> Self { + BlockNumHash { number: val.0, hash: val.1 } + } +} + +impl From<(BlockHash, BlockNumber)> for BlockNumHash { + fn from(val: (BlockHash, BlockNumber)) -> Self { + BlockNumHash { hash: val.0, number: val.1 } + } +} + +/// Either a block hash _or_ a block number +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) +)] +pub enum BlockHashOrNumber { + /// A block hash + Hash(B256), + /// A block number + Number(u64), +} + +// === impl BlockHashOrNumber === + +impl BlockHashOrNumber { + /// Returns the block number if it is a [`BlockHashOrNumber::Number`]. + #[inline] + pub const fn as_number(self) -> Option { + match self { + BlockHashOrNumber::Hash(_) => None, + BlockHashOrNumber::Number(num) => Some(num), + } + } +} + +impl From for BlockHashOrNumber { + fn from(value: B256) -> Self { + BlockHashOrNumber::Hash(value) + } +} + +impl From for BlockHashOrNumber { + fn from(value: u64) -> Self { + BlockHashOrNumber::Number(value) + } +} + +impl From for BlockHashOrNumber { + fn from(value: U64) -> Self { + value.to::().into() + } +} + +/// 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]) -> alloy_rlp::Result { + let header: u8 = *buf.first().ok_or(RlpError::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 = B256::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)?)) + } + } +} + +impl fmt::Display for BlockHashOrNumber { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Hash(hash) => write!(f, "{}", hash), + Self::Number(num) => write!(f, "{}", num), + } + } +} + +/// Error thrown when parsing a [BlockHashOrNumber] from a string. +#[derive(Debug, thiserror::Error)] +#[error("failed to parse {input:?} as a number: {parse_int_error} or hash: {hex_error}")] +pub struct ParseBlockHashOrNumberError { + input: String, + parse_int_error: ParseIntError, + hex_error: alloy_primitives::hex::FromHexError, +} + +impl FromStr for BlockHashOrNumber { + type Err = ParseBlockHashOrNumberError; + + fn from_str(s: &str) -> Result { + match u64::from_str(s) { + Ok(val) => Ok(val.into()), + Err(pares_int_error) => match B256::from_str(s) { + Ok(val) => Ok(val.into()), + Err(hex_error) => Err(ParseBlockHashOrNumberError { + input: s.to_string(), + parse_int_error: pares_int_error, + hex_error, + }), + }, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index c5ed82c66b6..8a519b02116 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -23,7 +23,9 @@ pub mod eip1559; pub use eip1559::calc_next_block_base_fee; pub mod eip1898; -pub use eip1898::{BlockId, BlockNumberOrTag, RpcBlockHash}; +pub use eip1898::{ + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash, +}; pub mod eip2718; diff --git a/crates/rpc-types/src/eth/block.rs b/crates/rpc-types/src/eth/block.rs index 61f253e8bc2..d9c8360119f 100644 --- a/crates/rpc-types/src/eth/block.rs +++ b/crates/rpc-types/src/eth/block.rs @@ -4,12 +4,12 @@ use crate::{other::OtherFields, Transaction, Withdrawal}; pub use alloy_eips::{ - calc_blob_gasprice, calc_excess_blob_gas, BlockId, BlockNumberOrTag, RpcBlockHash, + calc_blob_gasprice, calc_excess_blob_gas, BlockHashOrNumber, BlockId, BlockNumHash, + BlockNumberOrTag, ForkBlock, RpcBlockHash, }; -use alloy_primitives::{Address, BlockHash, BlockNumber, Bloom, Bytes, B256, B64, U256, U64}; -use alloy_rlp::{bytes, Decodable, Encodable, Error as RlpError}; +use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256, U64}; use serde::{ser::Error, Deserialize, Serialize, Serializer}; -use std::{collections::BTreeMap, fmt, num::ParseIntError, ops::Deref, str::FromStr}; +use std::{collections::BTreeMap, ops::Deref}; /// Block representation #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] @@ -424,174 +424,6 @@ pub enum BlockError { RlpDecodeRawBlock(alloy_rlp::Error), } -/// Block number and hash. -#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] -pub struct BlockNumHash { - /// Block number - pub number: BlockNumber, - /// Block hash - pub hash: BlockHash, -} - -/// Block number and hash of the forked block. -pub type ForkBlock = BlockNumHash; - -impl fmt::Debug for BlockNumHash { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("").field(&self.number).field(&self.hash).finish() - } -} - -impl BlockNumHash { - /// Creates a new `BlockNumHash` from a block number and hash. - pub const fn new(number: BlockNumber, hash: BlockHash) -> Self { - Self { number, hash } - } - - /// Consumes `Self` and returns [`BlockNumber`], [`BlockHash`] - pub const fn into_components(self) -> (BlockNumber, BlockHash) { - (self.number, self.hash) - } - - /// Returns whether or not the block matches the given [BlockHashOrNumber]. - pub fn matches_block_or_num(&self, block: &BlockHashOrNumber) -> bool { - match block { - BlockHashOrNumber::Hash(hash) => self.hash == *hash, - BlockHashOrNumber::Number(number) => self.number == *number, - } - } -} - -impl From<(BlockNumber, BlockHash)> for BlockNumHash { - fn from(val: (BlockNumber, BlockHash)) -> Self { - BlockNumHash { number: val.0, hash: val.1 } - } -} - -impl From<(BlockHash, BlockNumber)> for BlockNumHash { - fn from(val: (BlockHash, BlockNumber)) -> Self { - BlockNumHash { hash: val.0, number: val.1 } - } -} - -/// Either a block hash _or_ a block number -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] -pub enum BlockHashOrNumber { - /// A block hash - Hash(B256), - /// A block number - Number(u64), -} - -// === impl BlockHashOrNumber === - -impl BlockHashOrNumber { - /// Returns the block number if it is a [`BlockHashOrNumber::Number`]. - #[inline] - pub const fn as_number(self) -> Option { - match self { - BlockHashOrNumber::Hash(_) => None, - BlockHashOrNumber::Number(num) => Some(num), - } - } -} - -impl From for BlockHashOrNumber { - fn from(value: B256) -> Self { - BlockHashOrNumber::Hash(value) - } -} - -impl From for BlockHashOrNumber { - fn from(value: u64) -> Self { - BlockHashOrNumber::Number(value) - } -} - -impl From for BlockHashOrNumber { - fn from(value: U64) -> Self { - value.to::().into() - } -} - -/// 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]) -> alloy_rlp::Result { - let header: u8 = *buf.first().ok_or(RlpError::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 = B256::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)?)) - } - } -} - -impl fmt::Display for BlockHashOrNumber { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Hash(hash) => write!(f, "{}", hash), - Self::Number(num) => write!(f, "{}", num), - } - } -} - -/// Error thrown when parsing a [BlockHashOrNumber] from a string. -#[derive(Debug, thiserror::Error)] -#[error("failed to parse {input:?} as a number: {parse_int_error} or hash: {hex_error}")] -pub struct ParseBlockHashOrNumberError { - input: String, - parse_int_error: ParseIntError, - hex_error: alloy_primitives::hex::FromHexError, -} - -impl FromStr for BlockHashOrNumber { - type Err = ParseBlockHashOrNumberError; - - fn from_str(s: &str) -> Result { - match u64::from_str(s) { - Ok(val) => Ok(val.into()), - Err(pares_int_error) => match B256::from_str(s) { - Ok(val) => Ok(val.into()), - Err(hex_error) => Err(ParseBlockHashOrNumberError { - input: s.to_string(), - parse_int_error: pares_int_error, - hex_error, - }), - }, - } - } -} - /// A Block representation that allows to include additional fields pub type RichBlock = Rich; From 9c2eadc5765b62f4ea88af9171887a6e4f49e905 Mon Sep 17 00:00:00 2001 From: lakshya-sky <8559992+lakshya-sky@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:27:22 -0400 Subject: [PATCH 2/4] change error to use std::error instead of thiserror. --- crates/eips/Cargo.toml | 42 +++++++++++++++++++++++++++----------- crates/eips/src/eip1898.rs | 16 +++++++++++++-- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 92b65585727..3e548575413 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -12,13 +12,16 @@ repository.workspace = true exclude.workspace = true [dependencies] -alloy-primitives = { workspace = true, features = ["rlp"], default-features = false } -alloy-rlp = { workspace = true, features = ["derive"], default-features = false } +alloy-primitives = { workspace = true, features = [ + "rlp", +], default-features = false } +alloy-rlp = { workspace = true, features = [ + "derive", +], default-features = false } alloy-serde.workspace = true -# misc +# serde serde = { workspace = true, default-features = false, optional = true } -thiserror.workspace = true # kzg derive_more = { workspace = true, optional = true } @@ -35,7 +38,11 @@ proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } [dev-dependencies] -alloy-primitives = { workspace = true, features = ["rand", "serde", "arbitrary"] } +alloy-primitives = { workspace = true, features = [ + "rand", + "serde", + "arbitrary", +] } arbitrary = { workspace = true, features = ["derive"] } proptest = { workspace = true } proptest-derive = { workspace = true } @@ -43,14 +50,25 @@ serde_json.workspace = true [features] default = ["std"] -std = ["alloy-primitives/std", "alloy-rlp/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] +std = [ + "alloy-primitives/std", + "alloy-rlp/std", + "serde?/std", + "c-kzg?/std", + "once_cell?/std", +] serde = ["dep:serde", "alloy-primitives/serde", "c-kzg?/serde"] kzg = ["dep:derive_more", "dep:c-kzg", "dep:once_cell"] -ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz"] +ssz = [ + "std", + "dep:ethereum_ssz", + "dep:ethereum_ssz_derive", + "alloy-primitives/ssz", +] arbitrary = [ - "std", - "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", - "alloy-primitives/arbitrary", + "std", + "dep:arbitrary", + "dep:proptest-derive", + "dep:proptest", + "alloy-primitives/arbitrary", ] diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 44b938b749b..44627b203c8 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -705,14 +705,26 @@ impl fmt::Display for BlockHashOrNumber { } /// Error thrown when parsing a [BlockHashOrNumber] from a string. -#[derive(Debug, thiserror::Error)] -#[error("failed to parse {input:?} as a number: {parse_int_error} or hash: {hex_error}")] +#[derive(Debug)] pub struct ParseBlockHashOrNumberError { input: String, parse_int_error: ParseIntError, hex_error: alloy_primitives::hex::FromHexError, } +impl fmt::Display for ParseBlockHashOrNumberError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "failed to parse {:?} as a number: {} or hash: {}", + self.input, self.parse_int_error, self.hex_error + ) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ParseBlockHashOrNumberError {} + impl FromStr for BlockHashOrNumber { type Err = ParseBlockHashOrNumberError; From a5cce7850741ebd3edf960e294fcc3884ea9d91c Mon Sep 17 00:00:00 2001 From: lakshya-sky <8559992+lakshya-sky@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:55:12 -0400 Subject: [PATCH 3/4] fix no-std errors --- crates/eips/src/eip1898.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 44627b203c8..4ebb8d5f53a 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -614,7 +614,8 @@ impl From<(BlockHash, BlockNumber)> for BlockNumHash { } /// Either a block hash _or_ a block number -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( any(test, feature = "arbitrary"), derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) @@ -707,7 +708,7 @@ impl fmt::Display for BlockHashOrNumber { /// Error thrown when parsing a [BlockHashOrNumber] from a string. #[derive(Debug)] pub struct ParseBlockHashOrNumberError { - input: String, + input: alloc::string::String, parse_int_error: ParseIntError, hex_error: alloy_primitives::hex::FromHexError, } @@ -729,6 +730,8 @@ impl FromStr for BlockHashOrNumber { type Err = ParseBlockHashOrNumberError; fn from_str(s: &str) -> Result { + #[allow(unused_imports)] + use alloc::string::ToString; match u64::from_str(s) { Ok(val) => Ok(val.into()), Err(pares_int_error) => match B256::from_str(s) { From 963d41f27c892a04668cf4ffbb773932eeb464e4 Mon Sep 17 00:00:00 2001 From: lakshya-sky <8559992+lakshya-sky@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:34:51 -0400 Subject: [PATCH 4/4] impl suggestions --- crates/eips/Cargo.toml | 39 ++++++++++---------------------------- crates/eips/src/eip1898.rs | 18 +++--------------- 2 files changed, 13 insertions(+), 44 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 3e548575413..cb186d0fb36 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -12,12 +12,8 @@ repository.workspace = true exclude.workspace = true [dependencies] -alloy-primitives = { workspace = true, features = [ - "rlp", -], default-features = false } -alloy-rlp = { workspace = true, features = [ - "derive", -], default-features = false } +alloy-primitives = { workspace = true, features = ["rlp"], default-features = false } +alloy-rlp = { workspace = true, features = ["derive"], default-features = false } alloy-serde.workspace = true # serde @@ -38,11 +34,7 @@ proptest = { workspace = true, optional = true } proptest-derive = { workspace = true, optional = true } [dev-dependencies] -alloy-primitives = { workspace = true, features = [ - "rand", - "serde", - "arbitrary", -] } +alloy-primitives = { workspace = true, features = ["rand", "serde", "arbitrary"] } arbitrary = { workspace = true, features = ["derive"] } proptest = { workspace = true } proptest-derive = { workspace = true } @@ -50,25 +42,14 @@ serde_json.workspace = true [features] default = ["std"] -std = [ - "alloy-primitives/std", - "alloy-rlp/std", - "serde?/std", - "c-kzg?/std", - "once_cell?/std", -] +std = ["alloy-primitives/std", "alloy-rlp/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] serde = ["dep:serde", "alloy-primitives/serde", "c-kzg?/serde"] kzg = ["dep:derive_more", "dep:c-kzg", "dep:once_cell"] -ssz = [ - "std", - "dep:ethereum_ssz", - "dep:ethereum_ssz_derive", - "alloy-primitives/ssz", -] +ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz"] arbitrary = [ - "std", - "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", - "alloy-primitives/arbitrary", + "std", + "dep:arbitrary", + "dep:proptest-derive", + "dep:proptest", + "alloy-primitives/arbitrary", ] diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 4ebb8d5f53a..5dff627bd49 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -558,7 +558,7 @@ impl FromStr for BlockId { } /// Block number and hash. -#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub struct BlockNumHash { /// Block number pub number: BlockNumber, @@ -569,18 +569,6 @@ pub struct BlockNumHash { /// Block number and hash of the forked block. pub type ForkBlock = BlockNumHash; -impl fmt::Debug for BlockNumHash { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("").field(&self.number).field(&self.hash).finish() - } -} - -impl fmt::Display for BlockNumHash { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "BlockNumHash{{ number: {}, hash: {} }}", self.number, self.hash) - } -} - impl BlockNumHash { /// Creates a new `BlockNumHash` from a block number and hash. pub const fn new(number: BlockNumber, hash: BlockHash) -> Self { @@ -734,11 +722,11 @@ impl FromStr for BlockHashOrNumber { use alloc::string::ToString; match u64::from_str(s) { Ok(val) => Ok(val.into()), - Err(pares_int_error) => match B256::from_str(s) { + Err(parse_int_error) => match B256::from_str(s) { Ok(val) => Ok(val.into()), Err(hex_error) => Err(ParseBlockHashOrNumberError { input: s.to_string(), - parse_int_error: pares_int_error, + parse_int_error, hex_error, }), },