Skip to content

Commit

Permalink
refactor(contract-verifier): Brush up contract verifier (#3189)
Browse files Browse the repository at this point in the history
## What ❔

Brushes up contract verifier code.

## Why ❔

Would make it easier to support EVM emulation in the contract verifier.

## Checklist

- [x] PR title corresponds to the body of PR (we generate changelog
entries from PRs).
- [x] Tests for the changes have been added / updated.
- [x] Documentation comments have been added / updated.
- [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev
lint`.
  • Loading branch information
slowli authored Nov 4, 2024
1 parent 9dae839 commit 719455c
Show file tree
Hide file tree
Showing 29 changed files with 1,344 additions and 576 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci-core-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
echo "SCCACHE_GCS_SERVICE_ACCOUNT=gha-ci-runners@matterlabs-infra.iam.gserviceaccount.com" >> .env
echo "SCCACHE_GCS_RW_MODE=READ_WRITE" >> .env
echo "RUSTC_WRAPPER=sccache" >> .env
echo RUN_CONTRACT_VERIFICATION_TEST=true >> .env
# TODO: Remove when we after upgrade of hardhat-plugins
- name: pre-download compilers
Expand Down Expand Up @@ -73,6 +74,9 @@ jobs:
- name: Contracts unit tests
run: ci_run yarn l1-contracts test

- name: Download compilers for contract verifier tests
run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.3 --zkvyper-version=v1.5.4 --solc-version=0.8.26 --vyper-version=v0.3.10 --era-vm-solc-version=0.8.26-1.0.1 --only --chain era

- name: Rust unit tests
run: |
ci_run zkstack dev test rust
Expand Down
9 changes: 4 additions & 5 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ hyper = "1.3"
insta = "1.29.0"
itertools = "0.10"
jsonrpsee = { version = "0.23", default-features = false }
lazy_static = "1.4"
leb128 = "0.2.5"
lru = { version = "0.12.1", default-features = false }
mini-moka = "0.10.0"
Expand Down
104 changes: 5 additions & 99 deletions core/bin/contract-verifier/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,105 +7,11 @@ use tokio::sync::watch;
use zksync_config::configs::PrometheusConfig;
use zksync_contract_verifier_lib::ContractVerifier;
use zksync_core_leftovers::temp_config_store::{load_database_secrets, load_general_config};
use zksync_dal::{ConnectionPool, Core, CoreDal};
use zksync_dal::{ConnectionPool, Core};
use zksync_queued_job_processor::JobProcessor;
use zksync_utils::{env::Workspace, wait_for_tasks::ManagedTasks};
use zksync_utils::wait_for_tasks::ManagedTasks;
use zksync_vlog::prometheus::PrometheusExporterConfig;

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 = Workspace::locate().core();

let zksolc_path = zksync_home.join("etc/zksolc-bin/");
let zksolc_versions: Vec<String> = std::fs::read_dir(zksolc_path)
.unwrap()
.filter_map(|file| {
let file = file.unwrap();
let Ok(file_type) = file.file_type() else {
return None;
};
if file_type.is_dir() {
file.file_name().into_string().ok()
} else {
None
}
})
.collect();
transaction
.contract_verification_dal()
.set_zksolc_versions(zksolc_versions)
.await
.unwrap();

let solc_path = zksync_home.join("etc/solc-bin/");
let solc_versions: Vec<String> = std::fs::read_dir(solc_path)
.unwrap()
.filter_map(|file| {
let file = file.unwrap();
let Ok(file_type) = file.file_type() else {
return None;
};
if file_type.is_dir() {
file.file_name().into_string().ok()
} else {
None
}
})
.collect();
transaction
.contract_verification_dal()
.set_solc_versions(solc_versions)
.await
.unwrap();

let zkvyper_path = zksync_home.join("etc/zkvyper-bin/");
let zkvyper_versions: Vec<String> = std::fs::read_dir(zkvyper_path)
.unwrap()
.filter_map(|file| {
let file = file.unwrap();
let Ok(file_type) = file.file_type() else {
return None;
};
if file_type.is_dir() {
file.file_name().into_string().ok()
} else {
None
}
})
.collect();
transaction
.contract_verification_dal()
.set_zkvyper_versions(zkvyper_versions)
.await
.unwrap();

let vyper_path = zksync_home.join("etc/vyper-bin/");
let vyper_versions: Vec<String> = std::fs::read_dir(vyper_path)
.unwrap()
.filter_map(|file| {
let file = file.unwrap();
let Ok(file_type) = file.file_type() else {
return None;
};
if file_type.is_dir() {
file.file_name().into_string().ok()
} else {
None
}
})
.collect();

transaction
.contract_verification_dal()
.set_vyper_versions(vyper_versions)
.await
.unwrap();

transaction.commit().await.unwrap();
}

#[derive(StructOpt)]
#[structopt(name = "ZKsync contract code verifier", author = "Matter Labs")]
struct Opt {
Expand Down Expand Up @@ -160,9 +66,9 @@ async fn main() -> anyhow::Result<()> {
.expect("Error setting Ctrl+C handler");
}

update_compiler_versions(&pool).await;

let contract_verifier = ContractVerifier::new(verifier_config, pool);
let contract_verifier = ContractVerifier::new(verifier_config.compilation_timeout(), pool)
.await
.context("failed initializing contract verifier")?;
let tasks = vec![
// TODO PLA-335: Leftovers after the prover DB split.
// The prover connection pool is not used by the contract verifier, but we need to pass it
Expand Down
7 changes: 0 additions & 7 deletions core/lib/config/src/configs/contract_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,16 @@ use serde::Deserialize;
pub struct ContractVerifierConfig {
/// Max time of a single compilation (in s).
pub compilation_timeout: u64,
/// Interval between polling db for verification requests (in ms).
pub polling_interval: Option<u64>,
/// Port to which the Prometheus exporter server is listening.
pub prometheus_port: u16,
pub threads_per_server: Option<u16>,
pub port: u16,
pub url: String,
}

impl ContractVerifierConfig {
pub fn compilation_timeout(&self) -> Duration {
Duration::from_secs(self.compilation_timeout)
}

pub fn polling_interval(&self) -> Duration {
Duration::from_millis(self.polling_interval.unwrap_or(1000))
}
pub fn bind_addr(&self) -> SocketAddr {
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), self.port)
}
Expand Down
3 changes: 0 additions & 3 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,8 @@ impl Distribution<configs::ContractVerifierConfig> for EncodeDist {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> configs::ContractVerifierConfig {
configs::ContractVerifierConfig {
compilation_timeout: self.sample(rng),
polling_interval: self.sample(rng),
prometheus_port: self.sample(rng),
threads_per_server: self.sample(rng),
port: self.sample(rng),
url: self.sample(rng),
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions core/lib/contract_verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ categories.workspace = true
[dependencies]
zksync_types.workspace = true
zksync_dal.workspace = true
zksync_config.workspace = true
zksync_contracts.workspace = true
zksync_queued_job_processor.workspace = true
zksync_utils.workspace = true
Expand All @@ -27,8 +26,11 @@ ethabi.workspace = true
vise.workspace = true
hex.workspace = true
serde = { workspace = true, features = ["derive"] }
lazy_static.workspace = true
tempfile.workspace = true
regex.workspace = true
tracing.workspace = true
semver.workspace = true

[dev-dependencies]
zksync_node_test_utils.workspace = true
zksync_vm_interface.workspace = true
12 changes: 10 additions & 2 deletions core/lib/contract_verifier/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#[derive(Debug, Clone, thiserror::Error)]
use zksync_dal::DalError;

#[derive(Debug, thiserror::Error)]
pub enum ContractVerifierError {
#[error("Internal error")]
InternalError,
Internal(#[from] anyhow::Error),
#[error("Deployed bytecode is not equal to generated one from given source")]
BytecodeMismatch,
#[error("Constructor arguments are not correct")]
Expand All @@ -23,3 +25,9 @@ pub enum ContractVerifierError {
#[error("Failed to deserialize standard JSON input")]
FailedToDeserializeInput,
}

impl From<DalError> for ContractVerifierError {
fn from(err: DalError) -> Self {
Self::Internal(err.generalize())
}
}
Loading

0 comments on commit 719455c

Please sign in to comment.