Fix fix interpreter

This commit is contained in:
wborgeaud 2022-10-20 14:32:28 +02:00
parent 61b6b16106
commit 71ed3c43ac
4 changed files with 48 additions and 19 deletions

View File

@ -23,10 +23,12 @@ 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.
MSize = 10,
}
impl ContextMetadata {
pub(crate) const COUNT: usize = 10;
pub(crate) const COUNT: usize = 11;
pub(crate) fn all() -> [Self; Self::COUNT] {
[
@ -40,6 +42,7 @@ impl ContextMetadata {
Self::CallValue,
Self::Static,
Self::StateTrieCheckpointPointer,
Self::MSize,
]
}
@ -56,6 +59,7 @@ impl ContextMetadata {
ContextMetadata::CallValue => "CTX_METADATA_CALL_VALUE",
ContextMetadata::Static => "CTX_METADATA_STATIC",
ContextMetadata::StateTrieCheckpointPointer => "CTX_METADATA_STATE_TRIE_CHECKPOINT_PTR",
ContextMetadata::MSize => "CTX_METADATA_MSIZE",
}
}
}

View File

@ -49,7 +49,7 @@ impl InterpreterMemory {
}
impl InterpreterMemory {
fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 {
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!(
value.bits() <= segment.bit_range(),
@ -145,18 +145,19 @@ impl<'a> Interpreter<'a> {
Ok(())
}
fn code(&self) -> &MemorySegmentState {
&self.memory.context_memory[self.context].segments[Segment::Code as usize]
fn code(&mut self) -> &mut MemorySegmentState {
&mut self.memory.context_memory[self.context].segments[Segment::Code as usize]
}
fn code_slice(&self, n: usize) -> Vec<u8> {
self.code().content[self.offset..self.offset + n]
fn code_slice(&mut self, n: usize) -> Vec<u8> {
let offset = self.offset;
self.code().content[offset..offset + n]
.iter()
.map(|u256| u256.byte(0))
.collect::<Vec<_>>()
}
pub(crate) fn get_txn_field(&self, field: NormalizedTxnField) -> U256 {
pub(crate) fn get_txn_field(&mut self, field: NormalizedTxnField) -> U256 {
self.memory.context_memory[0].segments[Segment::TxnFields as usize].get(field as usize)
}
@ -169,7 +170,7 @@ impl<'a> Interpreter<'a> {
&self.memory.context_memory[0].segments[Segment::TxnData as usize].content
}
pub(crate) fn get_global_metadata_field(&self, field: GlobalMetadata) -> U256 {
pub(crate) fn get_global_metadata_field(&mut self, field: GlobalMetadata) -> U256 {
self.memory.context_memory[0].segments[Segment::GlobalMetadata as usize].get(field as usize)
}
@ -224,7 +225,8 @@ impl<'a> Interpreter<'a> {
}
fn run_opcode(&mut self) -> anyhow::Result<()> {
let opcode = self.code().get(self.offset).byte(0);
let offset = self.offset;
let opcode = self.code().get(offset).byte(0);
self.incr(1);
match opcode {
0x00 => self.run_stop(), // "STOP",
@ -579,11 +581,9 @@ impl<'a> Interpreter<'a> {
}
fn run_msize(&mut self) {
let num_bytes = self.memory.context_memory[self.context].segments
[Segment::MainMemory as usize]
.content
.len();
self.push(U256::from(ceil_div_usize(num_bytes, 32) * 32));
self.push(U256::from(
self.memory.context_memory[self.context].segments[Segment::MainMemory as usize].msize,
))
}
fn run_jumpdest(&mut self) {
@ -709,7 +709,7 @@ mod tests {
0x53,
];
let pis = HashMap::new();
let run = run(&code, 0, vec![], &pis)?;
let mut run = run(&code, 0, vec![], &pis)?;
assert_eq!(run.stack(), &[0xff.into(), 0xff00.into()]);
assert_eq!(
run.memory.context_memory[0].segments[Segment::MainMemory as usize].get(0x27),

View File

@ -31,7 +31,8 @@ fn mpt_read() -> Result<()> {
interpreter.push(0xdeadbeefu32.into());
interpreter.push(0xABCDEFu64.into());
interpreter.push(6.into());
interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot));
let state_trie_root = interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot);
interpreter.push(state_trie_root);
interpreter.run()?;
assert_eq!(interpreter.stack().len(), 1);

View File

@ -1,4 +1,5 @@
use ethereum_types::U256;
use plonky2_util::ceil_div_usize;
use crate::memory::memory_stark::MemoryOp;
use crate::memory::segments::Segment;
@ -22,19 +23,34 @@ impl Default for MemoryState {
}
}
#[derive(Clone, Default, Debug)]
#[derive(Clone, Debug)]
pub(crate) struct MemoryContextState {
/// The content of each memory segment.
pub segments: [MemorySegmentState; Segment::COUNT],
}
#[derive(Clone, Default, Debug)]
impl Default for MemoryContextState {
fn default() -> Self {
Self {
segments: Segment::all().map(|segment| MemorySegmentState {
content: vec![],
segment,
msize: 0,
}),
}
}
}
#[derive(Clone, Debug)]
pub(crate) struct MemorySegmentState {
pub content: Vec<U256>,
pub segment: Segment,
pub msize: usize,
}
impl MemorySegmentState {
pub(crate) fn get(&self, virtual_addr: usize) -> U256 {
pub(crate) fn get(&mut self, virtual_addr: usize) -> U256 {
self.update_msize(virtual_addr);
self.content
.get(virtual_addr)
.copied()
@ -42,9 +58,17 @@ 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);
}
}