From 9982d79999cdbf577e5ba256dee3359164c81434 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 20 Oct 2022 19:23:01 +0200 Subject: [PATCH] Add msize --- evm/src/cpu/kernel/asm/memory/core.asm | 18 ++++++++++++ evm/src/cpu/kernel/asm/memory/metadata.asm | 20 +++++++++++++ .../cpu/kernel/constants/context_metadata.rs | 2 +- evm/src/cpu/kernel/interpreter.rs | 18 ++++++++++-- evm/src/generation/memory.rs | 29 ++----------------- 5 files changed, 57 insertions(+), 30 deletions(-) diff --git a/evm/src/cpu/kernel/asm/memory/core.asm b/evm/src/cpu/kernel/asm/memory/core.asm index 2b4d2b68..f6bb99b6 100644 --- a/evm/src/cpu/kernel/asm/memory/core.asm +++ b/evm/src/cpu/kernel/asm/memory/core.asm @@ -393,3 +393,21 @@ %mstore_kernel_general_2 // stack: (empty) %endmacro + +%macro mload_main + // stack: offset + DUP1 + // stack: offset, offset + %update_msize + // stack: offset + %mload_current(@SEGMENT_MAIN_MEMORY) +%endmacro + +%macro mstore_main + // stack: offset, value + DUP1 + // stack: offset, offset, value + %update_msize + // stack: offset, value + %mstore_current(@SEGMENT_MAIN_MEMORY) +%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/metadata.asm b/evm/src/cpu/kernel/asm/memory/metadata.asm index 644699e0..f5cc523c 100644 --- a/evm/src/cpu/kernel/asm/memory/metadata.asm +++ b/evm/src/cpu/kernel/asm/memory/metadata.asm @@ -45,3 +45,23 @@ %macro callvalue %mload_context_metadata(@CTX_METADATA_CALL_VALUE) %endmacro + +%macro msize + %mload_context_metadata(@CTX_METADATA_MSIZE) +%endmacro + +%macro update_msize + // stack: offset + %add_const(32) + // stack: 32 + offset + %div_const(32) + // stack: (offset+32)/32 = ceil_div_usize(offset+1, 32) + %mul_const(32) + // stack: ceil_div_usize(offset+1, 32)*32 + %msize + // stack: current_msize, ceil_div_usize(offset+1, 32) * 32 + %max + // stack: new_msize + %mstore_context_metadata(@CTX_METADATA_MSIZE) +%endmacro + diff --git a/evm/src/cpu/kernel/constants/context_metadata.rs b/evm/src/cpu/kernel/constants/context_metadata.rs index 0b2dbee5..fab74373 100644 --- a/evm/src/cpu/kernel/constants/context_metadata.rs +++ b/evm/src/cpu/kernel/constants/context_metadata.rs @@ -23,7 +23,7 @@ pub(crate) enum ContextMetadata { /// Pointer to the initial version of the state trie, at the creation of this context. Used when /// we need to revert a context. StateTrieCheckpointPointer = 9, - /// Size of active memory. + /// Size of the active main memory. MSize = 10, } diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 0e66a08b..4cc8c813 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -10,6 +10,7 @@ use plonky2_util::ceil_div_usize; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::assembler::Kernel; +use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField; use crate::generation::memory::{MemoryContextState, MemorySegmentState}; @@ -46,9 +47,7 @@ impl InterpreterMemory { mem } -} -impl InterpreterMemory { fn mload_general(&mut self, context: usize, segment: Segment, offset: usize) -> U256 { let value = self.context_memory[context].segments[segment as usize].get(offset); assert!( @@ -67,6 +66,16 @@ impl InterpreterMemory { ); self.context_memory[context].segments[segment as usize].set(offset, value) } + + fn update_msize(&mut self, context: usize, offset: usize) { + let current_msize = self.context_memory[context].segments + [Segment::ContextMetadata as usize] + .get(ContextMetadata::MSize as usize); + let msize = ceil_div_usize(offset + 1, 32) * 32; + let new_msize = current_msize.max(msize.into()); + self.context_memory[context].segments[Segment::ContextMetadata as usize] + .set(ContextMetadata::MSize as usize, new_msize) + } } pub struct Interpreter<'a> { @@ -502,6 +511,8 @@ impl<'a> Interpreter<'a> { fn run_keccak_general(&mut self) { let context = self.pop().as_usize(); let segment = Segment::all()[self.pop().as_usize()]; + // Not strictly needed but here to avoid surprises with MSIZE. + assert_ne!(segment, Segment::MainMemory, "Call KECCAK256 instead."); let offset = self.pop().as_usize(); let size = self.pop().as_usize(); let bytes = (offset..offset + size) @@ -582,7 +593,8 @@ impl<'a> Interpreter<'a> { fn run_msize(&mut self) { self.push(U256::from( - self.memory.context_memory[self.context].segments[Segment::MainMemory as usize].msize, + self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize] + .get(ContextMetadata::MSize as usize), )) } diff --git a/evm/src/generation/memory.rs b/evm/src/generation/memory.rs index 18ed2e16..d5dd21ac 100644 --- a/evm/src/generation/memory.rs +++ b/evm/src/generation/memory.rs @@ -23,34 +23,19 @@ impl Default for MemoryState { } } -#[derive(Clone, Debug)] +#[derive(Clone, Default, Debug)] pub(crate) struct MemoryContextState { /// The content of each memory segment. pub segments: [MemorySegmentState; Segment::COUNT], } -impl Default for MemoryContextState { - fn default() -> Self { - Self { - segments: Segment::all().map(|segment| MemorySegmentState { - content: vec![], - segment, - msize: 0, - }), - } - } -} - -#[derive(Clone, Debug)] +#[derive(Clone, Default, Debug)] pub(crate) struct MemorySegmentState { pub content: Vec, - pub segment: Segment, - pub msize: usize, } impl MemorySegmentState { - pub(crate) fn get(&mut self, virtual_addr: usize) -> U256 { - self.update_msize(virtual_addr); + pub(crate) fn get(&self, virtual_addr: usize) -> U256 { self.content .get(virtual_addr) .copied() @@ -58,17 +43,9 @@ impl MemorySegmentState { } pub(crate) fn set(&mut self, virtual_addr: usize, value: U256) { - assert_eq!(value >> self.segment.bit_range(), U256::zero()); - self.update_msize(virtual_addr); if virtual_addr >= self.content.len() { self.content.resize(virtual_addr + 1, U256::zero()); } self.content[virtual_addr] = value; } - - fn update_msize(&mut self, virtual_addr: usize) { - let word_size = 256 / self.segment.bit_range(); - let new_msize = ceil_div_usize(virtual_addr + 1, word_size) * 32; - self.msize = self.msize.max(new_msize); - } }