fix: sanitize compilerinput based on version (#1111)
* fix: sanitize compilerinput based on version * test: add compiler test * chore: remove unused warnings * style: make once lazy
This commit is contained in:
parent
ef1e715b86
commit
23e45e8531
|
@ -3,7 +3,7 @@ use ethers_core::abi::Abi;
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use md5::Digest;
|
use md5::Digest;
|
||||||
use semver::Version;
|
use semver::{Version, VersionReq};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, HashSet},
|
collections::{BTreeMap, HashSet},
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
|
@ -92,6 +92,22 @@ impl CompilerInput {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This will remove/adjust values in the `CompilerInput` that are not compatible with this
|
||||||
|
/// version
|
||||||
|
pub fn sanitized(mut self, version: &Version) -> Self {
|
||||||
|
static PRE_V0_6_0: once_cell::sync::Lazy<VersionReq> =
|
||||||
|
once_cell::sync::Lazy::new(|| VersionReq::parse("<0.6.0").unwrap());
|
||||||
|
|
||||||
|
if PRE_V0_6_0.matches(version) {
|
||||||
|
if let Some(ref mut meta) = self.settings.metadata {
|
||||||
|
// introduced in <https://docs.soliditylang.org/en/v0.6.0/using-the-compiler.html#compiler-api>
|
||||||
|
// missing in <https://docs.soliditylang.org/en/v0.5.17/using-the-compiler.html#compiler-api>
|
||||||
|
meta.bytecode_hash.take();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the settings for compilation
|
/// Sets the settings for compilation
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn settings(mut self, settings: Settings) -> Self {
|
pub fn settings(mut self, settings: Settings) -> Self {
|
||||||
|
@ -1400,4 +1416,24 @@ mod tests {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_sanitize_byte_code_hash() {
|
||||||
|
let version: Version = "0.6.0".parse().unwrap();
|
||||||
|
|
||||||
|
let settings = Settings { metadata: Some(BytecodeHash::Ipfs.into()), ..Default::default() };
|
||||||
|
|
||||||
|
let input = CompilerInput {
|
||||||
|
language: "Solidity".to_string(),
|
||||||
|
sources: Default::default(),
|
||||||
|
settings,
|
||||||
|
};
|
||||||
|
|
||||||
|
let i = input.clone().sanitized(&version);
|
||||||
|
assert_eq!(i.settings.metadata.unwrap().bytecode_hash, Some(BytecodeHash::Ipfs));
|
||||||
|
|
||||||
|
let version: Version = "0.5.17".parse().unwrap();
|
||||||
|
let i = input.sanitized(&version);
|
||||||
|
assert!(i.settings.metadata.unwrap().bytecode_hash.is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -451,7 +451,8 @@ fn compile_sequential(
|
||||||
let input = input
|
let input = input
|
||||||
.settings(opt_settings.clone())
|
.settings(opt_settings.clone())
|
||||||
.normalize_evm_version(&version)
|
.normalize_evm_version(&version)
|
||||||
.with_remappings(paths.remappings.clone());
|
.with_remappings(paths.remappings.clone())
|
||||||
|
.sanitized(&version);
|
||||||
|
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
"calling solc `{}` with {} sources {:?}",
|
"calling solc `{}` with {} sources {:?}",
|
||||||
|
@ -529,7 +530,8 @@ fn compile_parallel(
|
||||||
let job = input
|
let job = input
|
||||||
.settings(settings.clone())
|
.settings(settings.clone())
|
||||||
.normalize_evm_version(&version)
|
.normalize_evm_version(&version)
|
||||||
.with_remappings(paths.remappings.clone());
|
.with_remappings(paths.remappings.clone())
|
||||||
|
.sanitized(&version);
|
||||||
|
|
||||||
jobs.push((solc.clone(), version.clone(), job, actually_dirty))
|
jobs.push((solc.clone(), version.clone(), job, actually_dirty))
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ use rayon::prelude::*;
|
||||||
|
|
||||||
use semver::VersionReq;
|
use semver::VersionReq;
|
||||||
|
|
||||||
use crate::{error::Result, utils, ProjectPathsConfig, Solc, SolcError, Source, Sources};
|
use crate::{error::Result, utils, ProjectPathsConfig, SolcError, Source, Sources};
|
||||||
|
|
||||||
mod parse;
|
mod parse;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
@ -482,6 +482,8 @@ impl Graph {
|
||||||
&self,
|
&self,
|
||||||
offline: bool,
|
offline: bool,
|
||||||
) -> Result<HashMap<crate::SolcVersion, Vec<usize>>> {
|
) -> Result<HashMap<crate::SolcVersion, Vec<usize>>> {
|
||||||
|
use crate::Solc;
|
||||||
|
|
||||||
tracing::trace!("resolving input node versions");
|
tracing::trace!("resolving input node versions");
|
||||||
// this is likely called by an application and will be eventually printed so we don't exit
|
// this is likely called by an application and will be eventually printed so we don't exit
|
||||||
// on first error, instead gather all the errors and return a bundled error message instead
|
// on first error, instead gather all the errors and return a bundled error message instead
|
||||||
|
@ -683,7 +685,9 @@ impl VersionedSources {
|
||||||
pub fn get(
|
pub fn get(
|
||||||
self,
|
self,
|
||||||
allowed_lib_paths: &crate::AllowedLibPaths,
|
allowed_lib_paths: &crate::AllowedLibPaths,
|
||||||
) -> Result<std::collections::BTreeMap<Solc, (semver::Version, Sources)>> {
|
) -> Result<std::collections::BTreeMap<crate::Solc, (semver::Version, Sources)>> {
|
||||||
|
use crate::Solc;
|
||||||
|
|
||||||
// we take the installer lock here to ensure installation checking is done in sync
|
// we take the installer lock here to ensure installation checking is done in sync
|
||||||
#[cfg(any(test, feature = "tests"))]
|
#[cfg(any(test, feature = "tests"))]
|
||||||
let _lock = crate::compile::take_solc_installer_lock();
|
let _lock = crate::compile::take_solc_installer_lock();
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ethers_solc::{
|
use ethers_solc::{
|
||||||
|
artifacts::BytecodeHash,
|
||||||
cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME},
|
cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME},
|
||||||
project_util::*,
|
project_util::*,
|
||||||
remappings::Remapping,
|
remappings::Remapping,
|
||||||
|
@ -875,9 +876,27 @@ fn can_compile_sparse_with_link_references() {
|
||||||
let mut compiled = tmp.compile_sparse(TestFileFilter::default()).unwrap();
|
let mut compiled = tmp.compile_sparse(TestFileFilter::default()).unwrap();
|
||||||
assert!(!compiled.has_compiler_errors());
|
assert!(!compiled.has_compiler_errors());
|
||||||
|
|
||||||
println!("{}", compiled);
|
|
||||||
assert!(compiled.find("ATest").is_some());
|
assert!(compiled.find("ATest").is_some());
|
||||||
assert!(compiled.find("MyLib").is_some());
|
assert!(compiled.find("MyLib").is_some());
|
||||||
let lib = compiled.remove("MyLib").unwrap();
|
let lib = compiled.remove("MyLib").unwrap();
|
||||||
assert!(lib.bytecode.is_some());
|
assert!(lib.bytecode.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_sanitize_bytecode_hash() {
|
||||||
|
let mut tmp = TempProject::dapptools().unwrap();
|
||||||
|
tmp.project_mut().solc_config.settings.metadata = Some(BytecodeHash::Ipfs.into());
|
||||||
|
|
||||||
|
tmp.add_source(
|
||||||
|
"A",
|
||||||
|
r#"
|
||||||
|
pragma solidity =0.5.17;
|
||||||
|
contract A {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let compiled = tmp.compile().unwrap();
|
||||||
|
assert!(!compiled.has_compiler_errors());
|
||||||
|
assert!(compiled.find("A").is_some());
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue