mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 00:33:06 +00:00
Fix fix interpreter
This commit is contained in:
parent
61b6b16106
commit
71ed3c43ac
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user