Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt zksync era testing #201

Merged
merged 2 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion era-compiler-tester
6 changes: 3 additions & 3 deletions src/call_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use zkevm_opcode_defs::ethereum_types::Address;

use crate::{execution::Stack, state::StateSnapshot, utils::is_kernel};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct CallFrame {
pub pc: u64,
pub gas_left: Saturating<u32>,
Expand All @@ -13,7 +13,7 @@ pub struct CallFrame {
pub snapshot: StateSnapshot,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct CodePage(Vec<U256>);

impl CodePage {
Expand All @@ -25,7 +25,7 @@ impl CodePage {
}
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct Context {
pub frame: CallFrame,
pub near_call_frames: Vec<CallFrame>,
Expand Down
12 changes: 6 additions & 6 deletions src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ pub const CALLDATA_HEAP: u32 = 1;
pub const FIRST_HEAP: u32 = 2;
pub const FIRST_AUX_HEAP: u32 = 3;

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct Stack {
pub stack: Vec<TaggedValue>,
}

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct Heap {
heap: Vec<u8>,
}
#[derive(Debug, Clone)]

#[derive(Debug, Clone, PartialEq)]
pub struct Execution {
// The first register, r0, is actually always zero and not really used.
// Writing to it does nothing.
Expand All @@ -49,8 +50,6 @@ pub struct Execution {
pub use_hooks: bool,
}

// Totally arbitrary, probably we will have to change it later.
pub const DEFAULT_INITIAL_GAS: u32 = 1 << 16;
impl Execution {
#[allow(clippy::too_many_arguments)]
pub fn new(
Expand All @@ -63,6 +62,7 @@ impl Execution {
evm_interpreter_code_hash: [u8; 32],
hook_address: u32,
use_hooks: bool,
initial_gas: u32,
) -> Self {
let mut registers = [TaggedValue::default(); 15];
let calldata_ptr = FatPointer {
Expand All @@ -76,7 +76,7 @@ impl Execution {

let context = Context::new(
program_code.clone(),
u32::MAX - 0x80000000,
initial_gas,
contract_address,
contract_address,
caller,
Expand Down
2 changes: 1 addition & 1 deletion src/heaps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND;

use crate::{eravm_error::HeapError, execution::Heap};

#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Heaps {
heaps: Vec<Heap>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ pub mod vm;
pub use execution::Execution;
pub use opcode::Opcode;
pub use vm::EraVM;
mod rollbacks;
pub mod rollbacks;
pub mod state;
use zkevm_opcode_defs::Opcode as Variant;
20 changes: 17 additions & 3 deletions src/op_handlers/far_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn decommit_code_hash(
default_aa_code_hash: [u8; 32],
evm_interpreter_code_hash: [u8; 32],
is_constructor_call: bool,
) -> Result<(U256, bool), EraVmError> {
) -> Result<(U256, bool, u32), EraVmError> {
let mut is_evm = false;
let deployer_system_contract_address =
Address::from_low_u64_be(DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW as u64);
Expand Down Expand Up @@ -193,7 +193,16 @@ fn decommit_code_hash(

code_info_bytes[1] = 0;

Ok((U256::from_big_endian(&code_info_bytes), is_evm))
let code_key = U256::from_big_endian(&code_info_bytes);

let cost = if state.decommitted_hashes().contains(&code_key) {
0
} else {
let code_length_in_words = u16::from_be_bytes([code_info_bytes[2], code_info_bytes[3]]);
code_length_in_words as u32 * zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT
};

Ok((U256::from_big_endian(&code_info_bytes), is_evm, cost))
}

pub fn far_call(
Expand All @@ -212,14 +221,19 @@ pub fn far_call(
abi.is_constructor_call = abi.is_constructor_call && vm.current_context()?.is_kernel();
abi.is_system_call = abi.is_system_call && is_kernel(&contract_address);

let (code_key, is_evm) = decommit_code_hash(
let (code_key, is_evm, decommit_cost) = decommit_code_hash(
state,
contract_address,
vm.default_aa_code_hash,
vm.evm_interpreter_code_hash,
abi.is_constructor_call,
)?;

// Unlike all other gas costs, this one is not paid if low on gas.
if decommit_cost < vm.gas_left()? {
vm.decrease_gas(decommit_cost)?;
}

let FarCallParams {
ergs_passed,
forward_memory,
Expand Down
40 changes: 33 additions & 7 deletions src/rollbacks.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
use std::collections::{HashMap, HashSet};
use std::{
collections::{HashMap, HashSet},
hash::Hash,
};

pub trait Rollbackable {
type Snapshot;
fn rollback(&mut self, snapshot: Self::Snapshot);
fn snapshot(&self) -> Self::Snapshot;
}

#[derive(Debug, Default)]
pub struct RollbackableHashMap<K: Clone, V: Clone> {
#[derive(Debug, Default, Clone)]
pub struct RollbackableHashMap<K: Clone + Hash, V: Clone> {
pub map: HashMap<K, V>,
}

impl<K: Clone, V: Clone> Rollbackable for RollbackableHashMap<K, V> {
impl<K: Clone + Hash, V: Clone> RollbackableHashMap<K, V> {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
}

impl<K: Clone + Hash, V: Clone> Rollbackable for RollbackableHashMap<K, V> {
type Snapshot = HashMap<K, V>;
fn rollback(&mut self, snapshot: Self::Snapshot) {
self.map = snapshot;
Expand All @@ -22,11 +33,26 @@ impl<K: Clone, V: Clone> Rollbackable for RollbackableHashMap<K, V> {
}
}

#[derive(Debug, Default)]
impl<K: Clone + Hash, V: Clone> Iterator for RollbackableHashMap<K, V> {
type Item = (K, V);
fn next(&mut self) -> Option<Self::Item> {
self.map.iter().next().map(|(k, v)| (k.clone(), v.clone()))
}
}

#[derive(Debug, Default, Clone)]
pub struct RollbackableVec<T: Clone> {
pub entries: Vec<T>,
}

impl<T: Clone> RollbackableVec<T> {
pub fn new() -> Self {
Self {
entries: Vec::new(),
}
}
}

impl<T: Clone> Rollbackable for RollbackableVec<T> {
type Snapshot = Vec<T>;

Expand All @@ -38,7 +64,7 @@ impl<T: Clone> Rollbackable for RollbackableVec<T> {
}
}

#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub struct RollbackablePrimitive<T: Copy> {
pub value: T,
}
Expand All @@ -54,7 +80,7 @@ impl<T: Copy> Rollbackable for RollbackablePrimitive<T> {
}
}

#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub struct RollbackableHashSet<K: Clone> {
pub map: HashSet<K>,
}
Expand Down
23 changes: 17 additions & 6 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use crate::{
},
store::{Storage, StorageKey},
};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use std::{
cell::RefCell,
collections::{HashMap, HashSet},
rc::Rc,
};
use u256::{H160, U256};
use zkevm_opcode_defs::system_params::{
STORAGE_ACCESS_COLD_READ_COST, STORAGE_ACCESS_COLD_WRITE_COST, STORAGE_ACCESS_WARM_READ_COST,
Expand Down Expand Up @@ -35,13 +39,13 @@ pub struct Event {
pub tx_number: u16,
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct VMState {
pub storage: Rc<RefCell<dyn Storage>>,
storage_changes: RollbackableHashMap<StorageKey, U256>,
transient_storage: RollbackableHashMap<StorageKey, U256>,
l2_to_l1_logs: RollbackableVec<L2ToL1Log>,
events: RollbackableVec<Event>,
pub storage_changes: RollbackableHashMap<StorageKey, U256>,
pub transient_storage: RollbackableHashMap<StorageKey, U256>,
pub l2_to_l1_logs: RollbackableVec<L2ToL1Log>,
pub events: RollbackableVec<Event>,
// holds the sum of pubdata_costs
pubdata: RollbackablePrimitive<i32>,
pubdata_costs: RollbackableVec<i32>,
Expand All @@ -52,6 +56,7 @@ pub struct VMState {
// that is why we add them as rollbackable as well
read_storage_slots: RollbackableHashSet<StorageKey>,
written_storage_slots: RollbackableHashSet<StorageKey>,
decommitted_hashes: RollbackableHashSet<U256>,
}

impl VMState {
Expand All @@ -68,6 +73,7 @@ impl VMState {
refunds: RollbackableVec::<u32>::default(),
read_storage_slots: RollbackableHashSet::<StorageKey>::default(),
written_storage_slots: RollbackableHashSet::<StorageKey>::default(),
decommitted_hashes: RollbackableHashSet::<U256>::default(),
}
}

Expand Down Expand Up @@ -189,8 +195,13 @@ impl VMState {
}

pub fn decommit(&mut self, hash: U256) -> Option<Vec<U256>> {
self.decommitted_hashes.map.insert(hash);
self.storage.borrow_mut().decommit(hash)
}

pub fn decommitted_hashes(&self) -> &HashSet<U256> {
&self.decommitted_hashes.map
}
}

#[derive(Clone, Default, PartialEq, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl Storage for InitialStorageMemory {
}

/// Error type for storage operations.
#[derive(Error, Debug)]
#[derive(Error, Debug, PartialEq)]
pub enum StorageError {
#[error("Key not present in storage")]
KeyNotPresent,
Expand Down
1 change: 1 addition & 0 deletions src/tracers/last_state_saver_tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl LastStateSaverTracer {
Default::default(),
0,
false,
0,
),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use u256::U256;

/// In the zkEVM, all data in the stack and on registers is tagged to determine
/// whether they are a pointer or not.
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct TaggedValue {
pub value: U256,
pub is_pointer: bool,
Expand Down
2 changes: 1 addition & 1 deletion src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub enum ExecutionOutput {
SuspendedOnHook { hook: u32, pc_to_resume_from: u16 },
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct EraVM {
pub state: VMState,
pub execution: Execution,
Expand Down
Loading