Skip to content

Commit

Permalink
fuzzing results
Browse files Browse the repository at this point in the history
  • Loading branch information
montekki committed Jun 18, 2024
1 parent c65f675 commit 647ec57
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 34 deletions.
3 changes: 3 additions & 0 deletions afl-fuzz/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ fn main() {
if vm.is_in_valid_state() && vm.instruction_is_not_precompile_call() {
// Tests that running one instruction and converting to zk_evm produces the same result as
// first converting to zk_evm and then running one instruction.
vm.state
.heaps
.set_heap_id(vm.state.current_frame.heap.to_u32());

let mut zk_evm = vm2_to_zk_evm(
&vm,
Expand Down
27 changes: 27 additions & 0 deletions src/decommit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ impl WorldDiff {
Some((UnpaidDecommit { cost, code_key }, is_evm))
}

pub(crate) fn decommit_opcode(&mut self, code_hash: U256) -> Option<UnpaidDecommit> {
let mut code_info_bytes = [0; 32];
code_hash.to_big_endian(&mut code_info_bytes);

let cost = if self.decommitted_hashes.as_ref().contains_key(&code_hash) {
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
};

Some(UnpaidDecommit {
cost,
code_key: code_hash,
})
}

pub(crate) fn pay_for_decommit(
&mut self,
world: &mut dyn World,
Expand All @@ -91,8 +108,18 @@ impl WorldDiff {
self.decommitted_hashes.insert(decommit.code_key, ());
Some(world.decommit(decommit.code_key))
}

pub(crate) fn unpaid_decommit(
&mut self,
world: &mut dyn World,
decommit: UnpaidDecommit,
) -> Option<Program> {
self.decommitted_hashes.insert(decommit.code_key, ());
Some(world.decommit(decommit.code_key))
}
}

#[derive(Debug)]
pub(crate) struct UnpaidDecommit {
pub cost: u32,
pub code_key: U256,
Expand Down
71 changes: 46 additions & 25 deletions src/instruction_handlers/decommit.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
use u256::U256;
use zkevm_opcode_defs::{
BlobSha256Format, ContractCodeSha256Format, VersionedHashHeader, VersionedHashLen32,
VersionedHashNormalizedPreimage,
};

use crate::{
addressing_modes::{Arguments, Destination, Register1, Register2, Source},
decommit::UnpaidDecommit,
fat_pointer::FatPointer,
instruction::InstructionResult,
Instruction, VirtualMachine, World,
Expand All @@ -18,49 +23,65 @@ fn decommit(
instruction,
world,
|vm, args, world, continue_normally| {
let _extra_cost = Register2::get(args, &mut vm.state).low_u32();
let code_hash = Register1::get(args, &mut vm.state);
let extra_cost = Register2::get(args, &mut vm.state).low_u32();

let mut decommit_preimage_format_is_invalid = false;
let mut buffer = [0u8; 32];
code_hash.to_big_endian(&mut buffer);
let mut _decommit_preimage_normalized = VersionedHashNormalizedPreimage::default();

let mut preimage_len_in_bytes =
zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND;
let mut _decommit_header = VersionedHashHeader::default();

/*
let unpaid_decommit = vm.world_diff.decommit(
world,
CodeInfo::CodeHash(code_hash),
vm.settings.default_aa_code_hash,
vm.settings.evm_interpreter_code_hash,
vm.state.in_kernel_mode(),
);
if ContractCodeSha256Format::is_valid(&buffer) {
let (header, normalized_preimage) =
ContractCodeSha256Format::normalize_for_decommitment(&buffer);
_decommit_header = header;
_decommit_preimage_normalized = normalized_preimage;
} else if BlobSha256Format::is_valid(&buffer) {
let (header, normalized_preimage) =
BlobSha256Format::normalize_for_decommitment(&buffer);
_decommit_header = header;
_decommit_preimage_normalized = normalized_preimage;
} else {
preimage_len_in_bytes = 0;
decommit_preimage_format_is_invalid = true;
};

if vm.state.use_gas(extra_cost).is_err() {
Register1::set(args, &mut vm.state, U256::zero());
return continue_normally;
}

if unpaid_decommit.as_ref().unwrap().0.is_initial() {
vm.state.current_frame.gas.saturating_sub(extra_cost);
if decommit_preimage_format_is_invalid {
let value = U256::zero();
Register1::set(args, &mut vm.state, value);
return continue_normally;
}
*/

let unpaid_decommit = UnpaidDecommit {
cost: 1000,
code_key: code_hash,
let Some(unpaid_decommit) = vm.world_diff.decommit_opcode(code_hash) else {
Register1::set(args, &mut vm.state, U256::zero());
return continue_normally;
};

let decommit_result = vm.world_diff.pay_for_decommit(
world,
unpaid_decommit,
&mut vm.state.current_frame.gas,
);
let decommit_result = vm.world_diff.unpaid_decommit(world, unpaid_decommit);

let heap = vm.state.heaps.allocate();
let program = &decommit_result.unwrap();
let decommited_memory = program.code_page().as_ref();
let mut length = decommited_memory.len().try_into().unwrap();
length *= 32;
let mut _length: u32 = decommited_memory.len().try_into().unwrap();
_length *= 32;

vm.state.heaps[heap].memset(decommited_memory);

let value = FatPointer {
offset: 0,
memory_page: heap,
start: 0,
length,
length: preimage_len_in_bytes,
};
dbg!(&value);
let value = value.into_u256();
Register1::set_fat_ptr(args, &mut vm.state, value);

Expand Down
13 changes: 11 additions & 2 deletions src/single_instruction_test/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ impl HeapInterface for Heap {
vec![]
}

fn memset(&mut self, _memory: &[U256]) {}
fn memset(&mut self, src: &[U256]) {
for (i, word) in src.iter().enumerate() {
self.write_u256((i * 32) as u32, *word);
}
}
}

impl<'a> Arbitrary<'a> for Heap {
Expand All @@ -49,6 +53,7 @@ impl<'a> Arbitrary<'a> for Heap {

#[derive(Debug, Clone, Arbitrary)]
pub struct Heaps {
heap_id: u32,
pub(crate) read: MockRead<HeapId, Heap>,
}

Expand All @@ -62,10 +67,14 @@ impl Heaps {
}

pub(crate) fn allocate(&mut self) -> HeapId {
HeapId(3)
HeapId::from_u32_unchecked(self.heap_id)
}

pub(crate) fn deallocate(&mut self, _: HeapId) {}

pub fn set_heap_id(&mut self, heap_id: u32) {
self.heap_id = heap_id
}
}

impl Index<HeapId> for Heaps {
Expand Down
17 changes: 10 additions & 7 deletions src/single_instruction_test/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ impl VirtualMachine {
}

pub fn instruction_is_not_precompile_call(&self) -> bool {
// TODO PLA-972 implement StaticMemoryRead/Write
if (1096..=1103).contains(&self.current_opcode()) {
return false;
}
self.current_opcode() == 1093
/*
// TODO PLA-972 implement StaticMemoryRead/Write
if (1096..=1103).contains(&self.current_opcode()) {
return false;
}
// Precompilecall is not allowed because it accesses memory multiple times
// and only needs to work as used by trusted code
self.current_opcode() != 1056u64
// Precompilecall is not allowed because it accesses memory multiple times
// and only needs to work as used by trusted code
self.current_opcode() != 1056u64
*/
}

pub fn instruction_is_far_call(&self) -> bool {
Expand Down

0 comments on commit 647ec57

Please sign in to comment.