Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
juan518munoz committed Feb 4, 2025
1 parent 2116030 commit 45cc9ea
Show file tree
Hide file tree
Showing 106 changed files with 4,629 additions and 2,353 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-core-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
ci_run zkstack dev contracts
- 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
run: ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --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: |
Expand Down Expand Up @@ -431,7 +431,7 @@ jobs:
- name: Initialize Contract verifier
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
ci_run zkstack contract-verifier init --zksolc-version=v1.5.10 --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
ci_run zkstack contract-verifier run --chain era &> ${{ env.SERVER_LOGS_DIR }}/contract-verifier-rollup.log &
ci_run zkstack contract-verifier wait --chain era --verbose
Expand Down
2 changes: 1 addition & 1 deletion contracts
Submodule contracts updated 33 files
+36 −32 .github/workflows/l1-contracts-ci.yaml
+4 −140 AllContractsHashes.json
+ audits/ZKsync Gateway Audit (Audittens).pdf
+0 −4 da-contracts/contracts/da-layers/eigenda/EigenDAL1Validator.sol
+1 −1 docs/README.md
+33 −0 docs/bridging/asset_router/overview.md
+1 −1 docs/chain_management/upgrade_process.md
+1 −1 docs/l2_system_contracts/system_contracts_bootloader_description.md
+1 −1 docs/upgrade_history/gateway_upgrade/gateway_diff_review.md
+12 −43 docs/upgrade_history/gateway_upgrade/upgrade_process (no gateway chain).md
+0 −1 l1-contracts/deploy-scripts/DeployUtils.s.sol
+26 −0 l1-contracts/deploy-scripts/SecurityCouncilApproveStageUpgrade.s.sol
+26 −0 l1-contracts/deploy-scripts/SecurityCouncilEmergencyStageUpgrade.s.sol
+149 −61 l1-contracts/deploy-scripts/Utils.sol
+26 −0 l1-contracts/deploy-scripts/interfaces/ISecurityCouncil.sol
+4 −6 l1-contracts/deploy-scripts/upgrade/EcosystemUpgrade.s.sol
+161 −18 l1-contracts/deploy-scripts/upgrade/FinalizeUpgrade.s.sol
+23 −0 l1-contracts/deploy-scripts/upgrade/MulticallWithGas.sol
+14 −0 l1-contracts/deploy-scripts/upgrade/README.md
+67 −0 l1-contracts/upgrade-envs/outputs/stage-proofs/gateway-upgrade-ecosystem.toml
+97 −0 l1-contracts/upgrade-envs/outputs/stage-proofs/gateway_ecosystem_upgrade_output.yaml
+1,556 −0 l1-contracts/upgrade-envs/outputs/stage-proofs/run-latest.json
+31 −0 l1-contracts/upgrade-envs/outputs/stage-proofs/verification-logs
+35 −31 l1-contracts/upgrade-envs/outputs/stage/gateway-upgrade-ecosystem.toml
+88 −85 l1-contracts/upgrade-envs/outputs/stage/gateway_ecosystem_upgrade_output.yaml
+1,553 −1,525 l1-contracts/upgrade-envs/outputs/stage/run-latest.json
+31 −31 l1-contracts/upgrade-envs/outputs/stage/verification-logs
+2 −0 l1-contracts/upgrade-envs/stage-proofs-era.toml
+28 −0 l1-contracts/upgrade-envs/stage-proofs.toml
+5 −5 l1-contracts/upgrade-envs/stage.toml
+168 −66 scripts/calculate-hashes.ts
+0 −20 system-contracts/contracts/L2GatewayUpgrade.sol
+4 −3 system-contracts/test/DefaultAccount.spec.ts
14 changes: 8 additions & 6 deletions core/Cargo.lock

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

