Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): remove zksync home #2022

Merged
merged 15 commits into from
May 22, 2024
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions core/bin/contract-verifier/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{cell::RefCell, time::Duration};
use anyhow::Context as _;
use futures::{channel::mpsc, executor::block_on, SinkExt, StreamExt};
use prometheus_exporter::PrometheusExporterConfig;
use structopt::StructOpt;
use tokio::sync::watch;
use zksync_config::{
configs::{ObservabilityConfig, PrometheusConfig},
Expand All @@ -11,7 +12,7 @@ use zksync_config::{
use zksync_dal::{ConnectionPool, Core, CoreDal};
use zksync_env_config::FromEnv;
use zksync_queued_job_processor::JobProcessor;
use zksync_utils::wait_for_tasks::ManagedTasks;
use zksync_utils::{wait_for_tasks::ManagedTasks, workspace_dir_or_current_dir};

use crate::verifier::ContractVerifier;

Expand All @@ -25,9 +26,9 @@ async fn update_compiler_versions(connection_pool: &ConnectionPool<Core>) {
let mut storage = connection_pool.connection().await.unwrap();
let mut transaction = storage.start_transaction().await.unwrap();

let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let zksync_home = workspace_dir_or_current_dir();

let zksolc_path = format!("{}/etc/zksolc-bin/", zksync_home);
let zksolc_path = zksync_home.join("etc/zksolc-bin/");
let zksolc_versions: Vec<String> = std::fs::read_dir(zksolc_path)
.unwrap()
.filter_map(|file| {
Expand All @@ -48,7 +49,7 @@ async fn update_compiler_versions(connection_pool: &ConnectionPool<Core>) {
.await
.unwrap();

let solc_path = format!("{}/etc/solc-bin/", zksync_home);
let solc_path = zksync_home.join("etc/solc-bin/");
let solc_versions: Vec<String> = std::fs::read_dir(solc_path)
.unwrap()
.filter_map(|file| {
Expand All @@ -69,7 +70,7 @@ async fn update_compiler_versions(connection_pool: &ConnectionPool<Core>) {
.await
.unwrap();

let zkvyper_path = format!("{}/etc/zkvyper-bin/", zksync_home);
let zkvyper_path = zksync_home.join("etc/zkvyper-bin/");
let zkvyper_versions: Vec<String> = std::fs::read_dir(zkvyper_path)
.unwrap()
.filter_map(|file| {
Expand All @@ -90,7 +91,7 @@ async fn update_compiler_versions(connection_pool: &ConnectionPool<Core>) {
.await
.unwrap();

let vyper_path = format!("{}/etc/vyper-bin/", zksync_home);
let vyper_path = zksync_home.join("etc/vyper-bin/");
let vyper_versions: Vec<String> = std::fs::read_dir(vyper_path)
.unwrap()
.filter_map(|file| {
Expand All @@ -115,7 +116,6 @@ async fn update_compiler_versions(connection_pool: &ConnectionPool<Core>) {
transaction.commit().await.unwrap();
}

use structopt::StructOpt;
use zksync_config::configs::DatabaseSecrets;

#[derive(StructOpt)]
Expand Down
16 changes: 9 additions & 7 deletions core/bin/contract-verifier/src/verifier.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::{
collections::HashMap,
env,
path::Path,
time::{Duration, Instant},
};
Expand All @@ -22,6 +21,7 @@ use zksync_types::{
},
Address,
};
use zksync_utils::workspace_dir_or_current_dir;

use crate::{
error::ContractVerifierError,
Expand All @@ -34,6 +34,10 @@ lazy_static! {
static ref DEPLOYER_CONTRACT: Contract = zksync_contracts::deployer_contract();
}

fn home_path() -> &'static Path {
workspace_dir_or_current_dir()
}

#[derive(Debug)]
enum ConstructorArgs {
Check(Vec<u8>),
Expand Down Expand Up @@ -120,8 +124,7 @@ impl ContractVerifier {
};
let input = Self::build_zksolc_input(request.clone(), file_name.clone())?;

let zksync_home = env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let zksolc_path = Path::new(&zksync_home)
let zksolc_path = Path::new(&home_path())
.join("etc")
.join("zksolc-bin")
.join(request.req.compiler_versions.zk_compiler_version())
Expand All @@ -133,7 +136,7 @@ impl ContractVerifier {
));
}

let solc_path = Path::new(&zksync_home)
let solc_path = Path::new(&home_path())
.join("etc")
.join("solc-bin")
.join(request.req.compiler_versions.compiler_version())
Expand Down Expand Up @@ -219,8 +222,7 @@ impl ContractVerifier {
};
let input = Self::build_zkvyper_input(request.clone())?;

let zksync_home = env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let zkvyper_path = Path::new(&zksync_home)
let zkvyper_path = Path::new(&home_path())
.join("etc")
.join("zkvyper-bin")
.join(request.req.compiler_versions.zk_compiler_version())
Expand All @@ -232,7 +234,7 @@ impl ContractVerifier {
));
}

let vyper_path = Path::new(&zksync_home)
let vyper_path = Path::new(&home_path())
.join("etc")
.join("vyper-bin")
.join(request.req.compiler_versions.compiler_version())
Expand Down
5 changes: 3 additions & 2 deletions core/bin/system-constants-generator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use zksync_types::{
IntrinsicSystemGasConstants, ProtocolVersionId, GUARANTEED_PUBDATA_IN_TX,
L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
};
use zksync_utils::workspace_dir_or_current_dir;

// For configs we will use the default value of `800_000` to represent the rough amount of L1 gas
// needed to cover the batch expenses.
Expand Down Expand Up @@ -209,8 +210,8 @@ fn generate_rust_fee_constants(intrinsic_gas_constants: &IntrinsicSystemGasConst
}

fn save_file(path_in_repo: &str, content: String) {
let zksync_home = std::env::var("ZKSYNC_HOME").expect("No ZKSYNC_HOME env var");
let fee_constants_path = format!("{zksync_home}/{path_in_repo}");
let zksync_home = workspace_dir_or_current_dir();
let fee_constants_path = zksync_home.join(path_in_repo);

fs::write(fee_constants_path, content)
.unwrap_or_else(|_| panic!("Failed to write to {}", path_in_repo));
Expand Down
45 changes: 22 additions & 23 deletions core/lib/contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Set of utility functions to read contracts both in Yul and Sol format.
//!
//! Careful: some of the methods are reading the contracts based on the ZKSYNC_HOME environment variable.
//! Careful: some of the methods are reading the contracts based on the workspace environment variable.

#![allow(clippy::derive_partial_eq_without_eq)]

Expand All @@ -15,7 +15,7 @@ use ethabi::{
};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words};
use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, workspace_dir_or_current_dir};

pub mod test_contracts;

Expand Down Expand Up @@ -48,8 +48,12 @@ const LOADNEXT_CONTRACT_FILE: &str =
const LOADNEXT_SIMPLE_CONTRACT_FILE: &str =
"etc/contracts-test-data/artifacts-zk/contracts/loadnext/loadnext_contract.sol/Foo.json";

fn read_file_to_json_value(path: impl AsRef<Path>) -> serde_json::Value {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
fn home_path() -> &'static Path {
workspace_dir_or_current_dir()
}

fn read_file_to_json_value(path: impl AsRef<Path> + std::fmt::Debug) -> serde_json::Value {
let zksync_home = home_path();
let path = Path::new(&zksync_home).join(path);
serde_json::from_reader(
File::open(&path).unwrap_or_else(|e| panic!("Failed to open file {:?}: {}", path, e)),
Expand All @@ -58,7 +62,7 @@ fn read_file_to_json_value(path: impl AsRef<Path>) -> serde_json::Value {
}

fn load_contract_if_present<P: AsRef<Path> + std::fmt::Debug>(path: P) -> Option<Contract> {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let zksync_home = home_path();
let path = Path::new(&zksync_home).join(path);
path.exists().then(|| {
serde_json::from_value(read_file_to_json_value(&path)["abi"].take())
Expand All @@ -79,7 +83,7 @@ pub fn load_sys_contract(contract_name: &str) -> Contract {
))
}

pub fn read_contract_abi(path: impl AsRef<Path>) -> String {
pub fn read_contract_abi(path: impl AsRef<Path> + std::fmt::Debug) -> String {
read_file_to_json_value(path)["abi"]
.as_str()
.expect("Failed to parse abi")
Expand Down Expand Up @@ -149,6 +153,11 @@ pub fn l1_messenger_contract() -> Contract {
load_sys_contract("L1Messenger")
}

/// Reads bytecode from the path RELATIVE to the Cargo workspace location.
pub fn read_bytecode(relative_path: impl AsRef<Path> + std::fmt::Debug) -> Vec<u8> {
read_bytecode_from_path(relative_path)
}

pub fn eth_contract() -> Contract {
load_sys_contract("L2BaseToken")
}
Expand All @@ -157,16 +166,9 @@ pub fn known_codes_contract() -> Contract {
load_sys_contract("KnownCodesStorage")
}

/// Reads bytecode from the path RELATIVE to the ZKSYNC_HOME environment variable.
pub fn read_bytecode(relative_path: impl AsRef<Path>) -> Vec<u8> {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let artifact_path = Path::new(&zksync_home).join(relative_path);
read_bytecode_from_path(artifact_path)
}

/// Reads bytecode from a given path.
fn read_bytecode_from_path(artifact_path: PathBuf) -> Vec<u8> {
let artifact = read_file_to_json_value(artifact_path.clone());
fn read_bytecode_from_path(artifact_path: impl AsRef<Path> + std::fmt::Debug) -> Vec<u8> {
let artifact = read_file_to_json_value(&artifact_path);

let bytecode = artifact["bytecode"]
.as_str()
Expand All @@ -187,19 +189,17 @@ static DEFAULT_SYSTEM_CONTRACTS_REPO: Lazy<SystemContractsRepo> =

/// Structure representing a system contract repository - that allows
/// fetching contracts that are located there.
/// As most of the static methods in this file, is loading data based on ZKSYNC_HOME environment variable.
/// As most of the static methods in this file, is loading data based on the Cargo workspace location.
pub struct SystemContractsRepo {
// Path to the root of the system contracts repository.
pub root: PathBuf,
}

impl SystemContractsRepo {
/// Returns the default system contracts repository with directory based on the ZKSYNC_HOME environment variable.
/// Returns the default system contracts repository with directory based on the Cargo workspace location.
pub fn from_env() -> Self {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let zksync_home = PathBuf::from(zksync_home);
SystemContractsRepo {
root: zksync_home.join("contracts/system-contracts"),
root: home_path().join("contracts/system-contracts"),
}
}

Expand Down Expand Up @@ -237,10 +237,9 @@ fn read_playground_batch_bootloader_bytecode() -> Vec<u8> {
read_bootloader_code("playground_batch")
}

/// Reads zbin bytecode from a given path, relative to ZKSYNC_HOME.
/// Reads zbin bytecode from a given path, relative to workspace location.
pub fn read_zbin_bytecode(relative_zbin_path: impl AsRef<Path>) -> Vec<u8> {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
let bytecode_path = Path::new(&zksync_home).join(relative_zbin_path);
let bytecode_path = Path::new(&home_path()).join(relative_zbin_path);
read_zbin_bytecode_from_path(bytecode_path)
}

Expand Down
2 changes: 1 addition & 1 deletion core/lib/types/src/system_contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ static SYSTEM_CONTRACTS: Lazy<Vec<DeployedContract>> = Lazy::new(|| {
.collect::<Vec<_>>()
});

/// Gets default set of system contracts, based on ZKSYNC_HOME environment variable.
/// Gets default set of system contracts, based on Cargo workspace location.
pub fn get_system_smart_contracts() -> Vec<DeployedContract> {
SYSTEM_CONTRACTS.clone()
}
Expand Down
3 changes: 2 additions & 1 deletion core/lib/utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ futures.workspace = true
hex.workspace = true
reqwest = { workspace = true, features = ["blocking"] }
itertools.workspace = true
serde_json.workspace = true
once_cell.workspace = true

[dev-dependencies]
serde_json.workspace = true
rand.workspace = true
tokio = { workspace = true, features = ["macros", "rt"] }
bincode.workspace = true
68 changes: 68 additions & 0 deletions core/lib/utils/src/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::{
path::{Path, PathBuf},
str,
};

use anyhow::Context as _;
use once_cell::sync::OnceCell;

static WORKSPACE: OnceCell<Option<PathBuf>> = OnceCell::new();

fn locate_workspace_inner() -> anyhow::Result<PathBuf> {
let output = std::process::Command::new(
std::env::var("CARGO")
.ok()
.unwrap_or_else(|| "cargo".to_string()),
)
.arg("locate-project")
.arg("--workspace")
.output()
.context("Can't find Cargo workspace location")?;

let output =
serde_json::from_slice::<serde_json::Value>(&output.stdout).with_context(|| {
format!(
"Error parsing `cargo locate-project` output {}",
str::from_utf8(&output.stdout).unwrap_or("(non-utf8 output)")
)
})?;
let root = output.get("root").with_context(|| {
format!("root doesn't exist in output from `cargo locate-project` {output:?}")
})?;

let serde_json::Value::String(root) = root else {
return Err(anyhow::anyhow!("`root` is not a string: {root:?}"));
};
let root_path = PathBuf::from(root);
Ok(root_path
.parent()
.with_context(|| format!("`root` path doesn't have a parent: {}", root_path.display()))?
.to_path_buf())
}

/// Find the location of the current workspace, if this code works in workspace
/// then it will return the correct folder if, it's binary e.g. in docker container
/// you have to use fallback to another directory
/// The code has been inspired by `insta`
/// `https://github.com/mitsuhiko/insta/blob/master/insta/src/env.rs`
pub fn locate_workspace() -> Option<&'static Path> {
// Since `locate_workspace_inner()` should be deterministic, it makes little sense to call
// `OnceCell::get_or_try_init()` here; the repeated calls are just as unlikely to succeed as the initial call.
// Instead, we store `None` in the `OnceCell` if initialization failed.
WORKSPACE
.get_or_init(|| {
let result = locate_workspace_inner();
if let Err(err) = &result {
// `get_or_init()` is guaranteed to call the provided closure once per `OnceCell`;
// i.e., we won't spam logs here.
tracing::warn!("locate_workspace() failed: {err:?}");
}
result.ok()
})
.as_deref()
}

/// Returns [`locate_workspace()`] output with the "." fallback.
pub fn workspace_dir_or_current_dir() -> &'static Path {
locate_workspace().unwrap_or_else(|| Path::new("."))
}
5 changes: 2 additions & 3 deletions core/lib/utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

pub mod bytecode;
mod convert;
mod env;
pub mod http_with_retries;
pub mod misc;
pub mod panic_extractor;
mod serde_wrappers;
pub mod time;
pub mod wait_for_tasks;

pub use convert::*;
pub use misc::*;
pub use serde_wrappers::*;
pub use self::{convert::*, env::*, misc::*, serde_wrappers::*};
Loading
Loading