Skip to content

Commit

Permalink
Merge branch 'dev' into foundry-update-4af6cfa
Browse files Browse the repository at this point in the history
  • Loading branch information
nbaztec committed Jun 27, 2024
2 parents 10d538e + f505a53 commit 1dace28
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 185 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,10 @@ src = 'src'
out = 'out'
libs = ['lib']
[profile.zksync]
src = 'src'
libs = ['lib']
[profile.default.zksync]
compile = true
fallback_oz = true
mode = "3"
mode = '3'
```

### Additional Configuration
Expand Down
2 changes: 2 additions & 0 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,7 @@ impl<DB: DatabaseExt + Send> Inspector<DB> for Cheatcodes {

let constructor_input =
call.init_code[contract.evm_bytecode.len()..].to_vec();

let create_input = foundry_zksync_core::encode_create_params(
&call.scheme,
contract.zk_bytecode_hash,
Expand Down Expand Up @@ -1882,6 +1883,7 @@ impl<DB: DatabaseExt + Send> Inspector<DB> for Cheatcodes {

let factory_deps = self.dual_compiled_contracts.fetch_all_factory_deps(zk_contract);
tracing::debug!(contract = zk_contract.name, "using dual compiled contract");

let ccx = foundry_zksync_core::vm::CheatcodeTracerContext {
mocked_calls: self.mocked_calls.clone(),
expected_calls: Some(&mut self.expected_calls),
Expand Down
8 changes: 6 additions & 2 deletions crates/cli/src/opts/build/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use foundry_compilers::{
Project,
};
use foundry_config::{
figment,
figment::{
self,
error::Kind::InvalidType,
value::{Dict, Map, Value},
Figment, Metadata, Profile, Provider,
Expand Down Expand Up @@ -175,7 +175,11 @@ impl<'a> From<&'a CoreBuildArgs> for Figment {
let mut remappings = Remappings::new_with_remappings(args.project_paths.get_remappings());
remappings
.extend(figment.extract_inner::<Vec<Remapping>>("remappings").unwrap_or_default());
figment = figment.merge(("remappings", remappings.into_inner())).merge(args);
// override only set values from the CLI for zksync
let zksync =
args.compiler.zk.apply_overrides(figment.extract_inner("zksync").unwrap_or_default());

figment = figment.merge(("remappings", remappings.into_inner())).merge(args).merge(("zksync", zksync));

if let Some(skip) = &args.skip {
let mut skip = skip.iter().map(|s| s.file_pattern().to_string()).collect::<Vec<_>>();
Expand Down
76 changes: 5 additions & 71 deletions crates/cli/src/opts/build/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::path::PathBuf;

use clap::Parser;
use foundry_compilers::artifacts::{output_selection::ContractOutputSelection, EvmVersion};
use serde::Serialize;
Expand All @@ -10,6 +8,9 @@ pub use self::core::CoreBuildArgs;
mod paths;
pub use self::paths::ProjectPathsArgs;

mod zksync;
pub use self::zksync::ZkSyncArgs;

// A set of solc compiler settings that can be set via command line arguments, which are intended
// to be merged into an existing `foundry_config::Config`.
//
Expand Down Expand Up @@ -53,76 +54,9 @@ pub struct CompilerArgs {
#[serde(skip_serializing_if = "Vec::is_empty")]
pub extra_output_files: Vec<ContractOutputSelection>,

// @zksync
/// Use ZKSync era vm.
#[clap(help_heading = "Use ZKSync era vm", long)]
pub zksync: bool,

#[clap(
help_heading = "zkSync Compiler options",
help = "Solc compiler path to use when compiling with zksolc",
long = "zk-solc-path",
value_name = "ZK_SOLC_PATH"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub zk_solc_path: Option<PathBuf>,

/// A flag indicating whether to enable the system contract compilation mode.
#[clap(
help_heading = "zkSync Compiler options",
help = "Enable the system contract compilation mode.",
long = "is-system",
value_name = "SYSTEM_MODE"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub is_system: Option<bool>,

/// A flag indicating whether to forcibly switch to the EVM legacy assembly pipeline.
#[clap(
help_heading = "zkSync Compiler options",
help = "Forcibly switch to the EVM legacy assembly pipeline.",
long = "force-evmla",
value_name = "FORCE_EVMLA"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub force_evmla: Option<bool>,

/// Try to recompile with -Oz if the bytecode is too large.
#[clap(
help_heading = "zkSync Compiler options",
long = "fallback-oz",
value_name = "FALLBACK_OZ"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub fallback_oz: Option<bool>,

/// Path to cache missing library dependencies, used for compiling and deploying libraries.
#[clap(help_heading = "zkSync Compiler options", long = "detect-missing-libraries")]
pub detect_missing_libraries: bool,

/// Set the LLVM optimization parameter `-O[0 | 1 | 2 | 3 | s | z]`.
/// Use `3` for best performance and `z` for minimal size.
#[clap(
help_heading = "zkSync Compiler options",
short = 'O',
long = "optimization",
value_name = "LEVEL"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<String>,

/// Enables optimizations
#[clap(help_heading = "zkSync Compiler options", long = "zk-optimizer")]
#[clap(flatten)]
#[serde(skip)]
pub zk_optimizer: bool,

/// Contracts to avoid compiling on zkSync
#[clap(
long,
help_heading = "Contracts to avoid during zkSync compilation",
value_delimiter = ','
)]
pub avoid_contracts: Option<Vec<String>>,
pub zk: ZkSyncArgs,
}

#[cfg(test)]
Expand Down
140 changes: 140 additions & 0 deletions crates/cli/src/opts/build/zksync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::path::PathBuf;

use clap::Parser;
use foundry_config::ZkSyncConfig;
use serde::Serialize;

#[derive(Clone, Debug, Default, Serialize, Parser)]
#[clap(next_help_heading = "ZKSync configuration")]
pub struct ZkSyncArgs {
/// Compile for zkVM
#[clap(
long = "zk-compile",
value_name = "COMPILE_FOR_ZKVM",
num_args = 0..=1,
require_equals = true,
default_missing_value = "true",
default_value_if("startup", "true", "true"))]
pub compile: Option<bool>,

/// Enable zkVM at startup
#[clap(
long = "zk-startup",
visible_alias = "zksync",
display_order = 0,
value_name = "ENABLE_ZKVM_AT_STARTUP",
num_args = 0..=1,
require_equals = true,
default_missing_value = "true",
)]
pub startup: Option<bool>,

#[clap(
help = "Solc compiler path to use when compiling with zksolc",
long = "zk-solc-path",
value_name = "ZK_SOLC_PATH"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub solc_path: Option<PathBuf>,

/// A flag indicating whether to enable the system contract compilation mode.
#[clap(
help = "Enable the system contract compilation mode.",
long = "zk-eravm-extensions",
visible_alias = "enable-eravm-extensions",
visible_alias = "system-mode",
value_name = "ENABLE_ERAVM_EXTENSIONS",
num_args = 0..=1,
require_equals = true,
default_missing_value = "true"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub eravm_extensions: Option<bool>,

/// A flag indicating whether to forcibly switch to the EVM legacy assembly pipeline.
#[clap(
help = "Forcibly switch to the EVM legacy assembly pipeline.",
long = "zk-force-evmla",
visible_alias = "force-evmla",
value_name = "FORCE_EVMLA",
num_args = 0..=1,
require_equals = true,
default_missing_value = "true"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub force_evmla: Option<bool>,

/// Try to recompile with -Oz if the bytecode is too large.
#[clap(
long = "zk-fallback-oz",
visible_alias = "fallback-oz",
value_name = "FALLBACK_OZ",
num_args = 0..=1,
require_equals = true,
default_missing_value = "true"
)]
pub fallback_oz: Option<bool>,

/// Detect missing libraries, instead of erroring
///
/// Currently unused
#[clap(long = "zk-detect-missing-libraries")]
pub detect_missing_libraries: bool,

/// Set the LLVM optimization parameter `-O[0 | 1 | 2 | 3 | s | z]`.
/// Use `3` for best performance and `z` for minimal size.
#[clap(
short = 'O',
long = "zk-optimizer-mode",
visible_alias = "zk-optimization",
value_name = "LEVEL"
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub optimizer_mode: Option<String>,

/// Enables optimizations
#[clap(long = "zk-optimizer")]
pub optimizer: bool,

/// Contracts to avoid compiling on zkSync
#[clap(long = "zk-avoid-contracts", visible_alias = "avoid-contracts", value_delimiter = ',')]
pub avoid_contracts: Option<Vec<String>>,
}

impl ZkSyncArgs {
/// Returns true if zksync mode is enabled
pub fn enabled(&self) -> bool {
self.compile.unwrap_or_default()
}

/// Merge the current cli arguments into the specified zksync configuration
pub(crate) fn apply_overrides(&self, mut zksync: ZkSyncConfig) -> ZkSyncConfig {
macro_rules! set_if_some {
($src:expr, $dst:expr) => {
if let Some(src) = $src {
$dst = src.into();
}
};
}

set_if_some!(self.compile, zksync.compile);
set_if_some!(self.startup, zksync.startup);
set_if_some!(self.solc_path.clone(), zksync.solc_path);
set_if_some!(self.eravm_extensions, zksync.eravm_extensions);
set_if_some!(self.force_evmla, zksync.force_evmla);
set_if_some!(self.fallback_oz, zksync.fallback_oz);
set_if_some!(
self.detect_missing_libraries.then_some(true),
zksync.detect_missing_libraries
);
set_if_some!(self.avoid_contracts.clone(), zksync.avoid_contracts);

set_if_some!(self.optimizer.then_some(true), zksync.optimizer);
set_if_some!(
self.optimizer_mode.as_ref().and_then(|mode| mode.parse::<char>().ok()),
zksync.optimizer_mode
);

zksync
}
}
34 changes: 34 additions & 0 deletions crates/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,40 @@ tab_width = 2
bracket_spacing = true
```

