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

refactor(solc): rewrite compiler passes and cache change detection #802

Merged
merged 96 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
3f17eea
chore: clippy
mattsse Jan 17, 2022
abbc25d
Merge branch 'master' into matt/more-refactor
mattsse Jan 17, 2022
d624d32
refactor: rewrite compiler passes and cache
mattsse Jan 17, 2022
3026275
Merge branch 'master' into matt/more-refactor
mattsse Jan 22, 2022
8e16080
feat: more work on compile pipeline
mattsse Jan 24, 2022
c6c75d3
feat: add cache constructor
mattsse Jan 24, 2022
0ae4f1a
add artifact filtering
mattsse Jan 24, 2022
c7a6646
fine tune api
mattsse Jan 24, 2022
1346bb9
feat: prepare version integration
mattsse Jan 24, 2022
c5a9323
docs: more docs
mattsse Jan 24, 2022
68bfa4d
Merge branch 'master' into matt/more-refactor
mattsse Jan 26, 2022
3ec7a61
feat: add cacheentry2
mattsse Jan 26, 2022
c7d75dc
replace cacheentry types
mattsse Jan 26, 2022
c52dbe7
integrate new api
mattsse Jan 26, 2022
af560ca
Merge branch 'master' into matt/more-refactor
mattsse Jan 27, 2022
20ca411
docs: more docs
mattsse Jan 27, 2022
117b66c
feat: implement new output handler
mattsse Jan 27, 2022
0f33e57
feat: integrate cached files in new compile pipeline
mattsse Jan 27, 2022
6c6b5e1
refactor: more cache refactor
mattsse Jan 27, 2022
d5810f3
docs: more docs
mattsse Jan 27, 2022
35ee608
Merge branch 'master' into matt/more-refactor
mattsse Jan 27, 2022
ad82ba6
feat: add source name mapping
mattsse Jan 27, 2022
e26ede9
feat: implement new parallel solc
mattsse Jan 27, 2022
270a60b
refactor: do a little cleanup
mattsse Jan 27, 2022
5053823
refactor: even more cleanup
mattsse Jan 27, 2022
514a329
even more cleanup
mattsse Jan 27, 2022
c4d6883
chore: make it compile
mattsse Jan 27, 2022
dba9dbc
chore: make it compile with all features
mattsse Jan 27, 2022
dda718a
chore: clippy fix
mattsse Jan 27, 2022
77644b9
feat: integrate new compiler pipeline
mattsse Jan 27, 2022
741f9ee
docs: more docs
mattsse Jan 27, 2022
587a8c3
refactor: move stuff around
mattsse Jan 28, 2022
17a2829
refactor: start deprecating output type
mattsse Jan 28, 2022
fe57fec
Merge branch 'master' into matt/more-refactor
mattsse Jan 28, 2022
850497f
chore: make it compile again
mattsse Jan 28, 2022
14e020c
chore(deps): bump solc version 0.2.0
mattsse Jan 28, 2022
e26b301
Merge branch 'master' into matt/more-refactor
mattsse Jan 29, 2022
38da027
feat: unify output types
mattsse Jan 29, 2022
3ac275c
cargo fix
mattsse Jan 29, 2022
4718eb4
refactor: add contracts wrapper
mattsse Jan 29, 2022
0e3ad21
chore: replace ProjectCompileOutput
mattsse Jan 29, 2022
15c7c52
docs: add more docs
mattsse Jan 29, 2022
da2d790
feat: add offline mode
mattsse Jan 29, 2022
d720f87
feat: more artifact helpers
mattsse Jan 29, 2022
f2913a8
chore: cleanup cache
mattsse Jan 29, 2022
b6aaef5
chore: streamline types
mattsse Jan 29, 2022
f18f97d
fix: better artifacts mapping
mattsse Jan 29, 2022
fdaeb57
chore: some cleanup
mattsse Jan 29, 2022
87dc19e
chore: change artifact
mattsse Jan 30, 2022
b320761
chore: add configure solc fn
mattsse Jan 30, 2022
3fb6ea1
feat: add artifact reading
mattsse Jan 30, 2022
1431584
feat: implement retain and extend
mattsse Jan 30, 2022
2b554b5
feat: add cache extending
mattsse Jan 30, 2022
1651d97
feat: write to disk
mattsse Jan 30, 2022
1757db9
chore: make clippy happy
mattsse Jan 30, 2022
09fa9c2
Merge branch 'master' into matt/more-refactor
mattsse Jan 30, 2022
17d1431
feat: implement path mapping
mattsse Jan 30, 2022
8ea0eac
chore: nits
mattsse Jan 30, 2022
b354f7a
feat: introduce states
mattsse Jan 30, 2022
ddc30ac
feat: add compiler state machine
mattsse Jan 30, 2022
d782fcd
chore: move cache types to cache mod
mattsse Jan 30, 2022
cb45e51
chore: make clippy happy
mattsse Jan 30, 2022
1b757a9
Merge branch 'master' into matt/more-refactor
mattsse Jan 31, 2022
7a0f8d5
feat: add debug derives
mattsse Jan 31, 2022
1332582
fix: use resolved import source unit names
mattsse Jan 31, 2022
4198a07
Merge branch 'master' into matt/more-refactor
mattsse Jan 31, 2022
0e7d08f
fix: failing tests
mattsse Jan 31, 2022
6e5a98f
test: test multiple libs properly
mattsse Jan 31, 2022
57ed568
chore: make clippy happy
mattsse Jan 31, 2022
82dabeb
chore: update CHANGELOG
mattsse Jan 31, 2022
8e1b175
fix: doc tests
mattsse Jan 31, 2022
5ed8bbb
fix: set offline mode correctly
mattsse Jan 31, 2022
df7640a
Merge branch 'master' into matt/more-refactor
mattsse Jan 31, 2022
705fa9b
chore: make it compile again
mattsse Jan 31, 2022
bf6e5f1
Update ethers-solc/src/artifacts.rs
mattsse Feb 2, 2022
49b9942
feat: find remappings by default
mattsse Jan 31, 2022
83a2f09
typos
mattsse Feb 2, 2022
0a871ae
add eth_syncing RPC (#848)
rakita Feb 1, 2022
1a26010
fix(core): adjust Ganache for new cli output (#851)
wolflo Feb 1, 2022
5fe8d5a
fix: review comments
mattsse Feb 2, 2022
f3a5f58
fix: cache relative path bug
mattsse Feb 2, 2022
1ca1173
chore: add cache example
mattsse Feb 2, 2022
e962821
Merge branch 'master' into matt/more-refactor
mattsse Feb 2, 2022
a524c7c
chore: use absolute paths
mattsse Feb 2, 2022
0fa69c2
fix: remove overwritten files from cache
mattsse Feb 2, 2022
e2d9d05
fix: rustfmt
mattsse Feb 2, 2022
ac9c3c2
Merge branch 'master' into matt/more-refactor
mattsse Feb 2, 2022
ff9599c
chore: more helper functions
mattsse Feb 3, 2022
a73fe91
chore: export AggregatedOutput
mattsse Feb 3, 2022
7b3bb57
feat: implement helper functions
mattsse Feb 3, 2022
c15b634
feat: even more helpers
mattsse Feb 3, 2022
e19103c
fix: failing doc tests
mattsse Feb 3, 2022
a03a7bb
refactor: remove source name map tracking
mattsse Feb 3, 2022
072bbb5
fix: determine artifacts in ephemeral mode
mattsse Feb 3, 2022
4367538
Merge branch 'master' into matt/more-refactor
mattsse Feb 3, 2022
18e8218
refactor: allowed paths should not fail
mattsse Feb 3, 2022
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
14 changes: 14 additions & 0 deletions ethers-solc/src/artifact_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,20 @@ pub trait Artifact {

/// Returns the contents of this type as a single tuple of abi, bytecode and deployed bytecode
fn into_parts(self) -> (Option<Abi>, Option<Bytes>, Option<Bytes>);

/// Same as [`Self::into_parts()`] but returns `Err` if an element is `None`
fn try_into_parts(self) -> Result<(Abi, Bytes, Bytes)>
where
Self: Sized,
{
let (abi, bytecode, deployed_bytecode) = self.into_parts();

Ok((
abi.ok_or_else(|| SolcError::msg("abi missing"))?,
bytecode.ok_or_else(|| SolcError::msg("bytecode missing"))?,
deployed_bytecode.ok_or_else(|| SolcError::msg("deployed bytecode missing"))?,
))
}
}

impl<T> Artifact for T
Expand Down
96 changes: 90 additions & 6 deletions ethers-solc/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::{
contracts::VersionedContracts,
error::{Result, SolcError},
resolver::GraphEdges,
utils, ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Project, Source,
utils, ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Project, ProjectPathsConfig,
Source,
};
use semver::Version;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
Expand Down Expand Up @@ -63,6 +64,8 @@ impl SolFilesCache {

/// Reads the cache json file from the given path
///
/// See also [`Self::read_joined()`]
///
/// # Errors
///
/// If the cache file does not exist
Expand All @@ -88,6 +91,26 @@ impl SolFilesCache {
Ok(cache)
}

/// Reads the cache json file from the given path and returns the cache with modified paths
///
///
/// # Example
///
/// ```
/// # fn t() {
/// use ethers_solc::cache::SolFilesCache;
/// use ethers_solc::Project;
///
/// let project = Project::builder().build().unwrap();
/// let cache = SolFilesCache::read_joined(&project.paths).unwrap();
/// # }
/// ```
pub fn read_joined(paths: &ProjectPathsConfig) -> Result<Self> {
let mut cache = SolFilesCache::read(&paths.cache)?;
cache.join_all(&paths.artifacts);
Ok(cache)
}

/// Write the cache as json file to the given path
pub fn write(&self, path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();
Expand Down Expand Up @@ -130,6 +153,59 @@ impl SolFilesCache {
self.files.values().all(|entry| entry.all_artifacts_exist())
}

/// Returns the path to the artifact of the given `(file, contract)` pair
///
/// # Example
///
/// ```
/// # fn t() {
/// use ethers_solc::cache::SolFilesCache;
/// use ethers_solc::Project;
///
/// let project = Project::builder().build().unwrap();
/// let cache = SolFilesCache::read_joined(&project.paths).unwrap();
/// cache.find_artifact_path("/.../src/Greeter.sol", "Greeter");
mattsse marked this conversation as resolved.
Show resolved Hide resolved
/// # }
/// ```
pub fn find_artifact_path(
&self,
contract_file: impl AsRef<Path>,
contract_name: impl AsRef<str>,
) -> Option<&PathBuf> {
let entry = self.entry(contract_file)?;
entry.find_artifact_path(contract_name)
}

/// Finds the path to the artifact of the given `(file, contract)` pair, see
/// [`Self::find_artifact_path()`], and reads the artifact as json file
/// # Example
///
/// ```
/// # fn t() {
/// use ethers_solc::cache::SolFilesCache;
/// use ethers_solc::Project;
///
/// let project = Project::builder().build().unwrap();
/// let cache = SolFilesCache::read_joined(&project.paths).unwrap();
/// cache.read_artifact("/.../src/Greeter.sol", "Greeter");
/// # }
/// ```
pub fn read_artifact<Artifact: DeserializeOwned>(
&self,
contract_file: impl AsRef<Path>,
contract_name: impl AsRef<str>,
) -> Result<Artifact> {
let contract_file = contract_file.as_ref();
let contract_name = contract_name.as_ref();

let artifact_path =
self.find_artifact_path(contract_file, contract_name).ok_or_else(|| {
SolcError::ArtifactNotFound(contract_file.to_path_buf(), contract_name.to_string())
})?;

utils::read_json_file(artifact_path)
}

/// Reads all cached artifacts from disk using the given ArtifactOutput handler
///
/// # Example
Expand All @@ -140,8 +216,7 @@ impl SolFilesCache {
/// use ethers_solc::artifacts::CompactContractBytecode;
/// # fn t() {
/// let project = Project::builder().build().unwrap();
/// let mut cache = SolFilesCache::read(project.cache_path()).unwrap();
/// cache.join_all(project.artifacts_path());
/// let cache = SolFilesCache::read_joined(&project.paths).unwrap();
/// let artifacts = cache.read_artifacts::<CompactContractBytecode>().unwrap();
/// # }
/// ```
Expand Down Expand Up @@ -257,6 +332,17 @@ impl CacheEntry {
Duration::from_millis(self.last_modification_date)
}

/// Returns the artifact path for the contract name
/// ```
/// use ethers_solc::cache::CacheEntry;
/// # fn t(entry: CacheEntry) {
/// entry.find_artifact_path("Greeter");
/// # }
/// ```
pub fn find_artifact_path(&self, contract_name: impl AsRef<str>) -> Option<&PathBuf> {
self.artifacts.get(contract_name.as_ref())?.iter().next().map(|(_, p)| p)
}

/// Reads the last modification date from the file's metadata
pub fn read_last_modification_date(file: impl AsRef<Path>) -> Result<u64> {
let file = file.as_ref();
Expand Down Expand Up @@ -552,9 +638,7 @@ impl<'a, T: ArtifactOutput> ArtifactsCache<'a, T> {
let cache = if project.cached {
// read the cache file if it already exists
let cache = if project.cache_path().exists() {
let mut cache = SolFilesCache::read(project.cache_path()).unwrap_or_default();
cache.join_all(project.artifacts_path()).remove_missing_files();
cache
SolFilesCache::read_joined(&project.paths).unwrap_or_default()
} else {
SolFilesCache::default()
};
Expand Down
9 changes: 9 additions & 0 deletions ethers-solc/src/compile/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ impl VersionedContracts {
.flat_map(|c| c.iter().flat_map(|(name, c)| c.iter().map(move |c| (name, &c.contract))))
}

/// Returns an iterator over (`file`, `name`, `Contract`)
pub fn contracts_with_files(&self) -> impl Iterator<Item = (&String, &String, &Contract)> {
self.0.iter().flat_map(|(file, contracts)| {
contracts
.iter()
.flat_map(move |(name, c)| c.iter().map(move |c| (file, name, &c.contract)))
})
}

/// Returns an iterator over all contracts and their source names.
///
/// ```
Expand Down
3 changes: 3 additions & 0 deletions ethers-solc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub enum SolcError {
#[error("{0}")]
Message(String),

#[error("No artifact found for `{}:{}`", .0.display(), .1)]
ArtifactNotFound(PathBuf, String),

#[cfg(feature = "project-util")]
#[error(transparent)]
FsExtra(#[from] fs_extra::error::Error),
Expand Down
2 changes: 1 addition & 1 deletion ethers-solc/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ pub(crate) fn tempdir(name: &str) -> Result<tempfile::TempDir, SolcIoError> {
}

/// Reads the json file and deserialize it into the provided type
pub(crate) fn read_json_file<T: DeserializeOwned>(path: impl AsRef<Path>) -> Result<T, SolcError> {
pub fn read_json_file<T: DeserializeOwned>(path: impl AsRef<Path>) -> Result<T, SolcError> {
let path = path.as_ref();
let file = std::fs::File::open(path).map_err(|err| SolcError::io(err, path))?;
let file = std::io::BufReader::new(file);
Expand Down