Skip to content

Commit

Permalink
Merge branch 'main' into vv-change-evm-bytecode-hashes-encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov committed Dec 19, 2024
2 parents c1b612f + cbee99d commit 5049bff
Show file tree
Hide file tree
Showing 101 changed files with 2,007 additions and 1,448 deletions.
279 changes: 69 additions & 210 deletions Cargo.lock

Large diffs are not rendered by default.

33 changes: 15 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -228,34 +228,31 @@ tokio-stream = "0.1.16"
# We *always* pin the latest version of protocol to disallow accidental changes in the execution logic.
# However, for the historical version of protocol crates, we have lax requirements. Otherwise,
# Bumping a crypto dependency like `boojum` would require us to republish all the historical packages.
circuit_sequencer_api_1_3_3 = { package = "circuit_sequencer_api", version = "0.133" }
circuit_sequencer_api_1_4_0 = { package = "circuit_sequencer_api", version = "0.140" }
circuit_sequencer_api_1_4_1 = { package = "circuit_sequencer_api", version = "0.141" }
circuit_sequencer_api_1_4_2 = { package = "circuit_sequencer_api", version = "0.142" }
circuit_sequencer_api_1_5_0 = { package = "circuit_sequencer_api", version = "=0.150.7" }
crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.1" }
kzg = { package = "zksync_kzg", version = "=0.150.7" }
circuit_encodings = { package = "circuit_encodings", version = "=0.150.18" }
circuit_sequencer_api = { package = "circuit_sequencer_api", version = "=0.150.18" }
crypto_codegen = { package = "zksync_solidity_vk_codegen", version = "=0.30.11" }
kzg = { package = "zksync_kzg", version = "=0.150.18" }
zk_evm = { version = "=0.133.0" }
zk_evm_1_3_1 = { package = "zk_evm", version = "0.131.0-rc.2" }
zk_evm_1_3_3 = { package = "zk_evm", version = "0.133" }
zk_evm_1_4_0 = { package = "zk_evm", version = "0.140" }
zk_evm_1_4_1 = { package = "zk_evm", version = "0.141" }
zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.7" }
zk_evm_1_5_0 = { package = "zk_evm", version = "=0.150.18" }

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

# Consensus dependencies.
zksync_concurrency = "=0.6.0"
zksync_consensus_bft = "=0.6.0"
zksync_consensus_crypto = "=0.6.0"
zksync_consensus_executor = "=0.6.0"
zksync_consensus_network = "=0.6.0"
zksync_consensus_roles = "=0.6.0"
zksync_consensus_storage = "=0.6.0"
zksync_consensus_utils = "=0.6.0"
zksync_protobuf = "=0.6.0"
zksync_protobuf_build = "=0.6.0"
zksync_concurrency = "=0.7.0"
zksync_consensus_bft = "=0.7.0"
zksync_consensus_crypto = "=0.7.0"
zksync_consensus_executor = "=0.7.0"
zksync_consensus_network = "=0.7.0"
zksync_consensus_roles = "=0.7.0"
zksync_consensus_storage = "=0.7.0"
zksync_consensus_utils = "=0.7.0"
zksync_protobuf = "=0.7.0"
zksync_protobuf_build = "=0.7.0"

