Skip to content

Commit 3d393b6

Browse files
authored
fix(config): enable optimizer if optimizer runs > 0 in additional profiles (foundry-rs#9901)
* fix(config): enable optimizer if optimizer runs > 0 in additional profiles * Improved test
1 parent b184ebd commit 3d393b6

File tree

2 files changed

+167
-1
lines changed

2 files changed

+167
-1
lines changed

crates/config/src/compilation.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ impl SettingsOverrides {
4040

4141
if let Some(optimizer_runs) = self.optimizer_runs {
4242
settings.solc.optimizer.runs = Some(optimizer_runs);
43+
// Enable optimizer in optimizer runs set to a higher value than 0.
44+
if optimizer_runs > 0 && self.optimizer.is_none() {
45+
settings.solc.optimizer.enabled = Some(true);
46+
}
4347
}
4448

4549
if let Some(bytecode_hash) = self.bytecode_hash {

crates/forge/tests/cli/config.rs

Lines changed: 163 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ use foundry_compilers::{
88
};
99
use foundry_config::{
1010
cache::{CachedChains, CachedEndpoints, StorageCachingConfig},
11+
filter::GlobMatcher,
1112
fs_permissions::{FsAccessPermission, PathPermission},
12-
Config, FsPermissions, FuzzConfig, InvariantConfig, SolcReq,
13+
CompilationRestrictions, Config, FsPermissions, FuzzConfig, InvariantConfig, SettingsOverrides,
14+
SolcReq,
1315
};
1416
use foundry_evm::opts::EvmOpts;
1517
use foundry_test_utils::{
1618
foundry_compilers::artifacts::{remappings::Remapping, EvmVersion},
1719
util::{pretty_err, OutputExt, TestCommand, OTHER_SOLC_VERSION},
1820
};
1921
use path_slash::PathBufExt;
22+
use semver::VersionReq;
23+
use serde_json::Value;
2024
use similar_asserts::assert_eq;
2125
use std::{
2226
fs,
@@ -1631,3 +1635,161 @@ contract GasSnapshotEmitTest is DSTest {
16311635
// Assert that snapshots were not emitted to disk.
16321636
assert!(!prj.root().join("snapshots/GasSnapshotEmitTest.json").exists());
16331637
});
1638+
1639+
// Tests compilation restrictions enables optimizer if optimizer runs set to a value higher than 0.
1640+
forgetest_init!(test_additional_compiler_profiles, |prj, cmd| {
1641+
prj.add_source(
1642+
"v1/Counter.sol",
1643+
r#"
1644+
contract Counter {
1645+
}
1646+
"#,
1647+
)
1648+
.unwrap();
1649+
1650+
prj.add_source(
1651+
"v2/Counter.sol",
1652+
r#"
1653+
contract Counter {
1654+
}
1655+
"#,
1656+
)
1657+
.unwrap();
1658+
1659+
prj.add_source(
1660+
"v3/Counter.sol",
1661+
r#"
1662+
contract Counter {
1663+
}
1664+
"#,
1665+
)
1666+
.unwrap();
1667+
1668+
// Additional profiles are defined with optimizer runs but without explicitly enabling
1669+
// optimizer
1670+
//
1671+
// additional_compiler_profiles = [
1672+
// { name = "v1", optimizer_runs = 44444444, via_ir = true, evm_version = "cancun" },
1673+
// { name = "v2", optimizer_runs = 111, via_ir = true },
1674+
// { name = "v3", optimizer_runs = 800, evm_version = "istanbul", via_ir = false },
1675+
// ]
1676+
//
1677+
// compilation_restrictions = [
1678+
// # v1
1679+
// { paths = "src/v1/[!i]*.sol", version = "0.8.16", optimizer_runs = 44444444 },
1680+
// # v2
1681+
// { paths = "src/v2/{Counter}.sol", optimizer_runs = 111 },
1682+
// # v3
1683+
// { paths = "src/v3/*", optimizer_runs = 800 },
1684+
// ]
1685+
let v1_profile = SettingsOverrides {
1686+
name: "v1".to_string(),
1687+
via_ir: Some(true),
1688+
evm_version: Some(EvmVersion::Cancun),
1689+
optimizer: None,
1690+
optimizer_runs: Some(44444444),
1691+
bytecode_hash: None,
1692+
};
1693+
let v1_restrictions = CompilationRestrictions {
1694+
paths: GlobMatcher::from_str("src/v1/[!i]*.sol").unwrap(),
1695+
version: Some(VersionReq::from_str("0.8.16").unwrap()),
1696+
via_ir: None,
1697+
bytecode_hash: None,
1698+
min_optimizer_runs: None,
1699+
optimizer_runs: Some(44444444),
1700+
max_optimizer_runs: None,
1701+
min_evm_version: None,
1702+
evm_version: None,
1703+
max_evm_version: None,
1704+
};
1705+
let v2_profile = SettingsOverrides {
1706+
name: "v2".to_string(),
1707+
via_ir: Some(true),
1708+
evm_version: None,
1709+
optimizer: None,
1710+
optimizer_runs: Some(111),
1711+
bytecode_hash: None,
1712+
};
1713+
let v2_restrictions = CompilationRestrictions {
1714+
paths: GlobMatcher::from_str("src/v2/{Counter}.sol").unwrap(),
1715+
version: None,
1716+
via_ir: None,
1717+
bytecode_hash: None,
1718+
min_optimizer_runs: None,
1719+
optimizer_runs: Some(111),
1720+
max_optimizer_runs: None,
1721+
min_evm_version: None,
1722+
evm_version: None,
1723+
max_evm_version: None,
1724+
};
1725+
let v3_profile = SettingsOverrides {
1726+
name: "v3".to_string(),
1727+
via_ir: Some(false),
1728+
evm_version: Some(EvmVersion::Istanbul),
1729+
optimizer: None,
1730+
optimizer_runs: Some(800),
1731+
bytecode_hash: None,
1732+
};
1733+
let v3_restrictions = CompilationRestrictions {
1734+
paths: GlobMatcher::from_str("src/v3/*").unwrap(),
1735+
version: None,
1736+
via_ir: None,
1737+
bytecode_hash: None,
1738+
min_optimizer_runs: None,
1739+
optimizer_runs: Some(800),
1740+
max_optimizer_runs: None,
1741+
min_evm_version: None,
1742+
evm_version: None,
1743+
max_evm_version: None,
1744+
};
1745+
let additional_compiler_profiles = vec![v1_profile, v2_profile, v3_profile];
1746+
let compilation_restrictions = vec![v1_restrictions, v2_restrictions, v3_restrictions];
1747+
prj.update_config(|config| {
1748+
config.additional_compiler_profiles = additional_compiler_profiles;
1749+
config.compilation_restrictions = compilation_restrictions;
1750+
});
1751+
// Should find and build all profiles satisfying settings restrictions.
1752+
cmd.forge_fuse().args(["build"]).assert_success();
1753+
prj.assert_artifacts_dir_exists();
1754+
1755+
let artifact_settings =
1756+
|artifact| -> (Option<Value>, Option<Value>, Option<Value>, Option<Value>) {
1757+
let artifact: serde_json::Value = serde_json::from_reader(
1758+
fs::File::open(prj.artifacts().join(artifact)).expect("no artifact"),
1759+
)
1760+
.expect("invalid artifact");
1761+
let settings =
1762+
artifact.get("metadata").unwrap().get("settings").unwrap().as_object().unwrap();
1763+
let optimizer = settings.get("optimizer").unwrap();
1764+
(
1765+
settings.get("viaIR").cloned(),
1766+
settings.get("evmVersion").cloned(),
1767+
optimizer.get("enabled").cloned(),
1768+
optimizer.get("runs").cloned(),
1769+
)
1770+
};
1771+
1772+
let (via_ir, evm_version, enabled, runs) = artifact_settings("Counter.sol/Counter.json");
1773+
assert_eq!(None, via_ir);
1774+
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
1775+
assert_eq!("false", enabled.unwrap().to_string());
1776+
assert_eq!("200", runs.unwrap().to_string());
1777+
1778+
let (via_ir, evm_version, enabled, runs) = artifact_settings("v1/Counter.sol/Counter.json");
1779+
assert_eq!("true", via_ir.unwrap().to_string());
1780+
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
1781+
assert_eq!("true", enabled.unwrap().to_string());
1782+
assert_eq!("44444444", runs.unwrap().to_string());
1783+
1784+
let (via_ir, evm_version, enabled, runs) = artifact_settings("v2/Counter.sol/Counter.json");
1785+
assert_eq!("true", via_ir.unwrap().to_string());
1786+
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
1787+
assert_eq!("true", enabled.unwrap().to_string());
1788+
assert_eq!("111", runs.unwrap().to_string());
1789+
1790+
let (via_ir, evm_version, enabled, runs) = artifact_settings("v3/Counter.sol/Counter.json");
1791+
assert_eq!(None, via_ir);
1792+
assert_eq!("\"istanbul\"", evm_version.unwrap().to_string());
1793+
assert_eq!("true", enabled.unwrap().to_string());
1794+
assert_eq!("800", runs.unwrap().to_string());
1795+
});

0 commit comments

Comments
 (0)