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

chore: update to compatibility with latest version of vm2 #9

Merged
merged 8 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
23 changes: 23 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ members = [
"fuzzer"
]
resolver = "2"

[patch."https://github.com/matter-labs/vm2"]
vm2 = {path = "../vm2"}
2 changes: 1 addition & 1 deletion compiler_tester/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ zkevm-assembly = { git = "https://github.com/matter-labs/era-zkEVM-assembly", br
zkevm_opcode_defs = { git = "https://github.com/matter-labs/era-zkevm_opcode_defs", branch = "v1.5.0" }
zkevm_tester = { git = "https://github.com/matter-labs/era-zkevm_tester", branch = "v1.5.0" }

# vm2 = { git = "https://github.com/matter-labs/vm2", optional = true }
vm2 = { git = "https://github.com/matter-labs/vm2", optional = true }

era-compiler-common = { git = "https://github.com/matter-labs/era-compiler-common", branch = "main" }
era-compiler-llvm-context = { git = "https://github.com/matter-labs/era-compiler-llvm-context", branch = "main" }
Expand Down
147 changes: 89 additions & 58 deletions compiler_tester/src/vm/eravm/vm2_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

use std::collections::HashMap;

use web3::ethabi::Address;

use crate::vm::execution_result::ExecutionResult;
use anyhow::anyhow;
use vm2::initial_decommit;
use vm2::ExecutionEnd;
use vm2::Program;
use vm2::World;
use zkevm_assembly::zkevm_opcode_defs::Assembly;
use zkevm_assembly::Assembly;
use zkevm_opcode_defs::ethereum_types::{BigEndianHash, H256, U256};
use zkevm_tester::runners::compiler_tests::FullABIParams;
use zkevm_tester::runners::compiler_tests::StorageKey;
Expand All @@ -21,7 +23,6 @@ use crate::test::case::input::{
output::{event::Event, Output},
value::Value,
};
use crate::vm::eravm::execution_result::ExecutionResult;

pub fn run_vm(
contracts: HashMap<web3::ethabi::Address, Assembly>,
Expand Down Expand Up @@ -54,28 +55,34 @@ pub fn run_vm(
r5_value: None,
},
VmLaunchOption::ManualCallABI(abiparams) => abiparams,
x => return Err(anyhow::anyhow!("Unsupported launch option {x:?}")),
x => return Err(anyhow!("Unsupported launch option {x:?}")),
};

for (_, contract) in contracts {
let bytecode = contract.clone().compile_to_bytecode()?;
let hash = zkevm_assembly::zkevm_opcode_defs::bytecode_to_code_hash(&bytecode)?;
let hash = zkevm_assembly::zkevm_opcode_defs::bytecode_to_code_hash(&bytecode)
.map_err(|()| anyhow!("Failed to hash bytecode"))?;
known_contracts.insert(U256::from_big_endian(&hash), contract);
}

let context = context.unwrap_or_default();

let mut world = TestWorld {
storage,
contracts: known_contracts.clone(),
};
let initial_program = initial_decommit(&mut world, entry_address);

let mut vm = vm2::VirtualMachine::new(
Box::new(TestWorld {
storage,
contracts: known_contracts.clone(),
}),
entry_address,
initial_program,
context.msg_sender,
calldata.to_vec(),
u32::MAX,
// zkevm_tester subtracts this constant, I don't know why
u32::MAX - 0x80000000,
vm2::Settings {
default_aa_code_hash,
default_aa_code_hash: default_aa_code_hash.into(),
evm_interpreter_code_hash: evm_interpreter_code_hash.into(),
hook_address: 0,
},
);
Expand All @@ -90,48 +97,62 @@ pub fn run_vm(
vm.state.registers[4] = abi_params.r4_value.unwrap_or_default();
vm.state.registers[5] = abi_params.r5_value.unwrap_or_default();

let output = match vm.run() {
ExecutionEnd::ProgramFinished(return_value) => Output {
return_data: chunk_return_data(&return_value),
exception: false,
events: merge_events(vm.world.events()),
},
let mut storage_changes = HashMap::new();
let mut deployed_contracts = HashMap::new();

let output = match vm.run(&mut world) {
ExecutionEnd::ProgramFinished(return_value) => {
// Only successful transactions can have side effects
// The VM doesn't undo side effects done in the initial frame
// because that would mess with the bootloader.

storage_changes = vm
.world_diff
.get_storage_state()
.iter()
.map(|(&(address, key), value)| {
(StorageKey { address, key }, H256::from_uint(value))
})
.collect::<HashMap<_, _>>();
deployed_contracts = vm
.world_diff
.get_storage_state()
.iter()
.filter_map(|((address, key), value)| {
if *address == *zkevm_assembly::zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS {
let mut buffer = [0u8; 32];
key.to_big_endian(&mut buffer);
let deployed_address = web3::ethabi::Address::from_slice(&buffer[12..]);
if let Some(code) = known_contracts.get(&value) {
Some((deployed_address, code.clone()))
} else {
None
}
} else {
None
}
})
.collect::<HashMap<_, _>>();

Output {
return_data: chunk_return_data(&return_value),
exception: false,
events: merge_events(vm.world_diff.events()),
}
}
ExecutionEnd::Reverted(return_value) => Output {
return_data: chunk_return_data(&return_value),
exception: true,
events: vec![],
},
_panic => Output {
ExecutionEnd::Panicked => Output {
return_data: vec![],
exception: true,
events: vec![],
},
ExecutionEnd::SuspendedOnHook { .. } => unreachable!(),
};

let storage_changes = vm
.world
.get_storage_changes()
.map(|((address, key), value)| (StorageKey { address, key }, H256::from_uint(&value)))
.collect::<HashMap<_, _>>();
let deployed_contracts = vm
.world
.get_storage_changes()
.filter_map(|((address, key), value)| {
if address == *zkevm_assembly::zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS {
let mut buffer = [0u8; 32];
key.to_big_endian(&mut buffer);
let deployed_address = web3::ethabi::Address::from_slice(&buffer[12..]);
if let Some(code) = known_contracts.get(&value) {
Some((deployed_address, code.clone()))
} else {
None
}
} else {
None
}
})
.collect::<HashMap<_, _>>();

Ok((
ExecutionResult {
output,
Expand All @@ -150,17 +171,15 @@ struct TestWorld {
}

impl World for TestWorld {
fn decommit(
&mut self,
hash: U256,
) -> (std::sync::Arc<[vm2::Instruction]>, std::sync::Arc<[U256]>) {
let bytecode = self
fn decommit(&mut self, hash: U256) -> Program {
let Some(bytecode) = self
.contracts
.get(&hash)
.unwrap()
.clone()
.compile_to_bytecode()
.unwrap();
.map(|assembly| assembly.clone().compile_to_bytecode().unwrap())
else {
// This case only happens when a contract fails to deploy but the assumes it did deploy
return Program::new(vec![vm2::Instruction::from_invalid()], vec![]);
};
let instructions = bytecode
.iter()
.flat_map(|x| {
Expand All @@ -169,13 +188,12 @@ impl World for TestWorld {
})
.collect::<Vec<_>>();

(
vm2::decode::decode_program(&instructions, false).into(),
Program::new(
vm2::decode::decode_program(&instructions, false),
bytecode
.iter()
.map(|x| U256::from_big_endian(x))
.collect::<Vec<_>>()
.into(),
.collect::<Vec<_>>(),
)
}

Expand All @@ -193,8 +211,20 @@ impl World for TestWorld {
.unwrap_or(U256::zero())
}

fn handle_hook(&mut self, _: u32) {
unreachable!() // There is no bootloader
fn cost_of_writing_storage(
&mut self,
contract: web3::types::H160,
key: U256,
new_value: U256,
) -> u32 {
0
}

fn is_free_storage_slot(&self, contract: &web3::types::H160, key: &U256) -> bool {
self.storage.contains_key(&StorageKey {
address: *contract,
key: *key,
})
}
}

Expand Down Expand Up @@ -231,6 +261,7 @@ fn merge_events(events: &[vm2::Event]) -> Vec<Event> {
key,
value,
} = *message;
let tx_number = tx_number.into();

if !is_first {
if let Some((mut remaining_data_length, mut remaining_topics, mut event)) =
Expand Down
Loading