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

perf: replace hex with const-hex #2544

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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> {
hex::decode(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(serde::de::Error::custom)
}

#[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
9 changes: 3 additions & 6 deletions ethers-signers/src/trezor/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,10 @@ 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 mut address_bytes = [0; 20];
hex::decode_to_slice(address_str, &mut address_bytes)?;
Ok(address_bytes.into())
}

/// 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