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

Commit

Permalink
fix(solc): invalidate cache on unresolve error (#1337)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jun 2, 2022
1 parent 214d24d commit 030488e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 7 deletions.
19 changes: 15 additions & 4 deletions ethers-solc/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,26 +781,37 @@ pub(crate) enum ArtifactsCache<'a, T: ArtifactOutput> {

impl<'a, T: ArtifactOutput> ArtifactsCache<'a, T> {
pub fn new(project: &'a Project<T>, edges: GraphEdges) -> Result<Self> {
/// returns the [SolFilesCache] to use
fn get_cache<T: ArtifactOutput>(project: &Project<T>) -> SolFilesCache {
/// Returns the [SolFilesCache] to use
///
/// Returns a new empty cache if the cache does not exist or `invalidate_cache` is set.
fn get_cache<T: ArtifactOutput>(
project: &Project<T>,
invalidate_cache: bool,
) -> SolFilesCache {
// the currently configured paths
let paths = project.paths.paths_relative();

if project.cache_path().exists() {
if !invalidate_cache && project.cache_path().exists() {
if let Ok(cache) = SolFilesCache::read_joined(&project.paths) {
if cache.paths == paths {
// unchanged project paths
return cache
}
}
}

// new empty cache
SolFilesCache::new(Default::default(), paths)
}

let cache = if project.cached {
// we only read the existing cache if we were able to resolve the entire graph
// if we failed to resolve an import we invalidate the cache so don't get any false
// positives
let invalidate_cache = !edges.unresolved_imports().is_empty();

// read the cache file if it already exists
let mut cache = get_cache(project);
let mut cache = get_cache(project, invalidate_cache);

cache.remove_missing_files();

Expand Down
13 changes: 11 additions & 2 deletions ethers-solc/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ pub struct GraphEdges {
/// Combined with the `indices` this way we can determine if a file was original added to the
/// graph as input or was added as resolved import, see [`Self::is_input_file()`]
num_input_files: usize,
/// tracks all imports that we failed to resolve
unresolved_imports: HashSet<PathBuf>,
}

impl GraphEdges {
Expand All @@ -111,6 +113,11 @@ impl GraphEdges {
self.files().skip(self.num_input_files)
}

/// Returns all imports that we failed to resolve
pub fn unresolved_imports(&self) -> &HashSet<PathBuf> {
&self.unresolved_imports
}

/// Returns a list of nodes the given node index points to for the given kind.
pub fn imported_nodes(&self, from: usize) -> &[usize] {
&self.edges[from]
Expand Down Expand Up @@ -277,6 +284,7 @@ impl Graph {
self.nodes.iter().take(self.edges.num_input_files)
}

/// Returns all files imported by the given file
pub fn imports(&self, path: impl AsRef<Path>) -> HashSet<&PathBuf> {
self.edges.imports(path)
}
Expand Down Expand Up @@ -327,7 +335,7 @@ impl Graph {

// keep track of all unique paths that we failed to resolve to not spam the reporter with
// the same path
let mut unresolved_paths = HashSet::new();
let mut unresolved_imports = HashSet::new();

// now we need to resolve all imports for the source file and those imported from other
// locations
Expand All @@ -346,7 +354,7 @@ impl Graph {
add_node(&mut unresolved, &mut index, &mut resolved_imports, import)?;
}
Err(err) => {
if unresolved_paths.insert(import_path.to_path_buf()) {
if unresolved_imports.insert(import_path.to_path_buf()) {
crate::report::unresolved_import(import_path, &paths.remappings);
}
tracing::trace!(
Expand All @@ -372,6 +380,7 @@ impl Graph {
.map(|(idx, node)| (idx, node.data.version_req.clone()))
.collect(),
data: Default::default(),
unresolved_imports,
};
Ok(Graph { nodes, edges, root: paths.root.clone() })
}
Expand Down
45 changes: 44 additions & 1 deletion ethers-solc/tests/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{
collections::{BTreeMap, HashMap, HashSet},
io,
fs, io,
path::{Path, PathBuf},
str::FromStr,
};
Expand Down Expand Up @@ -1768,3 +1768,46 @@ contract D { }
cache.files.keys().cloned().collect::<Vec<_>>()
);
}

#[test]
fn test_failure_after_removing_file() {
let project = TempProject::dapptools().unwrap();
project
.add_source(
"A",
r#"
pragma solidity ^0.8.10;
import "./B.sol";
contract A { }
"#,
)
.unwrap();

project
.add_source(
"B",
r#"
pragma solidity ^0.8.10;
import "./C.sol";
contract B { }
"#,
)
.unwrap();

let c = project
.add_source(
"C",
r#"
pragma solidity ^0.8.10;
contract C { }
"#,
)
.unwrap();

let compiled = project.compile().unwrap();
assert!(!compiled.has_compiler_errors());

fs::remove_file(c).unwrap();
let compiled = project.compile().unwrap();
assert!(compiled.has_compiler_errors());
}

0 comments on commit 030488e

Please sign in to comment.