# "Local" dependencies
zksync_multivm = { version = "0.1.0", path = "core/lib/multivm" }
Expand Down
7 changes: 7 additions & 0 deletions core/lib/config/src/configs/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ pub struct ConsensusConfig {
/// Maximal allowed size of the payload in bytes.
pub max_payload_size: usize,

/// View timeout duration in milliseconds.
pub view_timeout: Option<time::Duration>,

/// Maximal allowed size of the sync-batch payloads in bytes.
///
/// The batch consists of block payloads and a Merkle proof of inclusion on L1 (~1kB),
Expand Down Expand Up @@ -155,6 +158,10 @@ pub struct ConsensusConfig {
}

impl ConsensusConfig {
pub fn view_timeout(&self) -> time::Duration {
self.view_timeout.unwrap_or(time::Duration::seconds(2))
}

pub fn rpc(&self) -> RpcConfig {
self.rpc.clone().unwrap_or_default()
}
Expand Down
1 change: 1 addition & 0 deletions core/lib/config/src/testonly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ impl Distribution<configs::consensus::ConsensusConfig> for EncodeDist {
server_addr: self.sample(rng),
public_addr: Host(self.sample(rng)),
max_payload_size: self.sample(rng),
view_timeout: self.sample(rng),
max_batch_size: self.sample(rng),
gossip_dynamic_inbound_limit: self.sample(rng),
gossip_static_inbound: self
Expand Down
2 changes: 1 addition & 1 deletion core/lib/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ pub fn l1_messenger_contract() -> Contract {

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

pub fn eth_contract() -> Contract {
Expand Down
6 changes: 1 addition & 5 deletions core/lib/multivm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ zk_evm_1_3_3.workspace = true
zk_evm_1_3_1.workspace = true
zksync_vm2.workspace = true

circuit_sequencer_api_1_3_3.workspace = true
circuit_sequencer_api_1_4_0.workspace = true
circuit_sequencer_api_1_4_1.workspace = true
circuit_sequencer_api_1_4_2.workspace = true
circuit_sequencer_api_1_5_0.workspace = true
circuit_sequencer_api.workspace = true

zksync_types.workspace = true
zksync_contracts.workspace = true
Expand Down
44 changes: 16 additions & 28 deletions core/lib/multivm/src/glue/types/vm/vm_block_result.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::collections::HashMap;

use circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries as sort_storage_access_queries_1_3_3;
use itertools::Itertools;
use zk_evm_1_3_1::aux_structures::LogQuery as LogQuery_1_3_1;
use circuit_sequencer_api::sort_storage_access::sort_storage_access_queries;
use zksync_types::l2_to_l1_log::UserL2ToL1Log;

use crate::{
Expand All @@ -11,6 +9,7 @@ use crate::{
CurrentExecutionState, ExecutionResult, Refunds, VmExecutionLogs, VmExecutionResultAndLogs,
VmExecutionStatistics,
},
utils::glue_log_query,
};

// Note: In version after vm `VmVirtualBlocks` the bootloader memory knowledge is encapsulated into the VM.
Expand All @@ -21,18 +20,12 @@ use crate::{
impl GlueFrom<crate::vm_m5::vm_instance::VmBlockResult> for crate::interface::FinishedL1Batch {
fn glue_from(value: crate::vm_m5::vm_instance::VmBlockResult) -> Self {
let storage_log_queries = value.full_result.storage_log_queries.clone();
let deduplicated_storage_logs: Vec<LogQuery_1_3_1> = sort_storage_access_queries_1_3_3(
&storage_log_queries
let deduplicated_storage_logs = sort_storage_access_queries(
storage_log_queries
.iter()
.map(|log| {
GlueInto::<zk_evm_1_3_3::aux_structures::LogQuery>::glue_into(log.log_query)
})
.collect_vec(),
.map(|log| glue_log_query(log.log_query)),
)
.1
.into_iter()
.map(GlueInto::<LogQuery_1_3_1>::glue_into)
.collect();
.1;

crate::interface::FinishedL1Batch {
block_tip_execution_result: VmExecutionResultAndLogs {
Expand Down Expand Up @@ -78,18 +71,12 @@ impl GlueFrom<crate::vm_m5::vm_instance::VmBlockResult> for crate::interface::Fi
impl GlueFrom<crate::vm_m6::vm_instance::VmBlockResult> for crate::interface::FinishedL1Batch {
fn glue_from(value: crate::vm_m6::vm_instance::VmBlockResult) -> Self {
let storage_log_queries = value.full_result.storage_log_queries.clone();
let deduplicated_storage_logs: Vec<LogQuery_1_3_1> = sort_storage_access_queries_1_3_3(
&storage_log_queries
let deduplicated_storage_logs = sort_storage_access_queries(
storage_log_queries
.iter()
.map(|log| {
GlueInto::<zk_evm_1_3_3::aux_structures::LogQuery>::glue_into(log.log_query)
})
.collect_vec(),
.map(|log| glue_log_query(log.log_query)),
)
.1
.into_iter()
.map(GlueInto::<LogQuery_1_3_1>::glue_into)
.collect();
.1;

crate::interface::FinishedL1Batch {
block_tip_execution_result: VmExecutionResultAndLogs {
Expand Down Expand Up @@ -135,11 +122,12 @@ impl GlueFrom<crate::vm_m6::vm_instance::VmBlockResult> for crate::interface::Fi
impl GlueFrom<crate::vm_1_3_2::vm_instance::VmBlockResult> for crate::interface::FinishedL1Batch {
fn glue_from(value: crate::vm_1_3_2::vm_instance::VmBlockResult) -> Self {
let storage_log_queries = value.full_result.storage_log_queries.clone();
let deduplicated_storage_logs =
circuit_sequencer_api_1_3_3::sort_storage_access::sort_storage_access_queries(
storage_log_queries.iter().map(|log| &log.log_query),
)
.1;
let deduplicated_storage_logs = sort_storage_access_queries(
storage_log_queries
.iter()
.map(|log| glue_log_query(log.log_query)),
)
.1;

crate::interface::FinishedL1Batch {
block_tip_execution_result: VmExecutionResultAndLogs {
Expand Down
2 changes: 1 addition & 1 deletion core/lib/multivm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![warn(unused_extern_crates)]
#![warn(unused_imports)]

pub use circuit_sequencer_api_1_5_0 as circuit_sequencer_api_latest;
pub use circuit_sequencer_api as circuit_sequencer_api_latest;
pub use zk_evm_1_5_0 as zk_evm_latest;
pub use zksync_types::vm::VmVersion;
pub use zksync_vm_interface as interface;
Expand Down
7 changes: 5 additions & 2 deletions core/lib/multivm/src/tracers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
pub use self::{
call_tracer::CallTracer, multivm_dispatcher::TracerDispatcher, prestate_tracer::PrestateTracer,
storage_invocation::StorageInvocations, validator::ValidationTracer,
call_tracer::CallTracer,
multivm_dispatcher::TracerDispatcher,
prestate_tracer::PrestateTracer,
storage_invocation::StorageInvocations,
validator::{ValidationTracer, TIMESTAMP_ASSERTER_FUNCTION_SELECTOR},
};

mod call_tracer;
Expand Down
12 changes: 5 additions & 7 deletions core/lib/multivm/src/tracers/validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::{
};

use once_cell::sync::OnceCell;
pub use vm_latest::TIMESTAMP_ASSERTER_FUNCTION_SELECTOR;
use zksync_system_constants::{
ACCOUNT_CODE_STORAGE_ADDRESS, BOOTLOADER_ADDRESS, CONTRACT_DEPLOYER_ADDRESS,
L2_BASE_TOKEN_ADDRESS, MSG_VALUE_SIMULATOR_ADDRESS, SYSTEM_CONTEXT_ADDRESS,
Expand All @@ -13,10 +14,7 @@ use zksync_types::{
address_to_u256, u256_to_h256, vm::VmVersion, web3::keccak256, AccountTreeId, Address,
StorageKey, H256, U256,
};
use zksync_vm_interface::{
tracer::{TimestampAsserterParams, ValidationTraces},
L1BatchEnv,
};
use zksync_vm_interface::tracer::{TimestampAsserterParams, ValidationTraces};

use self::types::{NewTrustedValidationItems, ValidationTracerMode};
use crate::{
Expand Down Expand Up @@ -54,7 +52,7 @@ pub struct ValidationTracer<H> {
computational_gas_limit: u32,
timestamp_asserter_params: Option<TimestampAsserterParams>,
vm_version: VmVersion,
l1_batch_env: L1BatchEnv,
l1_batch_timestamp: u64,
pub result: Arc<OnceCell<ViolatedValidationRule>>,
pub traces: Arc<Mutex<ValidationTraces>>,
_marker: PhantomData<fn(H) -> H>,
Expand All @@ -65,7 +63,7 @@ type ValidationRoundResult = Result<NewTrustedValidationItems, ViolatedValidatio
impl<H> ValidationTracer<H> {
const MAX_ALLOWED_SLOT_OFFSET: u32 = 127;

pub fn new(params: ValidationParams, vm_version: VmVersion, l1_batch_env: L1BatchEnv) -> Self {
pub fn new(params: ValidationParams, vm_version: VmVersion, l1_batch_timestamp: u64) -> Self {
Self {
validation_mode: ValidationTracerMode::NoValidation,
auxilary_allowed_slots: Default::default(),
Expand All @@ -83,7 +81,7 @@ impl<H> ValidationTracer<H> {
result: Arc::new(OnceCell::new()),
traces: Arc::new(Mutex::new(ValidationTraces::default())),
_marker: Default::default(),
l1_batch_env,
l1_batch_timestamp,
}
}

Expand Down
12 changes: 9 additions & 3 deletions core/lib/multivm/src/tracers/validator/vm_latest/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use zk_evm_1_5_0::{
tracing::{BeforeExecutionData, VmLocalStateData},
zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode},
zkevm_opcode_defs::{ContextOpcode, FarCallABI, LogOpcode, Opcode, RetOpcode},
};
use zksync_system_constants::KECCAK256_PRECOMPILE_ADDRESS;
use zksync_types::{
Expand Down Expand Up @@ -116,8 +116,7 @@ impl<H: HistoryMode> ValidationTracer<H> {
// using self.l1_batch_env.timestamp is ok here because the tracer is always
// used in a oneshot execution mode
if end
< self.l1_batch_env.timestamp
+ params.min_time_till_end.as_secs()
< self.l1_batch_timestamp + params.min_time_till_end.as_secs()
{
return Err(
ViolatedValidationRule::TimestampAssertionCloseToRangeEnd,
Expand Down Expand Up @@ -168,6 +167,13 @@ impl<H: HistoryMode> ValidationTracer<H> {
});
}
}

Opcode::Ret(RetOpcode::Panic)
if state.vm_local_state.callstack.current.ergs_remaining == 0 =>
{
// Actual gas limit was reached, not the validation gas limit.
return Err(ViolatedValidationRule::TookTooManyComputationalGas(0));
}
_ => {}
}

Expand Down
17 changes: 16 additions & 1 deletion core/lib/multivm/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,27 @@ use zksync_types::{
};

pub use self::deduplicator::{ModifiedSlot, StorageWritesDeduplicator};
use crate::interface::L1BatchEnv;
use crate::{
glue::{GlueFrom, GlueInto},
interface::L1BatchEnv,
};

pub(crate) mod bytecode;
mod deduplicator;
pub(crate) mod events;

/// Allows to convert `LogQuery` between two different versions, even if they don't provide
/// direct conversion between each other.
/// It transforms the input query to the `LogQuery` from `zksync_types` (for which most of the
/// `zk_evm` versions provide conversion) and then converts it to the target version.
pub fn glue_log_query<L, R>(l: L) -> R
where
L: GlueInto<zksync_types::zk_evm_types::LogQuery>,
R: GlueFrom<zksync_types::zk_evm_types::LogQuery>,
{
R::glue_from(l.glue_into())
}

/// Calculates the base fee and gas per pubdata for the given L1 gas price.
pub fn derive_base_fee_and_gas_per_pubdata(
batch_fee_input: BatchFeeInput,
Expand Down
2 changes: 1 addition & 1 deletion core/lib/multivm/src/versions/shadow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
mod tests;

type ReferenceVm<S = InMemoryStorage> = vm_latest::Vm<StorageView<S>, HistoryEnabled>;
type ShadowedFastVm<S = InMemoryStorage> = crate::vm_instance::ShadowedFastVm<S>;
type ShadowedFastVm<S = InMemoryStorage> = crate::vm_instance::ShadowedFastVm<S, (), ()>;

fn hash_block(block_env: L2BlockEnv, tx_hashes: &[H256]) -> H256 {
let mut hasher = L2BlockHasher::new(
Expand Down
59 changes: 59 additions & 0 deletions core/lib/multivm/src/versions/testonly/account_validation_rules.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use assert_matches::assert_matches;
use zksync_test_contracts::TestContract;
use zksync_types::{u256_to_h256, AccountTreeId, Address, StorageKey};
use zksync_vm_interface::tracer::ViolatedValidationRule;

use super::{
get_empty_storage, require_eip712::make_aa_transaction, tester::VmTesterBuilder,
ContractToDeploy, TestedVm, TestedVmForValidation,
};
use crate::interface::TxExecutionMode;

/// Checks that every limitation imposed on account validation results in an appropriate error.
/// The actual misbehavior cases are found in "validation-rule-breaker.sol".
pub(crate) fn test_account_validation_rules<VM: TestedVm + TestedVmForValidation>() {
assert_matches!(test_rule::<VM>(0), None);
assert_matches!(
test_rule::<VM>(1),
Some(ViolatedValidationRule::TouchedDisallowedStorageSlots(_, _))
);
assert_matches!(
test_rule::<VM>(2),
Some(ViolatedValidationRule::CalledContractWithNoCode(_))
);
assert_matches!(test_rule::<VM>(3), None);
assert_matches!(
test_rule::<VM>(4),
Some(ViolatedValidationRule::TookTooManyComputationalGas(_))
)
}

fn test_rule<VM: TestedVm + TestedVmForValidation>(rule: u32) -> Option<ViolatedValidationRule> {
let aa_address = Address::repeat_byte(0x10);
let beneficiary_address = Address::repeat_byte(0x20);

// Set the type of misbehaviour of the AA contract
let mut storage_with_rule_break_set = get_empty_storage();
storage_with_rule_break_set.set_value(
StorageKey::new(AccountTreeId::new(aa_address), u256_to_h256(0.into())),
u256_to_h256(rule.into()),
);

let bytecode = TestContract::validation_test().bytecode.to_vec();
let mut vm = VmTesterBuilder::new()
.with_empty_in_memory_storage()
.with_custom_contracts(vec![
ContractToDeploy::account(bytecode, aa_address).funded()
])
.with_storage(storage_with_rule_break_set)
.with_execution_mode(TxExecutionMode::VerifyExecute)
.with_rich_accounts(1)
.build::<VM>();

let private_account = vm.rich_accounts[0].clone();

vm.vm.run_validation(
make_aa_transaction(aa_address, beneficiary_address, &private_account),
55,
)
}
4 changes: 1 addition & 3 deletions core/lib/multivm/src/versions/testonly/l1_messenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ pub(crate) fn test_rollup_da_output_hash_match<VM: TestedVm>() {

// Firstly, deploy tx. It should publish the bytecode of the "test contract"
let counter_bytecode = TestContract::counter().bytecode;
let tx = account
.get_deploy_tx(&counter_bytecode, None, TxType::L2)
.tx;
let tx = account.get_deploy_tx(counter_bytecode, None, TxType::L2).tx;
// We do not use compression here, to have the bytecode published in full.
let (_, result) = vm
.vm
Expand Down
Loading

0 comments on commit 5049bff

Please sign in to comment.