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 md5::Digest;
|
||||
use semver::Version;
|
||||
use semver::{Version, VersionReq};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashSet},
|
||||
fmt, fs,
|
||||
|
@ -92,6 +92,22 @@ impl CompilerInput {
|
|||
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
|
||||
#[must_use]
|
||||
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
|
||||
.settings(opt_settings.clone())
|
||||
.normalize_evm_version(&version)
|
||||
.with_remappings(paths.remappings.clone());
|
||||
.with_remappings(paths.remappings.clone())
|
||||
.sanitized(&version);
|
||||
|
||||
tracing::trace!(
|
||||
"calling solc `{}` with {} sources {:?}",
|
||||
|
@ -529,7 +530,8 @@ fn compile_parallel(
|
|||
let job = input
|
||||
.settings(settings.clone())
|
||||
.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))
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ use rayon::prelude::*;
|
|||
|
||||
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 tree;
|
||||
|
@ -482,6 +482,8 @@ impl Graph {
|
|||
&self,
|
||||
offline: bool,
|
||||
) -> Result<HashMap<crate::SolcVersion, Vec<usize>>> {
|
||||
use crate::Solc;
|
||||
|
||||
tracing::trace!("resolving input node versions");
|
||||
// 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
|
||||
|
@ -683,7 +685,9 @@ impl VersionedSources {
|
|||
pub fn get(
|
||||
self,
|
||||
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
|
||||
#[cfg(any(test, feature = "tests"))]
|
||||
let _lock = crate::compile::take_solc_installer_lock();
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::{
|
|||
};
|
||||
|
||||
use ethers_solc::{
|
||||
artifacts::BytecodeHash,
|
||||
cache::{SolFilesCache, SOLIDITY_FILES_CACHE_FILENAME},
|
||||
project_util::*,
|
||||
remappings::Remapping,
|
||||
|
@ -875,9 +876,27 @@ fn can_compile_sparse_with_link_references() {
|
|||
let mut compiled = tmp.compile_sparse(TestFileFilter::default()).unwrap();
|
||||
assert!(!compiled.has_compiler_errors());
|
||||
|
||||
println!("{}", compiled);
|
||||
assert!(compiled.find("ATest").is_some());
|
||||
assert!(compiled.find("MyLib").is_some());
|
||||
let lib = compiled.remove("MyLib").unwrap();
|
||||
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