7 changes: 4 additions & 3 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ serde = "1"
serde_json = "1"
serde_with = "1"
serde_yaml = "0.9"
ciborium = "0.2"
sha2 = "0.10.8"
sha3 = "0.10.8"
sqlx = "0.8.1"
Expand Down Expand Up @@ -235,7 +236,7 @@ serial_test = { version = "3.1.1", features = ["file_locks"] }
circuit_encodings = "=0.150.20"
circuit_sequencer_api = "=0.150.20"
circuit_definitions = "=0.150.20"
crypto_codegen = { package = "zksync_solidity_vk_codegen",version = "=0.30.13" }
crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.13" }
kzg = { package = "zksync_kzg", version = "=0.150.20" }
zk_evm = { version = "=0.133.0" }
zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" }
Expand All @@ -244,10 +245,10 @@ zk_evm_1_4_0 = { package = "zk_evm", version = "0.140" }
zk_evm_1_4_1 = { package = "zk_evm", version = "0.141" }
zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.20" }
fflonk = "=0.30.13"
bellman = {package = "zksync_bellman", version = "=0.30.13"}
bellman = { package = "zksync_bellman", version = "=0.30.13" }

# New VM; pinned to a specific commit because of instability
zksync_vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "457d8a7eea9093af9440662e33e598c13ba41633" }
zksync_vm2 = { git = "https://github.com/matter-labs/vm2.git", rev = "3841f5a430288a63c8207853eca11560bf7a5712" }

# Consensus dependencies.
zksync_concurrency = "=0.8.0"
Expand Down
30 changes: 29 additions & 1 deletion core/bin/contract-verifier/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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};
use zksync_dal::{ConnectionPool, Core, CoreDal};
use zksync_queued_job_processor::JobProcessor;
use zksync_utils::wait_for_tasks::ManagedTasks;
use zksync_vlog::prometheus::PrometheusExporterConfig;
Expand All @@ -25,6 +25,32 @@ struct Opt {
secrets_path: Option<PathBuf>,
}

