Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
perf: replace hex with const-hex
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Aug 11, 2023
1 parent 5145992 commit 404f00f
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bytes = "1.4"
criterion = "0.5"
dunce = "1.0"
eyre = "0.6"
hex = "0.4"
hex = { package = "const-hex", version = "1.6", features = ["hex"] }
hex-literal = "0.4"
home = "0.5.5"
Inflector = "0.11"
Expand Down
2 changes: 1 addition & 1 deletion ethers-contract/ethers-contract-derive/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ fn parse_event_attributes(input: &DeriveInput) -> Result<EthEventAttributes> {
meta.input.parse::<Token![=]>()?;
let litstr: LitStr = meta.input.parse()?;
let s = litstr.value();
let b = hex::decode(s.strip_prefix("0x").unwrap_or(&s)).map_err(|e| meta.error(e))?;
let b = hex::decode(s).map_err(|e| meta.error(e))?;
result.signature = Some((b, litstr.span()));
}
"anonymous", result.anonymous => { result.anonymous = Some((true, meta.path.span())); }
Expand Down
2 changes: 1 addition & 1 deletion ethers-core/src/abi/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub trait AbiEncode {
where
Self: Sized,
{
format!("0x{}", hex::encode(self.encode()))
hex::encode_prefixed(self.encode())
}
}

Expand Down
28 changes: 12 additions & 16 deletions ethers-core/src/types/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ pub struct Bytes(
pub bytes::Bytes,
);

impl hex::FromHex for Bytes {
type Error = hex::FromHexError;

fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
Vec::<u8>::from_hex(hex).map(Into::into)
}
}

impl FromIterator<u8> for Bytes {
fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
iter.into_iter().collect::<bytes::Bytes>().into()
Expand Down Expand Up @@ -197,19 +205,13 @@ impl Decodable for Bytes {

#[derive(Debug, Clone, Error)]
#[error("Failed to parse bytes: {0}")]
pub struct ParseBytesError(String);
pub struct ParseBytesError(hex::FromHexError);

impl FromStr for Bytes {
type Err = ParseBytesError;

fn from_str(value: &str) -> Result<Self, Self::Err> {
if let Some(value) = value.strip_prefix("0x") {
hex::decode(value)
} else {
hex::decode(value)
}
.map(Into::into)
.map_err(|e| ParseBytesError(format!("Invalid hex: {e}")))
hex::FromHex::from_hex(value).map_err(ParseBytesError)
}
}

Expand All @@ -218,21 +220,15 @@ where
S: Serializer,
T: AsRef<[u8]>,
{
s.serialize_str(&format!("0x{}", hex::encode(x.as_ref())))
s.serialize_str(&hex::encode_prefixed(x))
}

pub fn deserialize_bytes<'de, D>(d: D) -> Result<bytes::Bytes, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(d)?;
if let Some(value) = value.strip_prefix("0x") {
hex::decode(value)
} else {
hex::decode(&value)
}
.map(Into::into)
.map_err(|e| serde::de::Error::custom(e.to_string()))
hex::decode(&value).map(Into::into).map_err(|e| serde::de::Error::custom(e.to_string()))
}

#[cfg(test)]
Expand Down
7 changes: 2 additions & 5 deletions ethers-core/src/types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ pub struct Signature {

impl fmt::Display for Signature {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let sig = <[u8; 65]>::from(self);
write!(f, "{}", hex::encode(&sig[..]))
f.write_str(hex::Buffer::<65, false>::new().format(&self.into()))
}
}

Expand Down Expand Up @@ -213,9 +212,7 @@ impl FromStr for Signature {
type Err = SignatureError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.strip_prefix("0x").unwrap_or(s);
let bytes = hex::decode(s)?;
Signature::try_from(&bytes[..])
Signature::try_from(&hex::decode(s)?[..])
}
}

