Skip to content

Commit

Permalink
perf(solc): wrap source content in Arc (#2138)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse committed Feb 11, 2023
1 parent bfe3ba9 commit c7547cb
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 12 deletions.
2 changes: 1 addition & 1 deletion ethers-solc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ keywords = ["ethereum", "web3", "solc", "solidity", "ethers"]
[dependencies]
ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false }
serde_json = "1.0.68"
serde = { version = "1.0.130", features = ["derive"] }
serde = { version = "1.0.130", features = ["derive", "rc"] }
semver = { version = "1.0.16", features = ["serde"] }
walkdir = "2.3.2"
tokio = { version = "1.18", default-features = false, features = ["rt"] }
Expand Down
36 changes: 27 additions & 9 deletions ethers-solc/src/artifacts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::{
fmt, fs,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
};
use tracing::warn;
use yansi::Paint;
Expand Down Expand Up @@ -1195,16 +1196,29 @@ pub struct DocLibraries {
pub libs: BTreeMap<String, serde_json::Value>,
}

/// Content of a solidity file
///
/// This contains the actual source code of a file
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct Source {
pub content: String,
/// Content of the file
///
/// This is an `Arc` because it may be cloned. If the [Graph](crate::resolver::Graph) of the
/// project contains multiple conflicting versions then the same [Source] may be required by
/// conflicting versions and needs to be duplicated.
pub content: Arc<String>,
}

impl Source {
/// Reads the file content
/// Creates a new instance of [Source] with the given content.
pub fn new(content: impl Into<String>) -> Self {
Self { content: Arc::new(content.into()) }
}

/// Reads the file's content
pub fn read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
let file = file.as_ref();
Ok(Self { content: fs::read_to_string(file).map_err(|err| SolcIoError::new(err, file))? })
Ok(Self::new(fs::read_to_string(file).map_err(|err| SolcIoError::new(err, file))?))
}

/// Recursively finds all source files under the given dir path and reads them all
Expand Down Expand Up @@ -1254,7 +1268,7 @@ impl Source {
/// Generate a non-cryptographically secure checksum of the file's content
pub fn content_hash(&self) -> String {
let mut hasher = md5::Md5::new();
hasher.update(&self.content);
hasher.update(self);
let result = hasher.finalize();
hex::encode(result)
}
Expand All @@ -1270,11 +1284,9 @@ impl Source {
/// async version of `Self::read`
pub async fn async_read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
let file = file.as_ref();
Ok(Self {
content: tokio::fs::read_to_string(file)
.await
.map_err(|err| SolcIoError::new(err, file))?,
})
Ok(Self::new(
tokio::fs::read_to_string(file).await.map_err(|err| SolcIoError::new(err, file))?,
))
}

/// Finds all source files under the given dir path and reads them all
Expand Down Expand Up @@ -1306,6 +1318,12 @@ impl AsRef<str> for Source {
}
}

impl AsRef<[u8]> for Source {
fn as_ref(&self) -> &[u8] {
self.content.as_bytes()
}
}

/// Output type `solc` produces
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
pub struct CompilerOutput {
Expand Down
2 changes: 1 addition & 1 deletion ethers-solc/src/buildinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ mod tests {
fn build_info_serde() {
let inputs = CompilerInput::with_sources(BTreeMap::from([(
PathBuf::from("input.sol"),
Source { content: "".to_string() },
Source::new(""),
)]));
let output = CompilerOutput::default();
let v: Version = "0.8.4+commit.c7e474f2".parse().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion ethers-solc/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,6 @@ mod tests {
///// helpers

fn source(version: &str) -> Source {
Source { content: format!("pragma solidity {version};\n") }
Source::new(format!("pragma solidity {version};\n"))
}
}

0 comments on commit c7547cb

Please sign in to comment.