async fn perform_storage_migration(pool: &ConnectionPool<Core>) -> anyhow::Result<()> {
const BATCH_SIZE: usize = 1000;

// Make it possible to override just in case.
let batch_size = std::env::var("CONTRACT_VERIFIER_MIGRATION_BATCH_SIZE")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(BATCH_SIZE);

let mut storage = pool.connection().await?;
let migration_performed = storage
.contract_verification_dal()
.is_verification_info_migration_performed()
.await?;
if !migration_performed {
tracing::info!(batch_size = %batch_size, "Running the storage migration for the contract verifier table");
storage
.contract_verification_dal()
.perform_verification_info_migration(batch_size)
.await?;
} else {
tracing::info!("Storage migration is not needed");
}
Ok(())
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let opt = Opt::parse();
Expand All @@ -51,6 +77,8 @@ async fn main() -> anyhow::Result<()> {
.build()
.await?;

perform_storage_migration(&pool).await?;

let (stop_sender, stop_receiver) = watch::channel(false);
let contract_verifier = ContractVerifier::new(verifier_config.compilation_timeout(), pool)
.await
Expand Down
2 changes: 1 addition & 1 deletion core/bin/verified_sources_fetcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::Write;
use zksync_config::configs::DatabaseSecrets;
use zksync_dal::{ConnectionPool, Core, CoreDal};
use zksync_env_config::FromEnv;
use zksync_types::contract_verification_api::SourceCodeData;
use zksync_types::contract_verification::api::SourceCodeData;

#[tokio::main]
async fn main() {
Expand Down
8 changes: 8 additions & 0 deletions core/lib/basic_types/src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ impl BytecodeMarker {
}
}

/// Removes padding from the bytecode, if necessary.
pub fn trim_bytecode(bytecode_hash: BytecodeHash, raw: &[u8]) -> anyhow::Result<&[u8]> {
match bytecode_hash.marker() {
BytecodeMarker::EraVm => Ok(raw),
BytecodeMarker::Evm => trim_padded_evm_bytecode(bytecode_hash, raw),
}
}

/// Removes padding from an EVM bytecode, returning the original EVM bytecode.
pub fn trim_padded_evm_bytecode(bytecode_hash: BytecodeHash, raw: &[u8]) -> anyhow::Result<&[u8]> {
if bytecode_hash.marker() != BytecodeMarker::Evm {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/contract_verifier/src/compilers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;

use anyhow::Context as _;
use serde::{Deserialize, Serialize};
use zksync_types::contract_verification_api::CompilationArtifacts;
use zksync_types::contract_verification::api::CompilationArtifacts;

pub(crate) use self::{
solc::{Solc, SolcInput},
Expand Down
2 changes: 1 addition & 1 deletion core/lib/contract_verifier/src/compilers/solc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, path::PathBuf, process::Stdio};
use anyhow::Context;
use tokio::io::AsyncWriteExt;
use zksync_queued_job_processor::async_trait;
use zksync_types::contract_verification_api::{
use zksync_types::contract_verification::api::{
CompilationArtifacts, SourceCodeData, VerificationIncomingRequest,
};

Expand Down
2 changes: 1 addition & 1 deletion core/lib/contract_verifier/src/compilers/vyper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, mem, path::PathBuf, process::Stdio};
use anyhow::Context;
use tokio::io::AsyncWriteExt;
use zksync_queued_job_processor::async_trait;
use zksync_types::contract_verification_api::{
use zksync_types::contract_verification::api::{
CompilationArtifacts, SourceCodeData, VerificationIncomingRequest,
};

Expand Down
26 changes: 21 additions & 5 deletions core/lib/contract_verifier/src/compilers/zksolc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use semver::Version;
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use zksync_queued_job_processor::async_trait;
use zksync_types::contract_verification_api::{
use zksync_types::contract_verification::api::{
CompilationArtifacts, SourceCodeData, VerificationIncomingRequest,
};

Expand Down Expand Up @@ -65,6 +65,7 @@ pub(crate) struct Optimizer {
/// Whether the optimizer is enabled.
pub enabled: bool,
/// The optimization mode string.
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<char>,
}

Expand Down Expand Up @@ -144,12 +145,24 @@ impl ZkSolc {
fn parse_single_file_yul_output(
output: &str,
) -> Result<CompilationArtifacts, ContractVerifierError> {
let re = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap();
let cap = re
.captures(output)
.context("Yul output doesn't match regex")?;
let cap = if output.contains("Binary:\n") {
// Format of the new output
// ======= /tmp/input.yul:Empty =======
// Binary:
// 00000001002 <..>
let re = Regex::new(r"Binary:\n([\da-f]+)").unwrap();
re.captures(output)
.with_context(|| format!("Yul output doesn't match regex. Output: {output}"))?
} else {
// Old compiler versions
let re_old = Regex::new(r"Contract `.*` bytecode: 0x([\da-f]+)").unwrap();
re_old
.captures(output)
.with_context(|| format!("Yul output doesn't match regex. Output: {output}"))?
};
let bytecode_str = cap.get(1).context("no matches in Yul output")?.as_str();
let bytecode = hex::decode(bytecode_str).context("invalid Yul output bytecode")?;

Ok(CompilationArtifacts {
bytecode,
deployed_bytecode: None,
Expand Down Expand Up @@ -255,6 +268,9 @@ impl Compiler<ZkSolcInput> for ZkSolc {
.context("cannot create temporary Yul file")?;
file.write_all(source_code.as_bytes())
.context("failed writing Yul file")?;

// TODO: `zksolc` support standard JSON for `yul` since 1.5.0, so we don't have
// to parse `--bin` output.
let child = command
.arg(file.path().to_str().unwrap())
.arg("--optimization")
Expand Down
2 changes: 1 addition & 1 deletion core/lib/contract_verifier/src/compilers/zkvyper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{ffi::OsString, path, path::Path, process::Stdio};
use anyhow::Context as _;
use tokio::{fs, io::AsyncWriteExt};
use zksync_queued_job_processor::async_trait;
use zksync_types::contract_verification_api::CompilationArtifacts;
use zksync_types::contract_verification::api::CompilationArtifacts;

use super::VyperInput;
use crate::{
Expand Down
64 changes: 47 additions & 17 deletions core/lib/contract_verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ use zksync_dal::{contract_verification_dal::DeployedContractData, ConnectionPool
use zksync_queued_job_processor::{async_trait, JobProcessor};
use zksync_types::{
bytecode::{trim_padded_evm_bytecode, BytecodeHash, BytecodeMarker},
contract_verification_api::{
self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo,
VerificationRequest,
contract_verification::{
api::{
self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo,
VerificationProblem, VerificationRequest,
},
contract_identifier::{ContractIdentifier, Match},
},
Address, CONTRACT_DEPLOYER_ADDRESS,
};
Expand Down Expand Up @@ -224,7 +227,7 @@ impl ContractVerifier {
async fn verify(
&self,
mut request: VerificationRequest,
) -> Result<VerificationInfo, ContractVerifierError> {
) -> Result<(VerificationInfo, ContractIdentifier), ContractVerifierError> {
// Bytecode should be present because it is checked when accepting request.
let mut storage = self
.connection_pool
Expand All @@ -245,6 +248,8 @@ impl ContractVerifier {
let bytecode_marker = BytecodeMarker::new(deployed_contract.bytecode_hash)
.context("unknown bytecode kind")?;
let artifacts = self.compile(request.req.clone(), bytecode_marker).await?;
let identifier =
ContractIdentifier::from_bytecode(bytecode_marker, artifacts.deployed_bytecode());
let constructor_args = match bytecode_marker {
BytecodeMarker::EraVm => self
.decode_era_vm_constructor_args(&deployed_contract, request.req.contract_address)?,
Expand All @@ -265,14 +270,28 @@ impl ContractVerifier {
.context("invalid stored EVM bytecode")?,
};

if artifacts.deployed_bytecode() != deployed_bytecode {
tracing::info!(
request_id = request.id,
deployed = hex::encode(deployed_bytecode),
compiled = hex::encode(artifacts.deployed_bytecode()),
"Deployed (runtime) bytecode mismatch",
);
return Err(ContractVerifierError::BytecodeMismatch);
let mut verification_problems = Vec::new();

match identifier.matches(deployed_bytecode) {
Match::Full => {}
Match::Partial => {
tracing::trace!(
request_id = request.id,
deployed = hex::encode(deployed_bytecode),
compiled = hex::encode(artifacts.deployed_bytecode()),
"Partial bytecode match",
);
verification_problems.push(VerificationProblem::IncorrectMetadata);
}
Match::None => {
tracing::trace!(
request_id = request.id,
deployed = hex::encode(deployed_bytecode),
compiled = hex::encode(artifacts.deployed_bytecode()),
"Deployed (runtime) bytecode mismatch",
);
return Err(ContractVerifierError::BytecodeMismatch);
}
}

match constructor_args {
Expand All @@ -284,6 +303,11 @@ impl ContractVerifier {
hex::encode(&args),
hex::encode(provided_constructor_args)
);
// We could, in theory, accept this contract and mark it as partially verified,
// but in during verification it is always possible to reconstruct the
// constructor arguments, so there is no reason for that.
// Mismatching constructor arguments are only needed for "similar bytecodes"
// (e.g. displayed contract as verified without a direct verification request).
return Err(ContractVerifierError::IncorrectConstructorArguments);
}
}
Expand All @@ -294,11 +318,13 @@ impl ContractVerifier {

let verified_at = Utc::now();
tracing::trace!(%verified_at, "verified request");
Ok(VerificationInfo {
let info = VerificationInfo {
request,
artifacts,
verified_at,
})
verification_problems,
};
Ok((info, identifier))
}

async fn compile_zksolc(
Expand Down Expand Up @@ -544,17 +570,21 @@ impl ContractVerifier {
async fn process_result(
&self,
request_id: usize,
verification_result: Result<VerificationInfo, ContractVerifierError>,
verification_result: Result<(VerificationInfo, ContractIdentifier), ContractVerifierError>,
) -> anyhow::Result<()> {
let mut storage = self
.connection_pool
.connection_tagged("contract_verifier")
.await?;
match verification_result {
Ok(info) => {
Ok((info, identifier)) => {
storage
.contract_verification_dal()
.save_verification_info(info)
.save_verification_info(
info,
identifier.bytecode_keccak256,
identifier.bytecode_without_metadata_keccak256,
)
.await?;
tracing::info!("Successfully processed request with id = {request_id}");
}
Expand Down
Loading

0 comments on commit 45cc9ea

Please sign in to comment.