From 4509179f62ead4b837dfb67760f52de76fac2e37 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Fri, 8 Nov 2024 15:55:59 +0200 Subject: [PATCH 1/8] feat(contract-verifier): Adapt contract verifier API for EVM bytecodes (#3234) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - Adapts contract verifier APIs to work with EVM bytecodes; adds corresponding request correctness checks. - Brushes up the verifier API server in general. ## Why ❔ Part of the efforts to support EVM bytecode verification. ## 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`. --- Cargo.lock | 12 +- Cargo.toml | 1 + core/bin/contract-verifier/Cargo.toml | 5 +- core/bin/contract-verifier/src/main.rs | 53 +-- core/lib/contract_verifier/src/lib.rs | 112 ++++-- core/lib/contract_verifier/src/resolver.rs | 19 +- core/lib/contract_verifier/src/tests/mod.rs | 45 ++- core/lib/contract_verifier/src/tests/real.rs | 40 +- ...6b602aa0cf9b0c5b1ef39b7d07d6309454fcd.json | 2 +- ...5094de508af93f4085be7cf3b54b1e8ecdadd.json | 2 +- ...make_zk_compiler_version_nullable.down.sql | 2 + ...2_make_zk_compiler_version_nullable.up.sql | 2 + core/lib/dal/src/contract_verification_dal.rs | 86 ++++- .../models/storage_verification_request.rs | 2 +- core/lib/dal/src/storage_logs_dal.rs | 65 +--- core/lib/dal/src/tokens_dal.rs | 2 +- .../types/src/contract_verification_api.rs | 14 +- .../contract_verification_server/Cargo.toml | 10 +- .../src/api_decl.rs | 11 +- .../src/api_impl.rs | 247 +++++++----- .../contract_verification_server/src/cache.rs | 122 ++++++ .../contract_verification_server/src/lib.rs | 9 +- .../contract_verification_server/src/tests.rs | 356 ++++++++++++++++++ .../layers/contract_verification_api.rs | 2 +- 24 files changed, 923 insertions(+), 298 deletions(-) create mode 100644 core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.down.sql create mode 100644 core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.up.sql create mode 100644 core/node/contract_verification_server/src/cache.rs create mode 100644 core/node/contract_verification_server/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 65ae365e3a2b..04a863448d69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10784,15 +10784,18 @@ version = "0.1.0" dependencies = [ "anyhow", "axum 0.7.7", - "serde", + "http-body-util", "serde_json", + "test-casing", "tokio", + "tower 0.4.13", "tower-http", "tracing", "vise", - "zksync_config", "zksync_dal", + "zksync_node_test_utils", "zksync_types", + "zksync_utils", ] [[package]] @@ -10800,16 +10803,13 @@ name = "zksync_contract_verifier" version = "0.1.0" dependencies = [ "anyhow", - "ctrlc", - "futures 0.3.31", - "structopt", + "clap 4.5.20", "tokio", "tracing", "zksync_config", "zksync_contract_verifier_lib", "zksync_core_leftovers", "zksync_dal", - "zksync_env_config", "zksync_queued_job_processor", "zksync_utils", "zksync_vlog", diff --git a/Cargo.toml b/Cargo.toml index 87e0de13129f..e491c64605bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,6 +130,7 @@ google-cloud-storage = "0.20.0" governor = "0.4.2" hex = "0.4" http = "1.1" +http-body-util = "0.1.2" httpmock = "0.7.0" hyper = "1.3" insta = "1.29.0" diff --git a/core/bin/contract-verifier/Cargo.toml b/core/bin/contract-verifier/Cargo.toml index f088c2337e71..5e9a9efc6e7e 100644 --- a/core/bin/contract-verifier/Cargo.toml +++ b/core/bin/contract-verifier/Cargo.toml @@ -12,7 +12,6 @@ publish = false [dependencies] zksync_dal.workspace = true -zksync_env_config.workspace = true zksync_config = { workspace = true, features = ["observability_ext"] } zksync_contract_verifier_lib.workspace = true zksync_queued_job_processor.workspace = true @@ -21,8 +20,6 @@ zksync_vlog.workspace = true zksync_core_leftovers.workspace = true anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } tokio = { workspace = true, features = ["full"] } -futures.workspace = true -ctrlc.workspace = true -structopt.workspace = true tracing.workspace = true diff --git a/core/bin/contract-verifier/src/main.rs b/core/bin/contract-verifier/src/main.rs index 6929f8bfe04d..88f25256c40d 100644 --- a/core/bin/contract-verifier/src/main.rs +++ b/core/bin/contract-verifier/src/main.rs @@ -1,8 +1,7 @@ -use std::{cell::RefCell, time::Duration}; +use std::{path::PathBuf, time::Duration}; -use anyhow::Context; -use futures::{channel::mpsc, executor::block_on, SinkExt, StreamExt}; -use structopt::StructOpt; +use anyhow::Context as _; +use clap::Parser; use tokio::sync::watch; use zksync_config::configs::PrometheusConfig; use zksync_contract_verifier_lib::ContractVerifier; @@ -12,27 +11,31 @@ use zksync_queued_job_processor::JobProcessor; use zksync_utils::wait_for_tasks::ManagedTasks; use zksync_vlog::prometheus::PrometheusExporterConfig; -#[derive(StructOpt)] -#[structopt(name = "ZKsync contract code verifier", author = "Matter Labs")] +#[derive(Debug, Parser)] +#[command(name = "ZKsync contract code verifier", author = "Matter Labs")] struct Opt { /// Number of jobs to process. If None, runs indefinitely. - #[structopt(long)] + #[arg(long)] jobs_number: Option, /// Path to the configuration file. - #[structopt(long)] - config_path: Option, + #[arg(long)] + config_path: Option, /// Path to the secrets file. - #[structopt(long)] - secrets_path: Option, + #[arg(long)] + secrets_path: Option, } #[tokio::main] async fn main() -> anyhow::Result<()> { - let opt = Opt::from_args(); + let opt = Opt::parse(); let general_config = load_general_config(opt.config_path).context("general config")?; - let database_secrets = load_database_secrets(opt.secrets_path).context("database secrets")?; + let observability_config = general_config + .observability + .context("ObservabilityConfig")?; + let _observability_guard = observability_config.install()?; + let database_secrets = load_database_secrets(opt.secrets_path).context("database secrets")?; let verifier_config = general_config .contract_verifier .context("ContractVerifierConfig")?; @@ -46,33 +49,13 @@ async fn main() -> anyhow::Result<()> { .context("Master DB URL is absent")?, ) .build() - .await - .unwrap(); - - let observability_config = general_config - .observability - .context("ObservabilityConfig")?; - - let _observability_guard = observability_config.install()?; + .await?; let (stop_sender, stop_receiver) = watch::channel(false); - let (stop_signal_sender, mut stop_signal_receiver) = mpsc::channel(256); - { - let stop_signal_sender = RefCell::new(stop_signal_sender.clone()); - ctrlc::set_handler(move || { - let mut sender = stop_signal_sender.borrow_mut(); - block_on(sender.send(true)).expect("Ctrl+C signal send"); - }) - .expect("Error setting Ctrl+C handler"); - } - 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 - // since `JobProcessor` trait requires it. tokio::spawn(contract_verifier.run(stop_receiver.clone(), opt.jobs_number)), tokio::spawn( PrometheusExporterConfig::pull(prometheus_config.listener_port).run(stop_receiver), @@ -82,7 +65,7 @@ async fn main() -> anyhow::Result<()> { let mut tasks = ManagedTasks::new(tasks); tokio::select! { () = tasks.wait_single() => {}, - _ = stop_signal_receiver.next() => { + _ = tokio::signal::ctrl_c() => { tracing::info!("Stop signal received, shutting down"); }, }; diff --git a/core/lib/contract_verifier/src/lib.rs b/core/lib/contract_verifier/src/lib.rs index 425440fa2eb6..686bb0d7bdc3 100644 --- a/core/lib/contract_verifier/src/lib.rs +++ b/core/lib/contract_verifier/src/lib.rs @@ -14,7 +14,7 @@ use zksync_dal::{contract_verification_dal::DeployedContractData, ConnectionPool use zksync_queued_job_processor::{async_trait, JobProcessor}; use zksync_types::{ contract_verification_api::{ - CompilationArtifacts, CompilerType, VerificationIncomingRequest, VerificationInfo, + self as api, CompilationArtifacts, VerificationIncomingRequest, VerificationInfo, VerificationRequest, }, Address, CONTRACT_DEPLOYER_ADDRESS, @@ -35,6 +35,65 @@ mod resolver; #[cfg(test)] mod tests; +#[derive(Debug)] +struct ZkCompilerVersions { + /// Version of the base / non-ZK compiler. + pub base: String, + /// Version of the ZK compiler. + pub zk: String, +} + +/// Internal counterpart of `ContractVersions` from API that encompasses all supported compilation modes. +#[derive(Debug)] +enum VersionedCompiler { + Solc(String), + #[allow(dead_code)] // TODO (EVM-864): add vyper support + Vyper(String), + ZkSolc(ZkCompilerVersions), + ZkVyper(ZkCompilerVersions), +} + +impl From for VersionedCompiler { + fn from(versions: api::CompilerVersions) -> Self { + match versions { + api::CompilerVersions::Solc { + compiler_solc_version, + compiler_zksolc_version: None, + } => Self::Solc(compiler_solc_version), + + api::CompilerVersions::Solc { + compiler_solc_version, + compiler_zksolc_version: Some(zk), + } => Self::ZkSolc(ZkCompilerVersions { + base: compiler_solc_version, + zk, + }), + + api::CompilerVersions::Vyper { + compiler_vyper_version, + compiler_zkvyper_version: None, + } => Self::Vyper(compiler_vyper_version), + + api::CompilerVersions::Vyper { + compiler_vyper_version, + compiler_zkvyper_version: Some(zk), + } => Self::ZkVyper(ZkCompilerVersions { + base: compiler_vyper_version, + zk, + }), + } + } +} + +impl VersionedCompiler { + fn expected_bytecode_kind(&self) -> BytecodeMarker { + match self { + Self::Solc(_) | Self::Vyper(_) => BytecodeMarker::Evm, + Self::ZkSolc(_) | Self::ZkVyper(_) => BytecodeMarker::EraVm, + } + } +} + enum ConstructorArgs { Check(Vec), Ignore, @@ -112,19 +171,19 @@ impl ContractVerifier { let mut transaction = storage.start_transaction().await?; transaction .contract_verification_dal() - .set_zksolc_versions(supported_versions.zksolc) + .set_zksolc_versions(&supported_versions.zksolc) .await?; transaction .contract_verification_dal() - .set_solc_versions(supported_versions.solc) + .set_solc_versions(&supported_versions.solc) .await?; transaction .contract_verification_dal() - .set_zkvyper_versions(supported_versions.zkvyper) + .set_zkvyper_versions(&supported_versions.zkvyper) .await?; transaction .contract_verification_dal() - .set_vyper_versions(supported_versions.vyper) + .set_vyper_versions(&supported_versions.vyper) .await?; transaction.commit().await?; Ok(()) @@ -214,13 +273,11 @@ impl ContractVerifier { async fn compile_zksolc( &self, + version: &ZkCompilerVersions, req: VerificationIncomingRequest, ) -> Result { - let zksolc = self - .compiler_resolver - .resolve_zksolc(&req.compiler_versions) - .await?; - tracing::debug!(?zksolc, ?req.compiler_versions, "resolved compiler"); + let zksolc = self.compiler_resolver.resolve_zksolc(version).await?; + tracing::debug!(?zksolc, ?version, "resolved compiler"); let input = ZkSolc::build_input(req)?; time::timeout(self.compilation_timeout, zksolc.compile(input)) @@ -230,13 +287,11 @@ impl ContractVerifier { async fn compile_zkvyper( &self, + version: &ZkCompilerVersions, req: VerificationIncomingRequest, ) -> Result { - let zkvyper = self - .compiler_resolver - .resolve_zkvyper(&req.compiler_versions) - .await?; - tracing::debug!(?zkvyper, ?req.compiler_versions, "resolved compiler"); + let zkvyper = self.compiler_resolver.resolve_zkvyper(version).await?; + tracing::debug!(?zkvyper, ?version, "resolved compiler"); let input = ZkVyper::build_input(req)?; time::timeout(self.compilation_timeout, zkvyper.compile(input)) .await @@ -245,12 +300,10 @@ impl ContractVerifier { async fn compile_solc( &self, + version: &str, req: VerificationIncomingRequest, ) -> Result { - let solc = self - .compiler_resolver - .resolve_solc(req.compiler_versions.compiler_version()) - .await?; + let solc = self.compiler_resolver.resolve_solc(version).await?; tracing::debug!(?solc, ?req.compiler_versions, "resolved compiler"); let input = Solc::build_input(req)?; @@ -276,15 +329,24 @@ impl ContractVerifier { return Err(err.into()); } - match (bytecode_marker, compiler_type) { - (BytecodeMarker::EraVm, CompilerType::Solc) => self.compile_zksolc(req).await, - (BytecodeMarker::EraVm, CompilerType::Vyper) => self.compile_zkvyper(req).await, - (BytecodeMarker::Evm, CompilerType::Solc) => self.compile_solc(req).await, - (BytecodeMarker::Evm, CompilerType::Vyper) => { - // TODO: add vyper support + let compiler = VersionedCompiler::from(req.compiler_versions.clone()); + if compiler.expected_bytecode_kind() != bytecode_marker { + let err = anyhow::anyhow!( + "bytecode kind expected by compiler {compiler:?} differs from the actual bytecode kind \ + of the verified contract ({bytecode_marker:?})", + ); + return Err(err.into()); + } + + match &compiler { + VersionedCompiler::Solc(version) => self.compile_solc(version, req).await, + VersionedCompiler::Vyper(_) => { + // TODO (EVM-864): add vyper support let err = anyhow::anyhow!("vyper toolchain is not yet supported for EVM contracts"); return Err(err.into()); } + VersionedCompiler::ZkSolc(version) => self.compile_zksolc(version, req).await, + VersionedCompiler::ZkVyper(version) => self.compile_zkvyper(version, req).await, } } diff --git a/core/lib/contract_verifier/src/resolver.rs b/core/lib/contract_verifier/src/resolver.rs index 347db8fff094..34a70b759797 100644 --- a/core/lib/contract_verifier/src/resolver.rs +++ b/core/lib/contract_verifier/src/resolver.rs @@ -6,12 +6,13 @@ use std::{ use anyhow::Context as _; use tokio::fs; use zksync_queued_job_processor::async_trait; -use zksync_types::contract_verification_api::{CompilationArtifacts, CompilerVersions}; +use zksync_types::contract_verification_api::CompilationArtifacts; use zksync_utils::env::Workspace; use crate::{ compilers::{Solc, SolcInput, ZkSolc, ZkSolcInput, ZkVyper, ZkVyperInput}, error::ContractVerifierError, + ZkCompilerVersions, }; #[derive(Debug, Clone, Copy)] @@ -111,13 +112,13 @@ pub(crate) trait CompilerResolver: fmt::Debug + Send + Sync { /// Resolves a `zksolc` compiler. async fn resolve_zksolc( &self, - versions: &CompilerVersions, + version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError>; /// Resolves a `zkvyper` compiler. async fn resolve_zkvyper( &self, - versions: &CompilerVersions, + version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError>; } @@ -198,14 +199,14 @@ impl CompilerResolver for EnvCompilerResolver { async fn resolve_zksolc( &self, - versions: &CompilerVersions, + version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError> { - let zksolc_version = versions.zk_compiler_version(); + let zksolc_version = &version.zk; let zksolc_path = CompilerType::ZkSolc .bin_path(&self.home_dir, zksolc_version) .await?; let solc_path = CompilerType::Solc - .bin_path(&self.home_dir, versions.compiler_version()) + .bin_path(&self.home_dir, &version.base) .await?; let compiler_paths = CompilerPaths { base: solc_path, @@ -219,13 +220,13 @@ impl CompilerResolver for EnvCompilerResolver { async fn resolve_zkvyper( &self, - versions: &CompilerVersions, + version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError> { let zkvyper_path = CompilerType::ZkVyper - .bin_path(&self.home_dir, versions.zk_compiler_version()) + .bin_path(&self.home_dir, &version.zk) .await?; let vyper_path = CompilerType::Vyper - .bin_path(&self.home_dir, versions.compiler_version()) + .bin_path(&self.home_dir, &version.base) .await?; let compiler_paths = CompilerPaths { base: vyper_path, diff --git a/core/lib/contract_verifier/src/tests/mod.rs b/core/lib/contract_verifier/src/tests/mod.rs index f05d3155a6d4..7caa5f32c991 100644 --- a/core/lib/contract_verifier/src/tests/mod.rs +++ b/core/lib/contract_verifier/src/tests/mod.rs @@ -280,18 +280,18 @@ impl CompilerResolver for MockCompilerResolver { async fn resolve_zksolc( &self, - versions: &CompilerVersions, + version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError> { - if versions.compiler_version() != SOLC_VERSION { + if version.base != SOLC_VERSION { return Err(ContractVerifierError::UnknownCompilerVersion( "solc", - versions.compiler_version().to_owned(), + version.base.clone(), )); } - if versions.zk_compiler_version() != ZKSOLC_VERSION { + if version.zk != ZKSOLC_VERSION { return Err(ContractVerifierError::UnknownCompilerVersion( "zksolc", - versions.zk_compiler_version().to_owned(), + version.zk.clone(), )); } Ok(Box::new(self.clone())) @@ -299,7 +299,7 @@ impl CompilerResolver for MockCompilerResolver { async fn resolve_zkvyper( &self, - _versions: &CompilerVersions, + _version: &ZkCompilerVersions, ) -> Result>, ContractVerifierError> { unreachable!("not tested") } @@ -311,7 +311,7 @@ fn test_request(address: Address, source: &str) -> VerificationIncomingRequest { source_code_data: SourceCodeData::SolSingleFile(source.into()), contract_name: "Counter".to_owned(), compiler_versions: CompilerVersions::Solc { - compiler_zksolc_version: ZKSOLC_VERSION.to_owned(), + compiler_zksolc_version: Some(ZKSOLC_VERSION.to_owned()), compiler_solc_version: SOLC_VERSION.to_owned(), }, optimization_used: true, @@ -375,7 +375,7 @@ async fn contract_verifier_basics(contract: TestContract) { req.constructor_arguments = ethabi::encode(contract.constructor_args()).into(); let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -468,10 +468,14 @@ async fn verifying_evm_bytecode(contract: TestContract) { ) .await; let mut req = test_request(address, contract.source()); + req.compiler_versions = CompilerVersions::Solc { + compiler_solc_version: SOLC_VERSION.to_owned(), + compiler_zksolc_version: None, + }; req.constructor_arguments = ethabi::encode(contract.constructor_args()).into(); let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -513,7 +517,7 @@ async fn bytecode_mismatch_error() { let req = test_request(address, COUNTER_CONTRACT); let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -578,6 +582,13 @@ async fn args_mismatch_error(contract: TestContract, bytecode_kind: BytecodeMark } let mut req = test_request(address, contract.source()); + if matches!(bytecode_kind, BytecodeMarker::Evm) { + req.compiler_versions = CompilerVersions::Solc { + compiler_zksolc_version: None, + compiler_solc_version: SOLC_VERSION.to_owned(), + }; + } + // Intentionally encode incorrect constructor args req.constructor_arguments = match contract { TestContract::Counter => ethabi::encode(&[Token::Bool(true)]).into(), @@ -585,7 +596,7 @@ async fn args_mismatch_error(contract: TestContract, bytecode_kind: BytecodeMark }; let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -648,10 +659,14 @@ async fn creation_bytecode_mismatch() { &[], ) .await; - let req = test_request(address, COUNTER_CONTRACT); + let mut req = test_request(address, COUNTER_CONTRACT); + req.compiler_versions = CompilerVersions::Solc { + compiler_zksolc_version: None, + compiler_solc_version: SOLC_VERSION.to_owned(), + }; let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -696,14 +711,14 @@ async fn no_compiler_version() { mock_deployment(&mut storage, address, vec![0xff; 32], &[]).await; let req = VerificationIncomingRequest { compiler_versions: CompilerVersions::Solc { - compiler_zksolc_version: ZKSOLC_VERSION.to_owned(), + compiler_zksolc_version: Some(ZKSOLC_VERSION.to_owned()), compiler_solc_version: "1.0.0".to_owned(), // a man can dream }, ..test_request(address, COUNTER_CONTRACT) }; let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); diff --git a/core/lib/contract_verifier/src/tests/real.rs b/core/lib/contract_verifier/src/tests/real.rs index 5f550a5feea8..a7113044b405 100644 --- a/core/lib/contract_verifier/src/tests/real.rs +++ b/core/lib/contract_verifier/src/tests/real.rs @@ -8,7 +8,7 @@ use zksync_utils::bytecode::validate_bytecode; use super::*; -#[derive(Debug)] +#[derive(Debug, Clone)] struct TestCompilerVersions { solc: String, zksolc: String, @@ -26,10 +26,20 @@ impl TestCompilerVersions { }) } - fn for_zksolc(self) -> CompilerVersions { + fn zksolc(self) -> ZkCompilerVersions { + ZkCompilerVersions { + base: self.solc, + zk: self.zksolc, + } + } + + fn solc_for_api(self, bytecode_kind: BytecodeMarker) -> CompilerVersions { CompilerVersions::Solc { compiler_solc_version: self.solc, - compiler_zksolc_version: self.zksolc, + compiler_zksolc_version: match bytecode_kind { + BytecodeMarker::Evm => None, + BytecodeMarker::EraVm => Some(self.zksolc), + }, } } } @@ -70,10 +80,12 @@ macro_rules! real_resolver { async fn using_real_compiler() { let (compiler_resolver, supported_compilers) = real_resolver!(); - let versions = supported_compilers.for_zksolc(); - let compiler = compiler_resolver.resolve_zksolc(&versions).await.unwrap(); + let compiler = compiler_resolver + .resolve_zksolc(&supported_compilers.clone().zksolc()) + .await + .unwrap(); let req = VerificationIncomingRequest { - compiler_versions: versions, + compiler_versions: supported_compilers.solc_for_api(BytecodeMarker::EraVm), ..test_request(Address::repeat_byte(1), COUNTER_CONTRACT) }; let input = ZkSolc::build_input(req).unwrap(); @@ -92,7 +104,7 @@ async fn using_standalone_solc() { let req = VerificationIncomingRequest { compiler_versions: CompilerVersions::Solc { compiler_solc_version: version.clone(), - compiler_zksolc_version: "1000.0.0".to_owned(), // not used + compiler_zksolc_version: None, }, ..test_request(Address::repeat_byte(1), COUNTER_CONTRACT) }; @@ -108,23 +120,22 @@ async fn using_standalone_solc() { async fn using_real_compiler_in_verifier(bytecode_kind: BytecodeMarker) { let (compiler_resolver, supported_compilers) = real_resolver!(); - let versions = supported_compilers.for_zksolc(); let req = VerificationIncomingRequest { - compiler_versions: versions, + compiler_versions: supported_compilers.clone().solc_for_api(bytecode_kind), ..test_request(Address::repeat_byte(1), COUNTER_CONTRACT) }; let address = Address::repeat_byte(1); let output = match bytecode_kind { BytecodeMarker::EraVm => { let compiler = compiler_resolver - .resolve_zksolc(&req.compiler_versions) + .resolve_zksolc(&supported_compilers.zksolc()) .await .unwrap(); let input = ZkSolc::build_input(req.clone()).unwrap(); compiler.compile(input).await.unwrap() } BytecodeMarker::Evm => { - let solc_version = req.compiler_versions.compiler_version(); + let solc_version = &supported_compilers.solc; let compiler = compiler_resolver.resolve_solc(solc_version).await.unwrap(); let input = Solc::build_input(req.clone()).unwrap(); compiler.compile(input).await.unwrap() @@ -151,7 +162,7 @@ async fn using_real_compiler_in_verifier(bytecode_kind: BytecodeMarker) { } let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); @@ -174,10 +185,9 @@ async fn using_real_compiler_in_verifier(bytecode_kind: BytecodeMarker) { async fn compilation_errors(bytecode_kind: BytecodeMarker) { let (compiler_resolver, supported_compilers) = real_resolver!(); - let versions = supported_compilers.for_zksolc(); let address = Address::repeat_byte(1); let req = VerificationIncomingRequest { - compiler_versions: versions, + compiler_versions: supported_compilers.solc_for_api(bytecode_kind), source_code_data: SourceCodeData::SolSingleFile("contract ???".to_owned()), ..test_request(Address::repeat_byte(1), COUNTER_CONTRACT) }; @@ -196,7 +206,7 @@ async fn compilation_errors(bytecode_kind: BytecodeMarker) { let request_id = storage .contract_verification_dal() - .add_contract_verification_request(req) + .add_contract_verification_request(&req) .await .unwrap(); diff --git a/core/lib/dal/.sqlx/query-2fa2ba4a62f79d780d239409d426b602aa0cf9b0c5b1ef39b7d07d6309454fcd.json b/core/lib/dal/.sqlx/query-2fa2ba4a62f79d780d239409d426b602aa0cf9b0c5b1ef39b7d07d6309454fcd.json index 1d515edba819..0db6ba6f51b6 100644 --- a/core/lib/dal/.sqlx/query-2fa2ba4a62f79d780d239409d426b602aa0cf9b0c5b1ef39b7d07d6309454fcd.json +++ b/core/lib/dal/.sqlx/query-2fa2ba4a62f79d780d239409d426b602aa0cf9b0c5b1ef39b7d07d6309454fcd.json @@ -69,7 +69,7 @@ false, false, false, - false, + true, false, false, true, diff --git a/core/lib/dal/.sqlx/query-a115f795672787fe25bfaa8fd345094de508af93f4085be7cf3b54b1e8ecdadd.json b/core/lib/dal/.sqlx/query-a115f795672787fe25bfaa8fd345094de508af93f4085be7cf3b54b1e8ecdadd.json index ebe8ce232cfb..ac7989a5be77 100644 --- a/core/lib/dal/.sqlx/query-a115f795672787fe25bfaa8fd345094de508af93f4085be7cf3b54b1e8ecdadd.json +++ b/core/lib/dal/.sqlx/query-a115f795672787fe25bfaa8fd345094de508af93f4085be7cf3b54b1e8ecdadd.json @@ -67,7 +67,7 @@ false, false, false, - false, + true, false, false, true, diff --git a/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.down.sql b/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.down.sql new file mode 100644 index 000000000000..2693a565fd02 --- /dev/null +++ b/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE contract_verification_requests + ALTER COLUMN zk_compiler_version SET NOT NULL; diff --git a/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.up.sql b/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.up.sql new file mode 100644 index 000000000000..92a689956f55 --- /dev/null +++ b/core/lib/dal/migrations/20241106093512_make_zk_compiler_version_nullable.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE contract_verification_requests + ALTER COLUMN zk_compiler_version DROP NOT NULL; diff --git a/core/lib/dal/src/contract_verification_dal.rs b/core/lib/dal/src/contract_verification_dal.rs index 1a827545ca13..93a4ce2fd35a 100644 --- a/core/lib/dal/src/contract_verification_dal.rs +++ b/core/lib/dal/src/contract_verification_dal.rs @@ -76,7 +76,7 @@ impl ContractVerificationDal<'_, '_> { pub async fn add_contract_verification_request( &mut self, - query: VerificationIncomingRequest, + query: &VerificationIncomingRequest, ) -> DalResult { sqlx::query!( r#" @@ -104,12 +104,12 @@ impl ContractVerificationDal<'_, '_> { query.contract_address.as_bytes(), // Serialization should always succeed. serde_json::to_string(&query.source_code_data).unwrap(), - query.contract_name, + &query.contract_name, query.compiler_versions.zk_compiler_version(), query.compiler_versions.compiler_version(), query.optimization_used, - query.optimizer_mode, - query.constructor_arguments.0, + query.optimizer_mode.as_deref(), + query.constructor_arguments.0.as_slice(), query.is_system, query.force_evmla, ) @@ -441,7 +441,7 @@ impl ContractVerificationDal<'_, '_> { async fn set_compiler_versions( &mut self, compiler: Compiler, - versions: Vec, + versions: &[String], ) -> DalResult<()> { let mut transaction = self.storage.start_transaction().await?; let compiler = format!("{compiler}"); @@ -472,7 +472,7 @@ impl ContractVerificationDal<'_, '_> { UNNEST($1::TEXT []) AS u (version) ON CONFLICT (version, compiler) DO NOTHING "#, - &versions, + versions, &compiler, ) .instrument("set_compiler_versions#insert") @@ -484,20 +484,20 @@ impl ContractVerificationDal<'_, '_> { transaction.commit().await } - pub async fn set_zksolc_versions(&mut self, versions: Vec) -> DalResult<()> { + pub async fn set_zksolc_versions(&mut self, versions: &[String]) -> DalResult<()> { self.set_compiler_versions(Compiler::ZkSolc, versions).await } - pub async fn set_solc_versions(&mut self, versions: Vec) -> DalResult<()> { + pub async fn set_solc_versions(&mut self, versions: &[String]) -> DalResult<()> { self.set_compiler_versions(Compiler::Solc, versions).await } - pub async fn set_zkvyper_versions(&mut self, versions: Vec) -> DalResult<()> { + pub async fn set_zkvyper_versions(&mut self, versions: &[String]) -> DalResult<()> { self.set_compiler_versions(Compiler::ZkVyper, versions) .await } - pub async fn set_vyper_versions(&mut self, versions: Vec) -> DalResult<()> { + pub async fn set_vyper_versions(&mut self, versions: &[String]) -> DalResult<()> { self.set_compiler_versions(Compiler::Vyper, versions).await } @@ -567,7 +567,9 @@ mod tests { use std::collections::HashMap; use zksync_types::{ - tx::IncludedTxLocation, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, + contract_verification_api::{CompilerVersions, SourceCodeData}, + tx::IncludedTxLocation, + Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, }; use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{tracer::ValidationTraces, TransactionExecutionMetrics}; @@ -645,4 +647,66 @@ mod tests { assert_eq!(contract.contract_address, Some(CONTRACT_DEPLOYER_ADDRESS)); assert_eq!(contract.calldata.unwrap(), tx.execute.calldata); } + + async fn test_working_with_verification_requests(zksolc: Option<&str>) { + let request = VerificationIncomingRequest { + contract_address: Address::repeat_byte(11), + source_code_data: SourceCodeData::SolSingleFile("contract Test {}".to_owned()), + contract_name: "Test".to_string(), + compiler_versions: CompilerVersions::Solc { + compiler_zksolc_version: zksolc.map(str::to_owned), + compiler_solc_version: "0.8.27".to_owned(), + }, + optimization_used: true, + optimizer_mode: Some("z".to_owned()), + constructor_arguments: web3::Bytes(b"test".to_vec()), + is_system: false, + force_evmla: true, + }; + + let pool = ConnectionPool::::test_pool().await; + let mut conn = pool.connection().await.unwrap(); + let id = conn + .contract_verification_dal() + .add_contract_verification_request(&request) + .await + .unwrap(); + + let status = conn + .contract_verification_dal() + .get_verification_request_status(id) + .await + .unwrap() + .expect("request not persisted"); + assert_eq!(status.status, "queued"); + + let req = conn + .contract_verification_dal() + .get_next_queued_verification_request(Duration::from_secs(600)) + .await + .unwrap() + .expect("request not queued"); + assert_eq!(req.id, id); + assert_eq!(req.req.contract_address, request.contract_address); + assert_eq!(req.req.contract_name, request.contract_name); + assert_eq!(req.req.compiler_versions, request.compiler_versions); + assert_eq!(req.req.optimization_used, request.optimization_used); + assert_eq!(req.req.optimizer_mode, request.optimizer_mode); + assert_eq!(req.req.constructor_arguments, request.constructor_arguments); + assert_eq!(req.req.is_system, request.is_system); + assert_eq!(req.req.force_evmla, request.force_evmla); + + let maybe_req = conn + .contract_verification_dal() + .get_next_queued_verification_request(Duration::from_secs(600)) + .await + .unwrap(); + assert!(maybe_req.is_none()); + } + + #[tokio::test] + async fn working_with_verification_requests() { + test_working_with_verification_requests(None).await; + test_working_with_verification_requests(Some("1.5.7")).await; + } } diff --git a/core/lib/dal/src/models/storage_verification_request.rs b/core/lib/dal/src/models/storage_verification_request.rs index 61895fab76d3..ae4718e41290 100644 --- a/core/lib/dal/src/models/storage_verification_request.rs +++ b/core/lib/dal/src/models/storage_verification_request.rs @@ -12,7 +12,7 @@ pub struct StorageVerificationRequest { pub contract_address: Vec, pub source_code: String, pub contract_name: String, - pub zk_compiler_version: String, + pub zk_compiler_version: Option, pub compiler_version: String, pub optimization_used: bool, pub optimizer_mode: Option, diff --git a/core/lib/dal/src/storage_logs_dal.rs b/core/lib/dal/src/storage_logs_dal.rs index ced8f594add3..1675d76643c2 100644 --- a/core/lib/dal/src/storage_logs_dal.rs +++ b/core/lib/dal/src/storage_logs_dal.rs @@ -225,60 +225,13 @@ impl StorageLogsDal<'_, '_> { Ok(()) } - pub async fn is_contract_deployed_at_address(&mut self, address: Address) -> bool { - let hashed_key = get_code_key(&address).hashed_key(); - let row = sqlx::query!( - r#" - SELECT - COUNT(*) AS "count!" - FROM - ( - SELECT - * - FROM - storage_logs - WHERE - hashed_key = $1 - AND miniblock_number <= COALESCE( - ( - SELECT - MAX(number) - FROM - miniblocks - ), - ( - SELECT - miniblock_number - FROM - snapshot_recovery - ) - ) - ORDER BY - miniblock_number DESC, - operation_number DESC - LIMIT - 1 - ) sl - WHERE - sl.value != $2 - "#, - hashed_key.as_bytes(), - FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH.as_bytes(), - ) - .fetch_one(self.storage.conn()) - .await - .unwrap(); - - row.count > 0 - } - /// Returns addresses and the corresponding deployment L2 block numbers among the specified contract /// `addresses`. `at_l2_block` allows filtering deployment by L2 blocks. pub async fn filter_deployed_contracts( &mut self, addresses: impl Iterator, at_l2_block: Option, - ) -> DalResult> { + ) -> DalResult> { let (bytecode_hashed_keys, address_by_hashed_key): (Vec<_>, HashMap<_, _>) = addresses .map(|address| { let hashed_key = get_code_key(&address).hashed_key().0; @@ -330,12 +283,13 @@ impl StorageLogsDal<'_, '_> { .await?; let deployment_data = rows.into_iter().filter_map(|row| { - if row.value == FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH.as_bytes() { + let bytecode_hash = H256::from_slice(&row.value); + if bytecode_hash == FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH { return None; } let l2_block_number = L2BlockNumber(row.miniblock_number as u32); let address = address_by_hashed_key[row.hashed_key.as_slice()]; - Some((address, l2_block_number)) + Some((address, (l2_block_number, bytecode_hash))) }); Ok(deployment_data.collect()) } @@ -1168,8 +1122,9 @@ mod tests { async fn filtering_deployed_contracts() { let contract_address = Address::repeat_byte(1); let other_contract_address = Address::repeat_byte(23); + let bytecode_hash = H256::repeat_byte(0xff); let successful_deployment = - StorageLog::new_write_log(get_code_key(&contract_address), H256::repeat_byte(0xff)); + StorageLog::new_write_log(get_code_key(&contract_address), bytecode_hash); let failed_deployment = StorageLog::new_write_log( get_code_key(&contract_address), FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH, @@ -1233,7 +1188,7 @@ mod tests { .unwrap(); assert_eq!( deployed_map, - HashMap::from([(contract_address, L2BlockNumber(2))]) + HashMap::from([(contract_address, (L2BlockNumber(2), bytecode_hash))]) ); } @@ -1268,7 +1223,7 @@ mod tests { .unwrap(); assert_eq!( deployed_map, - HashMap::from([(contract_address, L2BlockNumber(2))]) + HashMap::from([(contract_address, (L2BlockNumber(2), bytecode_hash))]) ); for new_l2_block in [None, Some(L2BlockNumber(3))] { @@ -1283,8 +1238,8 @@ mod tests { assert_eq!( deployed_map, HashMap::from([ - (contract_address, L2BlockNumber(2)), - (other_contract_address, L2BlockNumber(3)), + (contract_address, (L2BlockNumber(2), bytecode_hash)), + (other_contract_address, (L2BlockNumber(3), bytecode_hash)), ]) ); } diff --git a/core/lib/dal/src/tokens_dal.rs b/core/lib/dal/src/tokens_dal.rs index 218e152fa82a..b5fd67fc63c8 100644 --- a/core/lib/dal/src/tokens_dal.rs +++ b/core/lib/dal/src/tokens_dal.rs @@ -98,7 +98,7 @@ impl TokensDal<'_, '_> { .filter_map(|address| { if address.is_zero() { None - } else if let Some(deployed_at) = token_deployment_data.get(&address) { + } else if let Some((deployed_at, _)) = token_deployment_data.get(&address) { (deployed_at > &block_number).then_some(address.0) } else { // Token belongs to a "pending" L2 block that's not yet fully inserted to the database. diff --git a/core/lib/types/src/contract_verification_api.rs b/core/lib/types/src/contract_verification_api.rs index fcaa1aa9a535..21e511549beb 100644 --- a/core/lib/types/src/contract_verification_api.rs +++ b/core/lib/types/src/contract_verification_api.rs @@ -152,17 +152,19 @@ pub enum CompilerType { Vyper, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(untagged)] pub enum CompilerVersions { #[serde(rename_all = "camelCase")] Solc { - compiler_zksolc_version: String, // FIXME: optional? + #[serde(default, skip_serializing_if = "Option::is_none")] + compiler_zksolc_version: Option, compiler_solc_version: String, }, #[serde(rename_all = "camelCase")] Vyper { - compiler_zkvyper_version: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + compiler_zkvyper_version: Option, compiler_vyper_version: String, }, } @@ -175,16 +177,16 @@ impl CompilerVersions { } } - pub fn zk_compiler_version(&self) -> &str { + pub fn zk_compiler_version(&self) -> Option<&str> { match self { Self::Solc { compiler_zksolc_version, .. - } => compiler_zksolc_version, + } => compiler_zksolc_version.as_deref(), Self::Vyper { compiler_zkvyper_version, .. - } => compiler_zkvyper_version, + } => compiler_zkvyper_version.as_deref(), } } diff --git a/core/node/contract_verification_server/Cargo.toml b/core/node/contract_verification_server/Cargo.toml index eeb2c7828467..038347debc64 100644 --- a/core/node/contract_verification_server/Cargo.toml +++ b/core/node/contract_verification_server/Cargo.toml @@ -11,9 +11,9 @@ keywords.workspace = true categories.workspace = true [dependencies] -zksync_config.workspace = true zksync_dal.workspace = true zksync_types.workspace = true +zksync_utils.workspace = true vise.workspace = true anyhow.workspace = true @@ -21,5 +21,11 @@ axum.workspace = true tokio = { workspace = true, features = ["time"] } tower-http = { workspace = true, features = ["cors"] } tracing.workspace = true -serde.workspace = true + +[dev-dependencies] +zksync_node_test_utils.workspace = true + +http-body-util.workspace = true serde_json.workspace = true +test-casing.workspace = true +tower.workspace = true diff --git a/core/node/contract_verification_server/src/api_decl.rs b/core/node/contract_verification_server/src/api_decl.rs index 256062936d32..d451cd79add9 100644 --- a/core/node/contract_verification_server/src/api_decl.rs +++ b/core/node/contract_verification_server/src/api_decl.rs @@ -3,10 +3,13 @@ use std::sync::Arc; use tower_http::cors::CorsLayer; use zksync_dal::{ConnectionPool, Core}; +use crate::cache::SupportedCompilersCache; + #[derive(Debug, Clone)] -pub struct RestApi { - pub(super) master_connection_pool: ConnectionPool, - pub(super) replica_connection_pool: ConnectionPool, +pub(crate) struct RestApi { + pub(crate) master_connection_pool: ConnectionPool, + pub(crate) replica_connection_pool: ConnectionPool, + pub(crate) supported_compilers: Arc, } impl RestApi { @@ -14,7 +17,9 @@ impl RestApi { master_connection_pool: ConnectionPool, replica_connection_pool: ConnectionPool, ) -> Self { + let supported_compilers = SupportedCompilersCache::new(replica_connection_pool.clone()); Self { + supported_compilers: Arc::new(supported_compilers), master_connection_pool, replica_connection_pool, } diff --git a/core/node/contract_verification_server/src/api_impl.rs b/core/node/contract_verification_server/src/api_impl.rs index b8111e98a1cc..94be65673bad 100644 --- a/core/node/contract_verification_server/src/api_impl.rs +++ b/core/node/contract_verification_server/src/api_impl.rs @@ -1,195 +1,234 @@ -use std::sync::Arc; +use std::{collections::HashSet, iter, sync::Arc}; +use anyhow::Context as _; use axum::{ extract::{Path, State}, - response::Response, + http::StatusCode, + response::{IntoResponse, Response}, Json, }; -use serde::Serialize; -use zksync_dal::CoreDal; -use zksync_types::{contract_verification_api::VerificationIncomingRequest, Address}; +use zksync_dal::{CoreDal, DalError}; +use zksync_types::{ + contract_verification_api::{ + CompilerVersions, VerificationIncomingRequest, VerificationInfo, VerificationRequestStatus, + }, + Address, +}; +use zksync_utils::bytecode::BytecodeMarker; use super::{api_decl::RestApi, metrics::METRICS}; -fn ok_json(data: impl Serialize) -> Response { - Response::builder() - .status(axum::http::StatusCode::OK) - .body(serde_json::to_string(&data).expect("Failed to serialize")) - .unwrap() +#[derive(Debug)] +pub(crate) enum ApiError { + IncorrectCompilerVersions, + UnsupportedCompilerVersions, + MissingZkCompilerVersion, + BogusZkCompilerVersion, + NoDeployedContract, + RequestNotFound, + VerificationInfoNotFound, + Internal(anyhow::Error), +} + +impl From for ApiError { + fn from(err: anyhow::Error) -> Self { + Self::Internal(err) + } +} + +impl From for ApiError { + fn from(err: DalError) -> Self { + Self::Internal(err.generalize()) + } } -fn bad_request(message: &str) -> Response { - Response::builder() - .status(axum::http::StatusCode::BAD_REQUEST) - .body(message.to_string()) - .unwrap() +impl ApiError { + pub fn message(&self) -> &'static str { + match self { + Self::IncorrectCompilerVersions => "incorrect compiler versions", + Self::UnsupportedCompilerVersions => "unsupported compiler versions", + Self::MissingZkCompilerVersion => "missing zk compiler version for EraVM bytecode", + Self::BogusZkCompilerVersion => "zk compiler version specified for EVM bytecode", + Self::NoDeployedContract => "There is no deployed contract on this address", + Self::RequestNotFound => "request not found", + Self::VerificationInfoNotFound => "verification info not found for address", + Self::Internal(_) => "internal server error", + } + } } -fn not_found() -> Response { - Response::builder() - .status(axum::http::StatusCode::NOT_FOUND) - .body(String::new()) - .unwrap() +impl IntoResponse for ApiError { + fn into_response(self) -> Response { + let status_code = match &self { + Self::IncorrectCompilerVersions + | Self::UnsupportedCompilerVersions + | Self::MissingZkCompilerVersion + | Self::BogusZkCompilerVersion + | Self::NoDeployedContract => StatusCode::BAD_REQUEST, + + Self::RequestNotFound | Self::VerificationInfoNotFound => StatusCode::NOT_FOUND, + + Self::Internal(err) => { + // Do not expose the error details to the client, but log it. + tracing::warn!("Internal error: {err:#}"); + StatusCode::INTERNAL_SERVER_ERROR + } + }; + (status_code, self.message()).into_response() + } } +type ApiResult = Result, ApiError>; + impl RestApi { #[tracing::instrument(skip(query))] fn validate_contract_verification_query( query: &VerificationIncomingRequest, - ) -> Result<(), Response> { + ) -> Result<(), ApiError> { if query.source_code_data.compiler_type() != query.compiler_versions.compiler_type() { - return Err(bad_request("incorrect compiler versions")); + return Err(ApiError::IncorrectCompilerVersions); } - Ok(()) } + fn validate_compilers( + versions: &CompilerVersions, + bytecode_kind: BytecodeMarker, + ) -> Result<(), ApiError> { + match bytecode_kind { + BytecodeMarker::EraVm if versions.zk_compiler_version().is_none() => { + Err(ApiError::MissingZkCompilerVersion) + } + BytecodeMarker::Evm if versions.zk_compiler_version().is_some() => { + Err(ApiError::BogusZkCompilerVersion) + } + _ => Ok(()), + } + } + /// Add a contract verification job to the queue if the requested contract wasn't previously verified. + // FIXME: this doesn't seem to check that the contract isn't verified; should it? #[tracing::instrument(skip(self_, request))] pub async fn verification( State(self_): State>, Json(request): Json, - ) -> Response { + ) -> ApiResult { let method_latency = METRICS.call[&"contract_verification"].start(); - if let Err(res) = Self::validate_contract_verification_query(&request) { - return res; + Self::validate_contract_verification_query(&request)?; + + let is_compilation_supported = self_ + .supported_compilers + .get(|supported| supported.contain(&request.compiler_versions)) + .await?; + if !is_compilation_supported { + return Err(ApiError::UnsupportedCompilerVersions); } + let mut storage = self_ .master_connection_pool .connection_tagged("api") - .await - .unwrap(); - - if !storage + .await?; + let deployment_info = storage .storage_logs_dal() - .is_contract_deployed_at_address(request.contract_address) - .await - { - return bad_request("There is no deployed contract on this address"); - } + .filter_deployed_contracts(iter::once(request.contract_address), None) + .await?; + let &(_, bytecode_hash) = deployment_info + .get(&request.contract_address) + .ok_or(ApiError::NoDeployedContract)?; + let bytecode_marker = BytecodeMarker::new(bytecode_hash).with_context(|| { + format!( + "unknown bytecode marker for bytecode hash {bytecode_hash:?} at address {:?}", + request.contract_address + ) + })?; + Self::validate_compilers(&request.compiler_versions, bytecode_marker)?; let request_id = storage .contract_verification_dal() - .add_contract_verification_request(request) - .await - .unwrap(); - + .add_contract_verification_request(&request) + .await?; method_latency.observe(); - ok_json(request_id) + Ok(Json(request_id)) } #[tracing::instrument(skip(self_))] pub async fn verification_request_status( State(self_): State>, id: Path, - ) -> Response { + ) -> ApiResult { let method_latency = METRICS.call[&"contract_verification_request_status"].start(); let status = self_ .replica_connection_pool .connection_tagged("api") - .await - .unwrap() + .await? .contract_verification_dal() .get_verification_request_status(*id) - .await - .unwrap(); + .await? + .ok_or(ApiError::RequestNotFound)?; method_latency.observe(); - match status { - Some(status) => ok_json(status), - None => not_found(), - } + Ok(Json(status)) } #[tracing::instrument(skip(self_))] - pub async fn zksolc_versions(State(self_): State>) -> Response { + pub async fn zksolc_versions(State(self_): State>) -> ApiResult> { let method_latency = METRICS.call[&"contract_verification_zksolc_versions"].start(); let versions = self_ - .replica_connection_pool - .connection_tagged("api") - .await - .unwrap() - .contract_verification_dal() - .get_zksolc_versions() - .await - .unwrap(); - + .supported_compilers + .get(|supported| supported.zksolc.clone()) + .await?; method_latency.observe(); - ok_json(versions) + Ok(Json(versions)) } #[tracing::instrument(skip(self_))] - pub async fn solc_versions(State(self_): State>) -> Response { + pub async fn solc_versions(State(self_): State>) -> ApiResult> { let method_latency = METRICS.call[&"contract_verification_solc_versions"].start(); let versions = self_ - .replica_connection_pool - .connection_tagged("api") - .await - .unwrap() - .contract_verification_dal() - .get_solc_versions() - .await - .unwrap(); - + .supported_compilers + .get(|supported| supported.solc.clone()) + .await?; method_latency.observe(); - ok_json(versions) + Ok(Json(versions)) } #[tracing::instrument(skip(self_))] - pub async fn zkvyper_versions(State(self_): State>) -> Response { + pub async fn zkvyper_versions(State(self_): State>) -> ApiResult> { let method_latency = METRICS.call[&"contract_verification_zkvyper_versions"].start(); let versions = self_ - .replica_connection_pool - .connection_tagged("api") - .await - .unwrap() - .contract_verification_dal() - .get_zkvyper_versions() - .await - .unwrap(); - + .supported_compilers + .get(|supported| supported.zkvyper.clone()) + .await?; method_latency.observe(); - ok_json(versions) + Ok(Json(versions)) } #[tracing::instrument(skip(self_))] - pub async fn vyper_versions(State(self_): State>) -> Response { + pub async fn vyper_versions(State(self_): State>) -> ApiResult> { let method_latency = METRICS.call[&"contract_verification_vyper_versions"].start(); let versions = self_ - .replica_connection_pool - .connection_tagged("api") - .await - .unwrap() - .contract_verification_dal() - .get_vyper_versions() - .await - .unwrap(); - + .supported_compilers + .get(|supported| supported.vyper.clone()) + .await?; method_latency.observe(); - ok_json(versions) + Ok(Json(versions)) } #[tracing::instrument(skip(self_))] pub async fn verification_info( State(self_): State>, address: Path
, - ) -> Response { + ) -> ApiResult { let method_latency = METRICS.call[&"contract_verification_info"].start(); - let info = self_ .replica_connection_pool .connection_tagged("api") - .await - .unwrap() + .await? .contract_verification_dal() .get_contract_verification_info(*address) - .await - .unwrap(); - + .await? + .ok_or(ApiError::VerificationInfoNotFound)?; method_latency.observe(); - match info { - Some(info) => ok_json(info), - None => not_found(), - } + Ok(Json(info)) } } diff --git a/core/node/contract_verification_server/src/cache.rs b/core/node/contract_verification_server/src/cache.rs new file mode 100644 index 000000000000..c8e367515287 --- /dev/null +++ b/core/node/contract_verification_server/src/cache.rs @@ -0,0 +1,122 @@ +use std::{ + collections::HashSet, + time::{Duration, Instant}, +}; + +use tokio::sync::RwLock; +use zksync_dal::{Connection, ConnectionPool, Core, CoreDal, DalError}; +use zksync_types::contract_verification_api::CompilerVersions; + +/// Compiler versions supported by the contract verifier. +#[derive(Debug, Clone)] +pub(crate) struct SupportedCompilerVersions { + pub solc: HashSet, + pub zksolc: HashSet, + pub vyper: HashSet, + pub zkvyper: HashSet, +} + +impl SupportedCompilerVersions { + /// Checks whether the supported compilers include ones specified in a request. + pub fn contain(&self, versions: &CompilerVersions) -> bool { + match versions { + CompilerVersions::Solc { + compiler_solc_version, + compiler_zksolc_version, + } => { + self.solc.contains(compiler_solc_version) + && compiler_zksolc_version + .as_ref() + .map_or(true, |ver| self.zksolc.contains(ver)) + } + CompilerVersions::Vyper { + compiler_vyper_version, + compiler_zkvyper_version, + } => { + self.vyper.contains(compiler_vyper_version) + && compiler_zkvyper_version + .as_ref() + .map_or(true, |ver| self.zkvyper.contains(ver)) + } + } + } +} + +impl SupportedCompilerVersions { + async fn new(connection: &mut Connection<'_, Core>) -> Result { + let solc = connection + .contract_verification_dal() + .get_solc_versions() + .await?; + let zksolc = connection + .contract_verification_dal() + .get_zksolc_versions() + .await?; + let vyper = connection + .contract_verification_dal() + .get_vyper_versions() + .await?; + let zkvyper = connection + .contract_verification_dal() + .get_zkvyper_versions() + .await?; + Ok(Self { + solc: solc.into_iter().collect(), + zksolc: zksolc.into_iter().collect(), + vyper: vyper.into_iter().collect(), + zkvyper: zkvyper.into_iter().collect(), + }) + } +} + +/// Cache for compiler versions supported by the contract verifier. +#[derive(Debug)] +pub(crate) struct SupportedCompilersCache { + connection_pool: ConnectionPool, + inner: RwLock>, +} + +impl SupportedCompilersCache { + const CACHE_UPDATE_INTERVAL: Duration = Duration::from_secs(10); + + pub fn new(connection_pool: ConnectionPool) -> Self { + Self { + connection_pool, + inner: RwLock::new(None), + } + } + + fn get_cached( + cache: Option<&(SupportedCompilerVersions, Instant)>, + action: impl FnOnce(&SupportedCompilerVersions) -> R, + ) -> Option { + cache.and_then(|(versions, updated_at)| { + (updated_at.elapsed() <= Self::CACHE_UPDATE_INTERVAL).then(|| action(versions)) + }) + } + + pub async fn get( + &self, + action: impl Fn(&SupportedCompilerVersions) -> R, + ) -> Result { + let output = Self::get_cached(self.inner.read().await.as_ref(), &action); + if let Some(output) = output { + return Ok(output); + } + + // We don't want to hold an exclusive lock while querying Postgres. + let supported = { + let mut connection = self.connection_pool.connection_tagged("api").await?; + let mut db_transaction = connection + .transaction_builder()? + .set_readonly() + .build() + .await?; + SupportedCompilerVersions::new(&mut db_transaction).await? + }; + let output = action(&supported); + // Another task may have written to the cache already, but we should be fine with updating it again. + *self.inner.write().await = Some((supported, Instant::now())); + Ok(output) + } +} diff --git a/core/node/contract_verification_server/src/lib.rs b/core/node/contract_verification_server/src/lib.rs index eea45f8564bf..912cec55f0b8 100644 --- a/core/node/contract_verification_server/src/lib.rs +++ b/core/node/contract_verification_server/src/lib.rs @@ -1,21 +1,24 @@ +use std::net::SocketAddr; + use anyhow::Context as _; use tokio::sync::watch; -use zksync_config::ContractVerifierConfig; use zksync_dal::ConnectionPool; use self::api_decl::RestApi; mod api_decl; mod api_impl; +mod cache; mod metrics; +#[cfg(test)] +mod tests; pub async fn start_server( master_connection_pool: ConnectionPool, replica_connection_pool: ConnectionPool, - config: ContractVerifierConfig, + bind_address: SocketAddr, mut stop_receiver: watch::Receiver, ) -> anyhow::Result<()> { - let bind_address = config.bind_addr(); let api = RestApi::new(master_connection_pool, replica_connection_pool).into_router(); let listener = tokio::net::TcpListener::bind(bind_address) diff --git a/core/node/contract_verification_server/src/tests.rs b/core/node/contract_verification_server/src/tests.rs new file mode 100644 index 000000000000..b7b0d3e8efb4 --- /dev/null +++ b/core/node/contract_verification_server/src/tests.rs @@ -0,0 +1,356 @@ +//! Tests for contract verification API server. + +use std::{str, time::Duration}; + +use axum::{ + body::Body, + http::{header, Method, Request, Response, StatusCode}, +}; +use http_body_util::BodyExt as _; +use test_casing::test_casing; +use tower::ServiceExt; +use zksync_dal::{Connection, Core, CoreDal}; +use zksync_node_test_utils::create_l2_block; +use zksync_types::{ + contract_verification_api::CompilerVersions, get_code_key, Address, L2BlockNumber, + ProtocolVersion, StorageLog, +}; +use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode, BytecodeMarker}; + +use super::*; +use crate::api_impl::ApiError; + +const SOLC_VERSION: &str = "0.8.27"; +const ZKSOLC_VERSION: &str = "1.5.6"; + +async fn prepare_storage(storage: &mut Connection<'_, Core>) { + storage + .protocol_versions_dal() + .save_protocol_version_with_tx(&ProtocolVersion::default()) + .await + .unwrap(); + storage + .blocks_dal() + .insert_l2_block(&create_l2_block(0)) + .await + .unwrap(); + + storage + .contract_verification_dal() + .set_solc_versions(&[SOLC_VERSION.to_owned()]) + .await + .unwrap(); + storage + .contract_verification_dal() + .set_zksolc_versions(&[ZKSOLC_VERSION.to_owned()]) + .await + .unwrap(); +} + +async fn mock_deploy_contract( + storage: &mut Connection<'_, Core>, + address: Address, + kind: BytecodeMarker, +) { + let bytecode_hash = match kind { + BytecodeMarker::EraVm => hash_bytecode(&[0; 32]), + BytecodeMarker::Evm => hash_evm_bytecode(&[0; 96]), + }; + let deploy_log = StorageLog::new_write_log(get_code_key(&address), bytecode_hash); + storage + .storage_logs_dal() + .append_storage_logs(L2BlockNumber(0), &[deploy_log]) + .await + .unwrap() +} + +fn post_request(body: &serde_json::Value) -> Request { + Request::builder() + .method(Method::POST) + .uri("/contract_verification") + .header(header::CONTENT_TYPE, "application/json") + .body(Body::from(serde_json::to_vec(body).unwrap())) + .unwrap() +} + +async fn json_response(response: Response) -> serde_json::Value { + assert_eq!(response.status(), StatusCode::OK); + assert_eq!( + response.headers().get(header::CONTENT_TYPE).unwrap(), + "application/json" + ); + let response = response.into_body(); + let response = response.collect().await.unwrap().to_bytes(); + serde_json::from_slice(&response).unwrap() +} + +#[tokio::test] +async fn getting_compiler_versions() { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + + let router = RestApi::new(pool.clone(), pool).into_router(); + let req = Request::builder() + .method(Method::GET) + .uri("/contract_verification/zksolc_versions") + .body(Body::empty()) + .unwrap(); + let response = router.clone().oneshot(req).await.unwrap(); + let versions = json_response(response).await; + assert_eq!(versions, serde_json::json!([ZKSOLC_VERSION])); + + let req = Request::builder() + .method(Method::GET) + .uri("/contract_verification/solc_versions") + .body(Body::empty()) + .unwrap(); + let response = router.oneshot(req).await.unwrap(); + let versions = json_response(response).await; + assert_eq!(versions, serde_json::json!([SOLC_VERSION])); +} + +#[test_casing(2, [BytecodeMarker::EraVm, BytecodeMarker::Evm])] +#[tokio::test] +async fn submitting_request(bytecode_kind: BytecodeMarker) { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + + let address = Address::repeat_byte(0x23); + let verification_request = serde_json::json!({ + "contractAddress": address, + "sourceCode": "contract Test {}", + "contractName": "Test", + "compilerZksolcVersion": match bytecode_kind { + BytecodeMarker::EraVm => Some(ZKSOLC_VERSION), + BytecodeMarker::Evm => None, + }, + "compilerSolcVersion": SOLC_VERSION, + "optimizationUsed": true, + }); + + let router = RestApi::new(pool.clone(), pool).into_router(); + let response = router + .clone() + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); // the address is not deployed to + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!(error_message, ApiError::NoDeployedContract.message()); + + mock_deploy_contract(&mut storage, address, bytecode_kind).await; + + let response = router + .clone() + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + let id = json_response(response).await; + assert_eq!(id, serde_json::json!(1)); + + let request = storage + .contract_verification_dal() + .get_next_queued_verification_request(Duration::from_secs(600)) + .await + .unwrap() + .expect("request not persisted"); + assert_eq!(request.id, 1); + assert_eq!(request.req.contract_address, address); + assert_eq!( + request.req.compiler_versions, + CompilerVersions::Solc { + compiler_zksolc_version: match bytecode_kind { + BytecodeMarker::EraVm => Some(ZKSOLC_VERSION.to_owned()), + BytecodeMarker::Evm => None, + }, + compiler_solc_version: SOLC_VERSION.to_owned(), + } + ); + assert_eq!(request.req.contract_name, "Test"); + assert!(request.req.optimization_used); + + let req = Request::builder() + .method(Method::GET) + .uri("/contract_verification/1") + .body(Body::empty()) + .unwrap(); + let response = router.oneshot(req).await.unwrap(); + let request_status = json_response(response).await; + assert_eq!(request_status["status"], "in_progress"); +} + +#[test_casing(2, [BytecodeMarker::EraVm, BytecodeMarker::Evm])] +#[tokio::test] +async fn submitting_request_with_invalid_compiler_type(bytecode_kind: BytecodeMarker) { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + + let address = Address::repeat_byte(0x23); + mock_deploy_contract(&mut storage, address, bytecode_kind).await; + + let verification_request = serde_json::json!({ + "contractAddress": address, + "sourceCode": "contract Test {}", + "contractName": "Test", + // Intentionally incorrect versions "shape" + "compilerZksolcVersion": match bytecode_kind { + BytecodeMarker::Evm => Some(ZKSOLC_VERSION), + BytecodeMarker::EraVm => None, + }, + "compilerSolcVersion": SOLC_VERSION, + "optimizationUsed": true, + }); + let router = RestApi::new(pool.clone(), pool).into_router(); + let response = router + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + let expected_message = match bytecode_kind { + BytecodeMarker::Evm => ApiError::BogusZkCompilerVersion.message(), + BytecodeMarker::EraVm => ApiError::MissingZkCompilerVersion.message(), + }; + assert_eq!(error_message, expected_message); +} + +#[test_casing(2, [BytecodeMarker::EraVm, BytecodeMarker::Evm])] +#[tokio::test] +async fn submitting_request_with_unsupported_solc(bytecode_kind: BytecodeMarker) { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + + let address = Address::repeat_byte(0x23); + mock_deploy_contract(&mut storage, address, bytecode_kind).await; + + let verification_request = serde_json::json!({ + "contractAddress": address, + "sourceCode": "contract Test {}", + "contractName": "Test", + "compilerZksolcVersion": match bytecode_kind { + BytecodeMarker::Evm => None, + BytecodeMarker::EraVm => Some(ZKSOLC_VERSION), + }, + "compilerSolcVersion": "1.0.0", + "optimizationUsed": true, + }); + let router = RestApi::new(pool.clone(), pool).into_router(); + let response = router + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!( + error_message, + ApiError::UnsupportedCompilerVersions.message() + ); +} + +#[tokio::test] +async fn submitting_request_with_unsupported_zksolc() { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + + let address = Address::repeat_byte(0x23); + mock_deploy_contract(&mut storage, address, BytecodeMarker::EraVm).await; + + let verification_request = serde_json::json!({ + "contractAddress": address, + "sourceCode": "contract Test {}", + "contractName": "Test", + "compilerZksolcVersion": "1000.0.0", + "compilerSolcVersion": SOLC_VERSION, + "optimizationUsed": true, + }); + let router = RestApi::new(pool.clone(), pool).into_router(); + let response = router + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!( + error_message, + ApiError::UnsupportedCompilerVersions.message() + ); +} + +#[tokio::test] +async fn querying_missing_request() { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + let router = RestApi::new(pool.clone(), pool).into_router(); + + let req = Request::builder() + .method(Method::GET) + .uri("/contract_verification/1") + .body(Body::empty()) + .unwrap(); + let response = router.oneshot(req).await.unwrap(); + + assert_eq!(response.status(), StatusCode::NOT_FOUND); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!(error_message, ApiError::RequestNotFound.message()); +} + +#[tokio::test] +async fn querying_missing_verification_info() { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + let router = RestApi::new(pool.clone(), pool).into_router(); + + let req = Request::builder() + .method(Method::GET) + .uri("/contract_verification/info/0x2323232323232323232323232323232323232323") + .body(Body::empty()) + .unwrap(); + let response = router.oneshot(req).await.unwrap(); + + assert_eq!(response.status(), StatusCode::NOT_FOUND); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!(error_message, ApiError::VerificationInfoNotFound.message()); +} + +#[tokio::test] +async fn mismatched_compiler_type() { + let pool = ConnectionPool::test_pool().await; + let mut storage = pool.connection().await.unwrap(); + prepare_storage(&mut storage).await; + let address = Address::repeat_byte(0x23); + mock_deploy_contract(&mut storage, address, BytecodeMarker::EraVm).await; + + let verification_request = serde_json::json!({ + "contractAddress": address, + "sourceCode": "contract Test {}", + "contractName": "Test", + "compilerVyperVersion": "1.0.1", + "optimizationUsed": true, + }); + + let router = RestApi::new(pool.clone(), pool).into_router(); + let response = router + .oneshot(post_request(&verification_request)) + .await + .unwrap(); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); + let error_message = response.collect().await.unwrap().to_bytes(); + let error_message = str::from_utf8(&error_message).unwrap(); + assert_eq!(error_message, ApiError::IncorrectCompilerVersions.message()); +} diff --git a/core/node/node_framework/src/implementations/layers/contract_verification_api.rs b/core/node/node_framework/src/implementations/layers/contract_verification_api.rs index 3f1f76cc1c12..2ca7cc25a1fd 100644 --- a/core/node/node_framework/src/implementations/layers/contract_verification_api.rs +++ b/core/node/node_framework/src/implementations/layers/contract_verification_api.rs @@ -69,7 +69,7 @@ impl Task for ContractVerificationApiTask { zksync_contract_verification_server::start_server( self.master_pool, self.replica_pool, - self.config, + self.config.bind_addr(), stop_receiver.0, ) .await From 1bfff0e007e2fb5a4b4b885cf5c69a5cd290888b Mon Sep 17 00:00:00 2001 From: Yury Akudovich Date: Fri, 8 Nov 2024 22:07:51 +0100 Subject: [PATCH 2/8] fix(prover): Remove unneeded dependencies, add default for graceful_shutdown_timeout (#3242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Remove unneeded dependencies. Add default for graceful_shutdown_timeout. ## Why ❔ ## Checklist - [x] 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. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. ref ZKD-1855 --- prover/Cargo.lock | 2 -- prover/crates/bin/prover_autoscaler/Cargo.toml | 2 -- prover/crates/bin/prover_autoscaler/src/config.rs | 5 ++++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/prover/Cargo.lock b/prover/Cargo.lock index 0a86a44f145d..f119d4bd1951 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -8395,9 +8395,7 @@ dependencies = [ "url", "vise", "zksync_config", - "zksync_core_leftovers", "zksync_prover_job_monitor", - "zksync_types", "zksync_utils", "zksync_vlog", ] diff --git a/prover/crates/bin/prover_autoscaler/Cargo.toml b/prover/crates/bin/prover_autoscaler/Cargo.toml index 88569aa87e94..4e66ecc2b0e3 100644 --- a/prover/crates/bin/prover_autoscaler/Cargo.toml +++ b/prover/crates/bin/prover_autoscaler/Cargo.toml @@ -10,10 +10,8 @@ keywords.workspace = true categories.workspace = true [dependencies] -zksync_core_leftovers.workspace = true zksync_vlog.workspace = true zksync_utils.workspace = true -zksync_types.workspace = true zksync_config = { workspace = true, features = ["observability_ext"] } zksync_prover_job_monitor.workspace = true diff --git a/prover/crates/bin/prover_autoscaler/src/config.rs b/prover/crates/bin/prover_autoscaler/src/config.rs index 6729a5372d56..777ffe89fc91 100644 --- a/prover/crates/bin/prover_autoscaler/src/config.rs +++ b/prover/crates/bin/prover_autoscaler/src/config.rs @@ -11,7 +11,10 @@ use zksync_config::configs::ObservabilityConfig; #[derive(Debug, Clone, PartialEq, Deserialize)] pub struct ProverAutoscalerConfig { /// Amount of time ProverJobMonitor will wait all it's tasks to finish. - #[serde(with = "humantime_serde")] + #[serde( + with = "humantime_serde", + default = "ProverAutoscalerConfig::default_graceful_shutdown_timeout" + )] pub graceful_shutdown_timeout: Duration, pub agent_config: Option, pub scaler_config: Option, From fd913fe6c5e4a4a3b6edc9ac9df8fe0232cbe409 Mon Sep 17 00:00:00 2001 From: perekopskiy <53865202+perekopskiy@users.noreply.github.com> Date: Mon, 11 Nov 2024 10:24:55 +0200 Subject: [PATCH 3/8] chore: ignore derivative advisory (#3247) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Ignores RUSTSEC advisory for `derivative` crate being unmaintained ## Why ❔ ## Checklist - [ ] 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 `zkstack dev fmt` and `zkstack dev lint`. --- deny.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/deny.toml b/deny.toml index dc5a32c2c070..7e2070de65c6 100644 --- a/deny.toml +++ b/deny.toml @@ -17,6 +17,7 @@ ignore = [ "RUSTSEC-2021-0145", "RUSTSEC-2021-0139", "RUSTSEC-2024-0375", + "RUSTSEC-2024-0388", # `derivative` is unmaintained, crypto dependenicies (boojum, circuit_encodings and others) rely on it ] [licenses] From 6ea36d14940a19f638512556ccc4c5127150b5c9 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 11 Nov 2024 17:30:33 +0700 Subject: [PATCH 4/8] feat(api-server): add `yParity` for non-legacy txs (#3246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Closes #3245 ## Why ❔ See #3245 for more details. TLDR better compatibility with ETH spec. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [ ] 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`. --- core/lib/dal/src/models/storage_transaction.rs | 8 ++++++++ core/lib/types/src/api/mod.rs | 3 +++ core/lib/types/src/l2/mod.rs | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/core/lib/dal/src/models/storage_transaction.rs b/core/lib/dal/src/models/storage_transaction.rs index 459a3ec0c0fb..b55126800cce 100644 --- a/core/lib/dal/src/models/storage_transaction.rs +++ b/core/lib/dal/src/models/storage_transaction.rs @@ -541,6 +541,13 @@ impl StorageApiTransaction { .or_else(|| self.max_fee_per_gas.clone()) .unwrap_or_else(BigDecimal::zero), }; + // Legacy transactions are not supposed to have `yParity` and are reliant on `v` instead. + // Other transactions are required to have `yParity` which replaces the deprecated `v` value + // (still included for backwards compatibility). + let y_parity = match self.tx_format { + None | Some(0) => None, + _ => signature.as_ref().map(|s| U64::from(s.v())), + }; let mut tx = api::Transaction { hash: H256::from_slice(&self.tx_hash), nonce: U256::from(self.nonce.unwrap_or(0) as u64), @@ -553,6 +560,7 @@ impl StorageApiTransaction { gas_price: Some(bigdecimal_to_u256(gas_price)), gas: bigdecimal_to_u256(self.gas_limit.unwrap_or_else(BigDecimal::zero)), input: serde_json::from_value(self.calldata).expect("incorrect calldata in Postgres"), + y_parity, v: signature.as_ref().map(|s| U64::from(s.v())), r: signature.as_ref().map(|s| U256::from(s.r())), s: signature.as_ref().map(|s| U256::from(s.s())), diff --git a/core/lib/types/src/api/mod.rs b/core/lib/types/src/api/mod.rs index 409dc3727570..5f81e889b537 100644 --- a/core/lib/types/src/api/mod.rs +++ b/core/lib/types/src/api/mod.rs @@ -515,6 +515,9 @@ pub struct Transaction { pub gas: U256, /// Input data pub input: Bytes, + /// The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature + #[serde(rename = "yParity", default, skip_serializing_if = "Option::is_none")] + pub y_parity: Option, /// ECDSA recovery id #[serde(default, skip_serializing_if = "Option::is_none")] pub v: Option, diff --git a/core/lib/types/src/l2/mod.rs b/core/lib/types/src/l2/mod.rs index 48e813e571d2..e7d582ab17a1 100644 --- a/core/lib/types/src/l2/mod.rs +++ b/core/lib/types/src/l2/mod.rs @@ -396,6 +396,13 @@ impl From for api::Transaction { } else { (None, None, None) }; + // Legacy transactions are not supposed to have `yParity` and are reliant on `v` instead. + // Other transactions are required to have `yParity` which replaces the deprecated `v` value + // (still included for backwards compatibility). + let y_parity = match tx.common_data.transaction_type { + TransactionType::LegacyTransaction => None, + _ => v, + }; Self { hash: tx.hash(), @@ -409,6 +416,7 @@ impl From for api::Transaction { max_fee_per_gas: Some(tx.common_data.fee.max_fee_per_gas), gas: tx.common_data.fee.gas_limit, input: Bytes(tx.execute.calldata), + y_parity, v, r, s, From cce765b3b232f0382a7e921fdc4d34a7413cde9f Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 11 Nov 2024 13:10:59 +0200 Subject: [PATCH 5/8] refactor(utils): Recombobulate utils crate (#3237) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - Moves some of functionality of the `utils` crate to `basic_types`, such as conversions, `div_ceil_u256`, and `serde_wrappers`. - Inlines time-related utils at call sites (mostly the state keeper). ## Why ❔ - `utils` has moderately heavyweight deps (`tokio`, `reqwest`), which are not necessary for basic functionality. - Basic functionality better fits in `basic_types` by domain. ## 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`. --- Cargo.lock | 23 +-- core/bin/external_node/Cargo.toml | 1 - core/bin/genesis_generator/Cargo.toml | 1 - .../system-constants-generator/src/utils.rs | 25 ++- core/bin/zksync_server/Cargo.toml | 1 - core/lib/basic_types/src/conversions.rs | 36 ++++ core/lib/basic_types/src/lib.rs | 11 ++ .../src/serde_wrappers.rs | 6 +- core/lib/basic_types/src/web3/mod.rs | 8 + core/lib/constants/Cargo.toml | 1 - core/lib/constants/src/trusted_slots.rs | 3 +- core/lib/contract_verifier/src/tests/mod.rs | 6 +- core/lib/contracts/Cargo.toml | 3 + core/lib/contracts/src/lib.rs | 19 +- core/lib/contracts/src/serde_bytecode.rs | 112 +++++++++++ core/lib/crypto_primitives/Cargo.toml | 1 - .../src/packed_eth_signature.rs | 3 +- core/lib/dal/src/blocks_web3_dal.rs | 3 +- core/lib/dal/src/consensus/conv.rs | 6 +- core/lib/dal/src/contract_verification_dal.rs | 2 +- core/lib/dal/src/factory_deps_dal.rs | 19 +- core/lib/dal/src/models/mod.rs | 27 ++- .../lib/dal/src/models/storage_transaction.rs | 6 +- core/lib/dal/src/models/tests.rs | 49 ++++- core/lib/dal/src/storage_web3_dal.rs | 3 +- core/lib/dal/src/transactions_dal.rs | 6 +- core/lib/merkle_tree/Cargo.toml | 1 - .../src/glue/types/vm/block_context_mode.rs | 2 +- .../multivm/src/glue/types/vm/storage_log.rs | 3 +- .../multivm/src/glue/types/zk_evm_1_3_1.rs | 2 +- .../multivm/src/glue/types/zk_evm_1_3_3.rs | 6 +- .../multivm/src/glue/types/zk_evm_1_4_0.rs | 2 +- .../multivm/src/glue/types/zk_evm_1_4_1.rs | 6 +- .../multivm/src/glue/types/zk_evm_1_5_0.rs | 2 +- .../lib/multivm/src/pubdata_builders/tests.rs | 5 +- .../src/tracers/prestate_tracer/mod.rs | 5 +- core/lib/multivm/src/tracers/validator/mod.rs | 5 +- .../src/tracers/validator/vm_1_4_1/mod.rs | 9 +- .../src/tracers/validator/vm_1_4_2/mod.rs | 9 +- .../validator/vm_boojum_integration/mod.rs | 9 +- .../src/tracers/validator/vm_latest/mod.rs | 10 +- .../validator/vm_refunds_enhancement/mod.rs | 9 +- .../validator/vm_virtual_blocks/mod.rs | 9 +- core/lib/multivm/src/utils/bytecode.rs | 43 +++- core/lib/multivm/src/utils/deduplicator.rs | 6 +- core/lib/multivm/src/utils/events.rs | 3 +- .../src/versions/testonly/block_tip.rs | 4 +- .../src/versions/testonly/code_oracle.rs | 5 +- .../src/versions/testonly/default_aa.rs | 3 +- .../src/versions/testonly/evm_emulator.rs | 9 +- .../versions/testonly/get_used_contracts.rs | 4 +- .../src/versions/testonly/l1_tx_execution.rs | 5 +- .../src/versions/testonly/l2_blocks.rs | 10 +- core/lib/multivm/src/versions/testonly/mod.rs | 10 +- .../src/versions/testonly/secp256r1.rs | 3 +- .../multivm/src/versions/testonly/transfer.rs | 3 +- .../multivm/src/versions/testonly/upgrade.rs | 8 +- .../multivm/src/versions/vm_1_3_2/events.rs | 7 +- .../src/versions/vm_1_3_2/history_recorder.rs | 3 +- .../versions/vm_1_3_2/oracles/decommitter.rs | 7 +- .../src/versions/vm_1_3_2/oracles/storage.rs | 5 +- .../versions/vm_1_3_2/oracles/tracer/utils.rs | 3 +- .../vm_1_3_2/oracles/tracer/validation.rs | 13 +- .../multivm/src/versions/vm_1_3_2/refunds.rs | 3 +- .../src/versions/vm_1_3_2/test_utils.rs | 8 +- .../src/versions/vm_1_3_2/transaction_data.rs | 20 +- .../multivm/src/versions/vm_1_3_2/utils.rs | 3 +- core/lib/multivm/src/versions/vm_1_3_2/vm.rs | 4 +- .../versions/vm_1_3_2/vm_with_bootloader.rs | 30 +-- .../vm_1_4_1/bootloader_state/l2_block.rs | 5 +- .../vm_1_4_1/bootloader_state/utils.rs | 6 +- .../vm_1_4_1/implementation/bytecode.rs | 6 +- .../src/versions/vm_1_4_1/old_vm/events.rs | 7 +- .../vm_1_4_1/old_vm/history_recorder.rs | 3 +- .../vm_1_4_1/old_vm/oracles/decommitter.rs | 8 +- .../src/versions/vm_1_4_1/oracles/storage.rs | 2 +- .../vm_1_4_1/tracers/pubdata_tracer.rs | 23 ++- .../src/versions/vm_1_4_1/tracers/refunds.rs | 6 +- .../src/versions/vm_1_4_1/tracers/utils.rs | 3 +- .../vm_1_4_1/types/internals/pubdata.rs | 2 +- .../types/internals/transaction_data.rs | 20 +- .../vm_1_4_1/types/internals/vm_state.rs | 16 +- .../src/versions/vm_1_4_1/types/l1_batch.rs | 3 +- .../src/versions/vm_1_4_1/utils/fee.rs | 10 +- .../src/versions/vm_1_4_1/utils/l2_blocks.rs | 4 +- .../vm_1_4_2/bootloader_state/l2_block.rs | 5 +- .../vm_1_4_2/bootloader_state/utils.rs | 6 +- .../vm_1_4_2/implementation/bytecode.rs | 8 +- .../src/versions/vm_1_4_2/old_vm/events.rs | 7 +- .../vm_1_4_2/old_vm/history_recorder.rs | 3 +- .../vm_1_4_2/old_vm/oracles/decommitter.rs | 8 +- .../src/versions/vm_1_4_2/oracles/storage.rs | 2 +- .../vm_1_4_2/tracers/pubdata_tracer.rs | 23 ++- .../src/versions/vm_1_4_2/tracers/refunds.rs | 6 +- .../src/versions/vm_1_4_2/tracers/utils.rs | 3 +- .../vm_1_4_2/types/internals/pubdata.rs | 2 +- .../types/internals/transaction_data.rs | 20 +- .../vm_1_4_2/types/internals/vm_state.rs | 16 +- .../src/versions/vm_1_4_2/types/l1_batch.rs | 3 +- .../src/versions/vm_1_4_2/utils/fee.rs | 10 +- .../src/versions/vm_1_4_2/utils/l2_blocks.rs | 4 +- .../bootloader_state/l2_block.rs | 5 +- .../bootloader_state/utils.rs | 6 +- .../implementation/bytecode.rs | 8 +- .../vm_boojum_integration/old_vm/events.rs | 7 +- .../old_vm/history_recorder.rs | 3 +- .../old_vm/oracles/decommitter.rs | 7 +- .../vm_boojum_integration/oracles/storage.rs | 2 +- .../tracers/pubdata_tracer.rs | 23 ++- .../vm_boojum_integration/tracers/refunds.rs | 4 +- .../vm_boojum_integration/tracers/utils.rs | 3 +- .../types/internals/pubdata.rs | 2 +- .../types/internals/transaction_data.rs | 20 +- .../types/internals/vm_state.rs | 16 +- .../vm_boojum_integration/types/l1_batch.rs | 3 +- .../vm_boojum_integration/utils/fee.rs | 10 +- .../vm_boojum_integration/utils/l2_blocks.rs | 4 +- .../vm_boojum_integration/utils/overhead.rs | 3 +- .../vm_fast/bootloader_state/l2_block.rs | 5 +- .../vm_fast/bootloader_state/utils.rs | 6 +- .../multivm/src/versions/vm_fast/bytecode.rs | 4 +- .../multivm/src/versions/vm_fast/events.rs | 5 +- .../src/versions/vm_fast/evm_deploy_tracer.rs | 4 +- core/lib/multivm/src/versions/vm_fast/glue.rs | 6 +- .../vm_fast/initial_bootloader_memory.rs | 3 +- .../multivm/src/versions/vm_fast/pubdata.rs | 2 +- .../multivm/src/versions/vm_fast/refund.rs | 3 +- .../multivm/src/versions/vm_fast/tests/mod.rs | 5 +- .../src/versions/vm_fast/transaction_data.rs | 20 +- core/lib/multivm/src/versions/vm_fast/vm.rs | 6 +- .../vm_latest/bootloader_state/l2_block.rs | 5 +- .../vm_latest/bootloader_state/utils.rs | 6 +- .../vm_latest/implementation/bytecode.rs | 8 +- .../src/versions/vm_latest/old_vm/events.rs | 7 +- .../vm_latest/old_vm/history_recorder.rs | 3 +- .../vm_latest/old_vm/oracles/decommitter.rs | 6 +- .../src/versions/vm_latest/oracles/storage.rs | 5 +- .../src/versions/vm_latest/tests/mod.rs | 9 +- .../vm_latest/tracers/evm_deploy_tracer.rs | 13 +- .../vm_latest/tracers/pubdata_tracer.rs | 23 ++- .../src/versions/vm_latest/tracers/refunds.rs | 3 +- .../src/versions/vm_latest/tracers/utils.rs | 3 +- .../types/internals/transaction_data.rs | 20 +- .../vm_latest/types/internals/vm_state.rs | 21 +- .../src/versions/vm_latest/types/l1_batch.rs | 3 +- .../src/versions/vm_latest/utils/fee.rs | 10 +- .../src/versions/vm_latest/utils/l2_blocks.rs | 4 +- core/lib/multivm/src/versions/vm_latest/vm.rs | 5 +- core/lib/multivm/src/versions/vm_m5/events.rs | 7 +- .../src/versions/vm_m5/history_recorder.rs | 3 +- .../src/versions/vm_m5/oracles/decommitter.rs | 15 +- .../src/versions/vm_m5/oracles/storage.rs | 5 +- .../src/versions/vm_m5/oracles/tracer.rs | 35 ++-- .../lib/multivm/src/versions/vm_m5/refunds.rs | 3 +- .../multivm/src/versions/vm_m5/test_utils.rs | 8 +- .../src/versions/vm_m5/transaction_data.rs | 18 +- core/lib/multivm/src/versions/vm_m5/utils.rs | 3 +- core/lib/multivm/src/versions/vm_m5/vm.rs | 3 +- .../src/versions/vm_m5/vm_with_bootloader.rs | 26 +-- core/lib/multivm/src/versions/vm_m6/events.rs | 7 +- .../src/versions/vm_m6/history_recorder.rs | 3 +- .../src/versions/vm_m6/oracles/decommitter.rs | 15 +- .../src/versions/vm_m6/oracles/storage.rs | 5 +- .../versions/vm_m6/oracles/tracer/utils.rs | 3 +- .../vm_m6/oracles/tracer/validation.rs | 33 ++-- .../lib/multivm/src/versions/vm_m6/refunds.rs | 3 +- .../multivm/src/versions/vm_m6/test_utils.rs | 8 +- .../src/versions/vm_m6/transaction_data.rs | 18 +- core/lib/multivm/src/versions/vm_m6/utils.rs | 3 +- core/lib/multivm/src/versions/vm_m6/vm.rs | 4 +- .../src/versions/vm_m6/vm_with_bootloader.rs | 29 ++- .../bootloader_state/l2_block.rs | 5 +- .../bootloader_state/utils.rs | 8 +- .../implementation/bytecode.rs | 8 +- .../vm_refunds_enhancement/old_vm/events.rs | 7 +- .../old_vm/history_recorder.rs | 3 +- .../old_vm/oracles/decommitter.rs | 7 +- .../vm_refunds_enhancement/oracles/storage.rs | 5 +- .../vm_refunds_enhancement/tracers/refunds.rs | 4 +- .../vm_refunds_enhancement/tracers/utils.rs | 3 +- .../types/internals/transaction_data.rs | 20 +- .../types/internals/vm_state.rs | 16 +- .../vm_refunds_enhancement/types/l1_batch.rs | 3 +- .../vm_refunds_enhancement/utils/fee.rs | 10 +- .../vm_refunds_enhancement/utils/l2_blocks.rs | 4 +- .../vm_refunds_enhancement/utils/overhead.rs | 3 +- .../bootloader_state/l2_block.rs | 5 +- .../bootloader_state/utils.rs | 6 +- .../implementation/bytecode.rs | 8 +- .../vm_virtual_blocks/old_vm/events.rs | 7 +- .../old_vm/history_recorder.rs | 3 +- .../old_vm/oracles/decommitter.rs | 7 +- .../old_vm/oracles/storage.rs | 5 +- .../vm_virtual_blocks/tracers/refunds.rs | 6 +- .../vm_virtual_blocks/tracers/utils.rs | 3 +- .../types/internals/transaction_data.rs | 20 +- .../types/internals/vm_state.rs | 16 +- .../vm_virtual_blocks/types/l1_batch_env.rs | 3 +- .../versions/vm_virtual_blocks/utils/fee.rs | 10 +- .../vm_virtual_blocks/utils/l2_blocks.rs | 4 +- .../vm_virtual_blocks/utils/overhead.rs | 3 +- core/lib/state/Cargo.toml | 1 - core/lib/state/src/storage_factory/mod.rs | 8 +- core/lib/tee_verifier/Cargo.toml | 1 - core/lib/tee_verifier/src/lib.rs | 10 +- core/lib/types/src/abi.rs | 3 +- core/lib/types/src/block.rs | 5 +- core/lib/types/src/commitment/mod.rs | 2 +- core/lib/types/src/fee.rs | 9 +- core/lib/types/src/fee_model.rs | 5 +- core/lib/types/src/l1/mod.rs | 15 +- core/lib/types/src/l2_to_l1_log.rs | 5 +- core/lib/types/src/lib.rs | 14 +- core/lib/types/src/protocol_upgrade.rs | 5 +- core/lib/types/src/snapshots.rs | 6 +- core/lib/types/src/storage/log.rs | 2 +- core/lib/types/src/storage/mod.rs | 3 +- core/lib/types/src/transaction_request.rs | 10 +- core/lib/types/src/tx/execute.rs | 7 +- core/lib/types/src/utils.rs | 5 +- core/lib/utils/Cargo.toml | 6 - core/lib/utils/src/bytecode.rs | 20 +- core/lib/utils/src/convert.rs | 185 ------------------ core/lib/utils/src/format.rs | 78 -------- core/lib/utils/src/lib.rs | 6 - core/lib/utils/src/misc.rs | 55 ------ core/lib/utils/src/time.rs | 19 -- core/lib/vm_executor/src/oneshot/block.rs | 11 +- core/lib/vm_executor/src/oneshot/mod.rs | 4 +- .../src/execution_sandbox/storage.rs | 3 +- core/node/api_server/src/testonly.rs | 3 +- core/node/api_server/src/tx_sender/mod.rs | 3 +- .../api_server/src/web3/namespaces/eth.rs | 6 +- .../api_server/src/web3/namespaces/zks.rs | 3 +- core/node/api_server/src/web3/tests/mod.rs | 10 +- core/node/api_server/src/web3/tests/vm.rs | 3 +- core/node/base_token_adjuster/Cargo.toml | 1 - core/node/commitment_generator/Cargo.toml | 1 - core/node/commitment_generator/src/lib.rs | 2 +- core/node/commitment_generator/src/utils.rs | 11 +- core/node/consensus/Cargo.toml | 1 - core/node/da_dispatcher/Cargo.toml | 1 - core/node/eth_sender/Cargo.toml | 1 - core/node/eth_sender/src/eth_tx_manager.rs | 16 +- core/node/eth_sender/src/metrics.rs | 15 +- core/node/genesis/src/lib.rs | 3 +- core/node/genesis/src/utils.rs | 7 +- core/node/metadata_calculator/Cargo.toml | 1 - .../metadata_calculator/src/api_server/mod.rs | 3 +- core/node/metadata_calculator/src/metrics.rs | 19 +- core/node/metadata_calculator/src/tests.rs | 5 +- core/node/node_sync/src/client.rs | 4 +- core/node/node_sync/src/external_io.rs | 5 +- core/node/node_sync/src/genesis.rs | 9 +- core/node/proof_data_handler/Cargo.toml | 1 - .../state_keeper/src/executor/tests/tester.rs | 2 +- core/node/state_keeper/src/io/mempool.rs | 5 +- core/node/state_keeper/src/io/persistence.rs | 8 +- .../io/seal_logic/l2_block_seal_subtasks.rs | 11 +- .../state_keeper/src/io/seal_logic/mod.rs | 2 +- core/node/state_keeper/src/io/tests/mod.rs | 7 +- core/node/state_keeper/src/mempool_actor.rs | 9 +- .../state_keeper/src/seal_criteria/mod.rs | 17 +- core/node/state_keeper/src/testonly/mod.rs | 8 +- core/node/state_keeper/src/tests/mod.rs | 16 +- core/node/state_keeper/src/utils.rs | 14 ++ core/node/test_utils/Cargo.toml | 1 - core/node/test_utils/src/lib.rs | 2 +- core/node/vm_runner/src/impls/bwip.rs | 33 +++- core/node/vm_runner/src/tests/mod.rs | 5 +- core/tests/test_account/src/lib.rs | 7 +- core/tests/vm-benchmark/src/vm.rs | 4 +- prover/Cargo.lock | 6 - zkstack_cli/Cargo.lock | 6 - 274 files changed, 1214 insertions(+), 1351 deletions(-) create mode 100644 core/lib/basic_types/src/conversions.rs rename core/lib/{utils => basic_types}/src/serde_wrappers.rs (97%) create mode 100644 core/lib/contracts/src/serde_bytecode.rs delete mode 100644 core/lib/utils/src/convert.rs delete mode 100644 core/lib/utils/src/format.rs delete mode 100644 core/lib/utils/src/misc.rs delete mode 100644 core/lib/utils/src/time.rs diff --git a/Cargo.lock b/Cargo.lock index 04a863448d69..bdd2f84527b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3254,7 +3254,6 @@ dependencies = [ "zksync_protobuf", "zksync_protobuf_config", "zksync_types", - "zksync_utils", ] [[package]] @@ -10443,7 +10442,6 @@ dependencies = [ "zksync_external_price_api", "zksync_node_fee_model", "zksync_types", - "zksync_utils", ] [[package]] @@ -10557,7 +10555,6 @@ dependencies = [ "zksync_node_test_utils", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_web3_decl", ] @@ -10846,6 +10843,7 @@ dependencies = [ name = "zksync_contracts" version = "0.1.0" dependencies = [ + "bincode", "envy", "ethabi", "hex", @@ -10883,7 +10881,6 @@ dependencies = [ "sha2 0.10.8", "thiserror", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -10965,7 +10962,6 @@ dependencies = [ "zksync_da_client", "zksync_dal", "zksync_types", - "zksync_utils", ] [[package]] @@ -11083,7 +11079,6 @@ dependencies = [ "zksync_prover_interface", "zksync_shared_metrics", "zksync_types", - "zksync_utils", ] [[package]] @@ -11169,7 +11164,6 @@ dependencies = [ "zksync_state_keeper", "zksync_storage", "zksync_types", - "zksync_utils", "zksync_vlog", "zksync_web3_decl", ] @@ -11354,7 +11348,6 @@ dependencies = [ "zksync_storage", "zksync_system_constants", "zksync_types", - "zksync_utils", ] [[package]] @@ -11389,7 +11382,6 @@ dependencies = [ "zksync_shared_metrics", "zksync_storage", "zksync_types", - "zksync_utils", ] [[package]] @@ -11530,7 +11522,6 @@ dependencies = [ "zksync_system_constants", "zksync_test_account", "zksync_types", - "zksync_utils", "zksync_vm_executor", "zksync_vm_interface", "zksync_web3_decl", @@ -11731,7 +11722,6 @@ dependencies = [ "zksync_merkle_tree", "zksync_system_constants", "zksync_types", - "zksync_utils", "zksync_vm_interface", ] @@ -11795,7 +11785,6 @@ dependencies = [ "zksync_object_store", "zksync_prover_interface", "zksync_types", - "zksync_utils", "zksync_vm_executor", ] @@ -11933,7 +11922,6 @@ dependencies = [ "zksync_protobuf_config", "zksync_storage", "zksync_types", - "zksync_utils", "zksync_vlog", ] @@ -12010,7 +11998,6 @@ dependencies = [ "zksync_shared_metrics", "zksync_storage", "zksync_types", - "zksync_utils", "zksync_vm_interface", ] @@ -12072,7 +12059,6 @@ version = "0.1.0" dependencies = [ "once_cell", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -12116,7 +12102,6 @@ dependencies = [ "zksync_multivm", "zksync_prover_interface", "zksync_types", - "zksync_utils", ] [[package]] @@ -12174,16 +12159,10 @@ version = "0.1.0" dependencies = [ "anyhow", "assert_matches", - "bigdecimal", - "bincode", "const-decoder", "futures 0.3.31", - "hex", - "num", "once_cell", - "rand 0.8.5", "reqwest 0.12.9", - "serde", "serde_json", "thiserror", "tokio", diff --git a/core/bin/external_node/Cargo.toml b/core/bin/external_node/Cargo.toml index 4c8f73eda94d..9979e988bbbb 100644 --- a/core/bin/external_node/Cargo.toml +++ b/core/bin/external_node/Cargo.toml @@ -20,7 +20,6 @@ zksync_config.workspace = true zksync_protobuf_config.workspace = true zksync_eth_client.workspace = true zksync_storage.workspace = true -zksync_utils.workspace = true zksync_state.workspace = true zksync_contracts.workspace = true zksync_l1_contract_interface.workspace = true diff --git a/core/bin/genesis_generator/Cargo.toml b/core/bin/genesis_generator/Cargo.toml index 1ece9ea09d2e..d0bbcb668713 100644 --- a/core/bin/genesis_generator/Cargo.toml +++ b/core/bin/genesis_generator/Cargo.toml @@ -15,7 +15,6 @@ publish = false zksync_config.workspace = true zksync_env_config.workspace = true zksync_protobuf_config.workspace = true -zksync_utils.workspace = true zksync_types.workspace = true zksync_core_leftovers.workspace = true zksync_dal.workspace = true diff --git a/core/bin/system-constants-generator/src/utils.rs b/core/bin/system-constants-generator/src/utils.rs index 16167975cf0e..2c08de7970b8 100644 --- a/core/bin/system-constants-generator/src/utils.rs +++ b/core/bin/system-constants-generator/src/utils.rs @@ -22,12 +22,13 @@ use zksync_multivm::{ }; use zksync_types::{ block::L2BlockHasher, ethabi::Token, fee::Fee, fee_model::BatchFeeInput, l1::L1Tx, l2::L2Tx, - utils::storage_key_for_eth_balance, AccountTreeId, Address, Execute, K256PrivateKey, - L1BatchNumber, L1TxCommonData, L2BlockNumber, L2ChainId, Nonce, ProtocolVersionId, StorageKey, - Transaction, BOOTLOADER_ADDRESS, SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_GAS_PRICE_POSITION, - SYSTEM_CONTEXT_TX_ORIGIN_POSITION, U256, ZKPORTER_IS_AVAILABLE, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, Execute, + K256PrivateKey, L1BatchNumber, L1TxCommonData, L2BlockNumber, L2ChainId, Nonce, + ProtocolVersionId, StorageKey, Transaction, BOOTLOADER_ADDRESS, SYSTEM_CONTEXT_ADDRESS, + SYSTEM_CONTEXT_GAS_PRICE_POSITION, SYSTEM_CONTEXT_TX_ORIGIN_POSITION, U256, + ZKPORTER_IS_AVAILABLE, }; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use crate::intrinsic_costs::VmSpentResourcesResult; @@ -65,7 +66,7 @@ pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy = Lazy::new(|| { let hash = hash_bytecode(&bytecode); let bootloader = SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }; @@ -74,7 +75,7 @@ pub static GAS_TEST_SYSTEM_CONTRACTS: Lazy = Lazy::new(|| { BaseSystemContracts { default_aa: SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }, bootloader, @@ -214,7 +215,7 @@ pub(super) fn execute_internal_transfer_test() -> u32 { let bytecode = read_bootloader_test_code("transfer_test"); let hash = hash_bytecode(&bytecode); let bootloader = SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }; @@ -223,7 +224,7 @@ pub(super) fn execute_internal_transfer_test() -> u32 { let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); let hash = hash_bytecode(&bytecode); let default_aa = SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }; @@ -263,7 +264,11 @@ pub(super) fn execute_internal_transfer_test() -> u32 { } input }; - let input: Vec<_> = bytes_to_be_words(input).into_iter().enumerate().collect(); + let input: Vec<_> = input + .chunks(32) + .map(U256::from_big_endian) + .enumerate() + .collect(); let tracer_result = Rc::new(RefCell::new(0)); let tracer = SpecialBootloaderTracer { diff --git a/core/bin/zksync_server/Cargo.toml b/core/bin/zksync_server/Cargo.toml index 031183924064..4cf028be8210 100644 --- a/core/bin/zksync_server/Cargo.toml +++ b/core/bin/zksync_server/Cargo.toml @@ -17,7 +17,6 @@ zksync_env_config.workspace = true zksync_eth_client.workspace = true zksync_protobuf_config.workspace = true zksync_storage.workspace = true -zksync_utils.workspace = true zksync_types.workspace = true zksync_core_leftovers.workspace = true zksync_node_genesis.workspace = true diff --git a/core/lib/basic_types/src/conversions.rs b/core/lib/basic_types/src/conversions.rs new file mode 100644 index 000000000000..544d4adc08f8 --- /dev/null +++ b/core/lib/basic_types/src/conversions.rs @@ -0,0 +1,36 @@ +//! Conversions between basic types. + +use crate::{Address, H256, U256}; + +pub fn h256_to_u256(num: H256) -> U256 { + U256::from_big_endian(num.as_bytes()) +} + +pub fn address_to_h256(address: &Address) -> H256 { + let mut buffer = [0u8; 32]; + buffer[12..].copy_from_slice(address.as_bytes()); + H256(buffer) +} + +pub fn address_to_u256(address: &Address) -> U256 { + h256_to_u256(address_to_h256(address)) +} + +pub fn u256_to_h256(num: U256) -> H256 { + let mut bytes = [0u8; 32]; + num.to_big_endian(&mut bytes); + H256::from_slice(&bytes) +} + +/// Converts `U256` value into an [`Address`]. +pub fn u256_to_address(value: &U256) -> Address { + let mut bytes = [0u8; 32]; + value.to_big_endian(&mut bytes); + + Address::from_slice(&bytes[12..]) +} + +/// Converts `H256` value into an [`Address`]. +pub fn h256_to_address(value: &H256) -> Address { + Address::from_slice(&value.as_bytes()[12..]) +} diff --git a/core/lib/basic_types/src/lib.rs b/core/lib/basic_types/src/lib.rs index 1b462fdf77d1..5776416265d2 100644 --- a/core/lib/basic_types/src/lib.rs +++ b/core/lib/basic_types/src/lib.rs @@ -22,21 +22,32 @@ pub use ethabi::{ }; use serde::{de, Deserialize, Deserializer, Serialize}; +pub use self::conversions::{ + address_to_h256, address_to_u256, h256_to_address, h256_to_u256, u256_to_address, u256_to_h256, +}; + #[macro_use] mod macros; pub mod basic_fri_types; pub mod commitment; +mod conversions; pub mod network; pub mod protocol_version; pub mod prover_dal; pub mod pubdata_da; pub mod secrets; +pub mod serde_wrappers; pub mod settlement; pub mod tee_types; pub mod url; pub mod vm; pub mod web3; +/// Computes `ceil(a / b)`. +pub fn ceil_div_u256(a: U256, b: U256) -> U256 { + (a + b - U256::from(1)) / b +} + /// Parses H256 from a slice of bytes. pub fn parse_h256(bytes: &[u8]) -> anyhow::Result { Ok(<[u8; 32]>::try_from(bytes).context("invalid size")?.into()) diff --git a/core/lib/utils/src/serde_wrappers.rs b/core/lib/basic_types/src/serde_wrappers.rs similarity index 97% rename from core/lib/utils/src/serde_wrappers.rs rename to core/lib/basic_types/src/serde_wrappers.rs index cb9687a8a504..4cc470493dce 100644 --- a/core/lib/utils/src/serde_wrappers.rs +++ b/core/lib/basic_types/src/serde_wrappers.rs @@ -1,3 +1,5 @@ +//! Generic `serde` helpers. + use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; /// Trait for specifying prefix for bytes to hex serialization @@ -61,9 +63,7 @@ pub type ZeroPrefixHexSerde = BytesToHexSerde; #[cfg(test)] mod tests { - use serde::{Deserialize, Serialize}; - - use crate::ZeroPrefixHexSerde; + use super::*; #[derive(Serialize, Deserialize, PartialEq, Debug)] struct Execute { diff --git a/core/lib/basic_types/src/web3/mod.rs b/core/lib/basic_types/src/web3/mod.rs index aa7c49670333..e6d3cab37273 100644 --- a/core/lib/basic_types/src/web3/mod.rs +++ b/core/lib/basic_types/src/web3/mod.rs @@ -73,6 +73,14 @@ pub fn keccak256(bytes: &[u8]) -> [u8; 32] { output } +/// Hashes concatenation of the two provided hashes using `keccak256`. +pub fn keccak256_concat(hash1: H256, hash2: H256) -> H256 { + let mut bytes = [0_u8; 64]; + bytes[..32].copy_from_slice(hash1.as_bytes()); + bytes[32..].copy_from_slice(hash2.as_bytes()); + H256(keccak256(&bytes)) +} + // `Bytes`: from `web3::types::bytes` /// Raw bytes wrapper diff --git a/core/lib/constants/Cargo.toml b/core/lib/constants/Cargo.toml index b741b5734902..bc4d1f7bb57f 100644 --- a/core/lib/constants/Cargo.toml +++ b/core/lib/constants/Cargo.toml @@ -12,6 +12,5 @@ categories.workspace = true [dependencies] zksync_basic_types.workspace = true -zksync_utils.workspace = true once_cell.workspace = true diff --git a/core/lib/constants/src/trusted_slots.rs b/core/lib/constants/src/trusted_slots.rs index e5a626d49036..d66b2bfd4729 100644 --- a/core/lib/constants/src/trusted_slots.rs +++ b/core/lib/constants/src/trusted_slots.rs @@ -1,6 +1,5 @@ use once_cell::sync::Lazy; -use zksync_basic_types::{H256, U256}; -use zksync_utils::h256_to_u256; +use zksync_basic_types::{h256_to_u256, H256, U256}; /// /// Well known-slots (e.g. proxy addresses in popular EIPs). diff --git a/core/lib/contract_verifier/src/tests/mod.rs b/core/lib/contract_verifier/src/tests/mod.rs index 7caa5f32c991..15951e578ff0 100644 --- a/core/lib/contract_verifier/src/tests/mod.rs +++ b/core/lib/contract_verifier/src/tests/mod.rs @@ -7,6 +7,7 @@ use tokio::sync::watch; use zksync_dal::Connection; use zksync_node_test_utils::{create_l1_batch, create_l2_block}; use zksync_types::{ + address_to_h256, contract_verification_api::{CompilerVersions, SourceCodeData, VerificationIncomingRequest}, get_code_key, get_known_code_key, l2::L2Tx, @@ -14,10 +15,7 @@ use zksync_types::{ Execute, L1BatchNumber, L2BlockNumber, ProtocolVersion, StorageLog, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::{ - address_to_h256, - bytecode::{hash_bytecode, hash_evm_bytecode}, -}; +use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use zksync_vm_interface::{tracer::ValidationTraces, TransactionExecutionMetrics, VmEvent}; use super::*; diff --git a/core/lib/contracts/Cargo.toml b/core/lib/contracts/Cargo.toml index 2b80295cf440..efe37b301e28 100644 --- a/core/lib/contracts/Cargo.toml +++ b/core/lib/contracts/Cargo.toml @@ -19,3 +19,6 @@ serde.workspace = true once_cell.workspace = true hex.workspace = true envy.workspace = true + +[dev-dependencies] +bincode.workspace = true diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs index cb5be504c8a0..ad9f7739ba0d 100644 --- a/core/lib/contracts/src/lib.rs +++ b/core/lib/contracts/src/lib.rs @@ -10,14 +10,12 @@ use std::{ path::{Path, PathBuf}, }; -use ethabi::{ - ethereum_types::{H256, U256}, - Contract, Event, Function, -}; +use ethabi::{ethereum_types::H256, Contract, Event, Function}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, env::Workspace}; +use zksync_utils::{bytecode::hash_bytecode, env::Workspace}; +mod serde_bytecode; pub mod test_contracts; #[derive(Debug, Clone)] @@ -379,7 +377,8 @@ fn read_zbin_bytecode_from_hex_file(bytecode_path: PathBuf) -> Vec { /// Hash of code and code which consists of 32 bytes words #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SystemContractCode { - pub code: Vec, + #[serde(with = "serde_bytecode")] + pub code: Vec, pub hash: H256, } @@ -410,17 +409,15 @@ impl PartialEq for BaseSystemContracts { impl BaseSystemContracts { fn load_with_bootloader(bootloader_bytecode: Vec) -> Self { let hash = hash_bytecode(&bootloader_bytecode); - let bootloader = SystemContractCode { - code: bytes_to_be_words(bootloader_bytecode), + code: bootloader_bytecode, hash, }; let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol); let hash = hash_bytecode(&bytecode); - let default_aa = SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }; @@ -442,7 +439,7 @@ impl BaseSystemContracts { let bytecode = read_sys_contract_bytecode("", "EvmEmulator", ContractLanguage::Yul); let hash = hash_bytecode(&bytecode); self.evm_emulator = Some(SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }); self diff --git a/core/lib/contracts/src/serde_bytecode.rs b/core/lib/contracts/src/serde_bytecode.rs new file mode 100644 index 000000000000..43de12e8ddd1 --- /dev/null +++ b/core/lib/contracts/src/serde_bytecode.rs @@ -0,0 +1,112 @@ +use std::fmt; + +use ethabi::ethereum_types::U256; +use serde::{de, de::SeqAccess, ser, ser::SerializeSeq, Deserializer, Serializer}; + +pub(super) fn serialize(bytes: &[u8], serializer: S) -> Result { + if bytes.len() % 32 != 0 { + return Err(ser::Error::custom("bytecode length is not divisible by 32")); + } + let mut seq = serializer.serialize_seq(Some(bytes.len() / 32))?; + for chunk in bytes.chunks(32) { + let word = U256::from_big_endian(chunk); + seq.serialize_element(&word)?; + } + seq.end() +} + +#[derive(Debug)] +struct SeqVisitor; + +impl<'de> de::Visitor<'de> for SeqVisitor { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "sequence of `U256` words") + } + + fn visit_seq>(self, mut seq: A) -> Result { + let len = seq.size_hint().unwrap_or(0) * 32; + let mut bytes = Vec::with_capacity(len); + while let Some(value) = seq.next_element::()? { + let prev_len = bytes.len(); + bytes.resize(prev_len + 32, 0); + value.to_big_endian(&mut bytes[prev_len..]); + } + Ok(bytes) + } +} + +pub(super) fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + deserializer.deserialize_seq(SeqVisitor) +} + +#[cfg(test)] +mod tests { + use ethabi::ethereum_types::{H256, U256}; + use serde::{Deserialize, Serialize}; + + use crate::SystemContractCode; + + /// Code with legacy serialization logic. + #[derive(Debug, Serialize, Deserialize)] + struct LegacySystemContractCode { + code: Vec, + hash: H256, + } + + impl From<&SystemContractCode> for LegacySystemContractCode { + fn from(value: &SystemContractCode) -> Self { + Self { + code: value.code.chunks(32).map(U256::from_big_endian).collect(), + hash: value.hash, + } + } + } + + fn test_code() -> SystemContractCode { + let mut code = vec![0; 32]; + code.extend_from_slice(&[0; 30]); + code.extend_from_slice(&[0xab, 0xcd]); + code.extend_from_slice(&[0x23; 32]); + + SystemContractCode { + hash: H256::repeat_byte(0x42), + code, + } + } + + #[test] + fn serializing_system_contract_code() { + let system_contract_code = test_code(); + let json = serde_json::to_value(&system_contract_code).unwrap(); + assert_eq!( + json, + serde_json::json!({ + "code": ["0x0", "0xabcd", "0x2323232323232323232323232323232323232323232323232323232323232323"], + "hash": "0x4242424242424242424242424242424242424242424242424242424242424242", + }) + ); + + let legacy_code = LegacySystemContractCode::from(&system_contract_code); + let legacy_json = serde_json::to_value(&legacy_code).unwrap(); + assert_eq!(legacy_json, json); + + let restored: SystemContractCode = serde_json::from_value(json).unwrap(); + assert_eq!(restored.code, system_contract_code.code); + assert_eq!(restored.hash, system_contract_code.hash); + } + + #[test] + fn serializing_system_contract_code_using_bincode() { + let system_contract_code = test_code(); + let bytes = bincode::serialize(&system_contract_code).unwrap(); + let restored: SystemContractCode = bincode::deserialize(&bytes).unwrap(); + assert_eq!(restored.code, system_contract_code.code); + assert_eq!(restored.hash, system_contract_code.hash); + + let legacy_code = LegacySystemContractCode::from(&system_contract_code); + let legacy_bytes = bincode::serialize(&legacy_code).unwrap(); + assert_eq!(legacy_bytes, bytes); + } +} diff --git a/core/lib/crypto_primitives/Cargo.toml b/core/lib/crypto_primitives/Cargo.toml index 7efe5279b598..651609ec7949 100644 --- a/core/lib/crypto_primitives/Cargo.toml +++ b/core/lib/crypto_primitives/Cargo.toml @@ -15,7 +15,6 @@ categories.workspace = true secp256k1 = { workspace = true, features = ["global-context"] } sha2.workspace = true blake2.workspace = true -zksync_utils.workspace = true zksync_basic_types.workspace = true thiserror.workspace = true serde_json.workspace = true diff --git a/core/lib/crypto_primitives/src/packed_eth_signature.rs b/core/lib/crypto_primitives/src/packed_eth_signature.rs index 3d76de73560e..c4a26bf351b4 100644 --- a/core/lib/crypto_primitives/src/packed_eth_signature.rs +++ b/core/lib/crypto_primitives/src/packed_eth_signature.rs @@ -1,7 +1,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use thiserror::Error; -use zksync_basic_types::{web3::keccak256, Address, H256}; -use zksync_utils::ZeroPrefixHexSerde; +use zksync_basic_types::{serde_wrappers::ZeroPrefixHexSerde, web3::keccak256, Address, H256}; use crate::{ ecdsa_signature::{ diff --git a/core/lib/dal/src/blocks_web3_dal.rs b/core/lib/dal/src/blocks_web3_dal.rs index ba843bbf92f3..4699eac4e5eb 100644 --- a/core/lib/dal/src/blocks_web3_dal.rs +++ b/core/lib/dal/src/blocks_web3_dal.rs @@ -11,12 +11,11 @@ use zksync_types::{ web3::{BlockHeader, Bytes}, Bloom, L1BatchNumber, L2BlockNumber, ProtocolVersionId, H160, H256, U256, U64, }; -use zksync_utils::bigdecimal_to_u256; use zksync_vm_interface::Call; use crate::{ models::{ - parse_protocol_version, + bigdecimal_to_u256, parse_protocol_version, storage_block::{ ResolvedL1BatchForL2Block, StorageBlockDetails, StorageL1BatchDetails, LEGACY_BLOCK_GAS_LIMIT, diff --git a/core/lib/dal/src/consensus/conv.rs b/core/lib/dal/src/consensus/conv.rs index f0948adfd1da..3153343d6014 100644 --- a/core/lib/dal/src/consensus/conv.rs +++ b/core/lib/dal/src/consensus/conv.rs @@ -8,15 +8,15 @@ use zksync_types::{ commitment::{L1BatchCommitmentMode, PubdataParams}, ethabi, fee::Fee, + h256_to_u256, l1::{OpProcessingType, PriorityQueueType}, l2::TransactionType, parse_h160, parse_h256, protocol_upgrade::ProtocolUpgradeTxCommonData, transaction_request::PaymasterParams, - Execute, ExecuteTransactionCommon, InputData, L1BatchNumber, L1TxCommonData, L2TxCommonData, - Nonce, PriorityOpId, ProtocolVersionId, Transaction, H256, + u256_to_h256, Execute, ExecuteTransactionCommon, InputData, L1BatchNumber, L1TxCommonData, + L2TxCommonData, Nonce, PriorityOpId, ProtocolVersionId, Transaction, H256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use super::*; diff --git a/core/lib/dal/src/contract_verification_dal.rs b/core/lib/dal/src/contract_verification_dal.rs index 93a4ce2fd35a..0708063dff60 100644 --- a/core/lib/dal/src/contract_verification_dal.rs +++ b/core/lib/dal/src/contract_verification_dal.rs @@ -8,13 +8,13 @@ use std::{ use sqlx::postgres::types::PgInterval; use zksync_db_connection::{error::SqlxContext, instrument::InstrumentExt}; use zksync_types::{ + address_to_h256, contract_verification_api::{ VerificationIncomingRequest, VerificationInfo, VerificationRequest, VerificationRequestStatus, }, web3, Address, CONTRACT_DEPLOYER_ADDRESS, H256, }; -use zksync_utils::address_to_h256; use zksync_vm_interface::VmEvent; use crate::{ diff --git a/core/lib/dal/src/factory_deps_dal.rs b/core/lib/dal/src/factory_deps_dal.rs index 857e2973ae33..424d708da241 100644 --- a/core/lib/dal/src/factory_deps_dal.rs +++ b/core/lib/dal/src/factory_deps_dal.rs @@ -4,7 +4,6 @@ use anyhow::Context as _; use zksync_contracts::{BaseSystemContracts, SystemContractCode}; use zksync_db_connection::{connection::Connection, error::DalResult, instrument::InstrumentExt}; use zksync_types::{L2BlockNumber, H256, U256}; -use zksync_utils::{bytes_to_be_words, bytes_to_chunks}; use crate::Core; @@ -102,7 +101,7 @@ impl FactoryDepsDal<'_, '_> { .context("failed loading bootloader code")? .with_context(|| format!("bootloader code with hash {bootloader_hash:?} should be present in the database"))?; let bootloader_code = SystemContractCode { - code: bytes_to_be_words(bootloader_bytecode), + code: bootloader_bytecode, hash: bootloader_hash, }; @@ -113,7 +112,7 @@ impl FactoryDepsDal<'_, '_> { .with_context(|| format!("default account code with hash {default_aa_hash:?} should be present in the database"))?; let default_aa_code = SystemContractCode { - code: bytes_to_be_words(default_aa_bytecode), + code: default_aa_bytecode, hash: default_aa_hash, }; @@ -125,7 +124,7 @@ impl FactoryDepsDal<'_, '_> { .with_context(|| format!("EVM emulator code with hash {evm_emulator_hash:?} should be present in the database"))?; Some(SystemContractCode { - code: bytes_to_be_words(evm_emulator_bytecode), + code: evm_emulator_bytecode, hash: evm_emulator_hash, }) } else { @@ -140,10 +139,7 @@ impl FactoryDepsDal<'_, '_> { } /// Returns bytecodes for factory deps with the specified `hashes`. - pub async fn get_factory_deps( - &mut self, - hashes: &HashSet, - ) -> HashMap> { + pub async fn get_factory_deps(&mut self, hashes: &HashSet) -> HashMap> { let hashes_as_bytes: Vec<_> = hashes.iter().map(H256::as_bytes).collect(); sqlx::query!( @@ -162,12 +158,7 @@ impl FactoryDepsDal<'_, '_> { .await .unwrap() .into_iter() - .map(|row| { - ( - U256::from_big_endian(&row.bytecode_hash), - bytes_to_chunks(&row.bytecode), - ) - }) + .map(|row| (U256::from_big_endian(&row.bytecode_hash), row.bytecode)) .collect() } diff --git a/core/lib/dal/src/models/mod.rs b/core/lib/dal/src/models/mod.rs index 12e41ac780ad..885dcd46f41f 100644 --- a/core/lib/dal/src/models/mod.rs +++ b/core/lib/dal/src/models/mod.rs @@ -1,6 +1,8 @@ pub mod storage_block; + +use bigdecimal::{num_bigint::BigUint, BigDecimal}; use zksync_db_connection::error::SqlxContext; -use zksync_types::ProtocolVersionId; +use zksync_types::{ProtocolVersionId, U256}; mod call; pub mod storage_base_token_ratio; @@ -24,3 +26,26 @@ pub(crate) fn parse_protocol_version(raw: i32) -> sqlx::Result BigDecimal { + let mut u32_digits = vec![0_u32; 8]; + // `u64_digit`s from `U256` are little-endian + for (i, &u64_digit) in value.0.iter().enumerate() { + u32_digits[2 * i] = u64_digit as u32; + u32_digits[2 * i + 1] = (u64_digit >> 32) as u32; + } + let value = BigUint::new(u32_digits); + BigDecimal::new(value.into(), 0) +} + +/// Converts `BigUint` value into the corresponding `U256` value. +fn biguint_to_u256(value: BigUint) -> U256 { + let bytes = value.to_bytes_le(); + U256::from_little_endian(&bytes) +} + +/// Converts `BigDecimal` value into the corresponding `U256` value. +pub(crate) fn bigdecimal_to_u256(value: BigDecimal) -> U256 { + let bigint = value.with_scale(0).into_bigint_and_exponent().0; + biguint_to_u256(bigint.to_biguint().unwrap()) +} diff --git a/core/lib/dal/src/models/storage_transaction.rs b/core/lib/dal/src/models/storage_transaction.rs index b55126800cce..cceebc85cf2b 100644 --- a/core/lib/dal/src/models/storage_transaction.rs +++ b/core/lib/dal/src/models/storage_transaction.rs @@ -6,6 +6,7 @@ use sqlx::types::chrono::{DateTime, NaiveDateTime, Utc}; use zksync_types::{ api::{self, TransactionDetails, TransactionReceipt, TransactionStatus}, fee::Fee, + h256_to_address, l1::{OpProcessingType, PriorityQueueType}, l2::TransactionType, protocol_upgrade::ProtocolUpgradeTxCommonData, @@ -16,11 +17,10 @@ use zksync_types::{ TransactionTimeRangeConstraint, EIP_1559_TX_TYPE, EIP_2930_TX_TYPE, EIP_712_TX_TYPE, H160, H256, PRIORITY_OPERATION_L2_TX_TYPE, PROTOCOL_UPGRADE_TX_TYPE, U256, U64, }; -use zksync_utils::{bigdecimal_to_u256, h256_to_account_address}; use zksync_vm_interface::Call; use super::call::{LegacyCall, LegacyMixedCall}; -use crate::BigDecimal; +use crate::{models::bigdecimal_to_u256, BigDecimal}; #[derive(Debug, Clone, sqlx::FromRow)] #[cfg_attr(test, derive(Default))] @@ -403,7 +403,7 @@ impl From for TransactionReceipt { ), contract_address: storage_receipt .contract_address - .map(|addr| h256_to_account_address(&H256::from_slice(&addr))), + .map(|addr| h256_to_address(&H256::from_slice(&addr))), logs: vec![], l2_to_l1_logs: vec![], status, diff --git a/core/lib/dal/src/models/tests.rs b/core/lib/dal/src/models/tests.rs index b4949dc101d6..c30c84702b13 100644 --- a/core/lib/dal/src/models/tests.rs +++ b/core/lib/dal/src/models/tests.rs @@ -1,4 +1,6 @@ +use bigdecimal::num_bigint::BigInt; use chrono::Utc; +use rand::{prelude::StdRng, Rng, SeedableRng}; use zksync_types::{ fee::Fee, l1::{OpProcessingType, PriorityQueueType}, @@ -7,9 +9,9 @@ use zksync_types::{ Address, Execute, ExecuteTransactionCommon, Transaction, EIP_1559_TX_TYPE, EIP_2930_TX_TYPE, EIP_712_TX_TYPE, H160, H256, PRIORITY_OPERATION_L2_TX_TYPE, PROTOCOL_UPGRADE_TX_TYPE, U256, }; -use zksync_utils::bigdecimal_to_u256; -use crate::{models::storage_transaction::StorageTransaction, BigDecimal}; +use super::*; +use crate::models::storage_transaction::StorageTransaction; fn default_execute() -> Execute { Execute { @@ -96,6 +98,49 @@ fn l2_storage_tx(tx_format: i32) -> StorageTransaction { } } +#[test] +fn test_u256_to_bigdecimal() { + const RNG_SEED: u64 = 123; + + let mut rng = StdRng::seed_from_u64(RNG_SEED); + // Small values. + for _ in 0..10_000 { + let value: u64 = rng.gen(); + let expected = BigDecimal::from(value); + assert_eq!(u256_to_big_decimal(value.into()), expected); + } + + // Arbitrary values + for _ in 0..10_000 { + let u64_digits: [u64; 4] = rng.gen(); + let value = u64_digits + .iter() + .enumerate() + .map(|(i, &digit)| U256::from(digit) << (i * 64)) + .fold(U256::zero(), |acc, x| acc + x); + let expected_value = u64_digits + .iter() + .enumerate() + .map(|(i, &digit)| BigInt::from(digit) << (i * 64)) + .fold(BigInt::from(0), |acc, x| acc + x); + assert_eq!( + u256_to_big_decimal(value), + BigDecimal::new(expected_value, 0) + ); + } +} + +#[test] +fn test_bigdecimal_to_u256() { + let value = BigDecimal::from(100u32); + let expected = U256::from(100u32); + assert_eq!(bigdecimal_to_u256(value), expected); + + let value = BigDecimal::new(BigInt::from(100), -2); + let expected = U256::from(10000u32); + assert_eq!(bigdecimal_to_u256(value), expected); +} + #[test] fn storage_tx_to_l1_tx() { let stx = l1_storage_tx(); diff --git a/core/lib/dal/src/storage_web3_dal.rs b/core/lib/dal/src/storage_web3_dal.rs index 10d2cfe61525..794f49c59ac4 100644 --- a/core/lib/dal/src/storage_web3_dal.rs +++ b/core/lib/dal/src/storage_web3_dal.rs @@ -6,12 +6,11 @@ use zksync_db_connection::{ instrument::{InstrumentExt, Instrumented}, }; use zksync_types::{ - get_code_key, get_nonce_key, + get_code_key, get_nonce_key, h256_to_u256, utils::{decompose_full_nonce, storage_key_for_standard_token_balance}, AccountTreeId, Address, L1BatchNumber, L2BlockNumber, Nonce, StorageKey, FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH, H256, U256, }; -use zksync_utils::h256_to_u256; use crate::{models::storage_block::ResolvedL1BatchForL2Block, Core, CoreDal}; diff --git a/core/lib/dal/src/transactions_dal.rs b/core/lib/dal/src/transactions_dal.rs index 9c0889ebfc75..a5dfb8932ddb 100644 --- a/core/lib/dal/src/transactions_dal.rs +++ b/core/lib/dal/src/transactions_dal.rs @@ -15,15 +15,15 @@ use zksync_types::{ L1BlockNumber, L2BlockNumber, PriorityOpId, ProtocolVersionId, Transaction, TransactionTimeRangeConstraint, H256, PROTOCOL_UPGRADE_TX_TYPE, U256, }; -use zksync_utils::u256_to_big_decimal; use zksync_vm_interface::{ tracer::ValidationTraces, Call, TransactionExecutionMetrics, TransactionExecutionResult, TxExecutionStatus, }; use crate::{ - models::storage_transaction::{ - parse_call_trace, serialize_call_into_bytes, StorageTransaction, + models::{ + storage_transaction::{parse_call_trace, serialize_call_into_bytes, StorageTransaction}, + u256_to_big_decimal, }, Core, CoreDal, }; diff --git a/core/lib/merkle_tree/Cargo.toml b/core/lib/merkle_tree/Cargo.toml index 579350bccf4e..e615258ba646 100644 --- a/core/lib/merkle_tree/Cargo.toml +++ b/core/lib/merkle_tree/Cargo.toml @@ -16,7 +16,6 @@ zksync_types.workspace = true zksync_crypto_primitives.workspace = true zksync_storage.workspace = true zksync_prover_interface.workspace = true -zksync_utils.workspace = true anyhow.workspace = true leb128.workspace = true diff --git a/core/lib/multivm/src/glue/types/vm/block_context_mode.rs b/core/lib/multivm/src/glue/types/vm/block_context_mode.rs index 094339705e14..66634e504386 100644 --- a/core/lib/multivm/src/glue/types/vm/block_context_mode.rs +++ b/core/lib/multivm/src/glue/types/vm/block_context_mode.rs @@ -1,4 +1,4 @@ -use zksync_utils::h256_to_u256; +use zksync_types::h256_to_u256; use crate::glue::GlueFrom; diff --git a/core/lib/multivm/src/glue/types/vm/storage_log.rs b/core/lib/multivm/src/glue/types/vm/storage_log.rs index 322bc491e9ab..5f79ca9e9e15 100644 --- a/core/lib/multivm/src/glue/types/vm/storage_log.rs +++ b/core/lib/multivm/src/glue/types/vm/storage_log.rs @@ -1,7 +1,6 @@ use zksync_types::{ - zk_evm_types::LogQuery, StorageLog, StorageLogQuery, StorageLogWithPreviousValue, + u256_to_h256, zk_evm_types::LogQuery, StorageLog, StorageLogQuery, StorageLogWithPreviousValue, }; -use zksync_utils::u256_to_h256; use crate::glue::{GlueFrom, GlueInto}; diff --git a/core/lib/multivm/src/glue/types/zk_evm_1_3_1.rs b/core/lib/multivm/src/glue/types/zk_evm_1_3_1.rs index dfe1121c04ec..08556b7b901a 100644 --- a/core/lib/multivm/src/glue/types/zk_evm_1_3_1.rs +++ b/core/lib/multivm/src/glue/types/zk_evm_1_3_1.rs @@ -1,4 +1,4 @@ -use zksync_utils::u256_to_h256; +use zksync_types::u256_to_h256; use crate::glue::{GlueFrom, GlueInto}; diff --git a/core/lib/multivm/src/glue/types/zk_evm_1_3_3.rs b/core/lib/multivm/src/glue/types/zk_evm_1_3_3.rs index 4c554c1bd53d..ab13de140cfb 100644 --- a/core/lib/multivm/src/glue/types/zk_evm_1_3_3.rs +++ b/core/lib/multivm/src/glue/types/zk_evm_1_3_3.rs @@ -2,8 +2,10 @@ use zk_evm_1_3_3::{ aux_structures::{LogQuery as LogQuery_1_3_3, Timestamp as Timestamp_1_3_3}, zkevm_opcode_defs::FarCallOpcode as FarCallOpcode_1_3_3, }; -use zksync_types::zk_evm_types::{FarCallOpcode, LogQuery, Timestamp}; -use zksync_utils::u256_to_h256; +use zksync_types::{ + u256_to_h256, + zk_evm_types::{FarCallOpcode, LogQuery, Timestamp}, +}; use crate::glue::{GlueFrom, GlueInto}; diff --git a/core/lib/multivm/src/glue/types/zk_evm_1_4_0.rs b/core/lib/multivm/src/glue/types/zk_evm_1_4_0.rs index 5af0e57c4bf9..c25a19b1aa3d 100644 --- a/core/lib/multivm/src/glue/types/zk_evm_1_4_0.rs +++ b/core/lib/multivm/src/glue/types/zk_evm_1_4_0.rs @@ -1,4 +1,4 @@ -use zksync_utils::u256_to_h256; +use zksync_types::u256_to_h256; use crate::glue::GlueFrom; diff --git a/core/lib/multivm/src/glue/types/zk_evm_1_4_1.rs b/core/lib/multivm/src/glue/types/zk_evm_1_4_1.rs index 933eafbb0354..6a8138bc2f24 100644 --- a/core/lib/multivm/src/glue/types/zk_evm_1_4_1.rs +++ b/core/lib/multivm/src/glue/types/zk_evm_1_4_1.rs @@ -2,8 +2,10 @@ use zk_evm_1_4_1::{ aux_structures::{LogQuery as LogQuery_1_4_1, Timestamp as Timestamp_1_4_1}, zkevm_opcode_defs::FarCallOpcode as FarCallOpcode_1_4_1, }; -use zksync_types::zk_evm_types::{FarCallOpcode, LogQuery, Timestamp}; -use zksync_utils::u256_to_h256; +use zksync_types::{ + u256_to_h256, + zk_evm_types::{FarCallOpcode, LogQuery, Timestamp}, +}; use crate::glue::{GlueFrom, GlueInto}; diff --git a/core/lib/multivm/src/glue/types/zk_evm_1_5_0.rs b/core/lib/multivm/src/glue/types/zk_evm_1_5_0.rs index eb1c8e1dd7e8..343843503bdd 100644 --- a/core/lib/multivm/src/glue/types/zk_evm_1_5_0.rs +++ b/core/lib/multivm/src/glue/types/zk_evm_1_5_0.rs @@ -1,4 +1,4 @@ -use zksync_utils::u256_to_h256; +use zksync_types::u256_to_h256; use crate::glue::{GlueFrom, GlueInto}; diff --git a/core/lib/multivm/src/pubdata_builders/tests.rs b/core/lib/multivm/src/pubdata_builders/tests.rs index bc24b8e47346..b06cb9405aa7 100644 --- a/core/lib/multivm/src/pubdata_builders/tests.rs +++ b/core/lib/multivm/src/pubdata_builders/tests.rs @@ -1,8 +1,7 @@ use zksync_types::{ - writes::StateDiffRecord, Address, ProtocolVersionId, ACCOUNT_CODE_STORAGE_ADDRESS, - BOOTLOADER_ADDRESS, + u256_to_h256, writes::StateDiffRecord, Address, ProtocolVersionId, + ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, }; -use zksync_utils::u256_to_h256; use super::{rollup::RollupPubdataBuilder, validium::ValidiumPubdataBuilder}; use crate::interface::pubdata::{L1MessengerL2ToL1Log, PubdataBuilder, PubdataInput}; diff --git a/core/lib/multivm/src/tracers/prestate_tracer/mod.rs b/core/lib/multivm/src/tracers/prestate_tracer/mod.rs index e8a7cc2cc420..363480c016bf 100644 --- a/core/lib/multivm/src/tracers/prestate_tracer/mod.rs +++ b/core/lib/multivm/src/tracers/prestate_tracer/mod.rs @@ -2,10 +2,9 @@ use std::{collections::HashMap, fmt, sync::Arc}; use once_cell::sync::OnceCell; use zksync_types::{ - get_code_key, get_nonce_key, web3::keccak256, AccountTreeId, Address, StorageKey, StorageValue, - H160, H256, L2_BASE_TOKEN_ADDRESS, U256, + address_to_h256, get_code_key, get_nonce_key, h256_to_u256, web3::keccak256, AccountTreeId, + Address, StorageKey, StorageValue, H160, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::{address_to_h256, h256_to_u256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/tracers/validator/mod.rs b/core/lib/multivm/src/tracers/validator/mod.rs index a095be9f3748..88249467a575 100644 --- a/core/lib/multivm/src/tracers/validator/mod.rs +++ b/core/lib/multivm/src/tracers/validator/mod.rs @@ -10,9 +10,9 @@ use zksync_system_constants::{ L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, }; use zksync_types::{ - vm::VmVersion, web3::keccak256, AccountTreeId, Address, StorageKey, H256, U256, + address_to_u256, u256_to_h256, vm::VmVersion, web3::keccak256, AccountTreeId, Address, + StorageKey, H256, U256, }; -use zksync_utils::{address_to_u256, be_bytes_to_safe_address, u256_to_h256}; use zksync_vm_interface::{ tracer::{TimestampAsserterParams, ValidationTraces}, L1BatchEnv, @@ -25,6 +25,7 @@ use crate::{ storage::{StoragePtr, WriteStorage}, tracer::{ValidationParams, ViolatedValidationRule}, }, + utils::bytecode::be_bytes_to_safe_address, }; mod types; diff --git a/core/lib/multivm/src/tracers/validator/vm_1_4_1/mod.rs b/core/lib/multivm/src/tracers/validator/vm_1_4_1/mod.rs index d1ddb2b44c80..3b5636c1c528 100644 --- a/core/lib/multivm/src/tracers/validator/vm_1_4_1/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_1_4_1/mod.rs @@ -3,8 +3,9 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, +}; use crate::{ interface::{ @@ -48,7 +49,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -115,7 +116,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/tracers/validator/vm_1_4_2/mod.rs b/core/lib/multivm/src/tracers/validator/vm_1_4_2/mod.rs index a51644ff9ea2..0a48792aaa9e 100644 --- a/core/lib/multivm/src/tracers/validator/vm_1_4_2/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_1_4_2/mod.rs @@ -3,8 +3,9 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, +}; use crate::{ interface::{ @@ -48,7 +49,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -115,7 +116,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/tracers/validator/vm_boojum_integration/mod.rs b/core/lib/multivm/src/tracers/validator/vm_boojum_integration/mod.rs index 7f9767a5e632..da6ffd4948cf 100644 --- a/core/lib/multivm/src/tracers/validator/vm_boojum_integration/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_boojum_integration/mod.rs @@ -3,8 +3,9 @@ use zk_evm_1_4_0::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, +}; use crate::{ interface::{ @@ -48,7 +49,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -115,7 +116,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs index d3dc7fd87c42..3c819384137f 100644 --- a/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_latest/mod.rs @@ -3,8 +3,10 @@ use zk_evm_1_5_0::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256, U256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, + U256, +}; use crate::{ interface::{ @@ -48,7 +50,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -161,7 +163,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs b/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs index 0badd7c58775..ea95c567181e 100644 --- a/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_refunds_enhancement/mod.rs @@ -3,8 +3,9 @@ use zk_evm_1_3_3::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, +}; use crate::{ interface::{ @@ -48,7 +49,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -115,7 +116,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/tracers/validator/vm_virtual_blocks/mod.rs b/core/lib/multivm/src/tracers/validator/vm_virtual_blocks/mod.rs index 86a639915c9d..94f31ddf138d 100644 --- a/core/lib/multivm/src/tracers/validator/vm_virtual_blocks/mod.rs +++ b/core/lib/multivm/src/tracers/validator/vm_virtual_blocks/mod.rs @@ -3,8 +3,9 @@ use zk_evm_1_3_3::{ zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode}, }; use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS; -use zksync_types::{get_code_key, AccountTreeId, StorageKey, H256}; -use zksync_utils::{h256_to_account_address, u256_to_account_address, u256_to_h256}; +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, AccountTreeId, StorageKey, H256, +}; use crate::{ interface::{ @@ -48,7 +49,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -115,7 +116,7 @@ impl ValidationTracer { let value = storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/utils/bytecode.rs b/core/lib/multivm/src/utils/bytecode.rs index 260749b44f3c..c1937e992990 100644 --- a/core/lib/multivm/src/utils/bytecode.rs +++ b/core/lib/multivm/src/utils/bytecode.rs @@ -1,10 +1,51 @@ use std::collections::HashMap; -use zksync_types::ethabi::{self, Token}; +use zksync_types::{ + ethabi::{self, Token}, + Address, H256, U256, +}; use zksync_utils::bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}; use crate::interface::CompressedBytecodeInfo; +pub(crate) fn be_chunks_to_h256_words(chunks: Vec<[u8; 32]>) -> Vec { + chunks.into_iter().map(|el| H256::from_slice(&el)).collect() +} + +pub(crate) fn be_words_to_bytes(words: &[U256]) -> Vec { + words + .iter() + .flat_map(|w| { + let mut bytes = [0u8; 32]; + w.to_big_endian(&mut bytes); + bytes + }) + .collect() +} + +pub(crate) fn bytes_to_be_words(bytes: &[u8]) -> Vec { + assert_eq!( + bytes.len() % 32, + 0, + "Bytes must be divisible by 32 to split into chunks" + ); + bytes.chunks(32).map(U256::from_big_endian).collect() +} + +pub(crate) fn be_bytes_to_safe_address(bytes: &[u8]) -> Option
{ + if bytes.len() < 20 { + return None; + } + + let (zero_bytes, address_bytes) = bytes.split_at(bytes.len() - 20); + + if zero_bytes.iter().any(|b| *b != 0) { + None + } else { + Some(Address::from_slice(address_bytes)) + } +} + #[derive(Debug, thiserror::Error)] pub(crate) enum FailedToCompressBytecodeError { #[error("Number of unique 8-bytes bytecode chunks exceed the limit of 2^16 - 1")] diff --git a/core/lib/multivm/src/utils/deduplicator.rs b/core/lib/multivm/src/utils/deduplicator.rs index e9a870e6901d..0cb4c3fa7cd8 100644 --- a/core/lib/multivm/src/utils/deduplicator.rs +++ b/core/lib/multivm/src/utils/deduplicator.rs @@ -1,10 +1,9 @@ use std::collections::HashMap; use zksync_types::{ - writes::compression::compress_with_best_strategy, StorageKey, StorageLogKind, + h256_to_u256, writes::compression::compress_with_best_strategy, StorageKey, StorageLogKind, StorageLogWithPreviousValue, H256, }; -use zksync_utils::h256_to_u256; use crate::interface::DeduplicatedWritesMetrics; @@ -211,8 +210,7 @@ impl StorageWritesDeduplicator { #[cfg(test)] mod tests { - use zksync_types::{AccountTreeId, StorageLog, H160, U256}; - use zksync_utils::u256_to_h256; + use zksync_types::{u256_to_h256, AccountTreeId, StorageLog, H160, U256}; use super::*; diff --git a/core/lib/multivm/src/utils/events.rs b/core/lib/multivm/src/utils/events.rs index d84651989e75..37124b822040 100644 --- a/core/lib/multivm/src/utils/events.rs +++ b/core/lib/multivm/src/utils/events.rs @@ -93,8 +93,7 @@ mod tests { use zksync_system_constants::{ BOOTLOADER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L2_BASE_TOKEN_ADDRESS, }; - use zksync_types::{Address, L1BatchNumber}; - use zksync_utils::u256_to_h256; + use zksync_types::{u256_to_h256, Address, L1BatchNumber}; use super::*; diff --git a/core/lib/multivm/src/versions/testonly/block_tip.rs b/core/lib/multivm/src/versions/testonly/block_tip.rs index 220653308a7e..61678e01a443 100644 --- a/core/lib/multivm/src/versions/testonly/block_tip.rs +++ b/core/lib/multivm/src/versions/testonly/block_tip.rs @@ -6,9 +6,9 @@ use zksync_system_constants::{ }; use zksync_types::{ commitment::SerializeCommitment, fee_model::BatchFeeInput, get_code_key, - l2_to_l1_log::L2ToL1Log, writes::StateDiffRecord, Address, Execute, H256, U256, + l2_to_l1_log::L2ToL1Log, u256_to_h256, writes::StateDiffRecord, Address, Execute, H256, U256, }; -use zksync_utils::{bytecode::hash_bytecode, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use super::{ default_pubdata_builder, get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, diff --git a/core/lib/multivm/src/versions/testonly/code_oracle.rs b/core/lib/multivm/src/versions/testonly/code_oracle.rs index 767a294f44ab..6a1fcfb28df3 100644 --- a/core/lib/multivm/src/versions/testonly/code_oracle.rs +++ b/core/lib/multivm/src/versions/testonly/code_oracle.rs @@ -1,8 +1,9 @@ use ethabi::Token; use zksync_types::{ - get_known_code_key, web3::keccak256, Address, Execute, StorageLogWithPreviousValue, U256, + get_known_code_key, h256_to_u256, u256_to_h256, web3::keccak256, Address, Execute, + StorageLogWithPreviousValue, U256, }; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use super::{ get_empty_storage, load_precompiles_contract, read_precompiles_contract, read_test_contract, diff --git a/core/lib/multivm/src/versions/testonly/default_aa.rs b/core/lib/multivm/src/versions/testonly/default_aa.rs index c69c00de4508..a05d42d3918f 100644 --- a/core/lib/multivm/src/versions/testonly/default_aa.rs +++ b/core/lib/multivm/src/versions/testonly/default_aa.rs @@ -1,11 +1,10 @@ use zksync_test_account::{DeployContractsTx, TxType}; use zksync_types::{ - get_code_key, get_known_code_key, get_nonce_key, + get_code_key, get_known_code_key, get_nonce_key, h256_to_u256, system_contracts::{DEPLOYMENT_NONCE_INCREMENT, TX_NONCE_INCREMENT}, utils::storage_key_for_eth_balance, U256, }; -use zksync_utils::h256_to_u256; use super::{default_pubdata_builder, read_test_contract, tester::VmTesterBuilder, TestedVm}; use crate::{ diff --git a/core/lib/multivm/src/versions/testonly/evm_emulator.rs b/core/lib/multivm/src/versions/testonly/evm_emulator.rs index a77274ec581c..1e7e136e4b99 100644 --- a/core/lib/multivm/src/versions/testonly/evm_emulator.rs +++ b/core/lib/multivm/src/versions/testonly/evm_emulator.rs @@ -9,14 +9,11 @@ use zksync_system_constants::{ }; use zksync_test_account::TxType; use zksync_types::{ - get_code_key, get_known_code_key, + get_code_key, get_known_code_key, h256_to_u256, utils::{key_for_eth_balance, storage_key_for_eth_balance}, AccountTreeId, Address, Execute, StorageKey, H256, U256, }; -use zksync_utils::{ - bytecode::{hash_bytecode, hash_evm_bytecode}, - bytes_to_be_words, h256_to_u256, -}; +use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use super::{default_system_env, TestedVm, VmTester, VmTesterBuilder}; use crate::interface::{ @@ -97,7 +94,7 @@ impl EvmTestBuilder { system_env.base_system_smart_contracts.evm_emulator = Some(SystemContractCode { hash: hash_bytecode(&mock_emulator), - code: bytes_to_be_words(mock_emulator), + code: mock_emulator, }); } else { let emulator_hash = hash_bytecode(&mock_emulator); diff --git a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs index 9d0908807e21..fa6470b44c47 100644 --- a/core/lib/multivm/src/versions/testonly/get_used_contracts.rs +++ b/core/lib/multivm/src/versions/testonly/get_used_contracts.rs @@ -5,8 +5,8 @@ use ethabi::Token; use zk_evm_1_3_1::zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; use zksync_test_account::{Account, TxType}; -use zksync_types::{AccountTreeId, Address, Execute, StorageKey, H256, U256}; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_types::{h256_to_u256, AccountTreeId, Address, Execute, StorageKey, H256, U256}; +use zksync_utils::bytecode::hash_bytecode; use super::{ read_proxy_counter_contract, read_test_contract, diff --git a/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs b/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs index 37a2bf2bec20..4a33f478b419 100644 --- a/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs +++ b/core/lib/multivm/src/versions/testonly/l1_tx_execution.rs @@ -4,11 +4,10 @@ use zksync_contracts::l1_messenger_contract; use zksync_system_constants::{BOOTLOADER_ADDRESS, L1_MESSENGER_ADDRESS}; use zksync_test_account::TxType; use zksync_types::{ - get_code_key, get_known_code_key, + get_code_key, get_known_code_key, h256_to_u256, l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, - Address, Execute, ExecuteTransactionCommon, U256, + u256_to_h256, Address, Execute, ExecuteTransactionCommon, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use super::{ read_test_contract, tester::VmTesterBuilder, ContractToDeploy, TestedVm, BASE_SYSTEM_CONTRACTS, diff --git a/core/lib/multivm/src/versions/testonly/l2_blocks.rs b/core/lib/multivm/src/versions/testonly/l2_blocks.rs index 947d8b5859f8..0dfe600b73be 100644 --- a/core/lib/multivm/src/versions/testonly/l2_blocks.rs +++ b/core/lib/multivm/src/versions/testonly/l2_blocks.rs @@ -7,12 +7,12 @@ use assert_matches::assert_matches; use zksync_system_constants::REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE; use zksync_types::{ block::{pack_block_info, L2BlockHasher}, - AccountTreeId, Address, Execute, ExecuteTransactionCommon, L1BatchNumber, L1TxCommonData, - L2BlockNumber, ProtocolVersionId, StorageKey, Transaction, H256, SYSTEM_CONTEXT_ADDRESS, - SYSTEM_CONTEXT_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, - SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, U256, + h256_to_u256, u256_to_h256, AccountTreeId, Address, Execute, ExecuteTransactionCommon, + L1BatchNumber, L1TxCommonData, L2BlockNumber, ProtocolVersionId, StorageKey, Transaction, H256, + SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_BLOCK_INFO_POSITION, + SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, + U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use super::{default_l1_batch, get_empty_storage, tester::VmTesterBuilder, TestedVm}; use crate::{ diff --git a/core/lib/multivm/src/versions/testonly/mod.rs b/core/lib/multivm/src/versions/testonly/mod.rs index 309c0edff583..3377a49064f8 100644 --- a/core/lib/multivm/src/versions/testonly/mod.rs +++ b/core/lib/multivm/src/versions/testonly/mod.rs @@ -18,11 +18,11 @@ use zksync_contracts::{ SystemContractCode, }; use zksync_types::{ - block::L2BlockHasher, fee_model::BatchFeeInput, get_code_key, get_is_account_key, - utils::storage_key_for_eth_balance, Address, L1BatchNumber, L2BlockNumber, L2ChainId, - ProtocolVersionId, U256, + block::L2BlockHasher, fee_model::BatchFeeInput, get_code_key, get_is_account_key, h256_to_u256, + u256_to_h256, utils::storage_key_for_eth_balance, Address, L1BatchNumber, L2BlockNumber, + L2ChainId, ProtocolVersionId, U256, }; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{ pubdata::PubdataBuilder, L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, }; @@ -133,7 +133,7 @@ pub(crate) fn get_bootloader(test: &str) -> SystemContractCode { let bootloader_code = read_bootloader_code(test); let bootloader_hash = hash_bytecode(&bootloader_code); SystemContractCode { - code: bytes_to_be_words(bootloader_code), + code: bootloader_code, hash: bootloader_hash, } } diff --git a/core/lib/multivm/src/versions/testonly/secp256r1.rs b/core/lib/multivm/src/versions/testonly/secp256r1.rs index 37d428f82101..8a6077ab522f 100644 --- a/core/lib/multivm/src/versions/testonly/secp256r1.rs +++ b/core/lib/multivm/src/versions/testonly/secp256r1.rs @@ -1,7 +1,6 @@ use zk_evm_1_5_0::zkevm_opcode_defs::p256; use zksync_system_constants::P256VERIFY_PRECOMPILE_ADDRESS; -use zksync_types::{web3::keccak256, Execute, H256, U256}; -use zksync_utils::h256_to_u256; +use zksync_types::{h256_to_u256, web3::keccak256, Execute, H256, U256}; use super::{tester::VmTesterBuilder, TestedVm}; use crate::interface::{ExecutionResult, InspectExecutionMode, TxExecutionMode, VmInterfaceExt}; diff --git a/core/lib/multivm/src/versions/testonly/transfer.rs b/core/lib/multivm/src/versions/testonly/transfer.rs index 3572adba147c..86588cc5f681 100644 --- a/core/lib/multivm/src/versions/testonly/transfer.rs +++ b/core/lib/multivm/src/versions/testonly/transfer.rs @@ -1,7 +1,6 @@ use ethabi::Token; use zksync_contracts::{load_contract, read_bytecode}; -use zksync_types::{utils::storage_key_for_eth_balance, Address, Execute, U256}; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, utils::storage_key_for_eth_balance, Address, Execute, U256}; use super::{ default_pubdata_builder, get_empty_storage, tester::VmTesterBuilder, ContractToDeploy, TestedVm, diff --git a/core/lib/multivm/src/versions/testonly/upgrade.rs b/core/lib/multivm/src/versions/testonly/upgrade.rs index 359f19faedb2..3fb6257f7070 100644 --- a/core/lib/multivm/src/versions/testonly/upgrade.rs +++ b/core/lib/multivm/src/versions/testonly/upgrade.rs @@ -2,13 +2,13 @@ use zksync_contracts::{deployer_contract, load_sys_contract, read_bytecode}; use zksync_test_account::TxType; use zksync_types::{ ethabi::{Contract, Token}, - get_code_key, get_known_code_key, + get_code_key, get_known_code_key, h256_to_u256, protocol_upgrade::ProtocolUpgradeTxCommonData, - Address, Execute, ExecuteTransactionCommon, Transaction, COMPLEX_UPGRADER_ADDRESS, - CONTRACT_DEPLOYER_ADDRESS, CONTRACT_FORCE_DEPLOYER_ADDRESS, H256, + u256_to_h256, Address, Execute, ExecuteTransactionCommon, Transaction, + COMPLEX_UPGRADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS, CONTRACT_FORCE_DEPLOYER_ADDRESS, H256, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, U256, }; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use super::{ get_complex_upgrade_abi, get_empty_storage, read_complex_upgrade, read_test_contract, diff --git a/core/lib/multivm/src/versions/vm_1_3_2/events.rs b/core/lib/multivm/src/versions/vm_1_3_2/events.rs index 7b1f03c8ac99..0e62312185a2 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/events.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_3_3::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub fn merge_events(events: Vec) -> Vec { .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_1_3_2/history_recorder.rs b/core/lib/multivm/src/versions/vm_1_3_2/history_recorder.rs index 2912fad2841d..bfd33b4b355e 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/history_recorder.rs @@ -1,8 +1,7 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash}; use zk_evm_1_3_3::{aux_structures::Timestamp, vm_state::PrimitiveValue, zkevm_opcode_defs}; -use zksync_types::{StorageKey, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs index e9a85f8ba4b1..07fcdb0f522f 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/oracles/decommitter.rs @@ -6,12 +6,13 @@ use zk_evm_1_3_3::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{StoragePtr, WriteStorage}, + utils::bytecode::bytes_to_be_words, vm_1_3_2::history_recorder::{HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory}, }; @@ -59,7 +60,7 @@ impl DecommitterOracle .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_1_3_2/oracles/storage.rs b/core/lib/multivm/src/versions/vm_1_3_2/oracles/storage.rs index ac4cc3df1706..e3614cbd471c 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/oracles/storage.rs @@ -6,10 +6,9 @@ use zk_evm_1_3_3::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ - utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, StorageLogKind, - BOOTLOADER_ADDRESS, U256, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, + StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use super::OracleWithHistory; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/utils.rs index 86ed02365a94..ef2d4f0b5769 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_1_3_2::{ history_recorder::HistoryMode, diff --git a/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/validation.rs b/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/validation.rs index f52b6b8940db..fbb6795d89a3 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/validation.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/oracles/tracer/validation.rs @@ -11,13 +11,14 @@ use zksync_system_constants::{ KECCAK256_PRECOMPILE_ADDRESS, L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, }; -use zksync_types::{get_code_key, web3::keccak256, AccountTreeId, Address, StorageKey, H256, U256}; -use zksync_utils::{ - be_bytes_to_safe_address, h256_to_account_address, u256_to_account_address, u256_to_h256, +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, web3::keccak256, AccountTreeId, + Address, StorageKey, H256, U256, }; use crate::{ interface::storage::{StoragePtr, WriteStorage}, + utils::bytecode::be_bytes_to_safe_address, vm_1_3_2::{ errors::VmRevertReasonParsingResult, history_recorder::HistoryMode, @@ -242,7 +243,7 @@ impl ValidationTracer { // The user is allowed to touch its own slots or slots semantically related to him. let valid_users_slot = address == self.user_address - || u256_to_account_address(&key) == self.user_address + || u256_to_address(&key) == self.user_address || self.auxilary_allowed_slots.contains(&u256_to_h256(key)); if valid_users_slot { return true; @@ -309,7 +310,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -376,7 +377,7 @@ impl ValidationTracer { let value = self.storage.borrow_mut().read_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/versions/vm_1_3_2/refunds.rs b/core/lib/multivm/src/versions/vm_1_3_2/refunds.rs index 163992516d27..b0d70c3522c4 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/refunds.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/refunds.rs @@ -1,6 +1,5 @@ use zk_evm_1_3_3::aux_structures::Timestamp; -use zksync_types::U256; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, U256}; use crate::{ interface::storage::WriteStorage, diff --git a/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs index 34c70e0f9c45..42106bbdfa22 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/test_utils.rs @@ -12,13 +12,13 @@ use itertools::Itertools; use zk_evm_1_3_3::{aux_structures::Timestamp, vm_state::VmLocalState}; use zksync_contracts::deployer_contract; use zksync_types::{ + address_to_h256, ethabi::{Address, Token}, + h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, h256_to_account_address, u256_to_h256, -}; +use zksync_utils::bytecode::hash_bytecode; use crate::interface::storage::WriteStorage; /// The tests here help us with the testing the VM @@ -174,7 +174,7 @@ pub fn get_create_zksync_address(sender_address: Address, sender_nonce: Nonce) - let hash = keccak256(&digest); - h256_to_account_address(&H256(hash)) + h256_to_address(&H256(hash)) } pub fn verify_required_storage( diff --git a/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs index 0285320daa30..e63b6ec5a87d 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/transaction_data.rs @@ -1,19 +1,22 @@ use zk_evm_1_3_3::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_types::{ + address_to_h256, ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, + h256_to_u256, l1::is_l1_tx_type, l2::TransactionType, ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, ceil_div_u256, h256_to_u256, -}; +use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::MAX_TXS_IN_BLOCK; -use crate::vm_1_3_2::vm_with_bootloader::{ - BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, - MAX_GAS_PER_PUBDATA_BYTE, +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_1_3_2::vm_with_bootloader::{ + BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, + MAX_GAS_PER_PUBDATA_BYTE, + }, }; // This structure represents the data that is used by @@ -197,10 +200,7 @@ impl TransactionData { } pub fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn effective_gas_price_per_pubdata(&self, block_gas_price_per_pubdata: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_1_3_2/utils.rs b/core/lib/multivm/src/versions/vm_1_3_2/utils.rs index 7870b1ff7443..5c72ba204d89 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/utils.rs @@ -7,8 +7,7 @@ use zk_evm_1_3_3::{ }; use zksync_contracts::BaseSystemContracts; use zksync_system_constants::ZKPORTER_IS_AVAILABLE; -use zksync_types::{Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; -use zksync_utils::h256_to_u256; +use zksync_types::{h256_to_u256, Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; use crate::{ interface::storage::WriteStorage, diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs index d9768652c2f3..45b8a09c5a34 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm.rs @@ -1,7 +1,7 @@ use std::{collections::HashSet, rc::Rc}; -use zksync_types::Transaction; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_types::{h256_to_u256, Transaction}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs index fd4d483fba5e..eee1baa59d60 100644 --- a/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_1_3_2/vm_with_bootloader.rs @@ -15,16 +15,14 @@ use zk_evm_1_3_3::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - fee_model::L1PeggedBatchFeeModelInput, l1::is_l1_tx_type, Address, Transaction, - BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, -}; -use zksync_utils::{ - address_to_u256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, misc::ceil_div, + address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, l1::is_l1_tx_type, + Address, Transaction, BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, }; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{storage::WriteStorage, CompressedBytecodeInfo, L1BatchEnv}, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_1_3_2::{ bootloader_state::BootloaderState, history_recorder::HistoryMode, @@ -84,8 +82,11 @@ pub(crate) fn eth_price_per_pubdata_byte(l1_gas_price: u64) -> u64 { pub fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } pub(crate) fn derive_base_fee_and_gas_per_pubdata( @@ -102,7 +103,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( @@ -391,7 +392,7 @@ pub fn init_vm_inner( oracle_tools.decommittment_processor.populate( vec![( h256_to_u256(base_system_contract.default_aa.hash), - base_system_contract.default_aa.code.clone(), + bytes_to_be_words(&base_system_contract.default_aa.code), )], Timestamp(0), ); @@ -399,7 +400,7 @@ pub fn init_vm_inner( oracle_tools.memory.populate( vec![( BOOTLOADER_CODE_PAGE, - base_system_contract.bootloader.code.clone(), + bytes_to_be_words(&base_system_contract.bootloader.code), )], Timestamp(0), ); @@ -645,7 +646,7 @@ pub(crate) fn get_bootloader_memory_for_encoded_tx( .flat_map(bytecode::encode_call) .collect(); - let memory_addition = bytes_to_be_words(memory_addition); + let memory_addition = bytes_to_be_words(&memory_addition); memory.extend( (compressed_bytecodes_offset..compressed_bytecodes_offset + memory_addition.len()) @@ -727,12 +728,11 @@ fn formal_calldata_abi() -> PrimitiveValue { } } +// FIXME: &[u8] pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/l2_block.rs index d3c428ab282b..a5157e323408 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn interim_version(&self) -> BootloaderL2Block { diff --git a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/utils.rs index 1acf75b27e1b..33b15e68005b 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::{ethabi, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{ethabi, h256_to_u256, U256}; use super::tx::BootloaderTx; use crate::{ @@ -25,8 +24,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs index 5f24f2465a32..c8adcf116d74 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/implementation/bytecode.rs @@ -1,6 +1,6 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytecode::bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/events.rs b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/events.rs index ffa4b4d50b8e..bc5befe3810c 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_4_1::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/history_recorder.rs index c9d899742202..bfd7b9130f50 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_4_1::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, H256, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, H256, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs index 636a4058a037..e4df1e4c7fcd 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/old_vm/oracles/decommitter.rs @@ -6,16 +6,18 @@ use zk_evm_1_4_1::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_1_4_1::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, }; + /// The main job of the DecommiterOracle is to implement the DecommittmentProcessor trait - that is /// used by the VM to 'load' bytecodes into memory. #[derive(Debug)] @@ -60,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/oracles/storage.rs b/core/lib/multivm/src/versions/vm_1_4_1/oracles/storage.rs index 3debfd1ca627..921e9b81f71f 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/oracles/storage.rs @@ -6,6 +6,7 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ + u256_to_h256, utils::storage_key_for_eth_balance, writes::{ compression::compress_with_best_strategy, BYTES_PER_DERIVED_KEY, @@ -13,7 +14,6 @@ use zksync_types::{ }, AccountTreeId, Address, StorageKey, StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use crate::{ glue::GlueInto, diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs index 6f927c5c99a8..a51c5ce46197 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/pubdata_tracer.rs @@ -5,8 +5,10 @@ use zk_evm_1_4_1::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{writes::StateDiffRecord, AccountTreeId, StorageKey, L1_MESSENGER_ADDRESS}; -use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; +use zksync_types::{ + h256_to_u256, u256_to_h256, writes::StateDiffRecord, AccountTreeId, StorageKey, + L1_MESSENGER_ADDRESS, +}; use crate::{ interface::{ @@ -16,9 +18,12 @@ use crate::{ L1BatchEnv, VmEvent, VmExecutionMode, }, tracers::dynamic::vm_1_4_1::DynTracer, - utils::events::{ - extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, + utils::{ + bytecode::be_words_to_bytes, + events::{ + extract_bytecode_publication_requests_from_l1_messenger, + extract_l2tol1logs_from_l1_messenger, + }, }, vm_1_4_1::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -100,15 +105,13 @@ impl PubdataTracer { bytecode_publication_requests .iter() .map(|bytecode_publication_request| { - state + let bytecode_words = state .decommittment_processor .known_bytecodes .inner() .get(&h256_to_u256(bytecode_publication_request.bytecode_hash)) - .unwrap() - .iter() - .flat_map(u256_to_bytes_be) - .collect() + .unwrap(); + be_words_to_bytes(bytecode_words) }) .collect() } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs index 2586d8d7f873..ab883d9bcbd2 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/refunds.rs @@ -8,8 +8,10 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::system_params::L1_MESSAGE_PUBDATA_BYTES, }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_types::{l2_to_l1_log::L2ToL1Log, L1BatchNumber, H256, U256}; -use zksync_utils::{bytecode::bytecode_len_in_bytes, ceil_div_u256, u256_to_h256}; +use zksync_types::{ + ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, H256, U256, +}; +use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_1_4_1/tracers/utils.rs b/core/lib/multivm/src/versions/vm_1_4_1/tracers/utils.rs index 7b24e482b72d..536ea79e22f9 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_1_4_1::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs index c1ca93152a03..f938696297b5 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/pubdata.rs @@ -64,7 +64,7 @@ impl PubdataInput { #[cfg(test)] mod tests { use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_utils::u256_to_h256; + use zksync_types::u256_to_h256; use super::*; diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs index f7384da76d0d..872ab3d05dd5 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_1_4_1::{ - constants::{L1_TX_TYPE, MAX_GAS_PER_PUBDATA_BYTE, PRIORITY_TX_MAX_GAS_LIMIT}, - utils::overhead::derive_overhead, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_1_4_1::{ + constants::{L1_TX_TYPE, MAX_GAS_PER_PUBDATA_BYTE, PRIORITY_TX_MAX_GAS_LIMIT}, + utils::overhead::derive_overhead, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn overhead_gas(&self) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs index b91733c7ca14..9c3ecd9741a3 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_4_1::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_1_4_1::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -89,11 +89,7 @@ pub(crate) fn new_vm_state( decommittment_processor.populate( vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )], Timestamp(0), ); @@ -101,11 +97,7 @@ pub(crate) fn new_vm_state( memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_1_4_1/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_1_4_1/types/l1_batch.rs index ca2f0688154b..31807cb66cc1 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/types/l1_batch.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/types/l1_batch.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_1_4_1::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_1_4_1/utils/fee.rs b/core/lib/multivm/src/versions/vm_1_4_1/utils/fee.rs index b5d4cc971b9e..7f214b457317 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::PubdataIndependentBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{interface::L1BatchEnv, vm_1_4_1::constants::MAX_GAS_PER_PUBDATA_BYTE}; @@ -18,11 +17,14 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(fair_pubdata_price, MAX_GAS_PER_PUBDATA_BYTE), + fair_pubdata_price.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); - let gas_per_pubdata = ceil_div(fair_pubdata_price, base_fee); - + let gas_per_pubdata = if fair_pubdata_price == 0 { + 0 + } else { + fair_pubdata_price.div_ceil(base_fee) + }; (base_fee, gas_per_pubdata) } diff --git a/core/lib/multivm/src/versions/vm_1_4_1/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_1_4_1/utils/l2_blocks.rs index ff5536ae0b97..1095abd82db1 100644 --- a/core/lib/multivm/src/versions/vm_1_4_1/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_1_4_1/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/l2_block.rs index d151e3078b4a..a6376852fb28 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn interim_version(&self) -> BootloaderL2Block { diff --git a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/utils.rs index 182f6eff4414..8b367c5c5cae 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::{ethabi, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{ethabi, h256_to_u256, U256}; use super::tx::BootloaderTx; use crate::{ @@ -25,8 +24,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs index 1033fff90e46..2a6ef1d1ab4d 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/implementation/bytecode.rs @@ -1,13 +1,13 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, CompressedBytecodeInfo, }, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_1_4_2::Vm, HistoryMode, }; @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/events.rs b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/events.rs index ffa4b4d50b8e..bc5befe3810c 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_4_1::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/history_recorder.rs index d8d32a2b6c50..9e562de59866 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_4_1::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, H256, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, H256, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs index 706e70d4b116..3d0e9bda8030 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/old_vm/oracles/decommitter.rs @@ -6,16 +6,18 @@ use zk_evm_1_4_1::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_1_4_2::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, }; + /// The main job of the DecommiterOracle is to implement the DecommittmentProcessor trait - that is /// used by the VM to 'load' bytecodes into memory. #[derive(Debug)] @@ -60,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/oracles/storage.rs b/core/lib/multivm/src/versions/vm_1_4_2/oracles/storage.rs index e8d387621907..170bed0eed5d 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/oracles/storage.rs @@ -6,6 +6,7 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ + u256_to_h256, utils::storage_key_for_eth_balance, writes::{ compression::compress_with_best_strategy, BYTES_PER_DERIVED_KEY, @@ -13,7 +14,6 @@ use zksync_types::{ }, AccountTreeId, Address, StorageKey, StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use crate::{ glue::GlueInto, diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs index 6c4f737f9e94..58318f5d845e 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/pubdata_tracer.rs @@ -5,8 +5,10 @@ use zk_evm_1_4_1::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{writes::StateDiffRecord, AccountTreeId, StorageKey, L1_MESSENGER_ADDRESS}; -use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; +use zksync_types::{ + h256_to_u256, u256_to_h256, writes::StateDiffRecord, AccountTreeId, StorageKey, + L1_MESSENGER_ADDRESS, +}; use crate::{ interface::{ @@ -16,9 +18,12 @@ use crate::{ L1BatchEnv, VmEvent, VmExecutionMode, }, tracers::dynamic::vm_1_4_1::DynTracer, - utils::events::{ - extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, + utils::{ + bytecode::be_words_to_bytes, + events::{ + extract_bytecode_publication_requests_from_l1_messenger, + extract_l2tol1logs_from_l1_messenger, + }, }, vm_1_4_2::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -120,15 +125,13 @@ impl PubdataTracer { bytecode_publication_requests .iter() .map(|bytecode_publication_request| { - state + let bytecode_words = state .decommittment_processor .known_bytecodes .inner() .get(&h256_to_u256(bytecode_publication_request.bytecode_hash)) - .unwrap() - .iter() - .flat_map(u256_to_bytes_be) - .collect() + .unwrap(); + be_words_to_bytes(bytecode_words) }) .collect() } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs index 0da5736bf955..8cfcd8c327e4 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/refunds.rs @@ -8,8 +8,10 @@ use zk_evm_1_4_1::{ zkevm_opcode_defs::system_params::L1_MESSAGE_PUBDATA_BYTES, }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_types::{l2_to_l1_log::L2ToL1Log, L1BatchNumber, H256, U256}; -use zksync_utils::{bytecode::bytecode_len_in_bytes, ceil_div_u256, u256_to_h256}; +use zksync_types::{ + ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, H256, U256, +}; +use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_1_4_2/tracers/utils.rs b/core/lib/multivm/src/versions/vm_1_4_2/tracers/utils.rs index 5832241d262d..2caf7b060563 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_1_4_2::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs index c1ca93152a03..f938696297b5 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/pubdata.rs @@ -64,7 +64,7 @@ impl PubdataInput { #[cfg(test)] mod tests { use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_utils::u256_to_h256; + use zksync_types::u256_to_h256; use super::*; diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs index 38280aa80513..693690e3b42e 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_1_4_2::{ - constants::{L1_TX_TYPE, MAX_GAS_PER_PUBDATA_BYTE, PRIORITY_TX_MAX_GAS_LIMIT}, - utils::overhead::derive_overhead, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_1_4_2::{ + constants::{L1_TX_TYPE, MAX_GAS_PER_PUBDATA_BYTE, PRIORITY_TX_MAX_GAS_LIMIT}, + utils::overhead::derive_overhead, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn overhead_gas(&self) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs index 87630a1ff372..52a0dc61d740 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_4_1::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_1_4_2::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -89,11 +89,7 @@ pub(crate) fn new_vm_state( decommittment_processor.populate( vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )], Timestamp(0), ); @@ -101,11 +97,7 @@ pub(crate) fn new_vm_state( memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_1_4_2/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_1_4_2/types/l1_batch.rs index b3a54c410f4d..d2233a515eab 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/types/l1_batch.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/types/l1_batch.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_1_4_2::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_1_4_2/utils/fee.rs b/core/lib/multivm/src/versions/vm_1_4_2/utils/fee.rs index 11f8b6b6c427..b01b18716836 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::PubdataIndependentBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{interface::L1BatchEnv, vm_1_4_2::constants::MAX_GAS_PER_PUBDATA_BYTE}; @@ -18,11 +17,14 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(fair_pubdata_price, MAX_GAS_PER_PUBDATA_BYTE), + fair_pubdata_price.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); - let gas_per_pubdata = ceil_div(fair_pubdata_price, base_fee); - + let gas_per_pubdata = if fair_pubdata_price == 0 { + 0 + } else { + fair_pubdata_price.div_ceil(base_fee) + }; (base_fee, gas_per_pubdata) } diff --git a/core/lib/multivm/src/versions/vm_1_4_2/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_1_4_2/utils/l2_blocks.rs index ff5536ae0b97..1095abd82db1 100644 --- a/core/lib/multivm/src/versions/vm_1_4_2/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_1_4_2/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/l2_block.rs index 47bbbb5bae64..501207e52bd9 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn interim_version(&self) -> BootloaderL2Block { diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/utils.rs index c97d3ff30e49..6605bea1f6b5 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::{ethabi, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{ethabi, h256_to_u256, U256}; use super::tx::BootloaderTx; use crate::{ @@ -25,8 +24,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs index 2d6f081a1886..38d5b40af7e4 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/implementation/bytecode.rs @@ -1,13 +1,13 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, CompressedBytecodeInfo, }, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_boojum_integration::Vm, HistoryMode, }; @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/events.rs b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/events.rs index 1e95d0bc8f35..48db28747bef 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_4_0::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/history_recorder.rs index 704a774893d3..19da0ffda77c 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_4_0::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs index eb7db7097920..b61560afe39d 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/old_vm/oracles/decommitter.rs @@ -6,12 +6,13 @@ use zk_evm_1_4_0::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_boojum_integration::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, @@ -61,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/oracles/storage.rs b/core/lib/multivm/src/versions/vm_boojum_integration/oracles/storage.rs index acdfbaaa42e0..b5fc1c5b92f8 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/oracles/storage.rs @@ -6,6 +6,7 @@ use zk_evm_1_4_0::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ + u256_to_h256, utils::storage_key_for_eth_balance, writes::{ compression::compress_with_best_strategy, BYTES_PER_DERIVED_KEY, @@ -13,7 +14,6 @@ use zksync_types::{ }, AccountTreeId, Address, StorageKey, StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use crate::{ interface::storage::{StoragePtr, WriteStorage}, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs index 2f7d141cb0a7..6396d143b401 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/pubdata_tracer.rs @@ -5,8 +5,10 @@ use zk_evm_1_4_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{writes::StateDiffRecord, AccountTreeId, StorageKey, L1_MESSENGER_ADDRESS}; -use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; +use zksync_types::{ + h256_to_u256, u256_to_h256, writes::StateDiffRecord, AccountTreeId, StorageKey, + L1_MESSENGER_ADDRESS, +}; use crate::{ interface::{ @@ -16,9 +18,12 @@ use crate::{ L1BatchEnv, VmEvent, VmExecutionMode, }, tracers::dynamic::vm_1_4_0::DynTracer, - utils::events::{ - extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, + utils::{ + bytecode::be_words_to_bytes, + events::{ + extract_bytecode_publication_requests_from_l1_messenger, + extract_l2tol1logs_from_l1_messenger, + }, }, vm_boojum_integration::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -98,15 +103,13 @@ impl PubdataTracer { bytecode_publication_requests .iter() .map(|bytecode_publication_request| { - state + let bytecode_words = state .decommittment_processor .known_bytecodes .inner() .get(&h256_to_u256(bytecode_publication_request.bytecode_hash)) - .unwrap() - .iter() - .flat_map(u256_to_bytes_be) - .collect() + .unwrap(); + be_words_to_bytes(bytecode_words) }) .collect() } diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs index ffbb1d80a80e..0d944724afd2 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/refunds.rs @@ -7,8 +7,8 @@ use zk_evm_1_4_0::{ vm_state::VmLocalState, }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_types::{l2_to_l1_log::L2ToL1Log, L1BatchNumber, U256}; -use zksync_utils::{bytecode::bytecode_len_in_bytes, ceil_div_u256, u256_to_h256}; +use zksync_types::{ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, U256}; +use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/utils.rs b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/utils.rs index aafdab9ee428..e916d6e0e66c 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_boojum_integration::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs index 152ccad2fbcb..cb400ab5fa7d 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/pubdata.rs @@ -64,7 +64,7 @@ impl PubdataInput { #[cfg(test)] mod tests { use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_utils::u256_to_h256; + use zksync_types::u256_to_h256; use super::*; diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs index 8bf575effe06..774d2061beb2 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_boojum_integration::{ - constants::MAX_GAS_PER_PUBDATA_BYTE, - utils::overhead::{get_amortized_overhead, OverheadCoefficients}, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_boojum_integration::{ + constants::MAX_GAS_PER_PUBDATA_BYTE, + utils::overhead::{get_amortized_overhead, OverheadCoefficients}, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn effective_gas_price_per_pubdata(&self, block_gas_price_per_pubdata: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs index 5b6b9b2eca17..dc41926c4485 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_4_0::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_boojum_integration::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -89,11 +89,7 @@ pub(crate) fn new_vm_state( decommittment_processor.populate( vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )], Timestamp(0), ); @@ -101,11 +97,7 @@ pub(crate) fn new_vm_state( memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_boojum_integration/types/l1_batch.rs index 386dc040099b..91082e98f9d1 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/types/l1_batch.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/types/l1_batch.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_boojum_integration::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/utils/fee.rs b/core/lib/multivm/src/versions/vm_boojum_integration/utils/fee.rs index 8e785775697a..6fa1a38828e0 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::L1PeggedBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{ interface::L1BatchEnv, @@ -12,8 +11,11 @@ use crate::{ /// Calculates the amount of gas required to publish one byte of pubdata pub fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } /// Calculates the base fee and gas per pubdata for the given L1 gas price. @@ -30,7 +32,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_boojum_integration/utils/l2_blocks.rs index ff5536ae0b97..1095abd82db1 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_boojum_integration/utils/overhead.rs b/core/lib/multivm/src/versions/vm_boojum_integration/utils/overhead.rs index 02fe0b8b3000..c6d299075f2a 100644 --- a/core/lib/multivm/src/versions/vm_boojum_integration/utils/overhead.rs +++ b/core/lib/multivm/src/versions/vm_boojum_integration/utils/overhead.rs @@ -1,7 +1,6 @@ use zk_evm_1_4_0::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; -use zksync_types::{l1::is_l1_tx_type, U256}; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, l1::is_l1_tx_type, U256}; use crate::vm_boojum_integration::constants::{ BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK, diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs index adb406eec789..4f05ef30a46d 100644 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_fast/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use super::{snapshot::L2BlockSnapshot, tx::BootloaderTx}; use crate::{ @@ -51,7 +50,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn make_snapshot(&self) -> L2BlockSnapshot { diff --git a/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs index 770f232019bf..838c2d6ba60f 100644 --- a/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_fast/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::{ethabi, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{ethabi, h256_to_u256, U256}; use super::{l2_block::BootloaderL2Block, tx::BootloaderTx}; use crate::{ @@ -22,8 +21,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_fast/bytecode.rs b/core/lib/multivm/src/versions/vm_fast/bytecode.rs index b75e33a21b05..abbd4461c25e 100644 --- a/core/lib/multivm/src/versions/vm_fast/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_fast/bytecode.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use zksync_types::H256; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_types::{h256_to_u256, H256}; +use zksync_utils::bytecode::hash_bytecode; use super::Vm; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_fast/events.rs b/core/lib/multivm/src/versions/vm_fast/events.rs index 294e8adce32b..4fb26d306897 100644 --- a/core/lib/multivm/src/versions/vm_fast/events.rs +++ b/core/lib/multivm/src/versions/vm_fast/events.rs @@ -1,5 +1,4 @@ -use zksync_types::{L1BatchNumber, H256}; -use zksync_utils::h256_to_account_address; +use zksync_types::{h256_to_address, L1BatchNumber, H256}; use zksync_vm2::interface::Event; use crate::interface::VmEvent; @@ -16,7 +15,7 @@ impl EventAccumulator { fn into_vm_event(self, block_number: L1BatchNumber) -> VmEvent { VmEvent { location: (block_number, self.tx_number_in_block as u32), - address: h256_to_account_address(&H256(self.topics[0])), + address: h256_to_address(&H256(self.topics[0])), indexed_topics: self.topics[1..].iter().map(H256::from).collect(), value: self.data, } diff --git a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs b/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs index 62aba8df5b9b..fb619fa3e5ff 100644 --- a/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs +++ b/core/lib/multivm/src/versions/vm_fast/evm_deploy_tracer.rs @@ -3,8 +3,8 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc}; use zksync_system_constants::{CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS}; -use zksync_types::U256; -use zksync_utils::{bytecode::hash_evm_bytecode, h256_to_u256}; +use zksync_types::{h256_to_u256, U256}; +use zksync_utils::bytecode::hash_evm_bytecode; use zksync_vm2::interface::{ CallframeInterface, CallingMode, GlobalStateInterface, Opcode, OpcodeType, ShouldStop, Tracer, }; diff --git a/core/lib/multivm/src/versions/vm_fast/glue.rs b/core/lib/multivm/src/versions/vm_fast/glue.rs index c2d38f351c04..f1a43d557358 100644 --- a/core/lib/multivm/src/versions/vm_fast/glue.rs +++ b/core/lib/multivm/src/versions/vm_fast/glue.rs @@ -1,5 +1,7 @@ -use zksync_types::l2_to_l1_log::{L2ToL1Log, SystemL2ToL1Log}; -use zksync_utils::u256_to_h256; +use zksync_types::{ + l2_to_l1_log::{L2ToL1Log, SystemL2ToL1Log}, + u256_to_h256, +}; use zksync_vm2::interface; use crate::glue::GlueFrom; diff --git a/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs b/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs index b3bf15cb1be5..89b22d328ac5 100644 --- a/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs +++ b/core/lib/multivm/src/versions/vm_fast/initial_bootloader_memory.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_fast/pubdata.rs b/core/lib/multivm/src/versions/vm_fast/pubdata.rs index c1ca93152a03..f938696297b5 100644 --- a/core/lib/multivm/src/versions/vm_fast/pubdata.rs +++ b/core/lib/multivm/src/versions/vm_fast/pubdata.rs @@ -64,7 +64,7 @@ impl PubdataInput { #[cfg(test)] mod tests { use zksync_system_constants::{ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS}; - use zksync_utils::u256_to_h256; + use zksync_types::u256_to_h256; use super::*; diff --git a/core/lib/multivm/src/versions/vm_fast/refund.rs b/core/lib/multivm/src/versions/vm_fast/refund.rs index 05648acddcfe..13637ff97122 100644 --- a/core/lib/multivm/src/versions/vm_fast/refund.rs +++ b/core/lib/multivm/src/versions/vm_fast/refund.rs @@ -1,5 +1,4 @@ -use zksync_types::{H256, U256}; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, H256, U256}; use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs index 27192f46d8dd..e00a71a43c36 100644 --- a/core/lib/multivm/src/versions/vm_fast/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_fast/tests/mod.rs @@ -1,7 +1,8 @@ use std::{any::Any, collections::HashSet, fmt, rc::Rc}; -use zksync_types::{writes::StateDiffRecord, StorageKey, Transaction, H160, H256, U256}; -use zksync_utils::h256_to_u256; +use zksync_types::{ + h256_to_u256, writes::StateDiffRecord, StorageKey, Transaction, H160, H256, U256, +}; use zksync_vm2::interface::{Event, HeapId, StateInterface}; use zksync_vm_interface::{ pubdata::PubdataBuilder, storage::ReadStorage, CurrentExecutionState, L2BlockEnv, diff --git a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs b/core/lib/multivm/src/versions/vm_fast/transaction_data.rs index 2ec86eb3ceaf..afc0ef51e7d4 100644 --- a/core/lib/multivm/src/versions/vm_fast/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_fast/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_latest::{ - constants::{MAX_GAS_PER_PUBDATA_BYTE, TX_MAX_COMPUTE_GAS_LIMIT}, - utils::overhead::derive_overhead, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_latest::{ + constants::{MAX_GAS_PER_PUBDATA_BYTE, TX_MAX_COMPUTE_GAS_LIMIT}, + utils::overhead::derive_overhead, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn overhead_gas(&self) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_fast/vm.rs b/core/lib/multivm/src/versions/vm_fast/vm.rs index d18f7b91f323..2aab2bfc7d96 100644 --- a/core/lib/multivm/src/versions/vm_fast/vm.rs +++ b/core/lib/multivm/src/versions/vm_fast/vm.rs @@ -5,8 +5,10 @@ use zk_evm_1_5_0::{ }; use zksync_contracts::SystemContractCode; use zksync_types::{ + h256_to_u256, l1::is_l1_tx_type, l2_to_l1_log::UserL2ToL1Log, + u256_to_h256, utils::key_for_eth_balance, writes::{ compression::compress_with_best_strategy, StateDiffRecord, BYTES_PER_DERIVED_KEY, @@ -16,7 +18,7 @@ use zksync_types::{ Transaction, BOOTLOADER_ADDRESS, H160, H256, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm2::{ interface::{CallframeInterface, HeapId, StateInterface, Tracer}, ExecutionEnd, FatPointer, Program, Settings, StorageSlot, VirtualMachine, @@ -845,7 +847,7 @@ impl World { ) -> (U256, Program) { ( h256_to_u256(code.hash), - Program::from_words(code.code.clone(), is_bootloader), + Program::new(&code.code, is_bootloader), ) } diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs index 103c5d16540e..95502b8dc60c 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn make_snapshot(&self) -> L2BlockSnapshot { diff --git a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs index c409bda35c1d..58dc20346a6f 100644 --- a/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::{ethabi, ProtocolVersionId, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{ethabi, h256_to_u256, ProtocolVersionId, U256}; use super::tx::BootloaderTx; use crate::{ @@ -27,8 +26,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs index 2cd98c8e58a3..d0390444e1cb 100644 --- a/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_latest/implementation/bytecode.rs @@ -1,13 +1,13 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, CompressedBytecodeInfo, }, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_latest::Vm, HistoryMode, }; @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_latest/old_vm/events.rs b/core/lib/multivm/src/versions/vm_latest/old_vm/events.rs index fd6f393155d7..bded254c7fcc 100644 --- a/core/lib/multivm/src/versions/vm_latest/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_latest/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_5_0::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs index e7277f38289d..9dac6480dc57 100644 --- a/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_latest/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_5_0::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, H256, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, H256, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_latest/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_latest/old_vm/oracles/decommitter.rs index 507e3d8c7598..1afa9b483ec5 100644 --- a/core/lib/multivm/src/versions/vm_latest/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_latest/old_vm/oracles/decommitter.rs @@ -10,12 +10,12 @@ use zk_evm_1_5_0::{ }, zkevm_opcode_defs::{VersionedHashHeader, VersionedHashNormalizedPreimage}, }; -use zksync_types::{H256, U256}; -use zksync_utils::{bytes_to_be_words, h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, H256, U256}; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_latest::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, @@ -69,7 +69,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .unwrap_or_else(|| panic!("Trying to decommit unexisting hash: {}", hash)); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs b/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs index 9c7b68c1ad51..242cdc6a2239 100644 --- a/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_latest/oracles/storage.rs @@ -10,6 +10,7 @@ use zk_evm_1_5_0::{ }, }; use zksync_types::{ + h256_to_u256, u256_to_h256, utils::storage_key_for_eth_balance, writes::{ compression::compress_with_best_strategy, BYTES_PER_DERIVED_KEY, @@ -17,7 +18,6 @@ use zksync_types::{ }, AccountTreeId, Address, StorageKey, StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::{ glue::GlueInto, @@ -620,8 +620,7 @@ fn get_pubdata_price_bytes(initial_value: U256, final_value: U256, is_initial: b #[cfg(test)] mod tests { - use zksync_types::H256; - use zksync_utils::h256_to_u256; + use zksync_types::{h256_to_u256, H256}; use super::*; use crate::interface::storage::{InMemoryStorage, StorageView}; diff --git a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs index 96d59f208b03..51c9dde0dd56 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/mod.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/mod.rs @@ -8,8 +8,10 @@ use zk_evm_1_5_0::{ vm_state::VmLocalState, zkevm_opcode_defs::{ContractCodeSha256Format, VersionedHashLen32}, }; -use zksync_types::{writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, U256}; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; +use zksync_types::{ + h256_to_u256, writes::StateDiffRecord, StorageKey, StorageValue, Transaction, H256, U256, +}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::pubdata::PubdataBuilder; use super::{HistoryEnabled, Vm}; @@ -18,6 +20,7 @@ use crate::{ storage::{InMemoryStorage, ReadStorage, StorageView, WriteStorage}, CurrentExecutionState, L2BlockEnv, VmExecutionMode, VmExecutionResultAndLogs, }, + utils::bytecode::bytes_to_be_words, versions::testonly::{filter_out_base_system_contracts, TestedVm}, vm_latest::{ constants::BOOTLOADER_HEAP_PAGE, @@ -111,7 +114,7 @@ impl TestedVm for TestedLatestVm { .iter() .map(|&bytecode| { let hash = hash_bytecode(bytecode); - let words = bytes_to_be_words(bytecode.to_vec()); + let words = bytes_to_be_words(bytecode); (h256_to_u256(hash), words) }) .collect(); diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs index 61c8ef0b5abf..98ae14ff7f89 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/evm_deploy_tracer.rs @@ -7,14 +7,17 @@ use zk_evm_1_5_0::{ FarCallOpcode, FatPointer, Opcode, CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER, }, }; -use zksync_types::{CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS}; -use zksync_utils::{bytecode::hash_evm_bytecode, bytes_to_be_words, h256_to_u256}; -use zksync_vm_interface::storage::StoragePtr; +use zksync_types::{h256_to_u256, CONTRACT_DEPLOYER_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS}; +use zksync_utils::bytecode::hash_evm_bytecode; use super::{traits::VmTracer, utils::read_pointer}; use crate::{ - interface::{storage::WriteStorage, tracer::TracerExecutionStatus}, + interface::{ + storage::{StoragePtr, WriteStorage}, + tracer::TracerExecutionStatus, + }, tracers::dynamic::vm_1_5_0::DynTracer, + utils::bytecode::bytes_to_be_words, vm_latest::{BootloaderState, HistoryMode, SimpleMemory, ZkSyncVmState}, }; @@ -92,7 +95,7 @@ impl VmTracer for EvmDeployTracer { let timestamp = Timestamp(state.local_state.timestamp); for published_bytecode in mem::take(&mut self.pending_bytecodes) { let hash = h256_to_u256(hash_evm_bytecode(&published_bytecode)); - let as_words = bytes_to_be_words(published_bytecode); + let as_words = bytes_to_be_words(&published_bytecode); state .decommittment_processor .insert_dynamic_bytecode(hash, as_words, timestamp); diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs index 998e8a13ad25..4c71c3b2fc49 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/pubdata_tracer.rs @@ -5,8 +5,10 @@ use zk_evm_1_5_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{writes::StateDiffRecord, AccountTreeId, StorageKey, L1_MESSENGER_ADDRESS}; -use zksync_utils::{h256_to_u256, u256_to_bytes_be, u256_to_h256}; +use zksync_types::{ + h256_to_u256, u256_to_h256, writes::StateDiffRecord, AccountTreeId, StorageKey, + L1_MESSENGER_ADDRESS, +}; use zksync_vm_interface::pubdata::PubdataBuilder; use crate::{ @@ -17,9 +19,12 @@ use crate::{ L1BatchEnv, VmEvent, VmExecutionMode, }, tracers::dynamic::vm_1_5_0::DynTracer, - utils::events::{ - extract_bytecode_publication_requests_from_l1_messenger, - extract_l2tol1logs_from_l1_messenger, + utils::{ + bytecode::be_words_to_bytes, + events::{ + extract_bytecode_publication_requests_from_l1_messenger, + extract_l2tol1logs_from_l1_messenger, + }, }, vm_latest::{ bootloader_state::{utils::apply_pubdata_to_memory, BootloaderState}, @@ -132,15 +137,13 @@ impl PubdataTracer { bytecode_publication_requests .iter() .map(|bytecode_publication_request| { - state + let bytecode_words = state .decommittment_processor .known_bytecodes .inner() .get(&h256_to_u256(bytecode_publication_request.bytecode_hash)) - .unwrap() - .iter() - .flat_map(u256_to_bytes_be) - .collect() + .unwrap(); + be_words_to_bytes(bytecode_words) }) .collect() } diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs index 78826a16313d..f3fc1b167b45 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/refunds.rs @@ -5,8 +5,7 @@ use zk_evm_1_5_0::{ aux_structures::Timestamp, tracing::{BeforeExecutionData, VmLocalStateData}, }; -use zksync_types::{H256, U256}; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, H256, U256}; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs b/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs index 0a11f5d3f849..50901dca62fc 100644 --- a/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_latest/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, SECP256R1_VERIFY_PRECOMPILE_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_latest::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs index 90948f2f89fd..544934665adf 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_latest::{ - constants::{MAX_GAS_PER_PUBDATA_BYTE, TX_MAX_COMPUTE_GAS_LIMIT}, - utils::overhead::derive_overhead, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_latest::{ + constants::{MAX_GAS_PER_PUBDATA_BYTE, TX_MAX_COMPUTE_GAS_LIMIT}, + utils::overhead::derive_overhead, + }, }; /// This structure represents the data that is used by @@ -209,10 +214,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn overhead_gas(&self) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs index 90bb0c610e2c..03f306f36c52 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_5_0::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_latest::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -88,25 +88,20 @@ pub(crate) fn new_vm_state( DecommitterOracle::new(storage); let mut initial_bytecodes = vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )]; if let Some(evm_emulator) = &system_env.base_system_smart_contracts.evm_emulator { - initial_bytecodes.push((h256_to_u256(evm_emulator.hash), evm_emulator.code.clone())); + initial_bytecodes.push(( + h256_to_u256(evm_emulator.hash), + bytes_to_be_words(&evm_emulator.code), + )); } decommittment_processor.populate(initial_bytecodes, Timestamp(0)); memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs index b3bf15cb1be5..89b22d328ac5 100644 --- a/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs +++ b/core/lib/multivm/src/versions/vm_latest/types/l1_batch.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_latest::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_latest/utils/fee.rs b/core/lib/multivm/src/versions/vm_latest/utils/fee.rs index 666fcca87e12..58b457dce68a 100644 --- a/core/lib/multivm/src/versions/vm_latest/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_latest/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::PubdataIndependentBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{interface::L1BatchEnv, vm_latest::constants::MAX_GAS_PER_PUBDATA_BYTE}; @@ -18,11 +17,14 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(fair_pubdata_price, MAX_GAS_PER_PUBDATA_BYTE), + fair_pubdata_price.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); - let gas_per_pubdata = ceil_div(fair_pubdata_price, base_fee); - + let gas_per_pubdata = if fair_pubdata_price == 0 { + 0 + } else { + fair_pubdata_price.div_ceil(base_fee) + }; (base_fee, gas_per_pubdata) } diff --git a/core/lib/multivm/src/versions/vm_latest/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_latest/utils/l2_blocks.rs index 59d3eb0ef0fc..840f1687ccfa 100644 --- a/core/lib/multivm/src/versions/vm_latest/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_latest/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_latest/vm.rs b/core/lib/multivm/src/versions/vm_latest/vm.rs index ff90eb14ee42..5a0e77023a5e 100644 --- a/core/lib/multivm/src/versions/vm_latest/vm.rs +++ b/core/lib/multivm/src/versions/vm_latest/vm.rs @@ -2,11 +2,12 @@ use std::{collections::HashMap, rc::Rc}; use circuit_sequencer_api_1_5_0::sort_storage_access::sort_storage_access_queries; use zksync_types::{ + h256_to_u256, l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, + u256_to_h256, vm::VmVersion, Transaction, H256, }; -use zksync_utils::{be_words_to_bytes, h256_to_u256, u256_to_h256}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ @@ -18,7 +19,7 @@ use crate::{ VmExecutionResultAndLogs, VmFactory, VmInterface, VmInterfaceHistoryEnabled, VmTrackingContracts, }, - utils::events::extract_l2tol1logs_from_l1_messenger, + utils::{bytecode::be_words_to_bytes, events::extract_l2tol1logs_from_l1_messenger}, vm_latest::{ bootloader_state::BootloaderState, old_vm::{events::merge_events, history_recorder::HistoryEnabled}, diff --git a/core/lib/multivm/src/versions/vm_m5/events.rs b/core/lib/multivm/src/versions/vm_m5/events.rs index a444ad37feb5..659b41cc2060 100644 --- a/core/lib/multivm/src/versions/vm_m5/events.rs +++ b/core/lib/multivm/src/versions/vm_m5/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_3_1::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub fn merge_events(events: Vec) -> Vec { .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_m5/history_recorder.rs b/core/lib/multivm/src/versions/vm_m5/history_recorder.rs index f744be32d0bf..f7923e42b667 100644 --- a/core/lib/multivm/src/versions/vm_m5/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_m5/history_recorder.rs @@ -9,8 +9,7 @@ use zk_evm_1_3_1::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, U256}; use crate::vm_m5::storage::{Storage, StoragePtr}; diff --git a/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs index bc43c72966ea..ca6fde506f87 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracles/decommitter.rs @@ -6,13 +6,16 @@ use zk_evm_1_3_1::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; -use crate::vm_m5::{ - history_recorder::HistoryRecorder, - storage::{Storage, StoragePtr}, +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_m5::{ + history_recorder::HistoryRecorder, + storage::{Storage, StoragePtr}, + }, }; #[derive(Debug)] @@ -53,7 +56,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs b/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs index 7ccfdf2f30c7..ab373e9e7696 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracles/storage.rs @@ -7,10 +7,9 @@ use zk_evm_1_3_1::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ - utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, StorageLogKind, - BOOTLOADER_ADDRESS, U256, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, + StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use super::OracleWithHistory; use crate::vm_m5::{ diff --git a/core/lib/multivm/src/versions/vm_m5/oracles/tracer.rs b/core/lib/multivm/src/versions/vm_m5/oracles/tracer.rs index 45f8ed88f834..ea92307d1224 100644 --- a/core/lib/multivm/src/versions/vm_m5/oracles/tracer.rs +++ b/core/lib/multivm/src/versions/vm_m5/oracles/tracer.rs @@ -16,22 +16,23 @@ use zk_evm_1_3_1::{ }, }; use zksync_types::{ - get_code_key, web3::keccak256, AccountTreeId, Address, StorageKey, - ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS, H256, - KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, - L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, U256, -}; -use zksync_utils::{ - be_bytes_to_safe_address, h256_to_account_address, u256_to_account_address, u256_to_h256, + get_code_key, h256_to_address, u256_to_address, u256_to_h256, web3::keccak256, AccountTreeId, + Address, StorageKey, ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, + CONTRACT_DEPLOYER_ADDRESS, H256, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, + L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, + SYSTEM_CONTEXT_ADDRESS, U256, }; -use crate::vm_m5::{ - errors::VmRevertReasonParsingResult, - memory::SimpleMemory, - storage::{Storage, StoragePtr}, - utils::{aux_heap_page_from_base, heap_page_from_base}, - vm_instance::{get_vm_hook_params, VM_HOOK_POSITION}, - vm_with_bootloader::BOOTLOADER_HEAP_PAGE, +use crate::{ + utils::bytecode::be_bytes_to_safe_address, + vm_m5::{ + errors::VmRevertReasonParsingResult, + memory::SimpleMemory, + storage::{Storage, StoragePtr}, + utils::{aux_heap_page_from_base, heap_page_from_base}, + vm_instance::{get_vm_hook_params, VM_HOOK_POSITION}, + vm_with_bootloader::BOOTLOADER_HEAP_PAGE, + }, }; pub trait ExecutionEndTracer: Tracer { @@ -322,7 +323,7 @@ impl ValidationTracer { // The user is allowed to touch its own slots or slots semantically related to him. let valid_users_slot = address == self.user_address - || u256_to_account_address(&key) == self.user_address + || u256_to_address(&key) == self.user_address || self.auxilary_allowed_slots.contains(&u256_to_h256(key)); if valid_users_slot { return true; @@ -383,7 +384,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -450,7 +451,7 @@ impl ValidationTracer { let value = self.storage.borrow_mut().get_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/versions/vm_m5/refunds.rs b/core/lib/multivm/src/versions/vm_m5/refunds.rs index fd4e2788f035..8b0d3e5d84c4 100644 --- a/core/lib/multivm/src/versions/vm_m5/refunds.rs +++ b/core/lib/multivm/src/versions/vm_m5/refunds.rs @@ -1,6 +1,5 @@ use zk_evm_1_3_1::aux_structures::Timestamp; -use zksync_types::U256; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, U256}; use crate::vm_m5::{ storage::Storage, diff --git a/core/lib/multivm/src/versions/vm_m5/test_utils.rs b/core/lib/multivm/src/versions/vm_m5/test_utils.rs index d7c0dfb9f6d0..ff6ed0392c85 100644 --- a/core/lib/multivm/src/versions/vm_m5/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_m5/test_utils.rs @@ -14,13 +14,13 @@ use zk_evm_1_3_1::{ }; use zksync_contracts::deployer_contract; use zksync_types::{ + address_to_h256, ethabi::{Address, Token}, + h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, h256_to_account_address, u256_to_h256, -}; +use zksync_utils::bytecode::hash_bytecode; use super::utils::StorageLogQuery; use crate::vm_m5::{ @@ -172,5 +172,5 @@ pub fn get_create_zksync_address(sender_address: Address, sender_nonce: Nonce) - let hash = keccak256(&digest); - h256_to_account_address(&H256(hash)) + h256_to_address(&H256(hash)) } diff --git a/core/lib/multivm/src/versions/vm_m5/transaction_data.rs b/core/lib/multivm/src/versions/vm_m5/transaction_data.rs index b64e3f770185..2307c5e24127 100644 --- a/core/lib/multivm/src/versions/vm_m5/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_m5/transaction_data.rs @@ -1,17 +1,20 @@ use zk_evm_1_3_1::zkevm_opcode_defs::system_params::{MAX_PUBDATA_PER_BLOCK, MAX_TX_ERGS_LIMIT}; use zksync_types::{ + address_to_h256, ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, + h256_to_u256, l2::TransactionType, ExecuteTransactionCommon, Transaction, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, ceil_div_u256, h256_to_u256, -}; +use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::MAX_GAS_PER_PUBDATA_BYTE; -use crate::vm_m5::vm_with_bootloader::{ - BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK, +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_m5::vm_with_bootloader::{ + BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK, + }, }; const L1_TX_TYPE: u8 = 255; @@ -171,10 +174,7 @@ impl TransactionData { } pub fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub fn overhead_gas(&self) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_m5/utils.rs b/core/lib/multivm/src/versions/vm_m5/utils.rs index a38618395b1f..de8c746bfb80 100644 --- a/core/lib/multivm/src/versions/vm_m5/utils.rs +++ b/core/lib/multivm/src/versions/vm_m5/utils.rs @@ -7,8 +7,7 @@ use zk_evm_1_3_1::{ }; use zksync_contracts::BaseSystemContracts; use zksync_system_constants::ZKPORTER_IS_AVAILABLE; -use zksync_types::{Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; -use zksync_utils::h256_to_u256; +use zksync_types::{h256_to_u256, Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; use crate::{ glue::GlueInto, diff --git a/core/lib/multivm/src/versions/vm_m5/vm.rs b/core/lib/multivm/src/versions/vm_m5/vm.rs index 55afeed17cd1..266a0a437e5e 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm.rs @@ -1,7 +1,6 @@ use std::rc::Rc; -use zksync_types::{vm::VmVersion, Transaction}; -use zksync_utils::h256_to_u256; +use zksync_types::{h256_to_u256, vm::VmVersion, Transaction}; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs index cd2979db5e57..653169cd7ff0 100644 --- a/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m5/vm_with_bootloader.rs @@ -14,15 +14,14 @@ use zk_evm_1_3_1::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - fee_model::L1PeggedBatchFeeModelInput, Address, Transaction, BOOTLOADER_ADDRESS, - L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, -}; -use zksync_utils::{ - address_to_u256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, misc::ceil_div, + address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, Address, Transaction, + BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, }; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::L1BatchEnv, + utils::bytecode::bytes_to_be_words, vm_m5::{ bootloader_state::BootloaderState, oracles::OracleWithHistory, @@ -73,8 +72,11 @@ pub(crate) fn eth_price_per_pubdata_byte(l1_gas_price: u64) -> u64 { pub(crate) fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } pub(crate) fn derive_base_fee_and_gas_per_pubdata( @@ -91,7 +93,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( @@ -347,7 +349,7 @@ pub fn init_vm_inner( oracle_tools.decommittment_processor.populate( vec![( h256_to_u256(base_system_contract.default_aa.hash), - base_system_contract.default_aa.code.clone(), + bytes_to_be_words(&base_system_contract.default_aa.code), )], Timestamp(0), ); @@ -355,7 +357,7 @@ pub fn init_vm_inner( oracle_tools.memory.populate( vec![( BOOTLOADER_CODE_PAGE, - base_system_contract.bootloader.code.clone(), + bytes_to_be_words(&base_system_contract.bootloader.code), )], Timestamp(0), ); @@ -585,9 +587,7 @@ fn formal_calldata_abi() -> PrimitiveValue { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_m6/events.rs b/core/lib/multivm/src/versions/vm_m6/events.rs index a444ad37feb5..659b41cc2060 100644 --- a/core/lib/multivm/src/versions/vm_m6/events.rs +++ b/core/lib/multivm/src/versions/vm_m6/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_3_1::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub fn merge_events(events: Vec) -> Vec { .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_m6/history_recorder.rs b/core/lib/multivm/src/versions/vm_m6/history_recorder.rs index 63dc9be4933a..5f7a116c62ac 100644 --- a/core/lib/multivm/src/versions/vm_m6/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_m6/history_recorder.rs @@ -9,8 +9,7 @@ use zk_evm_1_3_1::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, U256}; use crate::vm_m6::storage::{Storage, StoragePtr}; diff --git a/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs index fe59580e2ce9..a43ec4ec4fd8 100644 --- a/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_m6/oracles/decommitter.rs @@ -6,13 +6,16 @@ use zk_evm_1_3_1::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; -use crate::vm_m6::{ - history_recorder::{HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory}, - storage::{Storage, StoragePtr}, +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_m6::{ + history_recorder::{HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory}, + storage::{Storage, StoragePtr}, + }, }; /// The main job of the DecommiterOracle is to implement the DecommitmentProcessor trait - that is @@ -59,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_m6/oracles/storage.rs b/core/lib/multivm/src/versions/vm_m6/oracles/storage.rs index 5393b9e48169..7a59754140c9 100644 --- a/core/lib/multivm/src/versions/vm_m6/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_m6/oracles/storage.rs @@ -6,10 +6,9 @@ use zk_evm_1_3_1::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ - utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, StorageLogKind, - BOOTLOADER_ADDRESS, U256, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, + StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use super::OracleWithHistory; use crate::vm_m6::{ diff --git a/core/lib/multivm/src/versions/vm_m6/oracles/tracer/utils.rs b/core/lib/multivm/src/versions/vm_m6/oracles/tracer/utils.rs index 4d963d08952d..9b94ec9de84f 100644 --- a/core/lib/multivm/src/versions/vm_m6/oracles/tracer/utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/oracles/tracer/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_m6::{ history_recorder::HistoryMode, diff --git a/core/lib/multivm/src/versions/vm_m6/oracles/tracer/validation.rs b/core/lib/multivm/src/versions/vm_m6/oracles/tracer/validation.rs index f046ba5befe9..e6b040b93f5d 100644 --- a/core/lib/multivm/src/versions/vm_m6/oracles/tracer/validation.rs +++ b/core/lib/multivm/src/versions/vm_m6/oracles/tracer/validation.rs @@ -11,22 +11,25 @@ use zksync_system_constants::{ KECCAK256_PRECOMPILE_ADDRESS, L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS, }; -use zksync_types::{get_code_key, web3::keccak256, AccountTreeId, Address, StorageKey, H256, U256}; -use zksync_utils::{ - be_bytes_to_safe_address, h256_to_account_address, u256_to_account_address, u256_to_h256, +use zksync_types::{ + get_code_key, h256_to_address, u256_to_address, u256_to_h256, web3::keccak256, AccountTreeId, + Address, StorageKey, H256, U256, }; -use crate::vm_m6::{ - errors::VmRevertReasonParsingResult, - history_recorder::HistoryMode, - memory::SimpleMemory, - oracles::tracer::{ - utils::{ - computational_gas_price, get_calldata_page_via_abi, print_debug_if_needed, VmHook, +use crate::{ + utils::bytecode::be_bytes_to_safe_address, + vm_m6::{ + errors::VmRevertReasonParsingResult, + history_recorder::HistoryMode, + memory::SimpleMemory, + oracles::tracer::{ + utils::{ + computational_gas_price, get_calldata_page_via_abi, print_debug_if_needed, VmHook, + }, + ExecutionEndTracer, PendingRefundTracer, PubdataSpentTracer, StorageInvocationTracer, }, - ExecutionEndTracer, PendingRefundTracer, PubdataSpentTracer, StorageInvocationTracer, + storage::{Storage, StoragePtr}, }, - storage::{Storage, StoragePtr}, }; #[derive(Debug, Clone, Eq, PartialEq, Copy)] @@ -252,7 +255,7 @@ impl ValidationTracer { // The user is allowed to touch its own slots or slots semantically related to him. let valid_users_slot = address == self.user_address - || u256_to_account_address(&key) == self.user_address + || u256_to_address(&key) == self.user_address || self.auxilary_allowed_slots.contains(&u256_to_h256(key)); if valid_users_slot { return true; @@ -319,7 +322,7 @@ impl ValidationTracer { let packed_abi = data.src0_value.value; let call_destination_value = data.src1_value.value; - let called_address = u256_to_account_address(&call_destination_value); + let called_address = u256_to_address(&call_destination_value); let far_call_abi = FarCallABI::from_u256(packed_abi); if called_address == KECCAK256_PRECOMPILE_ADDRESS @@ -386,7 +389,7 @@ impl ValidationTracer { let value = self.storage.borrow_mut().get_value(&storage_key); return Ok(NewTrustedValidationItems { - new_trusted_addresses: vec![h256_to_account_address(&value)], + new_trusted_addresses: vec![h256_to_address(&value)], ..Default::default() }); } diff --git a/core/lib/multivm/src/versions/vm_m6/refunds.rs b/core/lib/multivm/src/versions/vm_m6/refunds.rs index 406bf380a0b2..f98c84409410 100644 --- a/core/lib/multivm/src/versions/vm_m6/refunds.rs +++ b/core/lib/multivm/src/versions/vm_m6/refunds.rs @@ -1,6 +1,5 @@ use zk_evm_1_3_1::aux_structures::Timestamp; -use zksync_types::U256; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, U256}; use crate::vm_m6::{ history_recorder::HistoryMode, diff --git a/core/lib/multivm/src/versions/vm_m6/test_utils.rs b/core/lib/multivm/src/versions/vm_m6/test_utils.rs index 4bd39bc56dd4..438a67129ac6 100644 --- a/core/lib/multivm/src/versions/vm_m6/test_utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/test_utils.rs @@ -12,13 +12,13 @@ use itertools::Itertools; use zk_evm_1_3_1::{aux_structures::Timestamp, vm_state::VmLocalState}; use zksync_contracts::deployer_contract; use zksync_types::{ + address_to_h256, ethabi::{Address, Token}, + h256_to_address, u256_to_h256, web3::keccak256, Execute, Nonce, StorageKey, StorageValue, CONTRACT_DEPLOYER_ADDRESS, H256, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, h256_to_account_address, u256_to_h256, -}; +use zksync_utils::bytecode::hash_bytecode; use super::utils::StorageLogQuery; use crate::vm_m6::{ @@ -172,5 +172,5 @@ pub fn get_create_zksync_address(sender_address: Address, sender_nonce: Nonce) - let hash = keccak256(&digest); - h256_to_account_address(&H256(hash)) + h256_to_address(&H256(hash)) } diff --git a/core/lib/multivm/src/versions/vm_m6/transaction_data.rs b/core/lib/multivm/src/versions/vm_m6/transaction_data.rs index a8f80ea3255e..cfd2ebf00e44 100644 --- a/core/lib/multivm/src/versions/vm_m6/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_m6/transaction_data.rs @@ -1,18 +1,21 @@ use zk_evm_1_3_1::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_types::{ + address_to_h256, ceil_div_u256, ethabi::{encode, Address, Token}, fee::encoding_len, + h256_to_u256, l1::is_l1_tx_type, l2::TransactionType, ExecuteTransactionCommon, Transaction, MAX_L2_TX_GAS_LIMIT, U256, }; -use zksync_utils::{ - address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, ceil_div_u256, h256_to_u256, -}; +use zksync_utils::bytecode::hash_bytecode; use super::vm_with_bootloader::{MAX_GAS_PER_PUBDATA_BYTE, MAX_TXS_IN_BLOCK}; -use crate::vm_m6::vm_with_bootloader::{ - BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_m6::vm_with_bootloader::{ + BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, + }, }; pub(crate) const L1_TX_TYPE: u8 = 255; @@ -198,10 +201,7 @@ impl TransactionData { } pub fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn effective_gas_price_per_pubdata(&self, block_gas_price_per_pubdata: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_m6/utils.rs b/core/lib/multivm/src/versions/vm_m6/utils.rs index 912a30a4eafc..a9304f5cd525 100644 --- a/core/lib/multivm/src/versions/vm_m6/utils.rs +++ b/core/lib/multivm/src/versions/vm_m6/utils.rs @@ -7,8 +7,7 @@ use zk_evm_1_3_1::{ }; use zksync_contracts::BaseSystemContracts; use zksync_system_constants::ZKPORTER_IS_AVAILABLE; -use zksync_types::{Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; -use zksync_utils::h256_to_u256; +use zksync_types::{h256_to_u256, Address, StorageLogKind, H160, MAX_L2_TX_GAS_LIMIT, U256}; use crate::{ glue::GlueInto, diff --git a/core/lib/multivm/src/versions/vm_m6/vm.rs b/core/lib/multivm/src/versions/vm_m6/vm.rs index 4c67a2184180..0443dc8fb55e 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm.rs @@ -1,7 +1,7 @@ use std::{collections::HashSet, rc::Rc}; -use zksync_types::{vm::VmVersion, Transaction}; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_types::{h256_to_u256, vm::VmVersion, Transaction}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{pubdata::PubdataBuilder, InspectExecutionMode}; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs index ae44e721b0d7..a47ffb116364 100644 --- a/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs +++ b/core/lib/multivm/src/versions/vm_m6/vm_with_bootloader.rs @@ -14,16 +14,14 @@ use zk_evm_1_3_1::{ use zksync_contracts::BaseSystemContracts; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; use zksync_types::{ - fee_model::L1PeggedBatchFeeModelInput, Address, Transaction, BOOTLOADER_ADDRESS, - L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, -}; -use zksync_utils::{ - address_to_u256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256, misc::ceil_div, + address_to_u256, fee_model::L1PeggedBatchFeeModelInput, h256_to_u256, Address, Transaction, + BOOTLOADER_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, U256, }; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{CompressedBytecodeInfo, L1BatchEnv}, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_m6::{ bootloader_state::BootloaderState, history_recorder::HistoryMode, @@ -84,8 +82,11 @@ pub(crate) fn eth_price_per_pubdata_byte(l1_gas_price: u64) -> u64 { pub(crate) fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } pub(crate) fn derive_base_fee_and_gas_per_pubdata( @@ -102,7 +103,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( @@ -396,7 +397,7 @@ pub fn init_vm_inner( oracle_tools.decommittment_processor.populate( vec![( h256_to_u256(base_system_contract.default_aa.hash), - base_system_contract.default_aa.code.clone(), + bytes_to_be_words(&base_system_contract.default_aa.code), )], Timestamp(0), ); @@ -404,7 +405,7 @@ pub fn init_vm_inner( oracle_tools.memory.populate( vec![( BOOTLOADER_CODE_PAGE, - base_system_contract.bootloader.code.clone(), + bytes_to_be_words(&base_system_contract.bootloader.code), )], Timestamp(0), ); @@ -821,7 +822,7 @@ pub(crate) fn get_bootloader_memory_for_encoded_tx( .flat_map(bytecode::encode_call) .collect(); - let memory_addition = bytes_to_be_words(memory_addition); + let memory_addition = bytes_to_be_words(&memory_addition); memory.extend( (compressed_bytecodes_offset..compressed_bytecodes_offset + memory_addition.len()) @@ -906,9 +907,7 @@ fn formal_calldata_abi() -> PrimitiveValue { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/l2_block.rs index e8cabebc9f7c..3bc669105b05 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn interim_version(&self) -> BootloaderL2Block { diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/utils.rs index 14c895d7a0b4..a05dc1ae2430 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/bootloader_state/utils.rs @@ -1,10 +1,9 @@ -use zksync_types::U256; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{h256_to_u256, U256}; use super::tx::BootloaderTx; use crate::{ interface::{BootloaderMemory, CompressedBytecodeInfo, TxExecutionMode}, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_refunds_enhancement::{ bootloader_state::l2_block::BootloaderL2Block, constants::{ @@ -23,8 +22,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs index f7ab9ae8b517..766cac391e32 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/implementation/bytecode.rs @@ -1,13 +1,13 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, CompressedBytecodeInfo, }, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_refunds_enhancement::Vm, HistoryMode, }; @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/events.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/events.rs index 52a4ed8a2876..05ec6557e905 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_3_3::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/history_recorder.rs index 8af2c42db957..d25d2a57259d 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_3_3::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, H256, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, H256, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs index ccc8d9052b7e..fc9d0794b958 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/old_vm/oracles/decommitter.rs @@ -6,12 +6,13 @@ use zk_evm_1_3_3::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_refunds_enhancement::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, @@ -61,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/oracles/storage.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/oracles/storage.rs index a9c5b71e782e..73a5d610bc26 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/oracles/storage.rs @@ -6,10 +6,9 @@ use zk_evm_1_3_3::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ - utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, StorageLogKind, - BOOTLOADER_ADDRESS, U256, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, + StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use crate::{ glue::GlueInto, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs index 0dbf5a3cbf40..98fee074a940 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/refunds.rs @@ -5,8 +5,8 @@ use zk_evm_1_3_3::{ vm_state::VmLocalState, }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_types::{l2_to_l1_log::L2ToL1Log, L1BatchNumber, U256}; -use zksync_utils::{bytecode::bytecode_len_in_bytes, ceil_div_u256, u256_to_h256}; +use zksync_types::{ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, U256}; +use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs index 1d3e9a272764..d744261e4f48 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_refunds_enhancement::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs index 22ab09296c91..5bc13bfac2d0 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_refunds_enhancement::{ - constants::MAX_GAS_PER_PUBDATA_BYTE, - utils::overhead::{get_amortized_overhead, OverheadCoefficients}, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_refunds_enhancement::{ + constants::MAX_GAS_PER_PUBDATA_BYTE, + utils::overhead::{get_amortized_overhead, OverheadCoefficients}, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn effective_gas_price_per_pubdata(&self, block_gas_price_per_pubdata: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs index 22f92891e40a..6776bc37c9d5 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_3_3::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_refunds_enhancement::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -89,11 +89,7 @@ pub(crate) fn new_vm_state( decommittment_processor.populate( vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )], Timestamp(0), ); @@ -101,11 +97,7 @@ pub(crate) fn new_vm_state( memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/l1_batch.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/l1_batch.rs index b449165be348..58419acbe60a 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/types/l1_batch.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/types/l1_batch.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_refunds_enhancement::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/fee.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/fee.rs index f7203b57b4c4..8bd06c7faa6b 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::L1PeggedBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{ interface::L1BatchEnv, @@ -12,8 +11,11 @@ use crate::{ /// Calculates the amount of gas required to publish one byte of pubdata pub(crate) fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } /// Calculates the base fee and gas per pubdata for the given L1 gas price. @@ -30,7 +32,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/l2_blocks.rs index ff5536ae0b97..1095abd82db1 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/overhead.rs b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/overhead.rs index af25c4b4d7c4..efcee968db40 100644 --- a/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/overhead.rs +++ b/core/lib/multivm/src/versions/vm_refunds_enhancement/utils/overhead.rs @@ -1,7 +1,6 @@ use zk_evm_1_3_3::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; -use zksync_types::{l1::is_l1_tx_type, U256}; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, l1::is_l1_tx_type, U256}; use crate::vm_refunds_enhancement::constants::{ BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK, diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/l2_block.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/l2_block.rs index 197ecbff5896..d100b17c7c08 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/l2_block.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/l2_block.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; -use zksync_types::{L2BlockNumber, H256}; -use zksync_utils::concat_and_hash; +use zksync_types::{web3::keccak256_concat, L2BlockNumber, H256}; use crate::{ interface::{L2Block, L2BlockEnv}, @@ -53,7 +52,7 @@ impl BootloaderL2Block { } fn update_rolling_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash) + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash) } pub(crate) fn interim_version(&self) -> BootloaderL2Block { diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/utils.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/utils.rs index 3e2474835fa4..4c33aeb6e147 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/utils.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/bootloader_state/utils.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{bytes_to_be_words, h256_to_u256}; +use zksync_types::{h256_to_u256, U256}; use super::tx::BootloaderTx; use crate::{ @@ -23,8 +22,7 @@ pub(super) fn get_memory_for_compressed_bytecodes( .iter() .flat_map(bytecode::encode_call) .collect(); - - bytes_to_be_words(memory_addition) + bytecode::bytes_to_be_words(&memory_addition) } #[allow(clippy::too_many_arguments)] diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs index d5f2b50b83fc..2b26d4fc9d6d 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/implementation/bytecode.rs @@ -1,13 +1,13 @@ use itertools::Itertools; use zksync_types::U256; -use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, CompressedBytecodeInfo, }, - utils::bytecode, + utils::{bytecode, bytecode::bytes_to_be_words}, vm_virtual_blocks::Vm, HistoryMode, }; @@ -34,9 +34,7 @@ impl Vm { pub(crate) fn bytecode_to_factory_dep(bytecode: Vec) -> (U256, Vec) { let bytecode_hash = hash_bytecode(&bytecode); let bytecode_hash = U256::from_big_endian(bytecode_hash.as_bytes()); - - let bytecode_words = bytes_to_be_words(bytecode); - + let bytecode_words = bytes_to_be_words(&bytecode); (bytecode_hash, bytecode_words) } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/events.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/events.rs index 52a4ed8a2876..05ec6557e905 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/events.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/events.rs @@ -1,8 +1,7 @@ use zk_evm_1_3_3::{ethereum_types::Address, reference_impls::event_sink::EventMessage}; -use zksync_types::{L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use zksync_utils::{be_chunks_to_h256_words, h256_to_account_address}; +use zksync_types::{h256_to_address, L1BatchNumber, EVENT_WRITER_ADDRESS, H256}; -use crate::interface::VmEvent; +use crate::{interface::VmEvent, utils::bytecode::be_chunks_to_h256_words}; #[derive(Clone)] pub(crate) struct SolidityLikeEvent { @@ -135,7 +134,7 @@ pub(crate) fn merge_events(events: Vec) -> Vec .filter(|e| e.address == EVENT_WRITER_ADDRESS) .map(|event| { // The events writer events where the first topic is the actual address of the event and the rest of the topics are real topics - let address = h256_to_account_address(&H256(event.topics[0])); + let address = h256_to_address(&H256(event.topics[0])); let topics = event.topics.into_iter().skip(1).collect(); SolidityLikeEvent { diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/history_recorder.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/history_recorder.rs index cbd4dc0ed738..111a337bf449 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/history_recorder.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/history_recorder.rs @@ -5,8 +5,7 @@ use zk_evm_1_3_3::{ vm_state::PrimitiveValue, zkevm_opcode_defs::{self}, }; -use zksync_types::{StorageKey, H256, U256}; -use zksync_utils::{h256_to_u256, u256_to_h256}; +use zksync_types::{h256_to_u256, u256_to_h256, StorageKey, H256, U256}; use crate::interface::storage::{StoragePtr, WriteStorage}; diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs index 3c8d72b0b33a..fad51513dbca 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/decommitter.rs @@ -6,12 +6,13 @@ use zk_evm_1_3_3::{ DecommittmentQuery, MemoryIndex, MemoryLocation, MemoryPage, MemoryQuery, Timestamp, }, }; -use zksync_types::U256; -use zksync_utils::{bytecode::bytecode_len_in_words, bytes_to_be_words, u256_to_h256}; +use zksync_types::{u256_to_h256, U256}; +use zksync_utils::bytecode::bytecode_len_in_words; use super::OracleWithHistory; use crate::{ interface::storage::{ReadStorage, StoragePtr}, + utils::bytecode::bytes_to_be_words, vm_virtual_blocks::old_vm::history_recorder::{ HistoryEnabled, HistoryMode, HistoryRecorder, WithHistory, }, @@ -61,7 +62,7 @@ impl DecommitterOracle { .load_factory_dep(u256_to_h256(hash)) .expect("Trying to decode unexisting hash"); - let value = bytes_to_be_words(value); + let value = bytes_to_be_words(&value); self.known_bytecodes.insert(hash, value.clone(), timestamp); value } diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/storage.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/storage.rs index defbad70f1a9..0b3a590d8d18 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/storage.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/old_vm/oracles/storage.rs @@ -6,10 +6,9 @@ use zk_evm_1_3_3::{ zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES, }; use zksync_types::{ - utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, StorageLogKind, - BOOTLOADER_ADDRESS, U256, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, StorageKey, + StorageLogKind, BOOTLOADER_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use super::OracleWithHistory; use crate::{ diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs index a2ca08a7ef96..b35dfecfa400 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/refunds.rs @@ -8,8 +8,10 @@ use zk_evm_1_3_3::{ vm_state::VmLocalState, }; use zksync_system_constants::{PUBLISH_BYTECODE_OVERHEAD, SYSTEM_CONTEXT_ADDRESS}; -use zksync_types::{l2_to_l1_log::L2ToL1Log, L1BatchNumber, StorageKey, U256}; -use zksync_utils::{bytecode::bytecode_len_in_bytes, ceil_div_u256, u256_to_h256}; +use zksync_types::{ + ceil_div_u256, l2_to_l1_log::L2ToL1Log, u256_to_h256, L1BatchNumber, StorageKey, U256, +}; +use zksync_utils::bytecode::bytecode_len_in_bytes; use crate::{ interface::{ diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs index ef8219ec2b4d..6db2bac819df 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/tracers/utils.rs @@ -9,8 +9,7 @@ use zksync_system_constants::{ ECRECOVER_PRECOMPILE_ADDRESS, KECCAK256_PRECOMPILE_ADDRESS, KNOWN_CODES_STORAGE_ADDRESS, L1_MESSENGER_ADDRESS, SHA256_PRECOMPILE_ADDRESS, }; -use zksync_types::U256; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, U256}; use crate::vm_virtual_blocks::{ constants::{ diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs index c96004163a65..a2540d12a670 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/transaction_data.rs @@ -1,19 +1,24 @@ use std::convert::TryInto; use zksync_types::{ + address_to_h256, ethabi::{encode, Address, Token}, fee::{encoding_len, Fee}, + h256_to_u256, l1::is_l1_tx_type, l2::{L2Tx, TransactionType}, transaction_request::{PaymasterParams, TransactionRequest}, web3::Bytes, Execute, ExecuteTransactionCommon, L2ChainId, L2TxCommonData, Nonce, Transaction, H256, U256, }; -use zksync_utils::{address_to_h256, bytecode::hash_bytecode, bytes_to_be_words, h256_to_u256}; - -use crate::vm_virtual_blocks::{ - constants::MAX_GAS_PER_PUBDATA_BYTE, - utils::overhead::{get_amortized_overhead, OverheadCoefficients}, +use zksync_utils::bytecode::hash_bytecode; + +use crate::{ + utils::bytecode::bytes_to_be_words, + vm_virtual_blocks::{ + constants::MAX_GAS_PER_PUBDATA_BYTE, + utils::overhead::{get_amortized_overhead, OverheadCoefficients}, + }, }; /// This structure represents the data that is used by @@ -196,10 +201,7 @@ impl TransactionData { } pub(crate) fn into_tokens(self) -> Vec { - let bytes = self.abi_encode(); - assert!(bytes.len() % 32 == 0); - - bytes_to_be_words(bytes) + bytes_to_be_words(&self.abi_encode()) } pub(crate) fn effective_gas_price_per_pubdata(&self, block_gas_price_per_pubdata: u32) -> u32 { diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs index d26acc4e9301..d1509bd016d8 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/types/internals/vm_state.rs @@ -11,14 +11,14 @@ use zk_evm_1_3_3::{ }, }; use zksync_system_constants::BOOTLOADER_ADDRESS; -use zksync_types::{block::L2BlockHasher, Address, L2BlockNumber}; -use zksync_utils::h256_to_u256; +use zksync_types::{block::L2BlockHasher, h256_to_u256, Address, L2BlockNumber}; use crate::{ interface::{ storage::{StoragePtr, WriteStorage}, L1BatchEnv, L2Block, SystemEnv, }, + utils::bytecode::bytes_to_be_words, vm_virtual_blocks::{ bootloader_state::BootloaderState, constants::BOOTLOADER_HEAP_PAGE, @@ -89,11 +89,7 @@ pub(crate) fn new_vm_state( decommittment_processor.populate( vec![( h256_to_u256(system_env.base_system_smart_contracts.default_aa.hash), - system_env - .base_system_smart_contracts - .default_aa - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.default_aa.code), )], Timestamp(0), ); @@ -101,11 +97,7 @@ pub(crate) fn new_vm_state( memory.populate( vec![( BOOTLOADER_CODE_PAGE, - system_env - .base_system_smart_contracts - .bootloader - .code - .clone(), + bytes_to_be_words(&system_env.base_system_smart_contracts.bootloader.code), )], Timestamp(0), ); diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/types/l1_batch_env.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/types/l1_batch_env.rs index f86d8749c9ed..08fe00741189 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/types/l1_batch_env.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/types/l1_batch_env.rs @@ -1,5 +1,4 @@ -use zksync_types::U256; -use zksync_utils::{address_to_u256, h256_to_u256}; +use zksync_types::{address_to_u256, h256_to_u256, U256}; use crate::{interface::L1BatchEnv, vm_virtual_blocks::utils::fee::get_batch_base_fee}; diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/fee.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/fee.rs index a53951a851e1..e9d46570983d 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/fee.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/fee.rs @@ -1,6 +1,5 @@ //! Utility functions for vm use zksync_types::fee_model::L1PeggedBatchFeeModelInput; -use zksync_utils::ceil_div; use crate::{ interface::L1BatchEnv, @@ -12,8 +11,11 @@ use crate::{ /// Calculates the amount of gas required to publish one byte of pubdata pub(crate) fn base_fee_to_gas_per_pubdata(l1_gas_price: u64, base_fee: u64) -> u64 { let eth_price_per_pubdata_byte = eth_price_per_pubdata_byte(l1_gas_price); - - ceil_div(eth_price_per_pubdata_byte, base_fee) + if eth_price_per_pubdata_byte == 0 { + 0 + } else { + eth_price_per_pubdata_byte.div_ceil(base_fee) + } } /// Calculates the base fee and gas per pubdata for the given L1 gas price. @@ -31,7 +33,7 @@ pub(crate) fn derive_base_fee_and_gas_per_pubdata( // publish enough public data while compensating us for it. let base_fee = std::cmp::max( fair_l2_gas_price, - ceil_div(eth_price_per_pubdata_byte, MAX_GAS_PER_PUBDATA_BYTE), + eth_price_per_pubdata_byte.div_ceil(MAX_GAS_PER_PUBDATA_BYTE), ); ( diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/l2_blocks.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/l2_blocks.rs index ff5536ae0b97..1095abd82db1 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/l2_blocks.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/l2_blocks.rs @@ -4,9 +4,9 @@ use zksync_system_constants::{ SYSTEM_CONTEXT_STORED_L2_BLOCK_HASHES, }; use zksync_types::{ - block::unpack_block_info, web3::keccak256, AccountTreeId, L2BlockNumber, StorageKey, H256, U256, + block::unpack_block_info, h256_to_u256, u256_to_h256, web3::keccak256, AccountTreeId, + L2BlockNumber, StorageKey, H256, U256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::interface::{ storage::{ReadStorage, StoragePtr}, diff --git a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/overhead.rs b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/overhead.rs index cba4700002bb..6c79c05bc5b2 100644 --- a/core/lib/multivm/src/versions/vm_virtual_blocks/utils/overhead.rs +++ b/core/lib/multivm/src/versions/vm_virtual_blocks/utils/overhead.rs @@ -1,7 +1,6 @@ use zk_evm_1_3_3::zkevm_opcode_defs::system_params::MAX_TX_ERGS_LIMIT; use zksync_system_constants::MAX_L2_TX_GAS_LIMIT; -use zksync_types::{l1::is_l1_tx_type, U256}; -use zksync_utils::ceil_div_u256; +use zksync_types::{ceil_div_u256, l1::is_l1_tx_type, U256}; use crate::vm_virtual_blocks::constants::{ BLOCK_OVERHEAD_GAS, BLOCK_OVERHEAD_PUBDATA, BOOTLOADER_TX_ENCODING_SPACE, MAX_TXS_IN_BLOCK, diff --git a/core/lib/state/Cargo.toml b/core/lib/state/Cargo.toml index dd56368f3d2e..ced06de1a8e8 100644 --- a/core/lib/state/Cargo.toml +++ b/core/lib/state/Cargo.toml @@ -14,7 +14,6 @@ categories.workspace = true vise.workspace = true zksync_dal.workspace = true zksync_types.workspace = true -zksync_utils.workspace = true zksync_shared_metrics.workspace = true zksync_storage.workspace = true zksync_vm_interface.workspace = true diff --git a/core/lib/state/src/storage_factory/mod.rs b/core/lib/state/src/storage_factory/mod.rs index 0b514f8f9644..be7e20c5f83d 100644 --- a/core/lib/state/src/storage_factory/mod.rs +++ b/core/lib/state/src/storage_factory/mod.rs @@ -5,8 +5,7 @@ use async_trait::async_trait; use tokio::{runtime::Handle, sync::watch}; use zksync_dal::{Connection, ConnectionPool, Core, CoreDal}; use zksync_storage::RocksDB; -use zksync_types::{L1BatchNumber, StorageKey, StorageValue, H256}; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, L1BatchNumber, StorageKey, StorageValue, H256}; use zksync_vm_interface::storage::{ReadStorage, StorageSnapshot}; use self::metrics::{SnapshotStage, SNAPSHOT_METRICS}; @@ -201,10 +200,7 @@ impl CommonStorage<'static> { let factory_deps = bytecodes .into_iter() - .map(|(hash_u256, words)| { - let bytes: Vec = words.into_iter().flatten().collect(); - (u256_to_h256(hash_u256), bytes) - }) + .map(|(hash_u256, bytes)| (u256_to_h256(hash_u256), bytes)) .collect(); let storage = previous_values.into_iter().map(|(key, prev_value)| { diff --git a/core/lib/tee_verifier/Cargo.toml b/core/lib/tee_verifier/Cargo.toml index 331c47e365eb..289803fb5a89 100644 --- a/core/lib/tee_verifier/Cargo.toml +++ b/core/lib/tee_verifier/Cargo.toml @@ -17,7 +17,6 @@ zksync_merkle_tree.workspace = true zksync_multivm.workspace = true zksync_prover_interface.workspace = true zksync_types.workspace = true -zksync_utils.workspace = true anyhow.workspace = true once_cell.workspace = true diff --git a/core/lib/tee_verifier/src/lib.rs b/core/lib/tee_verifier/src/lib.rs index 140085dbb9fe..8e8362b57f4b 100644 --- a/core/lib/tee_verifier/src/lib.rs +++ b/core/lib/tee_verifier/src/lib.rs @@ -23,10 +23,9 @@ use zksync_prover_interface::inputs::{ StorageLogMetadata, V1TeeVerifierInput, WitnessInputMerklePaths, }; use zksync_types::{ - block::L2BlockExecutionData, commitment::PubdataParams, L1BatchNumber, StorageLog, - StorageValue, Transaction, H256, + block::L2BlockExecutionData, commitment::PubdataParams, u256_to_h256, L1BatchNumber, + StorageLog, StorageValue, Transaction, H256, }; -use zksync_utils::u256_to_h256; /// A structure to hold the result of verification. pub struct VerificationResult { @@ -305,7 +304,6 @@ mod tests { use zksync_contracts::{BaseSystemContracts, SystemContractCode}; use zksync_multivm::interface::{L1BatchEnv, SystemEnv, TxExecutionMode}; use zksync_prover_interface::inputs::{TeeVerifierInput, VMRunWitnessInputData}; - use zksync_types::U256; use super::*; @@ -345,11 +343,11 @@ mod tests { version: Default::default(), base_system_smart_contracts: BaseSystemContracts { bootloader: SystemContractCode { - code: vec![U256([1; 4])], + code: vec![1; 32], hash: H256([1; 32]), }, default_aa: SystemContractCode { - code: vec![U256([1; 4])], + code: vec![1; 32], hash: H256([1; 32]), }, evm_emulator: None, diff --git a/core/lib/types/src/abi.rs b/core/lib/types/src/abi.rs index 84f8aba64869..1ce709617ccf 100644 --- a/core/lib/types/src/abi.rs +++ b/core/lib/types/src/abi.rs @@ -1,9 +1,10 @@ use anyhow::Context as _; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ ethabi, ethabi::{ParamType, Token}, + h256_to_u256, transaction_request::TransactionRequest, web3, Address, H256, U256, }; diff --git a/core/lib/types/src/block.rs b/core/lib/types/src/block.rs index 310e3a73b8e8..804da61b7295 100644 --- a/core/lib/types/src/block.rs +++ b/core/lib/types/src/block.rs @@ -4,13 +4,12 @@ use serde::{Deserialize, Serialize}; use zksync_basic_types::{commitment::PubdataParams, Address, Bloom, BloomInput, H256, U256}; use zksync_contracts::BaseSystemContractsHashes; use zksync_system_constants::SYSTEM_BLOCK_INFO_BLOCK_NUMBER_MULTIPLIER; -use zksync_utils::concat_and_hash; use crate::{ fee_model::BatchFeeInput, l2_to_l1_log::{SystemL2ToL1Log, UserL2ToL1Log}, priority_op_onchain_data::PriorityOpOnchainData, - web3::keccak256, + web3::{keccak256, keccak256_concat}, AccountTreeId, L1BatchNumber, L2BlockNumber, ProtocolVersionId, Transaction, }; @@ -253,7 +252,7 @@ impl L2BlockHasher { /// Updates this hasher with a transaction hash. This should be called for all transactions in the block /// in the order of their execution. pub fn push_tx_hash(&mut self, tx_hash: H256) { - self.txs_rolling_hash = concat_and_hash(self.txs_rolling_hash, tx_hash); + self.txs_rolling_hash = keccak256_concat(self.txs_rolling_hash, tx_hash); } /// Returns the hash of the L2 block. diff --git a/core/lib/types/src/commitment/mod.rs b/core/lib/types/src/commitment/mod.rs index 40532a1e5899..1eba7e7a9ec0 100644 --- a/core/lib/types/src/commitment/mod.rs +++ b/core/lib/types/src/commitment/mod.rs @@ -17,7 +17,6 @@ use zksync_system_constants::{ KNOWN_CODES_STORAGE_ADDRESS, L2_TO_L1_LOGS_TREE_ROOT_KEY, STATE_DIFF_HASH_KEY_PRE_GATEWAY, ZKPORTER_IS_AVAILABLE, }; -use zksync_utils::u256_to_h256; use crate::{ blob::num_blobs_required, @@ -26,6 +25,7 @@ use crate::{ l2_to_l1_logs_tree_size, parse_system_logs_for_blob_hashes_pre_gateway, L2ToL1Log, SystemL2ToL1Log, UserL2ToL1Log, }, + u256_to_h256, web3::keccak256, writes::{ compress_state_diffs, InitialStorageWrite, RepeatedStorageWrite, StateDiffRecord, diff --git a/core/lib/types/src/fee.rs b/core/lib/types/src/fee.rs index 9dc2cda9e62b..f302c51cd4a9 100644 --- a/core/lib/types/src/fee.rs +++ b/core/lib/types/src/fee.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use zksync_utils::ceil_div; use crate::U256; @@ -43,10 +42,10 @@ pub fn encoding_len( // All of the fields are encoded as `bytes`, so their encoding takes ceil(len, 32) slots. // For factory deps we only provide hashes, which are encoded as an array of bytes32. - let dynamic_len = ceil_div(data_len, 32) - + ceil_div(signature_len, 32) - + ceil_div(paymaster_input_len, 32) - + ceil_div(reserved_dynamic_len, 32) + let dynamic_len = data_len.div_ceil(32) + + signature_len.div_ceil(32) + + paymaster_input_len.div_ceil(32) + + reserved_dynamic_len.div_ceil(32) + factory_deps_len; BASE_LEN + dynamic_len as usize diff --git a/core/lib/types/src/fee_model.rs b/core/lib/types/src/fee_model.rs index ae346656ea6f..79515e6f63a9 100644 --- a/core/lib/types/src/fee_model.rs +++ b/core/lib/types/src/fee_model.rs @@ -1,13 +1,10 @@ -// FIXME: separate crate together with node_fee_model interfaces? - use std::num::NonZeroU64; use bigdecimal::{BigDecimal, ToPrimitive}; use serde::{Deserialize, Serialize}; use zksync_system_constants::L1_GAS_PER_PUBDATA_BYTE; -use zksync_utils::ceil_div_u256; -use crate::{ProtocolVersionId, U256}; +use crate::{ceil_div_u256, ProtocolVersionId, U256}; /// Fee input to be provided into the VM. It contains two options: /// - `L1Pegged`: L1 gas price is provided to the VM, and the pubdata price is derived from it. Using this option is required for the diff --git a/core/lib/types/src/l1/mod.rs b/core/lib/types/src/l1/mod.rs index e8144c75db2e..0cc0f3b0e489 100644 --- a/core/lib/types/src/l1/mod.rs +++ b/core/lib/types/src/l1/mod.rs @@ -4,19 +4,18 @@ use std::convert::TryFrom; use serde::{Deserialize, Serialize}; use zksync_basic_types::{web3::Log, Address, L1BlockNumber, PriorityOpId, H256, U256}; -use zksync_utils::{ - address_to_u256, bytecode::hash_bytecode, h256_to_u256, u256_to_account_address, -}; +use zksync_utils::bytecode::hash_bytecode; use super::Transaction; use crate::{ - abi, ethabi, + abi, address_to_u256, ethabi, h256_to_u256, helpers::unix_timestamp_ms, l1::error::L1TxParseError, l2::TransactionType, priority_op_onchain_data::{PriorityOpOnchainData, PriorityOpOnchainMetadata}, tx::Execute, - ExecuteTransactionCommon, PRIORITY_OPERATION_L2_TX_TYPE, PROTOCOL_UPGRADE_TX_TYPE, + u256_to_address, ExecuteTransactionCommon, PRIORITY_OPERATION_L2_TX_TYPE, + PROTOCOL_UPGRADE_TX_TYPE, }; pub mod error; @@ -332,10 +331,10 @@ impl TryFrom for L1Tx { let common_data = L1TxCommonData { serial_id: PriorityOpId(req.transaction.nonce.try_into().unwrap()), canonical_tx_hash: H256::from_slice(&req.tx_hash), - sender: u256_to_account_address(&req.transaction.from), + sender: u256_to_address(&req.transaction.from), layer_2_tip_fee: U256::zero(), to_mint: req.transaction.reserved[0], - refund_recipient: u256_to_account_address(&req.transaction.reserved[1]), + refund_recipient: u256_to_address(&req.transaction.reserved[1]), full_fee: U256::zero(), gas_limit: req.transaction.gas_limit, max_fee_per_gas: req.transaction.max_fee_per_gas, @@ -347,7 +346,7 @@ impl TryFrom for L1Tx { }; let execute = Execute { - contract_address: Some(u256_to_account_address(&req.transaction.to)), + contract_address: Some(u256_to_address(&req.transaction.to)), calldata: req.transaction.data, factory_deps: req.factory_deps, value: req.transaction.value, diff --git a/core/lib/types/src/l2_to_l1_log.rs b/core/lib/types/src/l2_to_l1_log.rs index 957cfa9a1a6a..1b84a79024c7 100644 --- a/core/lib/types/src/l2_to_l1_log.rs +++ b/core/lib/types/src/l2_to_l1_log.rs @@ -117,11 +117,10 @@ pub fn parse_system_logs_for_blob_hashes_pre_gateway( #[cfg(test)] mod tests { - use zksync_basic_types::U256; use zksync_system_constants::L1_MESSENGER_ADDRESS; - use zksync_utils::u256_to_h256; - use super::L2ToL1Log; + use super::*; + use crate::{u256_to_h256, U256}; #[test] fn l2_to_l1_log_to_bytes() { diff --git a/core/lib/types/src/lib.rs b/core/lib/types/src/lib.rs index 320264f28f0a..48ed7445ef5e 100644 --- a/core/lib/types/src/lib.rs +++ b/core/lib/types/src/lib.rs @@ -17,9 +17,7 @@ pub use storage::*; pub use tx::Execute; pub use zksync_basic_types::{protocol_version::ProtocolVersionId, vm, *}; pub use zksync_crypto_primitives::*; -use zksync_utils::{ - address_to_u256, bytecode::hash_bytecode, h256_to_u256, u256_to_account_address, -}; +use zksync_utils::bytecode::hash_bytecode; use crate::{ l2::{L2Tx, TransactionType}, @@ -368,10 +366,10 @@ impl Transaction { .map_err(|err| anyhow::format_err!("{err}"))?, ), canonical_tx_hash: hash, - sender: u256_to_account_address(&tx.from), + sender: u256_to_address(&tx.from), layer_2_tip_fee: U256::zero(), to_mint: tx.reserved[0], - refund_recipient: u256_to_account_address(&tx.reserved[1]), + refund_recipient: u256_to_address(&tx.reserved[1]), full_fee: U256::zero(), gas_limit: tx.gas_limit, max_fee_per_gas: tx.max_fee_per_gas, @@ -385,9 +383,9 @@ impl Transaction { ExecuteTransactionCommon::ProtocolUpgrade(ProtocolUpgradeTxCommonData { upgrade_id: tx.nonce.try_into().unwrap(), canonical_tx_hash: hash, - sender: u256_to_account_address(&tx.from), + sender: u256_to_address(&tx.from), to_mint: tx.reserved[0], - refund_recipient: u256_to_account_address(&tx.reserved[1]), + refund_recipient: u256_to_address(&tx.reserved[1]), gas_limit: tx.gas_limit, max_fee_per_gas: tx.max_fee_per_gas, gas_per_pubdata_limit: tx.gas_per_pubdata_byte_limit, @@ -397,7 +395,7 @@ impl Transaction { unknown_type => anyhow::bail!("unknown tx type {unknown_type}"), }, execute: Execute { - contract_address: Some(u256_to_account_address(&tx.to)), + contract_address: Some(u256_to_address(&tx.to)), calldata: tx.data, factory_deps, value: tx.value, diff --git a/core/lib/types/src/protocol_upgrade.rs b/core/lib/types/src/protocol_upgrade.rs index 48f26dfd5c7f..7d8f678fa851 100644 --- a/core/lib/types/src/protocol_upgrade.rs +++ b/core/lib/types/src/protocol_upgrade.rs @@ -12,11 +12,10 @@ use zksync_contracts::{ BaseSystemContractsHashes, ADMIN_EXECUTE_UPGRADE_FUNCTION, ADMIN_UPGRADE_CHAIN_FROM_VERSION_FUNCTION, DIAMOND_CUT, }; -use zksync_utils::h256_to_u256; use crate::{ - abi, ethabi::ParamType, web3::Log, Address, Execute, ExecuteTransactionCommon, Transaction, - TransactionType, H256, U256, + abi, ethabi::ParamType, h256_to_u256, web3::Log, Address, Execute, ExecuteTransactionCommon, + Transaction, TransactionType, H256, U256, }; /// Represents a call to be made during governance operation. diff --git a/core/lib/types/src/snapshots.rs b/core/lib/types/src/snapshots.rs index 156d1e4723dd..b9ee62ab24ec 100644 --- a/core/lib/types/src/snapshots.rs +++ b/core/lib/types/src/snapshots.rs @@ -5,9 +5,8 @@ use num_enum::{IntoPrimitive, TryFromPrimitive}; use serde::{Deserialize, Serialize}; use zksync_basic_types::{AccountTreeId, L1BatchNumber, L2BlockNumber, H256}; use zksync_protobuf::{required, ProtoFmt}; -use zksync_utils::u256_to_h256; -use crate::{utils, web3::Bytes, ProtocolVersionId, StorageKey, StorageValue, U256}; +use crate::{u256_to_h256, utils, web3::Bytes, ProtocolVersionId, StorageKey, StorageValue, U256}; /// Information about all snapshots persisted by the node. #[derive(Debug, Clone, Serialize, Deserialize)] @@ -331,9 +330,8 @@ pub fn uniform_hashed_keys_chunk(chunk_id: u64, chunk_count: u64) -> ops::RangeI #[cfg(test)] mod tests { - use zksync_utils::h256_to_u256; - use super::*; + use crate::h256_to_u256; #[test] fn chunking_is_correct() { diff --git a/core/lib/types/src/storage/log.rs b/core/lib/types/src/storage/log.rs index a05e25abccb5..075a05781b67 100644 --- a/core/lib/types/src/storage/log.rs +++ b/core/lib/types/src/storage/log.rs @@ -2,10 +2,10 @@ use std::mem; use serde::{Deserialize, Serialize}; use zksync_basic_types::AccountTreeId; -use zksync_utils::{h256_to_u256, u256_to_h256}; use crate::{ api::ApiStorageLog, + h256_to_u256, u256_to_h256, zk_evm_types::{self, LogQuery, Timestamp}, StorageKey, StorageValue, U256, }; diff --git a/core/lib/types/src/storage/mod.rs b/core/lib/types/src/storage/mod.rs index 9ef037dc29b2..84a29ed8c039 100644 --- a/core/lib/types/src/storage/mod.rs +++ b/core/lib/types/src/storage/mod.rs @@ -5,9 +5,8 @@ pub use log::*; use serde::{Deserialize, Serialize}; use zksync_basic_types::{web3::keccak256, L2ChainId}; pub use zksync_system_constants::*; -use zksync_utils::{address_to_h256, u256_to_h256}; -use crate::{AccountTreeId, Address, H160, H256, U256}; +use crate::{address_to_h256, u256_to_h256, AccountTreeId, Address, H160, H256, U256}; pub mod log; pub mod witness_block_state; diff --git a/core/lib/types/src/transaction_request.rs b/core/lib/types/src/transaction_request.rs index a8713f301ba6..931615bad0fe 100644 --- a/core/lib/types/src/transaction_request.rs +++ b/core/lib/types/src/transaction_request.rs @@ -5,17 +5,15 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use zksync_basic_types::H256; use zksync_system_constants::{DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE, MAX_ENCODED_TX_SIZE}; -use zksync_utils::{ - bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}, - concat_and_hash, u256_to_h256, -}; +use zksync_utils::bytecode::{hash_bytecode, validate_bytecode, InvalidBytecodeError}; use super::{EIP_1559_TX_TYPE, EIP_2930_TX_TYPE, EIP_712_TX_TYPE}; use crate::{ fee::Fee, l1::L1Tx, l2::{L2Tx, TransactionType}, - web3::{keccak256, AccessList, Bytes}, + u256_to_h256, + web3::{keccak256, keccak256_concat, AccessList, Bytes}, Address, EIP712TypedStructure, Eip712Domain, L1TxCommonData, L2ChainId, Nonce, PackedEthSignature, StructBuilder, LEGACY_TX_TYPE, U256, U64, }; @@ -732,7 +730,7 @@ impl TransactionRequest { signed_message: H256, ) -> Result, SerializationTransactionError> { if self.is_eip712_tx() { - return Ok(Some(concat_and_hash( + return Ok(Some(keccak256_concat( signed_message, H256(keccak256(&self.get_signature()?)), ))); diff --git a/core/lib/types/src/tx/execute.rs b/core/lib/types/src/tx/execute.rs index 0edece9e46b4..0c3f63467cc4 100644 --- a/core/lib/types/src/tx/execute.rs +++ b/core/lib/types/src/tx/execute.rs @@ -1,9 +1,12 @@ use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use zksync_system_constants::CONTRACT_DEPLOYER_ADDRESS; -use zksync_utils::{bytecode::hash_bytecode, ZeroPrefixHexSerde}; +use zksync_utils::bytecode::hash_bytecode; -use crate::{ethabi, Address, EIP712TypedStructure, StructBuilder, H256, U256}; +use crate::{ + ethabi, serde_wrappers::ZeroPrefixHexSerde, Address, EIP712TypedStructure, StructBuilder, H256, + U256, +}; /// This struct is the `serde` schema for the `Execute` struct. /// It allows us to modify `Execute` struct without worrying diff --git a/core/lib/types/src/utils.rs b/core/lib/types/src/utils.rs index bf086d6cdcd4..56a8ccf9fe9f 100644 --- a/core/lib/types/src/utils.rs +++ b/core/lib/types/src/utils.rs @@ -2,11 +2,10 @@ use std::fmt; use chrono::{DateTime, TimeZone, Utc}; use zksync_basic_types::{Address, H256}; -use zksync_utils::{address_to_h256, u256_to_h256}; use crate::{ - system_contracts::DEPLOYMENT_NONCE_INCREMENT, web3::keccak256, AccountTreeId, StorageKey, - L2_BASE_TOKEN_ADDRESS, U256, + address_to_h256, system_contracts::DEPLOYMENT_NONCE_INCREMENT, u256_to_h256, web3::keccak256, + AccountTreeId, StorageKey, L2_BASE_TOKEN_ADDRESS, U256, }; /// Displays a Unix timestamp (seconds since epoch) in human-readable form. Useful for logging. diff --git a/core/lib/utils/Cargo.toml b/core/lib/utils/Cargo.toml index 9b65ccdd29cb..9ba286a7e493 100644 --- a/core/lib/utils/Cargo.toml +++ b/core/lib/utils/Cargo.toml @@ -15,22 +15,16 @@ zksync_basic_types.workspace = true zk_evm.workspace = true zksync_vlog.workspace = true -bigdecimal.workspace = true const-decoder.workspace = true -num = { workspace = true, features = ["serde"] } -serde = { workspace = true, features = ["derive"] } tokio = { workspace = true, features = ["time"] } tracing.workspace = true anyhow.workspace = true thiserror.workspace = true futures.workspace = true -hex.workspace = true reqwest = { workspace = true, features = ["blocking"] } serde_json.workspace = true once_cell.workspace = true [dev-dependencies] -rand.workspace = true tokio = { workspace = true, features = ["macros", "rt"] } -bincode.workspace = true assert_matches.workspace = true diff --git a/core/lib/utils/src/bytecode.rs b/core/lib/utils/src/bytecode.rs index 4fda5e9d48a0..fcba022f9277 100644 --- a/core/lib/utils/src/bytecode.rs +++ b/core/lib/utils/src/bytecode.rs @@ -1,11 +1,9 @@ -// FIXME: move to basic_types? +// FIXME (PLA-1064): move to basic_types use anyhow::Context as _; use zk_evm::k256::sha2::{Digest, Sha256}; use zksync_basic_types::{H256, U256}; -use crate::bytes_to_chunks; - const MAX_BYTECODE_LENGTH_IN_WORDS: usize = (1 << 16) - 1; const MAX_BYTECODE_LENGTH_BYTES: usize = MAX_BYTECODE_LENGTH_IN_WORDS * 32; @@ -42,6 +40,22 @@ pub fn validate_bytecode(code: &[u8]) -> Result<(), InvalidBytecodeError> { Ok(()) } +fn bytes_to_chunks(bytes: &[u8]) -> Vec<[u8; 32]> { + assert_eq!( + bytes.len() % 32, + 0, + "Bytes must be divisible by 32 to split into chunks" + ); + bytes + .chunks(32) + .map(|el| { + let mut chunk = [0u8; 32]; + chunk.copy_from_slice(el); + chunk + }) + .collect() +} + /// Hashes the provided EraVM bytecode. pub fn hash_bytecode(code: &[u8]) -> H256 { let chunked_code = bytes_to_chunks(code); diff --git a/core/lib/utils/src/convert.rs b/core/lib/utils/src/convert.rs deleted file mode 100644 index e086e385c8ef..000000000000 --- a/core/lib/utils/src/convert.rs +++ /dev/null @@ -1,185 +0,0 @@ -use std::convert::TryInto; - -use bigdecimal::BigDecimal; -use num::BigUint; -use zksync_basic_types::{Address, H256, U256}; - -pub fn u256_to_big_decimal(value: U256) -> BigDecimal { - let mut u32_digits = vec![0_u32; 8]; - // `u64_digit`s from `U256` are little-endian - for (i, &u64_digit) in value.0.iter().enumerate() { - u32_digits[2 * i] = u64_digit as u32; - u32_digits[2 * i + 1] = (u64_digit >> 32) as u32; - } - let value = BigUint::new(u32_digits); - BigDecimal::new(value.into(), 0) -} - -/// Converts `BigUint` value into the corresponding `U256` value. -fn biguint_to_u256(value: BigUint) -> U256 { - let bytes = value.to_bytes_le(); - U256::from_little_endian(&bytes) -} - -/// Converts `BigDecimal` value into the corresponding `U256` value. -pub fn bigdecimal_to_u256(value: BigDecimal) -> U256 { - let bigint = value.with_scale(0).into_bigint_and_exponent().0; - biguint_to_u256(bigint.to_biguint().unwrap()) -} - -fn ensure_chunkable(bytes: &[u8]) { - assert!( - bytes.len() % 32 == 0, - "Bytes must be divisible by 32 to split into chunks" - ); -} - -pub fn h256_to_u256(num: H256) -> U256 { - U256::from_big_endian(num.as_bytes()) -} - -pub fn address_to_h256(address: &Address) -> H256 { - let mut buffer = [0u8; 32]; - buffer[12..].copy_from_slice(address.as_bytes()); - H256(buffer) -} - -pub fn address_to_u256(address: &Address) -> U256 { - h256_to_u256(address_to_h256(address)) -} - -pub fn bytes_to_chunks(bytes: &[u8]) -> Vec<[u8; 32]> { - ensure_chunkable(bytes); - bytes - .chunks(32) - .map(|el| { - let mut chunk = [0u8; 32]; - chunk.copy_from_slice(el); - chunk - }) - .collect() -} - -pub fn be_chunks_to_h256_words(chunks: Vec<[u8; 32]>) -> Vec { - chunks.into_iter().map(|el| H256::from_slice(&el)).collect() -} - -pub fn bytes_to_be_words(vec: Vec) -> Vec { - ensure_chunkable(&vec); - vec.chunks(32).map(U256::from_big_endian).collect() -} - -pub fn be_words_to_bytes(words: &[U256]) -> Vec { - words - .iter() - .flat_map(|w| { - let mut bytes = [0u8; 32]; - w.to_big_endian(&mut bytes); - bytes - }) - .collect() -} - -pub fn u256_to_h256(num: U256) -> H256 { - let mut bytes = [0u8; 32]; - num.to_big_endian(&mut bytes); - H256::from_slice(&bytes) -} - -/// Converts `U256` value into the Address -pub fn u256_to_account_address(value: &U256) -> Address { - let mut bytes = [0u8; 32]; - value.to_big_endian(&mut bytes); - - Address::from_slice(&bytes[12..]) -} - -/// Converts `H256` value into the Address -pub fn h256_to_account_address(value: &H256) -> Address { - Address::from_slice(&value.as_bytes()[12..]) -} - -pub fn be_bytes_to_safe_address(bytes: &[u8]) -> Option
{ - if bytes.len() < 20 { - return None; - } - - let (zero_bytes, address_bytes) = bytes.split_at(bytes.len() - 20); - - if zero_bytes.iter().any(|b| *b != 0) { - None - } else { - Some(Address::from_slice(address_bytes)) - } -} - -/// Converts `h256` value as BE into the u32 -pub fn h256_to_u32(value: H256) -> u32 { - let be_u32_bytes: [u8; 4] = value[28..].try_into().unwrap(); - u32::from_be_bytes(be_u32_bytes) -} - -/// Converts u32 into the H256 as BE bytes -pub fn u32_to_h256(value: u32) -> H256 { - let mut result = [0u8; 32]; - result[28..].copy_from_slice(&value.to_be_bytes()); - H256(result) -} - -/// Converts `U256` value into bytes array -pub fn u256_to_bytes_be(value: &U256) -> Vec { - let mut bytes = vec![0u8; 32]; - value.to_big_endian(bytes.as_mut_slice()); - bytes -} - -#[cfg(test)] -mod test { - use num::BigInt; - use rand::{rngs::StdRng, Rng, SeedableRng}; - - use super::*; - - #[test] - fn test_u256_to_bigdecimal() { - const RNG_SEED: u64 = 123; - - let mut rng = StdRng::seed_from_u64(RNG_SEED); - // Small values. - for _ in 0..10_000 { - let value: u64 = rng.gen(); - let expected = BigDecimal::from(value); - assert_eq!(u256_to_big_decimal(value.into()), expected); - } - - // Arbitrary values - for _ in 0..10_000 { - let u64_digits: [u64; 4] = rng.gen(); - let value = u64_digits - .iter() - .enumerate() - .map(|(i, &digit)| U256::from(digit) << (i * 64)) - .fold(U256::zero(), |acc, x| acc + x); - let expected_value = u64_digits - .iter() - .enumerate() - .map(|(i, &digit)| BigInt::from(digit) << (i * 64)) - .fold(BigInt::from(0), |acc, x| acc + x); - assert_eq!( - u256_to_big_decimal(value), - BigDecimal::new(expected_value, 0) - ); - } - } - - #[test] - fn test_bigdecimal_to_u256() { - let value = BigDecimal::from(100u32); - let expected = U256::from(100u32); - assert_eq!(bigdecimal_to_u256(value), expected); - - let value = BigDecimal::new(BigInt::from(100), -2); - let expected = U256::from(10000u32); - assert_eq!(bigdecimal_to_u256(value), expected); - } -} diff --git a/core/lib/utils/src/format.rs b/core/lib/utils/src/format.rs deleted file mode 100644 index 9d15d4c358e7..000000000000 --- a/core/lib/utils/src/format.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Built-in deps -use std::collections::VecDeque; -use std::string::ToString; -// External deps -// Workspace deps - -/// Formats amount in wei to tokens with precision. -/// Behaves just like ethers.utils.formatUnits -pub fn format_units(wei: impl ToString, units: u8) -> String { - let mut chars: VecDeque = wei.to_string().chars().collect(); - - while chars.len() < units as usize { - chars.push_front('0'); - } - chars.insert(chars.len() - units as usize, '.'); - if *chars.front().unwrap() == '.' { - chars.push_front('0'); - } - while *chars.back().unwrap() == '0' { - chars.pop_back(); - } - if *chars.back().unwrap() == '.' { - chars.push_back('0'); - } - chars.iter().collect() -} - -/// Formats amount in wei to tokens. -/// Behaves just like js ethers.utils.formatEther -pub fn format_ether(wei: impl ToString) -> String { - format_units(wei, 18) -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_format_units() { - // Test vector of (decimals, wei input, expected output) - let vals = vec![ - (0, "1000000000000000100000", "1000000000000000100000.0"), - (1, "0", "0.0"), - (1, "11000000000000000000", "1100000000000000000.0"), - (2, "0", "0.0"), - (2, "1000000000000000100000", "10000000000000001000.0"), - (4, "10001000000", "1000100.0"), - (4, "10100000000000000000000", "1010000000000000000.0"), - (4, "110", "0.011"), - (6, "1000000000000000100000", "1000000000000000.1"), - (8, "0", "0.0"), - (8, "10100000000000000000000", "101000000000000.0"), - (8, "110", "0.0000011"), - (9, "10000000000000000001", "10000000000.000000001"), - (9, "11000000", "0.011"), - (9, "11000000000000000000", "11000000000.0"), - (10, "10001000000", "1.0001"), - (10, "20000000000000000000000", "2000000000000.0"), - (11, "0", "0.0"), - (11, "10100000000000000000000", "101000000000.0"), - (12, "1000000000000000100000", "1000000000.0000001"), - (12, "10001000000", "0.010001"), - (12, "10010000000", "0.01001"), - (12, "110", "0.00000000011"), - (13, "10010000000", "0.001001"), - (14, "10010000000", "0.0001001"), - (14, "110", "0.0000000000011"), - (15, "0", "0.0"), - (17, "1000000000000000100000", "10000.000000000001"), - (17, "10001000000", "0.00000010001"), - (18, "1000000000000000100000", "1000.0000000000001"), - ]; - - for (dec, input, output) in vals { - assert_eq!(format_units(&input, dec), output); - } - } -} diff --git a/core/lib/utils/src/lib.rs b/core/lib/utils/src/lib.rs index 92a1d7a0c470..e2ab70695113 100644 --- a/core/lib/utils/src/lib.rs +++ b/core/lib/utils/src/lib.rs @@ -1,13 +1,7 @@ //! Various helpers used in the ZKsync stack. pub mod bytecode; -mod convert; pub 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 self::{convert::*, misc::*, serde_wrappers::*}; diff --git a/core/lib/utils/src/misc.rs b/core/lib/utils/src/misc.rs deleted file mode 100644 index 52bd7657c4e1..000000000000 --- a/core/lib/utils/src/misc.rs +++ /dev/null @@ -1,55 +0,0 @@ -use zksync_basic_types::{web3::keccak256, H256, U256}; - -pub const fn ceil_div(a: u64, b: u64) -> u64 { - if a == 0 { - a - } else { - (a - 1) / b + 1 - } -} - -pub fn ceil_div_u256(a: U256, b: U256) -> U256 { - (a + b - U256::from(1)) / b -} - -pub fn concat_and_hash(hash1: H256, hash2: H256) -> H256 { - let mut bytes = [0_u8; 64]; - bytes[..32].copy_from_slice(&hash1.0); - bytes[32..].copy_from_slice(&hash2.0); - H256(keccak256(&bytes)) -} - -pub fn expand_memory_contents(packed: &[(usize, U256)], memory_size_bytes: usize) -> Vec { - let mut result: Vec = vec![0; memory_size_bytes]; - - for (offset, value) in packed { - value.to_big_endian(&mut result[(offset * 32)..(offset + 1) * 32]); - } - - result -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_ceil_div_u64_max() { - assert_eq!(0, ceil_div(u64::MIN, u64::MAX)); - assert_eq!(1, ceil_div(u64::MAX, u64::MAX)); - } - - #[test] - fn test_ceil_div_roundup_required() { - assert_eq!(3, ceil_div(5, 2)); - assert_eq!(4, ceil_div(10, 3)); - assert_eq!(3, ceil_div(15, 7)); - } - - #[test] - fn test_ceil_div_no_roundup_required() { - assert_eq!(2, ceil_div(4, 2)); - assert_eq!(2, ceil_div(6, 3)); - assert_eq!(2, ceil_div(14, 7)); - } -} diff --git a/core/lib/utils/src/time.rs b/core/lib/utils/src/time.rs deleted file mode 100644 index 70372db34f49..000000000000 --- a/core/lib/utils/src/time.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -pub fn seconds_since_epoch() -> u64 { - duration_since_epoch().as_secs() -} - -pub fn millis_since(since: u64) -> u64 { - (millis_since_epoch() - since as u128 * 1000) as u64 -} - -pub fn millis_since_epoch() -> u128 { - duration_since_epoch().as_millis() -} - -fn duration_since_epoch() -> Duration { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Incorrect system time") -} diff --git a/core/lib/vm_executor/src/oneshot/block.rs b/core/lib/vm_executor/src/oneshot/block.rs index d6118f15b98e..66bdd30e40ea 100644 --- a/core/lib/vm_executor/src/oneshot/block.rs +++ b/core/lib/vm_executor/src/oneshot/block.rs @@ -1,3 +1,5 @@ +use std::time::SystemTime; + use anyhow::Context; use zksync_dal::{Connection, Core, CoreDal, DalError}; use zksync_multivm::{ @@ -8,11 +10,10 @@ use zksync_types::{ api, block::{unpack_block_info, L2BlockHasher}, fee_model::BatchFeeInput, - AccountTreeId, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, H256, + h256_to_u256, AccountTreeId, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, H256, SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, ZKPORTER_IS_AVAILABLE, }; -use zksync_utils::{h256_to_u256, time::seconds_since_epoch}; use super::{env::OneshotEnvParameters, ContractsKind}; @@ -124,7 +125,11 @@ impl BlockInfo { state_l2_block_number = sealed_l2_block_header.number; // Timestamp of the next L1 batch must be greater than the timestamp of the last L2 block. - l1_batch_timestamp = seconds_since_epoch().max(sealed_l2_block_header.timestamp + 1); + let current_timestamp = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .context("incorrect system time")? + .as_secs(); + l1_batch_timestamp = current_timestamp.max(sealed_l2_block_header.timestamp + 1); sealed_l2_block_header }; diff --git a/core/lib/vm_executor/src/oneshot/mod.rs b/core/lib/vm_executor/src/oneshot/mod.rs index 7d45dcca8cd3..e95164c0fc87 100644 --- a/core/lib/vm_executor/src/oneshot/mod.rs +++ b/core/lib/vm_executor/src/oneshot/mod.rs @@ -33,14 +33,14 @@ use zksync_multivm::{ }; use zksync_types::{ block::pack_block_info, - get_nonce_key, + get_nonce_key, h256_to_u256, l2::L2Tx, + u256_to_h256, utils::{decompose_full_nonce, nonces_to_full_nonce, storage_key_for_eth_balance}, vm::FastVmMode, AccountTreeId, Nonce, StorageKey, Transaction, SYSTEM_CONTEXT_ADDRESS, SYSTEM_CONTEXT_CURRENT_L2_BLOCK_INFO_POSITION, SYSTEM_CONTEXT_CURRENT_TX_ROLLING_HASH_POSITION, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; pub use self::{ block::{BlockInfo, ResolvedBlockInfo}, diff --git a/core/node/api_server/src/execution_sandbox/storage.rs b/core/node/api_server/src/execution_sandbox/storage.rs index c80356f6e36e..026ac58733a4 100644 --- a/core/node/api_server/src/execution_sandbox/storage.rs +++ b/core/node/api_server/src/execution_sandbox/storage.rs @@ -3,11 +3,10 @@ use zksync_multivm::interface::storage::{ReadStorage, StorageWithOverrides}; use zksync_types::{ api::state_override::{OverrideState, StateOverride}, - get_code_key, get_known_code_key, get_nonce_key, + get_code_key, get_known_code_key, get_nonce_key, h256_to_u256, u256_to_h256, utils::{decompose_full_nonce, nonces_to_full_nonce, storage_key_for_eth_balance}, AccountTreeId, StorageKey, H256, }; -use zksync_utils::{h256_to_u256, u256_to_h256}; /// This method is blocking. pub(super) fn apply_state_override( diff --git a/core/node/api_server/src/testonly.rs b/core/node/api_server/src/testonly.rs index de6501716125..90001c908a9f 100644 --- a/core/node/api_server/src/testonly.rs +++ b/core/node/api_server/src/testonly.rs @@ -11,6 +11,7 @@ use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::utils::derive_base_fee_and_gas_per_pubdata; use zksync_system_constants::{L2_BASE_TOKEN_ADDRESS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE}; use zksync_types::{ + address_to_u256, api::state_override::{Bytecode, OverrideAccount, OverrideState, StateOverride}, ethabi, ethabi::Token, @@ -20,11 +21,11 @@ use zksync_types::{ l1::L1Tx, l2::L2Tx, transaction_request::{CallRequest, Eip712Meta, PaymasterParams}, + u256_to_h256, utils::storage_key_for_eth_balance, AccountTreeId, Address, K256PrivateKey, L2BlockNumber, L2ChainId, Nonce, ProtocolVersionId, StorageKey, StorageLog, EIP_712_TX_TYPE, H256, U256, }; -use zksync_utils::{address_to_u256, u256_to_h256}; const EXPENSIVE_CONTRACT_PATH: &str = "etc/contracts-test-data/artifacts-zk/contracts/expensive/expensive.sol/Expensive.json"; diff --git a/core/node/api_server/src/tx_sender/mod.rs b/core/node/api_server/src/tx_sender/mod.rs index 011d9e4e2b2f..180b53492839 100644 --- a/core/node/api_server/src/tx_sender/mod.rs +++ b/core/node/api_server/src/tx_sender/mod.rs @@ -24,7 +24,7 @@ use zksync_state_keeper::{ use zksync_types::{ api::state_override::StateOverride, fee_model::BatchFeeInput, - get_intrinsic_constants, + get_intrinsic_constants, h256_to_u256, l2::{error::TxCheckError::TxDuplication, L2Tx}, transaction_request::CallOverrides, utils::storage_key_for_eth_balance, @@ -32,7 +32,6 @@ use zksync_types::{ AccountTreeId, Address, L2ChainId, Nonce, ProtocolVersionId, Transaction, H160, H256, MAX_NEW_FACTORY_DEPS, U256, }; -use zksync_utils::h256_to_u256; use zksync_vm_executor::oneshot::{ CallOrExecute, EstimateGas, MultiVMBaseSystemContracts, OneshotEnvParameters, }; diff --git a/core/node/api_server/src/web3/namespaces/eth.rs b/core/node/api_server/src/web3/namespaces/eth.rs index e594af20d183..588316ce70e4 100644 --- a/core/node/api_server/src/web3/namespaces/eth.rs +++ b/core/node/api_server/src/web3/namespaces/eth.rs @@ -8,14 +8,12 @@ use zksync_types::{ }, l2::{L2Tx, TransactionType}, transaction_request::CallRequest, + u256_to_h256, utils::decompose_full_nonce, web3::{self, Bytes, SyncInfo, SyncState}, AccountTreeId, L2BlockNumber, StorageKey, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::{ - bytecode::{prepare_evm_bytecode, BytecodeMarker}, - u256_to_h256, -}; +use zksync_utils::bytecode::{prepare_evm_bytecode, BytecodeMarker}; use zksync_web3_decl::{ error::Web3Error, types::{Address, Block, Filter, FilterChanges, Log, U64}, diff --git a/core/node/api_server/src/web3/namespaces/zks.rs b/core/node/api_server/src/web3/namespaces/zks.rs index 1a4114bd2c6a..05c90f0b0140 100644 --- a/core/node/api_server/src/web3/namespaces/zks.rs +++ b/core/node/api_server/src/web3/namespaces/zks.rs @@ -7,12 +7,14 @@ use zksync_mini_merkle_tree::MiniMerkleTree; use zksync_multivm::interface::VmExecutionResultAndLogs; use zksync_system_constants::DEFAULT_L2_TX_GAS_PER_PUBDATA_BYTE; use zksync_types::{ + address_to_h256, api::{ state_override::StateOverride, BlockDetails, BridgeAddresses, GetLogsFilter, L1BatchDetails, L2ToL1LogProof, Proof, ProtocolVersion, StorageProof, TransactionDetails, }, fee::Fee, fee_model::{FeeParams, PubdataIndependentBatchFeeModelInput}, + h256_to_u256, l1::L1Tx, l2::L2Tx, l2_to_l1_log::{l2_to_l1_logs_tree_size, L2ToL1Log}, @@ -23,7 +25,6 @@ use zksync_types::{ AccountTreeId, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, Transaction, L1_MESSENGER_ADDRESS, L2_BASE_TOKEN_ADDRESS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, U256, U64, }; -use zksync_utils::{address_to_h256, h256_to_u256}; use zksync_web3_decl::{ error::Web3Error, types::{Address, Token, H256}, diff --git a/core/node/api_server/src/web3/tests/mod.rs b/core/node/api_server/src/web3/tests/mod.rs index b35bb9f5fad7..9080c5ba413c 100644 --- a/core/node/api_server/src/web3/tests/mod.rs +++ b/core/node/api_server/src/web3/tests/mod.rs @@ -40,16 +40,14 @@ use zksync_types::{ system_contracts::get_system_smart_contracts, tokens::{TokenInfo, TokenMetadata}, tx::IncludedTxLocation, + u256_to_h256, utils::{storage_key_for_eth_balance, storage_key_for_standard_token_balance}, AccountTreeId, Address, L1BatchNumber, Nonce, ProtocolVersionId, StorageKey, StorageLog, H256, U256, U64, }; -use zksync_utils::{ - bytecode::{ - hash_bytecode, hash_evm_bytecode, - testonly::{PROCESSED_EVM_BYTECODE, RAW_EVM_BYTECODE}, - }, - u256_to_h256, +use zksync_utils::bytecode::{ + hash_bytecode, hash_evm_bytecode, + testonly::{PROCESSED_EVM_BYTECODE, RAW_EVM_BYTECODE}, }; use zksync_vm_executor::oneshot::MockOneshotExecutor; use zksync_web3_decl::{ diff --git a/core/node/api_server/src/web3/tests/vm.rs b/core/node/api_server/src/web3/tests/vm.rs index 4e0426de7bfa..a82ca3b9e347 100644 --- a/core/node/api_server/src/web3/tests/vm.rs +++ b/core/node/api_server/src/web3/tests/vm.rs @@ -16,10 +16,9 @@ use zksync_multivm::interface::{ }; use zksync_types::{ api::ApiStorageLog, fee_model::BatchFeeInput, get_intrinsic_constants, - transaction_request::CallRequest, vm::FastVmMode, K256PrivateKey, L2ChainId, + transaction_request::CallRequest, u256_to_h256, vm::FastVmMode, K256PrivateKey, L2ChainId, PackedEthSignature, StorageLogKind, StorageLogWithPreviousValue, Transaction, U256, }; -use zksync_utils::u256_to_h256; use zksync_vm_executor::oneshot::{ BaseSystemContractsProvider, ContractsKind, MockOneshotExecutor, OneshotEnvParameters, ResolvedBlockInfo, diff --git a/core/node/base_token_adjuster/Cargo.toml b/core/node/base_token_adjuster/Cargo.toml index 9dcf5d796530..b326e7a6b42d 100644 --- a/core/node/base_token_adjuster/Cargo.toml +++ b/core/node/base_token_adjuster/Cargo.toml @@ -19,7 +19,6 @@ zksync_external_price_api.workspace = true zksync_contracts.workspace = true zksync_eth_client.workspace = true zksync_node_fee_model.workspace = true -zksync_utils.workspace = true vise.workspace = true bigdecimal.workspace = true diff --git a/core/node/commitment_generator/Cargo.toml b/core/node/commitment_generator/Cargo.toml index 1f4645414cbd..f0b4046bab42 100644 --- a/core/node/commitment_generator/Cargo.toml +++ b/core/node/commitment_generator/Cargo.toml @@ -16,7 +16,6 @@ zksync_types.workspace = true zksync_dal.workspace = true zksync_health_check.workspace = true zksync_l1_contract_interface.workspace = true -zksync_utils.workspace = true zksync_eth_client.workspace = true zksync_contracts.workspace = true zksync_multivm.workspace = true diff --git a/core/node/commitment_generator/src/lib.rs b/core/node/commitment_generator/src/lib.rs index 9a33d4766f6e..2ce0152abab6 100644 --- a/core/node/commitment_generator/src/lib.rs +++ b/core/node/commitment_generator/src/lib.rs @@ -12,10 +12,10 @@ use zksync_types::{ AuxCommitments, BlobHash, CommitmentCommonInput, CommitmentInput, L1BatchAuxiliaryOutput, L1BatchCommitment, L1BatchCommitmentArtifacts, L1BatchCommitmentMode, }, + h256_to_u256, writes::{InitialStorageWrite, RepeatedStorageWrite, StateDiffRecord}, L1BatchNumber, ProtocolVersionId, StorageKey, H256, U256, }; -use zksync_utils::h256_to_u256; use crate::{ metrics::{CommitmentStage, METRICS}, diff --git a/core/node/commitment_generator/src/utils.rs b/core/node/commitment_generator/src/utils.rs index d405a1256a29..cc44d7a03c71 100644 --- a/core/node/commitment_generator/src/utils.rs +++ b/core/node/commitment_generator/src/utils.rs @@ -21,13 +21,13 @@ use zksync_l1_contract_interface::i_executor::commit::kzg::ZK_SYNC_BYTES_PER_BLO use zksync_multivm::{interface::VmEvent, utils::get_used_bootloader_memory_bytes}; use zksync_system_constants::message_root::{AGG_TREE_HEIGHT_KEY, AGG_TREE_NODES_KEY}; use zksync_types::{ + address_to_u256, h256_to_u256, u256_to_h256, vm::VmVersion, web3::keccak256, zk_evm_types::{LogQuery, Timestamp}, AccountTreeId, L1BatchNumber, ProtocolVersionId, StorageKey, EVENT_WRITER_ADDRESS, H256, L2_MESSAGE_ROOT_ADDRESS, U256, }; -use zksync_utils::{address_to_u256, expand_memory_contents, h256_to_u256, u256_to_h256}; /// Encapsulates computations of commitment components. /// @@ -124,6 +124,15 @@ impl CommitmentComputer for RealCommitmentComputer { } } +fn expand_memory_contents(packed: &[(usize, U256)], memory_size_bytes: usize) -> Vec { + let mut result: Vec = vec![0; memory_size_bytes]; + + for (offset, value) in packed { + value.to_big_endian(&mut result[(offset * 32)..(offset + 1) * 32]); + } + + result +} fn to_log_query_1_3_3(log_query: LogQuery) -> LogQuery_1_3_3 { LogQuery_1_3_3 { timestamp: Timestamp_1_3_3(log_query.timestamp.0), diff --git a/core/node/consensus/Cargo.toml b/core/node/consensus/Cargo.toml index fdcc9089e339..120d355da9a8 100644 --- a/core/node/consensus/Cargo.toml +++ b/core/node/consensus/Cargo.toml @@ -30,7 +30,6 @@ zksync_state_keeper.workspace = true zksync_node_sync.workspace = true zksync_system_constants.workspace = true zksync_types.workspace = true -zksync_utils.workspace = true zksync_web3_decl.workspace = true zksync_state.workspace = true zksync_vm_executor.workspace = true diff --git a/core/node/da_dispatcher/Cargo.toml b/core/node/da_dispatcher/Cargo.toml index 8a10d6813a5a..57d00cabaaa8 100644 --- a/core/node/da_dispatcher/Cargo.toml +++ b/core/node/da_dispatcher/Cargo.toml @@ -14,7 +14,6 @@ categories.workspace = true [dependencies] vise.workspace = true zksync_dal.workspace = true -zksync_utils.workspace = true zksync_config.workspace = true zksync_types.workspace = true zksync_da_client.workspace = true diff --git a/core/node/eth_sender/Cargo.toml b/core/node/eth_sender/Cargo.toml index a7aa88c3550e..a33536baa986 100644 --- a/core/node/eth_sender/Cargo.toml +++ b/core/node/eth_sender/Cargo.toml @@ -17,7 +17,6 @@ zksync_dal.workspace = true zksync_config.workspace = true zksync_contracts.workspace = true zksync_eth_client.workspace = true -zksync_utils.workspace = true zksync_l1_contract_interface.workspace = true zksync_object_store.workspace = true zksync_prover_interface.workspace = true diff --git a/core/node/eth_sender/src/eth_tx_manager.rs b/core/node/eth_sender/src/eth_tx_manager.rs index 7de91a3b7736..6992bea1007c 100644 --- a/core/node/eth_sender/src/eth_tx_manager.rs +++ b/core/node/eth_sender/src/eth_tx_manager.rs @@ -1,4 +1,7 @@ -use std::{sync::Arc, time::Duration}; +use std::{ + sync::Arc, + time::{Duration, SystemTime}, +}; use tokio::sync::watch; use zksync_config::configs::eth_sender::SenderConfig; @@ -9,7 +12,6 @@ use zksync_eth_client::{ use zksync_node_fee_model::l1_gas_price::TxParamsProvider; use zksync_shared_metrics::BlockL1Stage; use zksync_types::{eth_sender::EthTx, Address, L1BlockNumber, H256, U256}; -use zksync_utils::time::seconds_since_epoch; use super::{metrics::METRICS, EthSenderError}; use crate::{ @@ -501,9 +503,13 @@ impl EthTxManager { ); let tx_type_label = tx.tx_type.into(); METRICS.l1_gas_used[&tx_type_label].observe(gas_used.low_u128() as f64); - METRICS.l1_tx_mined_latency[&tx_type_label].observe(Duration::from_secs( - seconds_since_epoch() - tx.created_at_timestamp, - )); + + let duration_since_epoch = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("incorrect system time"); + let tx_latency = + duration_since_epoch.saturating_sub(Duration::from_secs(tx.created_at_timestamp)); + METRICS.l1_tx_mined_latency[&tx_type_label].observe(tx_latency); let sent_at_block = storage .eth_sender_dal() diff --git a/core/node/eth_sender/src/metrics.rs b/core/node/eth_sender/src/metrics.rs index 462fe3ed6e59..571837036045 100644 --- a/core/node/eth_sender/src/metrics.rs +++ b/core/node/eth_sender/src/metrics.rs @@ -1,12 +1,14 @@ //! Metrics for the Ethereum sender component. -use std::{fmt, time::Duration}; +use std::{ + fmt, + time::{Duration, SystemTime}, +}; use vise::{Buckets, Counter, EncodeLabelSet, EncodeLabelValue, Family, Gauge, Histogram, Metrics}; use zksync_dal::{Connection, Core, CoreDal}; use zksync_shared_metrics::{BlockL1Stage, BlockStage, APP_METRICS}; use zksync_types::{aggregated_operations::AggregatedActionType, eth_sender::EthTx}; -use zksync_utils::time::seconds_since_epoch; use crate::abstract_l1_interface::{L1BlockNumbers, OperatorType}; @@ -143,10 +145,13 @@ impl EthSenderMetrics { return; } + let duration_since_epoch = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("incorrect system time"); for statistics in l1_batches_statistics { - APP_METRICS.block_latency[&stage].observe(Duration::from_secs( - seconds_since_epoch() - statistics.timestamp, - )); + let block_latency = + duration_since_epoch.saturating_sub(Duration::from_secs(statistics.timestamp)); + APP_METRICS.block_latency[&stage].observe(block_latency); APP_METRICS.processed_txs[&stage.into()] .inc_by(statistics.l2_tx_count as u64 + statistics.l1_tx_count as u64); APP_METRICS.processed_l1_txs[&stage.into()].inc_by(statistics.l1_tx_count as u64); diff --git a/core/node/genesis/src/lib.rs b/core/node/genesis/src/lib.rs index 82732342b407..03f51d5c5fc3 100644 --- a/core/node/genesis/src/lib.rs +++ b/core/node/genesis/src/lib.rs @@ -22,11 +22,12 @@ use zksync_types::{ protocol_upgrade::decode_set_chain_id_event, protocol_version::{L1VerifierConfig, ProtocolSemanticVersion}, system_contracts::get_system_smart_contracts, + u256_to_h256, web3::{BlockNumber, FilterBuilder}, AccountTreeId, Address, Bloom, L1BatchNumber, L1ChainId, L2BlockNumber, L2ChainId, ProtocolVersion, ProtocolVersionId, StorageKey, H256, U256, }; -use zksync_utils::{bytecode::hash_bytecode, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use crate::utils::{ add_eth_token, get_deduped_log_queries, get_storage_logs, diff --git a/core/node/genesis/src/utils.rs b/core/node/genesis/src/utils.rs index 6042513537cd..d89d7475e84b 100644 --- a/core/node/genesis/src/utils.rs +++ b/core/node/genesis/src/utils.rs @@ -11,12 +11,13 @@ use zksync_system_constants::{DEFAULT_ERA_CHAIN_ID, ETHEREUM_ADDRESS}; use zksync_types::{ block::{DeployedContract, L1BatchTreeData}, commitment::L1BatchCommitment, - get_code_key, get_known_code_key, get_system_context_init_logs, + get_code_key, get_known_code_key, get_system_context_init_logs, h256_to_u256, tokens::{TokenInfo, TokenMetadata}, + u256_to_h256, zk_evm_types::{LogQuery, Timestamp}, AccountTreeId, L1BatchNumber, L2BlockNumber, L2ChainId, StorageKey, StorageLog, H256, }; -use zksync_utils::{be_words_to_bytes, bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use crate::GenesisError; @@ -132,7 +133,7 @@ pub(super) async fn insert_base_system_contracts_to_factory_deps( let factory_deps = [&contracts.bootloader, &contracts.default_aa] .into_iter() .chain(contracts.evm_emulator.as_ref()) - .map(|c| (c.hash, be_words_to_bytes(&c.code))) + .map(|c| (c.hash, c.code.clone())) .collect(); Ok(storage diff --git a/core/node/metadata_calculator/Cargo.toml b/core/node/metadata_calculator/Cargo.toml index 5b566c09ff68..0d0522939e91 100644 --- a/core/node/metadata_calculator/Cargo.toml +++ b/core/node/metadata_calculator/Cargo.toml @@ -19,7 +19,6 @@ zksync_types.workspace = true zksync_config.workspace = true zksync_storage.workspace = true zksync_shared_metrics.workspace = true -zksync_utils.workspace = true zksync_object_store.workspace = true vise.workspace = true diff --git a/core/node/metadata_calculator/src/api_server/mod.rs b/core/node/metadata_calculator/src/api_server/mod.rs index 4612d859a3dd..ced29310408e 100644 --- a/core/node/metadata_calculator/src/api_server/mod.rs +++ b/core/node/metadata_calculator/src/api_server/mod.rs @@ -18,8 +18,7 @@ use zksync_merkle_tree::{ unstable::{NodeKey, RawNode}, NoVersionError, ValueHash, }; -use zksync_types::{web3, L1BatchNumber, H256, U256}; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, web3, L1BatchNumber, H256, U256}; use self::metrics::{MerkleTreeApiMethod, API_METRICS}; use crate::{AsyncTreeReader, LazyAsyncTreeReader, MerkleTreeInfo}; diff --git a/core/node/metadata_calculator/src/metrics.rs b/core/node/metadata_calculator/src/metrics.rs index 7eb49b95afd4..c6d7094ef839 100644 --- a/core/node/metadata_calculator/src/metrics.rs +++ b/core/node/metadata_calculator/src/metrics.rs @@ -1,6 +1,6 @@ //! Metrics for `MetadataCalculator`. -use std::time::{Duration, Instant}; +use std::time::{Duration, Instant, SystemTime}; use vise::{ Buckets, DurationAsSecs, EncodeLabelSet, EncodeLabelValue, Family, Gauge, Histogram, Info, @@ -9,7 +9,6 @@ use vise::{ use zksync_config::configs::database::MerkleTreeMode; use zksync_shared_metrics::{BlockStage, APP_METRICS}; use zksync_types::block::L1BatchHeader; -use zksync_utils::time::seconds_since_epoch; use super::{MetadataCalculator, MetadataCalculatorConfig}; @@ -187,6 +186,11 @@ impl MetadataCalculator { total_logs: usize, start: Instant, ) { + let (Some(first_header), Some(last_header)) = (batch_headers.first(), batch_headers.last()) + else { + return; + }; + let elapsed = start.elapsed(); METRICS.update_tree_latency.observe(elapsed); if total_logs > 0 { @@ -205,17 +209,20 @@ impl MetadataCalculator { METRICS.log_batch.observe(total_logs); METRICS.blocks_batch.observe(batch_headers.len()); - let first_batch_number = batch_headers.first().unwrap().number.0; - let last_batch_number = batch_headers.last().unwrap().number.0; + let first_batch_number = first_header.number.0; + let last_batch_number = last_header.number.0; tracing::info!( "L1 batches #{:?} processed in tree", first_batch_number..=last_batch_number ); APP_METRICS.block_number[&BlockStage::Tree].set(last_batch_number.into()); + let duration_since_epoch = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("incorrect system time"); let latency = - seconds_since_epoch().saturating_sub(batch_headers.first().unwrap().timestamp); - APP_METRICS.block_latency[&BlockStage::Tree].observe(Duration::from_secs(latency)); + duration_since_epoch.saturating_sub(Duration::from_secs(first_header.timestamp)); + APP_METRICS.block_latency[&BlockStage::Tree].observe(latency); } } diff --git a/core/node/metadata_calculator/src/tests.rs b/core/node/metadata_calculator/src/tests.rs index 1c003c4ecf78..9717ce5682ce 100644 --- a/core/node/metadata_calculator/src/tests.rs +++ b/core/node/metadata_calculator/src/tests.rs @@ -23,7 +23,6 @@ use zksync_types::{ block::{L1BatchHeader, L1BatchTreeData}, AccountTreeId, Address, L1BatchNumber, L2BlockNumber, StorageKey, StorageLog, H256, }; -use zksync_utils::u32_to_h256; use super::{ helpers::L1BatchWithLogs, GenericAsyncTree, MetadataCalculator, MetadataCalculatorConfig, @@ -904,9 +903,9 @@ pub(crate) fn gen_storage_logs( let proof_keys = accounts.iter().flat_map(|&account| { account_keys .clone() - .map(move |i| StorageKey::new(account, u32_to_h256(i))) + .map(move |i| StorageKey::new(account, H256::from_low_u64_be(i.into()))) }); - let proof_values = indices.map(u32_to_h256); + let proof_values = indices.map(|i| H256::from_low_u64_be(i.into())); let logs: Vec<_> = proof_keys .zip(proof_values) diff --git a/core/node/node_sync/src/client.rs b/core/node/node_sync/src/client.rs index ee89db10ddd1..d56d8ebc2631 100644 --- a/core/node/node_sync/src/client.rs +++ b/core/node/node_sync/src/client.rs @@ -8,7 +8,7 @@ use zksync_health_check::{CheckHealth, Health, HealthStatus}; use zksync_system_constants::ACCOUNT_CODE_STORAGE_ADDRESS; use zksync_types::{ api::{self, en}, - get_code_key, Address, L2BlockNumber, ProtocolVersionId, H256, U64, + get_code_key, h256_to_u256, Address, L2BlockNumber, ProtocolVersionId, H256, U64, }; use zksync_web3_decl::{ client::{DynClient, L2}, @@ -81,7 +81,7 @@ impl MainNodeClient for Box> { let code_hash = self .get_storage_at( ACCOUNT_CODE_STORAGE_ADDRESS, - zksync_utils::h256_to_u256(*code_key.key()), + h256_to_u256(*code_key.key()), Some(GENESIS_BLOCK), ) .rpc_context("get_storage_at") diff --git a/core/node/node_sync/src/external_io.rs b/core/node/node_sync/src/external_io.rs index 0f5f4d6253fa..d3d908cfc169 100644 --- a/core/node/node_sync/src/external_io.rs +++ b/core/node/node_sync/src/external_io.rs @@ -20,7 +20,6 @@ use zksync_types::{ protocol_version::{ProtocolSemanticVersion, VersionPatch}, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, H256, }; -use zksync_utils::bytes_to_be_words; use zksync_vm_executor::storage::L1BatchParamsProvider; use super::{ @@ -75,7 +74,7 @@ impl ExternalIO { Ok(match bytecode { Some(bytecode) => SystemContractCode { - code: bytes_to_be_words(bytecode), + code: bytecode, hash, }, None => { @@ -98,7 +97,7 @@ impl ExternalIO { ) .await?; SystemContractCode { - code: bytes_to_be_words(contract_bytecode), + code: contract_bytecode, hash, } } diff --git a/core/node/node_sync/src/genesis.rs b/core/node/node_sync/src/genesis.rs index c5d4869175df..7401bdd9c9d4 100644 --- a/core/node/node_sync/src/genesis.rs +++ b/core/node/node_sync/src/genesis.rs @@ -110,20 +110,17 @@ async fn fetch_base_system_contracts( .fetch_system_contract_by_hash(hash) .await? .context("EVM emulator bytecode is missing on main node")?; - Some(SystemContractCode { - code: zksync_utils::bytes_to_be_words(bytes), - hash, - }) + Some(SystemContractCode { code: bytes, hash }) } else { None }; Ok(BaseSystemContracts { bootloader: SystemContractCode { - code: zksync_utils::bytes_to_be_words(bootloader_bytecode), + code: bootloader_bytecode, hash: contract_hashes.bootloader, }, default_aa: SystemContractCode { - code: zksync_utils::bytes_to_be_words(default_aa_bytecode), + code: default_aa_bytecode, hash: contract_hashes.default_aa, }, evm_emulator, diff --git a/core/node/proof_data_handler/Cargo.toml b/core/node/proof_data_handler/Cargo.toml index e2ddc972a2f5..1bcda394a674 100644 --- a/core/node/proof_data_handler/Cargo.toml +++ b/core/node/proof_data_handler/Cargo.toml @@ -18,7 +18,6 @@ zksync_object_store.workspace = true zksync_prover_interface.workspace = true zksync_types.workspace = true zksync_vm_executor.workspace = true -zksync_utils.workspace = true anyhow.workspace = true axum.workspace = true tokio.workspace = true diff --git a/core/node/state_keeper/src/executor/tests/tester.rs b/core/node/state_keeper/src/executor/tests/tester.rs index 800bf398938d..247703c866e4 100644 --- a/core/node/state_keeper/src/executor/tests/tester.rs +++ b/core/node/state_keeper/src/executor/tests/tester.rs @@ -30,12 +30,12 @@ use zksync_types::{ protocol_version::ProtocolSemanticVersion, snapshots::{SnapshotRecoveryStatus, SnapshotStorageLog}, system_contracts::get_system_smart_contracts, + u256_to_h256, utils::storage_key_for_standard_token_balance, vm::FastVmMode, AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, PriorityOpId, ProtocolVersionId, StorageLog, Transaction, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::u256_to_h256; use zksync_vm_executor::batch::{MainBatchExecutorFactory, TraceCalls}; use super::{read_storage_factory::RocksdbStorageFactory, StorageType}; diff --git a/core/node/state_keeper/src/io/mempool.rs b/core/node/state_keeper/src/io/mempool.rs index 370d46fd544c..991ecee699c3 100644 --- a/core/node/state_keeper/src/io/mempool.rs +++ b/core/node/state_keeper/src/io/mempool.rs @@ -20,8 +20,6 @@ use zksync_types::{ utils::display_timestamp, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, H256, U256, }; -// TODO (SMA-1206): use seconds instead of milliseconds. -use zksync_utils::time::millis_since_epoch; use zksync_vm_executor::storage::L1BatchParamsProvider; use crate::{ @@ -36,6 +34,7 @@ use crate::{ IoSealCriteria, L2BlockMaxPayloadSizeSealer, TimeoutSealer, UnexecutableReason, }, updates::UpdatesManager, + utils::millis_since_epoch, MempoolGuard, }; @@ -531,9 +530,9 @@ impl MempoolIO { #[cfg(test)] mod tests { use tokio::time::timeout_at; - use zksync_utils::time::seconds_since_epoch; use super::*; + use crate::tests::seconds_since_epoch; // This test defensively uses large deadlines in order to account for tests running in parallel etc. #[tokio::test] diff --git a/core/node/state_keeper/src/io/persistence.rs b/core/node/state_keeper/src/io/persistence.rs index 8bfd812c8a1f..d8fd99bfc95d 100644 --- a/core/node/state_keeper/src/io/persistence.rs +++ b/core/node/state_keeper/src/io/persistence.rs @@ -7,8 +7,7 @@ use async_trait::async_trait; use tokio::sync::{mpsc, oneshot}; use zksync_dal::{ConnectionPool, Core, CoreDal}; use zksync_shared_metrics::{BlockStage, APP_METRICS}; -use zksync_types::{writes::TreeWrite, Address, ProtocolVersionId}; -use zksync_utils::u256_to_h256; +use zksync_types::{u256_to_h256, writes::TreeWrite, Address, ProtocolVersionId}; use crate::{ io::{ @@ -387,10 +386,9 @@ mod tests { use zksync_multivm::interface::{FinishedL1Batch, VmExecutionMetrics}; use zksync_node_genesis::{insert_genesis_batch, GenesisParams}; use zksync_types::{ - api::TransactionStatus, block::BlockGasCount, writes::StateDiffRecord, L1BatchNumber, - L2BlockNumber, StorageLogKind, H256, U256, + api::TransactionStatus, block::BlockGasCount, h256_to_u256, writes::StateDiffRecord, + L1BatchNumber, L2BlockNumber, StorageLogKind, H256, U256, }; - use zksync_utils::h256_to_u256; use super::*; use crate::{ diff --git a/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs b/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs index 53871c54a19f..a6356a838602 100644 --- a/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs +++ b/core/node/state_keeper/src/io/seal_logic/l2_block_seal_subtasks.rs @@ -5,11 +5,10 @@ use zksync_dal::{Connection, Core, CoreDal}; use zksync_multivm::interface::VmEvent; use zksync_system_constants::{CONTRACT_DEPLOYER_ADDRESS, L2_NATIVE_TOKEN_VAULT_ADDRESS}; use zksync_types::{ - ethabi, + ethabi, h256_to_address, tokens::{TokenInfo, TokenMetadata}, Address, L2BlockNumber, H256, }; -use zksync_utils::h256_to_account_address; use crate::{ io::seal_logic::SealStrategy, @@ -28,9 +27,9 @@ fn extract_added_tokens( event.address == CONTRACT_DEPLOYER_ADDRESS && event.indexed_topics.len() == 4 && event.indexed_topics[0] == VmEvent::DEPLOY_EVENT_SIGNATURE - && h256_to_account_address(&event.indexed_topics[1]) == l2_token_deployer_addr + && h256_to_address(&event.indexed_topics[1]) == l2_token_deployer_addr }) - .map(|event| h256_to_account_address(&event.indexed_topics[3])); + .map(|event| h256_to_address(&event.indexed_topics[3])); extract_added_token_info_from_addresses(all_generated_events, deployed_tokens) } @@ -73,7 +72,7 @@ fn extract_added_token_info_from_addresses( || event.indexed_topics[0] == *BRIDGE_INITIALIZATION_SIGNATURE_OLD) }) .map(|event| { - let l1_token_address = h256_to_account_address(&event.indexed_topics[1]); + let l1_token_address = h256_to_address(&event.indexed_topics[1]); let mut dec_ev = ethabi::decode( &[ ethabi::ParamType::String, @@ -467,11 +466,11 @@ mod tests { use zksync_types::{ block::L2BlockHeader, commitment::PubdataParams, + h256_to_u256, l2_to_l1_log::{L2ToL1Log, UserL2ToL1Log}, AccountTreeId, Address, L1BatchNumber, ProtocolVersionId, StorageKey, StorageLog, StorageLogKind, StorageLogWithPreviousValue, }; - use zksync_utils::h256_to_u256; use super::*; use crate::updates::L2BlockUpdates; diff --git a/core/node/state_keeper/src/io/seal_logic/mod.rs b/core/node/state_keeper/src/io/seal_logic/mod.rs index 7f05bda7a6f5..419413e127d3 100644 --- a/core/node/state_keeper/src/io/seal_logic/mod.rs +++ b/core/node/state_keeper/src/io/seal_logic/mod.rs @@ -22,11 +22,11 @@ use zksync_types::{ helpers::unix_timestamp_ms, l2_to_l1_log::UserL2ToL1Log, tx::IncludedTxLocation, + u256_to_h256, utils::display_timestamp, Address, BloomInput, ExecuteTransactionCommon, ProtocolVersionId, StorageKey, StorageLog, Transaction, H256, }; -use zksync_utils::u256_to_h256; use crate::{ io::seal_logic::l2_block_seal_subtasks::L2BlockSealProcess, diff --git a/core/node/state_keeper/src/io/tests/mod.rs b/core/node/state_keeper/src/io/tests/mod.rs index 7196236475df..4ea3460e6e30 100644 --- a/core/node/state_keeper/src/io/tests/mod.rs +++ b/core/node/state_keeper/src/io/tests/mod.rs @@ -20,17 +20,14 @@ use zksync_types::{ AccountTreeId, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersion, ProtocolVersionId, StorageKey, TransactionTimeRangeConstraint, H256, U256, }; -use zksync_utils::{ - bytecode::{hash_bytecode, hash_evm_bytecode}, - time::seconds_since_epoch, -}; +use zksync_utils::bytecode::{hash_bytecode, hash_evm_bytecode}; use self::tester::Tester; use crate::{ io::{seal_logic::l2_block_seal_subtasks::L2BlockSealProcess, StateKeeperIO}, mempool_actor::l2_tx_filter, testonly::BASE_SYSTEM_CONTRACTS, - tests::{create_execution_result, create_transaction, Query}, + tests::{create_execution_result, create_transaction, seconds_since_epoch, Query}, updates::{L2BlockSealCommand, L2BlockUpdates, UpdatesManager}, StateKeeperOutputHandler, StateKeeperPersistence, }; diff --git a/core/node/state_keeper/src/mempool_actor.rs b/core/node/state_keeper/src/mempool_actor.rs index 8e9d674f8787..fea1fcf89291 100644 --- a/core/node/state_keeper/src/mempool_actor.rs +++ b/core/node/state_keeper/src/mempool_actor.rs @@ -171,7 +171,9 @@ async fn get_transaction_nonces( Ok(nonce_values .into_iter() .map(|(nonce_key, nonce_value)| { - let nonce = Nonce(zksync_utils::h256_to_u32(nonce_value)); + // `unwrap()` is safe by construction. + let be_u32_bytes: [u8; 4] = nonce_value[28..].try_into().unwrap(); + let nonce = Nonce(u32::from_be_bytes(be_u32_bytes)); (address_by_nonce_key[&nonce_key], nonce) }) .collect()) @@ -183,8 +185,9 @@ mod tests { use zksync_node_fee_model::MockBatchFeeParamsProvider; use zksync_node_genesis::{insert_genesis_batch, GenesisParams}; use zksync_node_test_utils::create_l2_transaction; - use zksync_types::{L2BlockNumber, PriorityOpId, ProtocolVersionId, StorageLog, H256}; - use zksync_utils::u256_to_h256; + use zksync_types::{ + u256_to_h256, L2BlockNumber, PriorityOpId, ProtocolVersionId, StorageLog, H256, + }; use super::*; diff --git a/core/node/state_keeper/src/seal_criteria/mod.rs b/core/node/state_keeper/src/seal_criteria/mod.rs index c10b01e7e73d..4c6f56a6f5b7 100644 --- a/core/node/state_keeper/src/seal_criteria/mod.rs +++ b/core/node/state_keeper/src/seal_criteria/mod.rs @@ -20,18 +20,17 @@ use zksync_multivm::{ use zksync_types::{ block::BlockGasCount, utils::display_timestamp, ProtocolVersionId, Transaction, }; -use zksync_utils::time::millis_since; - -mod conditional_sealer; -pub(super) mod criteria; pub use self::conditional_sealer::{ConditionalSealer, NoopSealer, SequencerSealer}; -use super::{ +use crate::{ metrics::AGGREGATION_METRICS, updates::UpdatesManager, - utils::{gas_count_from_tx_and_metrics, gas_count_from_writes}, + utils::{gas_count_from_tx_and_metrics, gas_count_from_writes, millis_since}, }; +mod conditional_sealer; +pub(super) mod criteria; + fn halt_as_metric_label(halt: &Halt) -> &'static str { match halt { Halt::ValidationFailed(_) => "ValidationFailed", @@ -278,10 +277,10 @@ impl L2BlockMaxPayloadSizeSealer { #[cfg(test)] mod tests { - use zksync_utils::time::seconds_since_epoch; - use super::*; - use crate::tests::{create_execution_result, create_transaction, create_updates_manager}; + use crate::tests::{ + create_execution_result, create_transaction, create_updates_manager, seconds_since_epoch, + }; fn apply_tx_to_manager(tx: Transaction, manager: &mut UpdatesManager) { manager.extend_from_executed_transaction( diff --git a/core/node/state_keeper/src/testonly/mod.rs b/core/node/state_keeper/src/testonly/mod.rs index b0f641ccbc1a..023613cda61d 100644 --- a/core/node/state_keeper/src/testonly/mod.rs +++ b/core/node/state_keeper/src/testonly/mod.rs @@ -14,11 +14,11 @@ use zksync_multivm::interface::{ use zksync_state::OwnedStorage; use zksync_test_account::Account; use zksync_types::{ - commitment::PubdataParams, fee::Fee, utils::storage_key_for_standard_token_balance, - AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, PriorityOpId, StorageLog, - Transaction, L2_BASE_TOKEN_ADDRESS, SYSTEM_CONTEXT_MINIMAL_BASE_FEE, U256, + commitment::PubdataParams, fee::Fee, u256_to_h256, + utils::storage_key_for_standard_token_balance, AccountTreeId, Address, Execute, L1BatchNumber, + L2BlockNumber, PriorityOpId, StorageLog, Transaction, L2_BASE_TOKEN_ADDRESS, + SYSTEM_CONTEXT_MINIMAL_BASE_FEE, U256, }; -use zksync_utils::u256_to_h256; pub mod test_batch_executor; diff --git a/core/node/state_keeper/src/tests/mod.rs b/core/node/state_keeper/src/tests/mod.rs index 28e2f9886b49..ca078354c896 100644 --- a/core/node/state_keeper/src/tests/mod.rs +++ b/core/node/state_keeper/src/tests/mod.rs @@ -3,7 +3,7 @@ use std::{ atomic::{AtomicBool, AtomicU64, Ordering}, Arc, }, - time::Instant, + time::{Instant, SystemTime, UNIX_EPOCH}, }; use tokio::sync::watch; @@ -20,11 +20,10 @@ use zksync_types::{ aggregated_operations::AggregatedActionType, block::{BlockGasCount, L2BlockExecutionData, L2BlockHasher}, fee_model::{BatchFeeInput, PubdataIndependentBatchFeeModelInput}, - AccountTreeId, Address, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, StorageKey, - StorageLog, StorageLogKind, StorageLogWithPreviousValue, Transaction, H256, U256, - ZKPORTER_IS_AVAILABLE, + u256_to_h256, AccountTreeId, Address, L1BatchNumber, L2BlockNumber, L2ChainId, + ProtocolVersionId, StorageKey, StorageLog, StorageLogKind, StorageLogWithPreviousValue, + Transaction, H256, U256, ZKPORTER_IS_AVAILABLE, }; -use zksync_utils::u256_to_h256; use crate::{ io::PendingBatchData, @@ -46,6 +45,13 @@ use crate::{ ZkSyncStateKeeper, }; +pub(crate) fn seconds_since_epoch() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Incorrect system time") + .as_secs() +} + /// Creates a mock `PendingBatchData` object containing the provided sequence of L2 blocks. pub(crate) fn pending_batch_data(pending_l2_blocks: Vec) -> PendingBatchData { PendingBatchData { diff --git a/core/node/state_keeper/src/utils.rs b/core/node/state_keeper/src/utils.rs index 4240ad306251..320dd49583ed 100644 --- a/core/node/state_keeper/src/utils.rs +++ b/core/node/state_keeper/src/utils.rs @@ -1,3 +1,5 @@ +use std::time::{SystemTime, UNIX_EPOCH}; + use zksync_multivm::interface::{DeduplicatedWritesMetrics, VmExecutionMetrics}; use zksync_types::{ aggregated_operations::AggregatedActionType, block::BlockGasCount, ExecuteTransactionCommon, @@ -86,3 +88,15 @@ pub(super) fn gas_count_from_writes( execute: 0, } } + +// TODO (SMA-1206): use seconds instead of milliseconds. +pub(super) fn millis_since_epoch() -> u128 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Incorrect system time") + .as_millis() +} + +pub(super) fn millis_since(since: u64) -> u64 { + (millis_since_epoch() - since as u128 * 1000) as u64 +} diff --git a/core/node/test_utils/Cargo.toml b/core/node/test_utils/Cargo.toml index 6df100c51a7d..fd657c7d82c0 100644 --- a/core/node/test_utils/Cargo.toml +++ b/core/node/test_utils/Cargo.toml @@ -17,4 +17,3 @@ zksync_contracts.workspace = true zksync_merkle_tree.workspace = true zksync_system_constants.workspace = true zksync_vm_interface.workspace = true -zksync_utils.workspace = true diff --git a/core/node/test_utils/src/lib.rs b/core/node/test_utils/src/lib.rs index 2b446fff12c5..9a02c18cd235 100644 --- a/core/node/test_utils/src/lib.rs +++ b/core/node/test_utils/src/lib.rs @@ -226,7 +226,7 @@ impl Snapshot { factory_deps: [&contracts.bootloader, &contracts.default_aa] .into_iter() .chain(contracts.evm_emulator.as_ref()) - .map(|c| (c.hash, zksync_utils::be_words_to_bytes(&c.code))) + .map(|c| (c.hash, c.code.clone())) .collect(), storage_logs, } diff --git a/core/node/vm_runner/src/impls/bwip.rs b/core/node/vm_runner/src/impls/bwip.rs index a2cf126f5499..5d63d09b5caf 100644 --- a/core/node/vm_runner/src/impls/bwip.rs +++ b/core/node/vm_runner/src/impls/bwip.rs @@ -1,4 +1,7 @@ -use std::{collections::HashSet, sync::Arc}; +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; use anyhow::anyhow; use async_trait::async_trait; @@ -8,10 +11,9 @@ use zksync_object_store::ObjectStore; use zksync_prover_interface::inputs::VMRunWitnessInputData; use zksync_state::OwnedStorage; use zksync_types::{ - block::StorageOracleInfo, witness_block_state::WitnessStorageState, L1BatchNumber, L2ChainId, - H256, + block::StorageOracleInfo, h256_to_u256, u256_to_h256, witness_block_state::WitnessStorageState, + L1BatchNumber, L2ChainId, H256, }; -use zksync_utils::{bytes_to_chunks, h256_to_u256, u256_to_h256}; use zksync_vm_interface::{executor::BatchExecutorFactory, L1BatchEnv, L2BlockEnv, SystemEnv}; use crate::{ @@ -224,7 +226,6 @@ async fn get_updates_manager_witness_input_data( .get_sealed_factory_dep(default_aa) .await? .ok_or_else(|| anyhow!("Default account bytecode should exist"))?; - let account_bytecode = bytes_to_chunks(&account_bytecode_bytes); let used_contract_hashes = &output.batch.final_execution_state.used_contract_hashes; let hashes: HashSet = used_contract_hashes @@ -238,7 +239,7 @@ async fn get_updates_manager_witness_input_data( .get_factory_deps(&hashes) .await; if used_contract_hashes.contains(&account_code_hash) { - used_bytecodes.insert(account_code_hash, account_bytecode); + used_bytecodes.insert(account_code_hash, account_bytecode_bytes); } let evm_emulator_code_hash = if let Some(evm_emulator) = evm_emulator { @@ -249,7 +250,6 @@ async fn get_updates_manager_witness_input_data( .get_sealed_factory_dep(evm_emulator) .await? .ok_or_else(|| anyhow!("EVM emulator bytecode should exist"))?; - let evm_emulator_bytecode = bytes_to_chunks(&evm_emulator_bytecode); used_bytecodes.insert(evm_emulator_code_hash, evm_emulator_bytecode); } Some(evm_emulator_code_hash) @@ -266,7 +266,10 @@ async fn get_updates_manager_witness_input_data( Ok(VMRunWitnessInputData { l1_batch_number, - used_bytecodes, + used_bytecodes: used_bytecodes + .into_iter() + .map(|(hash, code)| (hash, bytes_to_chunks(&code))) + .collect(), initial_heap_content, protocol_version: system_env.version, bootloader_code, @@ -278,6 +281,13 @@ async fn get_updates_manager_witness_input_data( }) } +fn bytes_to_chunks(bytes: &[u8]) -> Vec<[u8; 32]> { + bytes + .chunks(32) + .map(|chunk| chunk.try_into().unwrap()) + .collect() +} + #[tracing::instrument(skip_all)] async fn assert_database_witness_input_data( connection: &mut Connection<'_, Core>, @@ -305,7 +315,6 @@ async fn assert_database_witness_input_data( .await .expect("Failed fetching default account bytecode from DB") .expect("Default account bytecode should exist"); - let account_bytecode = bytes_to_chunks(&account_bytecode_bytes); let hashes: HashSet = block_header .used_contract_hashes @@ -322,7 +331,7 @@ async fn assert_database_witness_input_data( .used_contract_hashes .contains(&account_code_hash) { - used_bytecodes.insert(account_code_hash, account_bytecode); + used_bytecodes.insert(account_code_hash, account_bytecode_bytes); } assert_eq!( @@ -331,6 +340,10 @@ async fn assert_database_witness_input_data( "{} factory deps are not found in DB", hashes.len() - used_bytecodes.len() ); + let used_bytecodes: HashMap<_, _> = used_bytecodes + .into_iter() + .map(|(hash, code)| (hash, bytes_to_chunks(&code))) + .collect(); let StorageOracleInfo { storage_refunds, diff --git a/core/node/vm_runner/src/tests/mod.rs b/core/node/vm_runner/src/tests/mod.rs index a3438d5a4e11..d56c70e5808d 100644 --- a/core/node/vm_runner/src/tests/mod.rs +++ b/core/node/vm_runner/src/tests/mod.rs @@ -13,13 +13,14 @@ use zksync_test_account::Account; use zksync_types::{ block::{L1BatchHeader, L2BlockHasher}, fee::Fee, - get_intrinsic_constants, + get_intrinsic_constants, h256_to_u256, l2::L2Tx, + u256_to_h256, utils::storage_key_for_standard_token_balance, AccountTreeId, Address, Execute, L1BatchNumber, L2BlockNumber, ProtocolVersionId, StorageKey, StorageLog, StorageLogKind, StorageValue, H160, H256, L2_BASE_TOKEN_ADDRESS, U256, }; -use zksync_utils::{bytecode::hash_bytecode, h256_to_u256, u256_to_h256}; +use zksync_utils::bytecode::hash_bytecode; use zksync_vm_interface::{ tracer::ValidationTraces, L1BatchEnv, L2BlockEnv, SystemEnv, TransactionExecutionMetrics, }; diff --git a/core/tests/test_account/src/lib.rs b/core/tests/test_account/src/lib.rs index cfb539c0e0f7..b8c79923a4e8 100644 --- a/core/tests/test_account/src/lib.rs +++ b/core/tests/test_account/src/lib.rs @@ -8,10 +8,11 @@ use zksync_system_constants::{ REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE, }; use zksync_types::{ - abi, fee::Fee, l2::L2Tx, utils::deployed_address_create, Address, Execute, K256PrivateKey, - L2ChainId, Nonce, Transaction, H256, PRIORITY_OPERATION_L2_TX_TYPE, U256, + abi, address_to_u256, fee::Fee, h256_to_u256, l2::L2Tx, utils::deployed_address_create, + Address, Execute, K256PrivateKey, L2ChainId, Nonce, Transaction, H256, + PRIORITY_OPERATION_L2_TX_TYPE, U256, }; -use zksync_utils::{address_to_u256, bytecode::hash_bytecode, h256_to_u256}; +use zksync_utils::bytecode::hash_bytecode; pub const L1_TEST_GAS_PER_PUBDATA_BYTE: u32 = 800; const BASE_FEE: u64 = 2_000_000_000; diff --git a/core/tests/vm-benchmark/src/vm.rs b/core/tests/vm-benchmark/src/vm.rs index bf969e0de5c0..e082b9c24da2 100644 --- a/core/tests/vm-benchmark/src/vm.rs +++ b/core/tests/vm-benchmark/src/vm.rs @@ -14,7 +14,7 @@ use zksync_multivm::{ zk_evm_latest::ethereum_types::{Address, U256}, }; use zksync_types::{ - block::L2BlockHasher, fee_model::BatchFeeInput, helpers::unix_timestamp_ms, + block::L2BlockHasher, fee_model::BatchFeeInput, helpers::unix_timestamp_ms, u256_to_h256, utils::storage_key_for_eth_balance, L1BatchNumber, L2BlockNumber, L2ChainId, ProtocolVersionId, Transaction, }; @@ -29,7 +29,7 @@ static STORAGE: Lazy = Lazy::new(|| { // Give `PRIVATE_KEY` some money let balance = U256::from(10u32).pow(U256::from(32)); //10^32 wei let key = storage_key_for_eth_balance(&PRIVATE_KEY.address()); - storage.set_value(key, zksync_utils::u256_to_h256(balance)); + storage.set_value(key, u256_to_h256(balance)); storage }); diff --git a/prover/Cargo.lock b/prover/Cargo.lock index f119d4bd1951..3250c99deda6 100644 --- a/prover/Cargo.lock +++ b/prover/Cargo.lock @@ -8030,7 +8030,6 @@ dependencies = [ "sha2 0.10.8", "thiserror", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -8592,7 +8591,6 @@ version = "0.1.0" dependencies = [ "once_cell", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -8632,14 +8630,10 @@ name = "zksync_utils" version = "0.1.0" dependencies = [ "anyhow", - "bigdecimal", "const-decoder 0.4.0", "futures 0.3.30", - "hex", - "num", "once_cell", "reqwest 0.12.5", - "serde", "serde_json", "thiserror", "tokio", diff --git a/zkstack_cli/Cargo.lock b/zkstack_cli/Cargo.lock index a9089719714d..a582fff958f5 100644 --- a/zkstack_cli/Cargo.lock +++ b/zkstack_cli/Cargo.lock @@ -6895,7 +6895,6 @@ dependencies = [ "sha2", "thiserror", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -6970,7 +6969,6 @@ version = "0.1.0" dependencies = [ "once_cell", "zksync_basic_types", - "zksync_utils", ] [[package]] @@ -7010,14 +7008,10 @@ name = "zksync_utils" version = "0.1.0" dependencies = [ "anyhow", - "bigdecimal", "const-decoder", "futures", - "hex", - "num", "once_cell", "reqwest 0.12.8", - "serde", "serde_json", "thiserror", "tokio", From cc4cd8d139c34e82cae5b3627961f53f280997f1 Mon Sep 17 00:00:00 2001 From: D025 Date: Mon, 11 Nov 2024 13:22:33 +0200 Subject: [PATCH 6/8] ci: migrate release workflows to new reusable workflows (#3198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Migrate build core and prover release workflows to new re-usable workflows ## Why ❔ Improve CI ## 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`. --- .github/workflows/release-test-stage.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-test-stage.yml b/.github/workflows/release-test-stage.yml index 18708420dab0..36a2b494c242 100644 --- a/.github/workflows/release-test-stage.yml +++ b/.github/workflows/release-test-stage.yml @@ -61,10 +61,11 @@ jobs: build-push-core-images: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-core-template.yml + uses: ./.github/workflows/new-build-core-template.yml if: needs.changed_files.outputs.core == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -84,10 +85,11 @@ jobs: build-push-contract-verifier: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-contract-verifier-template.yml + uses: ./.github/workflows/new-build-contract-verifier-template.yml if: needs.changed_files.outputs.core == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -95,12 +97,13 @@ jobs: build-push-prover-images: name: Build and push images needs: [setup, changed_files] - uses: ./.github/workflows/build-prover-template.yml + uses: ./.github/workflows/new-build-prover-template.yml if: needs.changed_files.outputs.prover == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }} ERA_BELLMAN_CUDA_RELEASE: ${{ vars.ERA_BELLMAN_CUDA_RELEASE }} CUDA_ARCH: "60;70;75;80;89" + action: "push" secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} @@ -108,13 +111,14 @@ jobs: build-push-witness-generator-image-avx512: name: Build and push prover images with avx512 instructions needs: [setup, changed_files] - uses: ./.github/workflows/build-witness-generator-template.yml + uses: ./.github/workflows/new-build-witness-generator-template.yml if: needs.changed_files.outputs.prover == 'true' || needs.changed_files.outputs.all == 'true' with: image_tag_suffix: ${{ needs.setup.outputs.image_tag_suffix }}-avx512 ERA_BELLMAN_CUDA_RELEASE: ${{ vars.ERA_BELLMAN_CUDA_RELEASE }} CUDA_ARCH: "60;70;75;80;89" WITNESS_GENERATOR_RUST_FLAGS: "-Ctarget_feature=+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512vl " + action: push secrets: DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} From 8552d9cd35e6f70a7cd9310847087fdaf97180d5 Mon Sep 17 00:00:00 2001 From: Jacob Lindahl Date: Mon, 11 Nov 2024 07:24:12 -0600 Subject: [PATCH 7/8] chore: Refine loadtest configurations (#2649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ This PR accomplishes two things: 1. Improves the precision with which the loadtest contract can be configured by splitting writes into two categories—initial and repeated—since the cost associated with each is different. 2. Introduces a set of standards which can be used to determine appropriate loadtest configurations. SQL queries are provided to assist in the calculations. ## Why ❔ Currently, the loadtests do not produce activity that closely emulates mainnet activity. ## 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. (See https://github.com/matter-labs/zksync-era-workflows/pull/229) - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zk fmt` and `zk lint`. --------- Co-authored-by: Roman Brodetski --- bin/run_loadtest_from_github_actions | 11 ++-- core/lib/contracts/src/test_contracts.rs | 12 +++-- .../src/versions/testonly/rollbacks.rs | 6 ++- .../src/versions/vm_latest/tests/rollbacks.rs | 2 +- .../api_server/src/tx_sender/tests/call.rs | 3 +- .../src/tx_sender/tests/gas_estimation.rs | 2 +- .../api_server/src/tx_sender/tests/mod.rs | 3 +- .../state_keeper/src/executor/tests/mod.rs | 4 +- .../state_keeper/src/executor/tests/tester.rs | 11 ++-- core/tests/loadnext/Cargo.toml | 1 + core/tests/loadnext/README.md | 28 ++++++----- .../src/account/tx_command_executor.rs | 3 +- core/tests/vm-benchmark/src/transaction.rs | 21 ++++---- .../how_to_calculate_loadtest_profiles.md | 15 ++++++ .../contracts/loadnext/loadnext_contract.sol | 41 ++++++++++++--- .../loadnext/query_event_metrics.sql | 19 +++++++ .../loadnext/query_execution_info_metrics.sql | 20 ++++++++ .../query_max_transactions_in_window.sql | 23 +++++++++ .../loadnext/query_read_metrics_basic.sql | 39 +++++++++++++++ .../loadnext/query_write_metrics.sql | 50 +++++++++++++++++++ 20 files changed, 262 insertions(+), 52 deletions(-) create mode 100644 etc/contracts-test-data/contracts/loadnext/how_to_calculate_loadtest_profiles.md create mode 100644 etc/contracts-test-data/contracts/loadnext/query_event_metrics.sql create mode 100644 etc/contracts-test-data/contracts/loadnext/query_execution_info_metrics.sql create mode 100644 etc/contracts-test-data/contracts/loadnext/query_max_transactions_in_window.sql create mode 100644 etc/contracts-test-data/contracts/loadnext/query_read_metrics_basic.sql create mode 100644 etc/contracts-test-data/contracts/loadnext/query_write_metrics.sql diff --git a/bin/run_loadtest_from_github_actions b/bin/run_loadtest_from_github_actions index f784ddd3180d..149988d63d8f 100755 --- a/bin/run_loadtest_from_github_actions +++ b/bin/run_loadtest_from_github_actions @@ -11,11 +11,12 @@ export TRANSACTION_WEIGHTS_WITHDRAWAL=${weights[3]} read -ra execution_params <<<"$CONTRACT_EXECUTION_PARAMS" #reading $CONTRACT_EXECUTION_PARAMS as an array as tokens separated by IFS export CONTRACT_EXECUTION_PARAMS_READS=${execution_params[0]} -export CONTRACT_EXECUTION_PARAMS_WRITES=${execution_params[1]} -export CONTRACT_EXECUTION_PARAMS_EVENTS=${execution_params[2]} -export CONTRACT_EXECUTION_PARAMS_HASHES=${execution_params[3]} -export CONTRACT_EXECUTION_PARAMS_RECURSIVE_CALLS=${execution_params[4]} -export CONTRACT_EXECUTION_PARAMS_DEPLOYS=${execution_params[5]} +export CONTRACT_EXECUTION_PARAMS_INITIAL_WRITES=${execution_params[1]} +export CONTRACT_EXECUTION_PARAMS_REPEATED_WRITES=${execution_params[2]} +export CONTRACT_EXECUTION_PARAMS_EVENTS=${execution_params[3]} +export CONTRACT_EXECUTION_PARAMS_HASHES=${execution_params[4]} +export CONTRACT_EXECUTION_PARAMS_RECURSIVE_CALLS=${execution_params[5]} +export CONTRACT_EXECUTION_PARAMS_DEPLOYS=${execution_params[6]} # Run the test cargo run --bin loadnext diff --git a/core/lib/contracts/src/test_contracts.rs b/core/lib/contracts/src/test_contracts.rs index eab1587f8335..a670d930f049 100644 --- a/core/lib/contracts/src/test_contracts.rs +++ b/core/lib/contracts/src/test_contracts.rs @@ -6,7 +6,8 @@ use crate::get_loadnext_contract; #[derive(Debug, Clone, Deserialize)] pub struct LoadnextContractExecutionParams { pub reads: usize, - pub writes: usize, + pub initial_writes: usize, + pub repeated_writes: usize, pub events: usize, pub hashes: usize, pub recursive_calls: usize, @@ -21,7 +22,8 @@ impl LoadnextContractExecutionParams { pub fn empty() -> Self { Self { reads: 0, - writes: 0, + initial_writes: 0, + repeated_writes: 0, events: 0, hashes: 0, recursive_calls: 0, @@ -34,7 +36,8 @@ impl Default for LoadnextContractExecutionParams { fn default() -> Self { Self { reads: 10, - writes: 10, + initial_writes: 10, + repeated_writes: 10, events: 10, hashes: 10, recursive_calls: 1, @@ -50,7 +53,8 @@ impl LoadnextContractExecutionParams { let params = vec![ Token::Uint(U256::from(self.reads)), - Token::Uint(U256::from(self.writes)), + Token::Uint(U256::from(self.initial_writes)), + Token::Uint(U256::from(self.repeated_writes)), Token::Uint(U256::from(self.hashes)), Token::Uint(U256::from(self.events)), Token::Uint(U256::from(self.recursive_calls)), diff --git a/core/lib/multivm/src/versions/testonly/rollbacks.rs b/core/lib/multivm/src/versions/testonly/rollbacks.rs index cab3427899ea..08f0136717c4 100644 --- a/core/lib/multivm/src/versions/testonly/rollbacks.rs +++ b/core/lib/multivm/src/versions/testonly/rollbacks.rs @@ -105,7 +105,8 @@ pub(crate) fn test_vm_loadnext_rollbacks() { contract_address: Some(address), calldata: LoadnextContractExecutionParams { reads: 100, - writes: 100, + initial_writes: 100, + repeated_writes: 100, events: 100, hashes: 500, recursive_calls: 10, @@ -123,7 +124,8 @@ pub(crate) fn test_vm_loadnext_rollbacks() { contract_address: Some(address), calldata: LoadnextContractExecutionParams { reads: 100, - writes: 100, + initial_writes: 100, + repeated_writes: 100, events: 100, hashes: 500, recursive_calls: 10, diff --git a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs index de674498427d..bb20670e5a6e 100644 --- a/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs +++ b/core/lib/multivm/src/versions/vm_latest/tests/rollbacks.rs @@ -87,7 +87,7 @@ fn test_layered_rollback() { let loadnext_transaction = account.get_loadnext_transaction( address, LoadnextContractExecutionParams { - writes: 1, + initial_writes: 1, recursive_calls: 20, ..LoadnextContractExecutionParams::empty() }, diff --git a/core/node/api_server/src/tx_sender/tests/call.rs b/core/node/api_server/src/tx_sender/tests/call.rs index e43f55b2b9af..08571790e8eb 100644 --- a/core/node/api_server/src/tx_sender/tests/call.rs +++ b/core/node/api_server/src/tx_sender/tests/call.rs @@ -238,7 +238,8 @@ async fn eth_call_with_load_test_transactions() { }, LoadnextContractExecutionParams { reads: 100, - writes: 100, + initial_writes: 100, + repeated_writes: 100, ..LoadnextContractExecutionParams::empty() }, ]; diff --git a/core/node/api_server/src/tx_sender/tests/gas_estimation.rs b/core/node/api_server/src/tx_sender/tests/gas_estimation.rs index 7db1b8339314..5e0c67477ffe 100644 --- a/core/node/api_server/src/tx_sender/tests/gas_estimation.rs +++ b/core/node/api_server/src/tx_sender/tests/gas_estimation.rs @@ -116,7 +116,7 @@ async fn initial_estimate_for_deep_recursion(with_reads: bool) { (75, 1.2), (100, 1.4), (125, 1.7), - (150, 2.1), + (150, 2.2), ] }; for &(recursion_depth, multiplier) in depths_and_multipliers { diff --git a/core/node/api_server/src/tx_sender/tests/mod.rs b/core/node/api_server/src/tx_sender/tests/mod.rs index cbe405b2aa63..d0fe3126c9ad 100644 --- a/core/node/api_server/src/tx_sender/tests/mod.rs +++ b/core/node/api_server/src/tx_sender/tests/mod.rs @@ -18,7 +18,8 @@ const LOAD_TEST_CASES: TestCases = test_casing: LoadnextContractExecutionParams::default(), // No storage modification LoadnextContractExecutionParams { - writes: 0, + initial_writes: 0, + repeated_writes: 0, events: 0, ..LoadnextContractExecutionParams::default() }, diff --git a/core/node/state_keeper/src/executor/tests/mod.rs b/core/node/state_keeper/src/executor/tests/mod.rs index 04fb016ab639..62e9cd1968f1 100644 --- a/core/node/state_keeper/src/executor/tests/mod.rs +++ b/core/node/state_keeper/src/executor/tests/mod.rs @@ -296,7 +296,7 @@ async fn deploy_and_call_loadtest(vm_mode: FastVmMode) { ); assert_executed( &executor - .execute_tx(alice.loadnext_custom_writes_call(tx.address, 1, 500_000_000)) + .execute_tx(alice.loadnext_custom_initial_writes_call(tx.address, 1, 500_000_000)) .await .unwrap(), ); @@ -344,7 +344,7 @@ async fn execute_reverted_tx(vm_mode: FastVmMode) { assert_reverted( &executor - .execute_tx(alice.loadnext_custom_writes_call( + .execute_tx(alice.loadnext_custom_initial_writes_call( tx.address, 1, 1_000_000, // We provide enough gas for tx to be executed, but not enough for the call to be successful. )) diff --git a/core/node/state_keeper/src/executor/tests/tester.rs b/core/node/state_keeper/src/executor/tests/tester.rs index 247703c866e4..49f456e82917 100644 --- a/core/node/state_keeper/src/executor/tests/tester.rs +++ b/core/node/state_keeper/src/executor/tests/tester.rs @@ -335,7 +335,7 @@ pub trait AccountLoadNextExecutable { /// Returns an `execute` transaction with custom factory deps (which aren't used in a transaction, /// so they are mostly useful to test bytecode compression). fn execute_with_factory_deps(&mut self, factory_deps: Vec>) -> Transaction; - fn loadnext_custom_writes_call( + fn loadnext_custom_initial_writes_call( &mut self, address: Address, writes: u32, @@ -407,17 +407,17 @@ impl AccountLoadNextExecutable for Account { /// Returns a transaction to the loadnext contract with custom amount of write requests. /// Increments the account nonce. - fn loadnext_custom_writes_call( + fn loadnext_custom_initial_writes_call( &mut self, address: Address, - writes: u32, + initial_writes: u32, gas_limit: u32, ) -> Transaction { // For each iteration of the expensive contract, there are two slots that are updated: // the length of the vector and the new slot with the element itself. let minimal_fee = 2 * testonly::DEFAULT_GAS_PER_PUBDATA - * writes + * initial_writes * INITIAL_STORAGE_WRITE_PUBDATA_BYTES as u32; let fee = testonly::fee(minimal_fee + gas_limit); @@ -427,7 +427,8 @@ impl AccountLoadNextExecutable for Account { contract_address: Some(address), calldata: LoadnextContractExecutionParams { reads: 100, - writes: writes as usize, + initial_writes: initial_writes as usize, + repeated_writes: 100, events: 100, hashes: 100, recursive_calls: 0, diff --git a/core/tests/loadnext/Cargo.toml b/core/tests/loadnext/Cargo.toml index adb5c9eca429..9ceac7d5372a 100644 --- a/core/tests/loadnext/Cargo.toml +++ b/core/tests/loadnext/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true keywords.workspace = true categories.workspace = true publish = false +exclude = ["./dump"] [dependencies] zksync_types.workspace = true diff --git a/core/tests/loadnext/README.md b/core/tests/loadnext/README.md index 59288a7160ec..2556c1d9ca74 100644 --- a/core/tests/loadnext/README.md +++ b/core/tests/loadnext/README.md @@ -27,21 +27,22 @@ It: ## Transactions Parameters -The smart contract that is used for every l2 transaction can be found here: -`etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol`. +The smart contract that is used for every L2 transaction can be found here: +[`etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol`](../../../etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol). The `execute` function of the contract has the following parameters: -``` - function execute(uint reads, uint writes, uint hashes, uint events, uint max_recursion, uint deploys) external returns(uint) { +```solidity +function execute(uint reads, uint initialWrites, uint repeatedWrites, uint hashes, uint events, uint maxRecursion, uint deploys) external returns(uint) { ``` which correspond to the following configuration options: -``` +```rust pub struct LoadnextContractExecutionParams { pub reads: usize, - pub writes: usize, + pub initial_writes: usize, + pub repeated_writes: usize, pub events: usize, pub hashes: usize, pub recursive_calls: usize, @@ -51,8 +52,9 @@ pub struct LoadnextContractExecutionParams { For example, to simulate an average transaction on mainnet, one could do: -``` -CONTRACT_EXECUTION_PARAMS_WRITES=2 +```env +CONTRACT_EXECUTION_PARAMS_INITIAL_WRITES=2 +CONTRACT_EXECUTION_PARAMS_REPEATED_WRITES=2 CONTRACT_EXECUTION_PARAMS_READS=6 CONTRACT_EXECUTION_PARAMS_EVENTS=2 CONTRACT_EXECUTION_PARAMS_HASHES=10 @@ -62,8 +64,9 @@ CONTRACT_EXECUTION_PARAMS_DEPLOYS=0 Similarly, to simulate a lightweight transaction: -``` -CONTRACT_EXECUTION_PARAMS_WRITES=0 +```env +CONTRACT_EXECUTION_PARAMS_INITIAL_WRITES=0 +CONTRACT_EXECUTION_PARAMS_REPEATED_WRITES=0 CONTRACT_EXECUTION_PARAMS_READS=0 CONTRACT_EXECUTION_PARAMS_EVENTS=0 CONTRACT_EXECUTION_PARAMS_HASHES=0 @@ -86,10 +89,11 @@ Example invocation: - `MASTER_WALLET_PK` needs to be set to the private key of the master account. - `MAIN_TOKEN` needs to be set to the address of the token to be used for the loadtest. -``` +```sh cargo build -CONTRACT_EXECUTION_PARAMS_WRITES=2 \ +CONTRACT_EXECUTION_PARAMS_INITIAL_WRITES=2 \ +CONTRACT_EXECUTION_PARAMS_REPEATED_WRITES=2 \ CONTRACT_EXECUTION_PARAMS_READS=6 \ CONTRACT_EXECUTION_PARAMS_EVENTS=2 \ CONTRACT_EXECUTION_PARAMS_HASHES=10 \ diff --git a/core/tests/loadnext/src/account/tx_command_executor.rs b/core/tests/loadnext/src/account/tx_command_executor.rs index 2a916564fd61..4703d257cfd9 100644 --- a/core/tests/loadnext/src/account/tx_command_executor.rs +++ b/core/tests/loadnext/src/account/tx_command_executor.rs @@ -380,7 +380,8 @@ impl AccountLifespan { function .encode_input(&vec![ ethabi::Token::Uint(U256::from(self.contract_execution_params.reads)), - ethabi::Token::Uint(U256::from(self.contract_execution_params.writes)), + ethabi::Token::Uint(U256::from(self.contract_execution_params.initial_writes)), + ethabi::Token::Uint(U256::from(self.contract_execution_params.repeated_writes)), ethabi::Token::Uint(U256::from(self.contract_execution_params.hashes)), ethabi::Token::Uint(U256::from(self.contract_execution_params.events)), ethabi::Token::Uint(U256::from(self.contract_execution_params.recursive_calls)), diff --git a/core/tests/vm-benchmark/src/transaction.rs b/core/tests/vm-benchmark/src/transaction.rs index d5fedfa4df94..c625018fb9bf 100644 --- a/core/tests/vm-benchmark/src/transaction.rs +++ b/core/tests/vm-benchmark/src/transaction.rs @@ -12,7 +12,7 @@ use zksync_types::{ }; use zksync_utils::bytecode::hash_bytecode; -const LOAD_TEST_MAX_READS: usize = 100; +const LOAD_TEST_MAX_READS: usize = 3000; pub(crate) static PRIVATE_KEY: Lazy = Lazy::new(|| K256PrivateKey::from_bytes(H256([42; 32])).expect("invalid key bytes")); @@ -112,7 +112,7 @@ pub fn get_load_test_deploy_tx() -> Transaction { Some(CONTRACT_DEPLOYER_ADDRESS), create_calldata, Nonce(0), - tx_fee(100_000_000), + tx_fee(500_000_000), U256::zero(), L2ChainId::from(270), &PRIVATE_KEY, @@ -138,7 +138,8 @@ pub fn get_load_test_tx(nonce: u32, gas_limit: u32, params: LoadTestParams) -> T let calldata = execute_function .encode_input(&vec![ Token::Uint(U256::from(params.reads)), - Token::Uint(U256::from(params.writes)), + Token::Uint(U256::from(params.initial_writes)), + Token::Uint(U256::from(params.repeated_writes)), Token::Uint(U256::from(params.hashes)), Token::Uint(U256::from(params.events)), Token::Uint(U256::from(params.recursive_calls)), @@ -168,9 +169,10 @@ pub fn get_realistic_load_test_tx(nonce: u32) -> Transaction { nonce, 10_000_000, LoadTestParams { - reads: 30, - writes: 2, - events: 5, + reads: 243, + initial_writes: 1, + repeated_writes: 11, + events: 6, hashes: 10, recursive_calls: 0, deploys: 0, @@ -183,9 +185,10 @@ pub fn get_heavy_load_test_tx(nonce: u32) -> Transaction { nonce, 10_000_000, LoadTestParams { - reads: 100, - writes: 5, - events: 20, + reads: 296, + initial_writes: 13, + repeated_writes: 92, + events: 140, hashes: 100, recursive_calls: 20, deploys: 5, diff --git a/etc/contracts-test-data/contracts/loadnext/how_to_calculate_loadtest_profiles.md b/etc/contracts-test-data/contracts/loadnext/how_to_calculate_loadtest_profiles.md new file mode 100644 index 000000000000..5918c4f2308a --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/how_to_calculate_loadtest_profiles.md @@ -0,0 +1,15 @@ +# Calculating loadtest profiles + +Use the SQL scripts in this directory to calculate the characteristics of transactions within a miniblock range. + +Calculate `CONTRACT_EXECUTION_PARAMS` as follows: + +- `light`: all zeroes. +- `realistic`: median (50th percentile). +- `heavy`: generally use 2.5× the values in the 99th percentile. However, some operations are even less frequent than that (e.g. contract deployments). At the time of writing, contract deployments is set to 5. + +Metrics may be averaged across different block ranges to calculate a more holistic "characteristic." + +## Compensating for implicit activity + +The mere act of executing a transaction entails some ancillary activity on the network. For example, some events are emitted when tokens are transferred for gas payments. The loadtest contract does not compensate for this activity, so it should be kept in mind when evaluating loadtest activity. diff --git a/etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol b/etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol index b14286a45038..9186ff6180a2 100644 --- a/etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol +++ b/etc/contracts-test-data/contracts/loadnext/loadnext_contract.sol @@ -8,25 +8,48 @@ contract LoadnextContract { uint[] readArray; uint[] writeArray; - constructor (uint reads) { + constructor(uint reads) { for (uint i = 0; i < reads; i++) { readArray.push(i); } } - function execute(uint reads, uint writes, uint hashes, uint events, uint max_recursion, uint deploys) external returns(uint) { - if (max_recursion > 0) { - return this.execute(reads, writes, hashes, events, max_recursion - 1, deploys); + function execute( + uint reads, + uint initialWrites, + uint repeatedWrites, + uint hashes, + uint events, + uint maxRecursion, + uint deploys + ) external returns (uint) { + if (maxRecursion > 0) { + return + this.execute( + reads, + initialWrites, + repeatedWrites, + hashes, + events, + maxRecursion - 1, + deploys + ); } + require(repeatedWrites <= readArray.length); uint sum = 0; // Somehow use result of storage read for compiler to not optimize this place. - for (uint i = 0; i < reads; i++) { + for (uint i = 0; i < repeatedWrites; i++) { + uint value = readArray[i]; + sum += value; + readArray[i] = value + 1; + } + for (uint i = repeatedWrites; i < reads; i++) { sum += readArray[i]; } - for (uint i = 0; i < writes; i++) { + for (uint i = 0; i < initialWrites; i++) { writeArray.push(i); } @@ -36,7 +59,9 @@ contract LoadnextContract { // Somehow use result of keccak for compiler to not optimize this place. for (uint i = 0; i < hashes; i++) { - sum += uint8(keccak256(abi.encodePacked("Message for encoding"))[0]); + sum += uint8( + keccak256(abi.encodePacked("Message for encoding"))[0] + ); } for (uint i = 0; i < deploys; i++) { @@ -47,7 +72,7 @@ contract LoadnextContract { function burnGas(uint256 gasToBurn) external { uint256 initialGas = gasleft(); - while(initialGas - gasleft() < gasToBurn) {} + while (initialGas - gasleft() < gasToBurn) {} } } diff --git a/etc/contracts-test-data/contracts/loadnext/query_event_metrics.sql b/etc/contracts-test-data/contracts/loadnext/query_event_metrics.sql new file mode 100644 index 000000000000..1a5d87d6fcfb --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/query_event_metrics.sql @@ -0,0 +1,19 @@ +-- calculate distribution of event emissions per transaction + +\set :start_from_miniblock_number 40000000 +\set :miniblock_range 10000 + +select stddev_samp(metric) as stddev, + avg(metric) as avg, + sum(metric) as sum, + min(metric) as min, + percentile_cont(0.01) within group (order by metric) as pct_01, + percentile_cont(0.50) within group (order by metric) as pct_50, + percentile_cont(0.99) within group (order by metric) as pct_99, + max(metric) as max +from (select tx.hash, count(ev.*) as metric + from transactions tx + left join events ev on ev.tx_hash = tx.hash + where ev.miniblock_number >= :start_from_miniblock_number + and ev.miniblock_number < :start_from_miniblock_number + :miniblock_range + group by tx.hash) s; diff --git a/etc/contracts-test-data/contracts/loadnext/query_execution_info_metrics.sql b/etc/contracts-test-data/contracts/loadnext/query_execution_info_metrics.sql new file mode 100644 index 000000000000..bf9faba4b6dc --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/query_execution_info_metrics.sql @@ -0,0 +1,20 @@ +-- calculate distribution of execution_info fields per transaction + +-- execution_info fields: gas_used, vm_events, cycles_used, storage_logs, l2_to_l1_logs, contracts_used, pubdata_published, total_log_queries, contracts_deployed, l2_l1_long_messages, computational_gas_used, published_bytecode_bytes +\set exection_info_field 'storage_logs' +\set start_from_miniblock_number 40000000 +\set miniblock_range 10000 + +select stddev_samp(metric) as stddev, + avg(metric) as avg, + sum(metric) as sum, + min(metric) as min, + percentile_cont(0.01) within group (order by metric) as pct_01, + percentile_cont(0.50) within group (order by metric) as pct_50, + percentile_cont(0.99) within group (order by metric) as pct_99, + max(metric) as max +from (select tx.miniblock_number, + (execution_info ->> :execution_info_field)::bigint as metric + from transactions tx) cd +where cd.miniblock_number >= :start_from_miniblock_number + and cd.miniblock_number < :start_from_miniblock_number + :miniblock_range; diff --git a/etc/contracts-test-data/contracts/loadnext/query_max_transactions_in_window.sql b/etc/contracts-test-data/contracts/loadnext/query_max_transactions_in_window.sql new file mode 100644 index 000000000000..91dd4bd47a7c --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/query_max_transactions_in_window.sql @@ -0,0 +1,23 @@ +-- not a metrics-collecting query, but may be useful to find an interesting range of transactions + +\set miniblock_number_range_start 36700000 +\set miniblock_number_range_end 36850000 +\set window_size 10000 +\set maximize_column l2_tx_count + +select miniblock_number_start, + miniblock_number_start + :window_size as miniblock_number_end, + metric_total +from (select mb.number as miniblock_number_start, + sum(mb.:maximize_column) + over lookahead + as metric_total + from miniblocks mb + where mb.number >= :miniblock_number_range_start + and mb.number < :miniblock_number_range_end + window lookahead as ( + order by mb.number + rows between current row and :window_size following + )) _s +order by metric_total desc +limit 10; diff --git a/etc/contracts-test-data/contracts/loadnext/query_read_metrics_basic.sql b/etc/contracts-test-data/contracts/loadnext/query_read_metrics_basic.sql new file mode 100644 index 000000000000..62195016f10e --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/query_read_metrics_basic.sql @@ -0,0 +1,39 @@ +-- calculate distribution of storage reads per transaction +-- does not calculate hot/cold reads + +\set start_from_miniblock_number 40000000 +\set miniblock_range 10000 + +with mb as (select * + from miniblocks mb + where mb.number >= :start_from_miniblock_number + order by mb.number + limit :miniblock_range) +select stddev_samp(metric) as stddev, + avg(metric) as avg, + sum(metric) as sum, + min(metric) as min, + percentile_cont(0.01) within group (order by metric) as pct_01, + percentile_cont(0.50) within group (order by metric) as pct_50, + percentile_cont(0.99) within group (order by metric) as pct_99, + max(metric) as max +from (select miniblock_number, + (sum(read_write_logs) - sum(write_logs)) / sum(transaction_count) as metric, + sum(transaction_count) as transaction_count + from (select mb.number as miniblock_number, + (tx.execution_info ->> 'storage_logs')::bigint as read_write_logs, + null as write_logs, + 1 as transaction_count + from transactions tx, + mb + where tx.miniblock_number = mb.number + union + select mb.number as miniblock_number, + null as read_write_logs, + count(sl.*) as write_logs, + 0 as transaction_count + from storage_logs sl, + mb + where sl.miniblock_number = mb.number + group by mb.number) s + group by s.miniblock_number) t, generate_series(1, t.transaction_count); diff --git a/etc/contracts-test-data/contracts/loadnext/query_write_metrics.sql b/etc/contracts-test-data/contracts/loadnext/query_write_metrics.sql new file mode 100644 index 000000000000..f142347f9801 --- /dev/null +++ b/etc/contracts-test-data/contracts/loadnext/query_write_metrics.sql @@ -0,0 +1,50 @@ +-- calculate distribution of initial and repeated writes per transaction + +\set start_from_miniblock_number 40000000; +\set miniblock_range 10000; + +select + -- initial writes + stddev_samp(initial_writes_per_tx) as initial_writes_stddev, + avg(initial_writes_per_tx) as initial_writes_avg, + min(initial_writes_per_tx) as initial_writes_min, + percentile_cont(0.01) within group (order by initial_writes_per_tx) as initial_writes_pct_01, + percentile_cont(0.50) within group (order by initial_writes_per_tx) as initial_writes_pct_50, + percentile_cont(0.99) within group (order by initial_writes_per_tx) as initial_writes_pct_99, + max(initial_writes_per_tx) as initial_writes_max, + + -- repeated writes + stddev_samp(repeated_writes_per_tx) as repeated_writes_stddev, + avg(repeated_writes_per_tx) as repeated_writes_avg, + min(repeated_writes_per_tx) as repeated_writes_min, + percentile_cont(0.01) within group (order by repeated_writes_per_tx) as repeated_writes_pct_01, + percentile_cont(0.50) within group (order by repeated_writes_per_tx) as repeated_writes_pct_50, + percentile_cont(0.99) within group (order by repeated_writes_per_tx) as repeated_writes_pct_99, + max(repeated_writes_per_tx) as repeated_writes_max +from (select initial_writes::real / l2_tx_count::real as initial_writes_per_tx, + (total_writes - initial_writes)::real / l2_tx_count::real as repeated_writes_per_tx + from (select mb.number as miniblock_number, + count(sl.hashed_key) as total_writes, + count(distinct sl.hashed_key) filter ( + where + iw.hashed_key is not null + ) as initial_writes, + mb.l2_tx_count as l2_tx_count + from miniblocks mb + join l1_batches l1b on l1b.number = mb.l1_batch_number + join storage_logs sl on sl.miniblock_number = mb.number + left join initial_writes iw on iw.hashed_key = sl.hashed_key + and iw.l1_batch_number = mb.l1_batch_number + and mb.number = ( + -- initial writes are only tracked by l1 batch number, so find the first miniblock in that batch that contains a write to that key + select miniblock_number + from storage_logs + where hashed_key = sl.hashed_key + order by miniblock_number + limit 1) + where mb.l2_tx_count <> 0 -- avoid div0 + and mb.number >= :start_from_miniblock_number + group by mb.number + order by mb.number desc + limit :miniblock_range) s, generate_series(1, s.l2_tx_count) -- scale by # of tx + ) t; From 8b31a85d47aae4c28868c76ce320ecedcd4bb3ad Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 11 Nov 2024 17:09:56 +0200 Subject: [PATCH 8/8] test(merkle-tree): Fix RocksDB termination in test (#3249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ Fixes RocksDB termination in a unit test. ## Why ❔ Without such a termination, the test sporadically fails with the "terminate called without an active exception" message. ## 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] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/node/metadata_calculator/src/recovery/tests.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/node/metadata_calculator/src/recovery/tests.rs b/core/node/metadata_calculator/src/recovery/tests.rs index 1d83c2f06031..4b2ba578a5b6 100644 --- a/core/node/metadata_calculator/src/recovery/tests.rs +++ b/core/node/metadata_calculator/src/recovery/tests.rs @@ -15,6 +15,7 @@ use zksync_health_check::{CheckHealth, HealthStatus, ReactiveHealthCheck}; use zksync_merkle_tree::{domain::ZkSyncTree, recovery::PersistenceThreadHandle, TreeInstruction}; use zksync_node_genesis::{insert_genesis_batch, GenesisParams}; use zksync_node_test_utils::prepare_recovery_snapshot; +use zksync_storage::RocksDB; use zksync_types::{L1BatchNumber, U256}; use super::*; @@ -543,4 +544,9 @@ async fn pruning_during_recovery_is_detected() { .unwrap_err(); let err = format!("{err:#}").to_lowercase(); assert!(err.contains("continuing recovery is impossible"), "{err}"); + + // Because of an abrupt error, terminating a RocksDB instance needs to be handled explicitly. + tokio::task::spawn_blocking(RocksDB::await_rocksdb_termination) + .await + .unwrap(); }