#### ZkSync settings

ZkSync configuration can be tweaked with the [`ZkSyncConfig`](./src/zksync.rs) object.
The `zksync` settings must be prefixed with the profile they correspond to:
`[profile.default.zksync]` belongs to the `[profile.default]` profile

``` toml
[profile.default.zksync]
# Compile contracts for zkVM
compile = false
# Enable zkVM at startup, needs `compile = true` to have effect
startup = true
# By default the latest version is used
zksolc = "1.5.0"
# By default the corresponding solc patched version from matter-labs is used
solc_path = "./solc-0.8.23-1.0.1"
bytecode_hash = "none"
# Allow compiler to use mode 'z' if contracts won't fit in the EraVM bytecode
# size limitations
fallback_oz = false
# Enable EraVM extensions (ex system-mode)
eravm_extensions = false
# Force compilation via EVMLA instead of Yul codegen pipeline
force_evmla = false
# List of globs that match contracts to avoid compiling with zksolc
avoid_contracts = []
# Enable optimizer on zksolc (defaults to true)
optimizer = true
# zksolc optimizer mode (0 | 1 | 2 | 3 | s | z)
optimizer_mode = '3'
# zksolc optimizer details
optimizer_details = { ... }
```

#### Additional Optimizer settings

Optimizer components can be tweaked with the `OptimizerDetails` object:
Expand Down
Loading

0 comments on commit 1dace28

Please sign in to comment.