Expand Down
3 changes: 1 addition & 2 deletions ethers-core/src/types/transaction/eip2718.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,6 @@ impl From<TypedTransaction> for Eip2930TransactionRequest {

#[cfg(test)]
mod tests {
use hex::ToHex;
use rlp::Decodable;

use super::*;
Expand Down Expand Up @@ -859,7 +858,7 @@ mod tests {
// compare rlp - sighash should then be the same
let tx_expected_rlp = "f90145052b85012a05f20085012a05f2148301b3cd8080b9012d608060405234801561001057600080fd5b5061010d806100206000396000f3fe6080604052348015600f57600080fd5b506004361060325760003560e01c8063cfae3217146037578063f8a8fd6d146066575b600080fd5b604080518082019091526003815262676d2160e81b60208201525b604051605d91906085565b60405180910390f35b6040805180820190915260048152636f6f662160e01b60208201526052565b600060208083528351808285015260005b8181101560b0578581018301518582016040015282016096565b8181111560c1576000604083870101525b50601f01601f191692909201604001939250505056fea2646970667358221220f89093a9819ba5d2a3384305511d0945ea94f36a8aa162ab62921b3841fe3afd64736f6c634300080c0033c0";
let tx_real_rlp_vec = tx.rlp().to_vec();
let tx_real_rlp: String = tx_real_rlp_vec.encode_hex();
let tx_real_rlp: String = hex::encode(tx_real_rlp_vec);
assert_eq!(tx_expected_rlp, tx_real_rlp);

let r =
Expand Down
4 changes: 1 addition & 3 deletions ethers-providers/src/ext/ens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ mod tests {
use super::*;

fn assert_hex(hash: H256, val: &str) {
let v = if let Some(stripped) = val.strip_prefix("0x") { stripped } else { val };

assert_eq!(hash.0.to_vec(), hex::decode(v).unwrap());
assert_eq!(hash.0.to_vec(), hex::decode(val).unwrap());
}

#[test]
Expand Down
20 changes: 12 additions & 8 deletions ethers-providers/src/rpc/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use ethers_core::{
utils,
};
use futures_util::{lock::Mutex, try_join};
use hex::FromHex;
use serde::{de::DeserializeOwned, Serialize};
use std::{
collections::VecDeque, convert::TryFrom, fmt::Debug, str::FromStr, sync::Arc, time::Duration,
Expand Down Expand Up @@ -584,11 +583,10 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
let data = utils::serialize(&data.into());
let from = utils::serialize(from);

// get the response from `eth_sign` call and trim the 0x-prefix if present.
// get the response from `eth_sign` call
let sig: String = self.request("eth_sign", [from, data]).await?;
let sig = sig.strip_prefix("0x").unwrap_or(&sig);

// decode the signature.
// decode the signature
let sig = hex::decode(sig)?;
Ok(Signature::try_from(sig.as_slice())
.map_err(|e| ProviderError::CustomError(e.to_string()))?)
Expand Down Expand Up @@ -682,11 +680,17 @@ impl<P: JsonRpcClient> Middleware for Provider<P> {
let from = utils::serialize(&from);
let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into()));

// get the hex encoded value.
// get the hex encoded value
let value: String = self.request("eth_getStorageAt", [from, position, block]).await?;
// get rid of the 0x prefix and left pad it with zeroes.
let value = format!("{:0>64}", value.replace("0x", ""));
Ok(H256::from_slice(&Vec::from_hex(value)?))
// decode and left-pad to 32 bytes
let bytes = hex::decode(&value)?;
if bytes.len() > 32 {
Err(hex::FromHexError::InvalidStringLength.into())
} else {
let mut buf = [0; 32];
buf[32 - bytes.len()..].copy_from_slice(&bytes);
Ok(H256(buf))
}
}

async fn get_code<T: Into<NameOrAddress> + Send + Sync>(
Expand Down
12 changes: 6 additions & 6 deletions ethers-signers/src/trezor/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ impl TrezorEthereum {
derivation: &DerivationType,
) -> Result<Address, TrezorError> {
let mut client = self.get_client(self.session_id.clone())?;

let address_str = client.ethereum_get_address(Self::convert_path(derivation))?;

let mut address = [0; 20];
address.copy_from_slice(&hex::decode(&address_str[2..])?);

Ok(Address::from(address))
let address_bytes = hex::decode(&address_str)?;
if address_bytes.len() == 20 {
Ok(Address::from_slice(&address_bytes))
} else {
Err(TrezorError::HexError(hex::FromHexError::InvalidStringLength))
}
}

/// Signs an Ethereum transaction (requires confirmation on the Trezor)
Expand Down
8 changes: 4 additions & 4 deletions ethers-signers/src/trezor/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ pub enum TrezorError {
FeaturesError,
#[error("Not able to unpack value for TrezorTransaction.")]
DataError,
#[error(transparent)]
/// Error when converting from a hex string
HexError(#[from] hex::FromHexError),
#[error(transparent)]
HexError(#[from] hex::FromHexError),
/// Error when converting a semver requirement
#[error(transparent)]
SemVerError(#[from] semver::Error),
/// Error when signing EIP712 struct with not compatible Trezor ETH app
#[error("Trezor ethereum app requires at least version: {0:?}")]
Expand Down Expand Up @@ -79,7 +79,7 @@ impl TrezorTransaction {
let to: String = match tx.to() {
Some(v) => match v {
NameOrAddress::Name(_) => return Err(TrezorError::NoENSSupport),
NameOrAddress::Address(value) => format!("0x{}", hex::encode(value)),
NameOrAddress::Address(value) => hex::encode_prefixed(value),
},
// Contract Creation
None => "".to_string(),
Expand Down Expand Up @@ -113,7 +113,7 @@ impl TrezorTransaction {

let mut access_list: Vec<Trezor_AccessListItem> = Vec::new();
for item in &eip1559_tx.access_list.0 {
let address: String = format!("0x{}", hex::encode(item.address));
let address: String = hex::encode_prefixed(item.address);
let mut storage_keys: Vec<Vec<u8>> = Vec::new();

for key in &item.storage_keys {
Expand Down
3 changes: 1 addition & 2 deletions ethers-signers/src/wallet/private_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,7 @@ impl FromStr for Wallet<SigningKey> {
type Err = WalletError;

fn from_str(src: &str) -> Result<Self, Self::Err> {
let src = src.strip_prefix("0x").or_else(|| src.strip_prefix("0X")).unwrap_or(src);
let src = hex::decode(src)?;
let src = hex::decode(src.strip_prefix("0X").unwrap_or(src))?;

if src.len() != 32 {
return Err(WalletError::HexError(hex::FromHexError::InvalidStringLength))
Expand Down
16 changes: 2 additions & 14 deletions ethers-solc/src/artifacts/serde_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,15 @@ pub fn deserialize_bytes<'de, D>(d: D) -> Result<Bytes, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(d)?.parse::<Bytes>().map_err(|e| serde::de::Error::custom(e.to_string()))
String::deserialize(d)?.parse::<Bytes>().map_err(serde::de::Error::custom)
}

pub fn deserialize_opt_bytes<'de, D>(d: D) -> Result<Option<Bytes>, D::Error>
where
D: Deserializer<'de>,
{
let value = Option::<String>::deserialize(d)?;
if let Some(value) = value {
Ok(Some(
if let Some(value) = value.strip_prefix("0x") {
hex::decode(value)
} else {
hex::decode(&value)
}
.map_err(|e| serde::de::Error::custom(e.to_string()))?
.into(),
))
} else {
Ok(None)
}
value.as_deref().map(str::parse).transpose().map_err(serde::de::Error::custom)
}

pub fn default_for_null<'de, D, T>(deserializer: D) -> Result<T, D::Error>
Expand Down
8 changes: 5 additions & 3 deletions ethers-solc/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,11 @@ pub fn library_fully_qualified_placeholder(name: impl AsRef<str>) -> String {

/// Returns the library hash placeholder as `$hex(library_hash(name))$`
pub fn library_hash_placeholder(name: impl AsRef<[u8]>) -> String {
let hash = library_hash(name);
let placeholder = hex::encode(hash);
format!("${placeholder}$")
let mut s = String::with_capacity(34 + 2);
s.push('$');
s.push_str(hex::Buffer::<17, false>::new().format(&library_hash(name)));
s.push('$');
s
}

/// Returns the library placeholder for the given name
Expand Down

0 comments on commit 404f00f

Please sign in to comment.