Skip to content

Commit

Permalink
feat(config): remove zksync home (#2022)
Browse files Browse the repository at this point in the history
## What ❔

<!-- What are the changes this PR brings about? -->
<!-- Example: This PR adds a PR template to the repo. -->
<!-- (For bigger PRs adding more context is appreciated) -->

## Why ❔

<!-- Why are these changes done? What goal do they contribute to? What
are the principles behind them? -->
<!-- Example: PR templates ensure PR reviewers, observers, and future
iterators are in context about the evolution of repos. -->

## Checklist

<!-- Check your PR fulfills the following items. -->
<!-- For draft PRs check the boxes as you complete them. -->

- [ ] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [ ] Tests for the changes have been added / updated.
- [ ] Documentation comments have been added / updated.
- [ ] Code has been formatted via `zk fmt` and `zk lint`.
- [ ] Spellcheck has been run via `zk spellcheck`.

---------

Signed-off-by: Danil <deniallugo@gmail.com>
Co-authored-by: Alex Ostrovski <aov@matterlabs.dev>
  • Loading branch information
Deniallugo and slowli authored May 22, 2024
1 parent fcbc089 commit d08fe81
Show file tree
Hide file tree
Showing 18 changed files with 198 additions and 145 deletions.
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

0 comments on commit d08fe81

Please sign in to comment.