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

suggestion: store max_cpu_len in Interpreter #80

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion evm_arithmetization/src/cpu/kernel/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct Kernel {
/// Computed using `hash_kernel`.
pub(crate) code_hash: H256,

pub global_labels: HashMap<String, usize>,
pub(crate) global_labels: HashMap<String, usize>,
pub(crate) ordered_labels: Vec<String>,

/// Map from `PROVER_INPUT` offsets to their corresponding `ProverInputFn`.
Expand Down
52 changes: 34 additions & 18 deletions evm_arithmetization/src/cpu/kernel/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub(crate) struct Interpreter<F: Field> {
/// Holds the value of the clock: the clock counts the number of operations
/// in the execution.
pub(crate) clock: usize,
/// TODO
max_cpu_len: Option<usize>,
}

/// Structure storing the state of the interpreter's registers.
Expand Down Expand Up @@ -87,7 +89,7 @@ pub(crate) fn run_interpreter_with_memory<F: Field>(
let label = KERNEL.global_labels[&memory_init.label];
let mut stack = memory_init.stack;
stack.reverse();
let mut interpreter = Interpreter::new(label, stack);
let mut interpreter = Interpreter::new(label, stack, 0);
for (pointer, data) in memory_init.memory {
for (i, term) in data.iter().enumerate() {
interpreter.generation_state.memory.set(
Expand All @@ -96,16 +98,16 @@ pub(crate) fn run_interpreter_with_memory<F: Field>(
)
}
}
interpreter.run(None)?;
interpreter.run()?;
Ok(interpreter)
}

pub(crate) fn run<F: Field>(
initial_offset: usize,
initial_stack: Vec<U256>,
) -> anyhow::Result<Interpreter<F>> {
let mut interpreter = Interpreter::new(initial_offset, initial_stack);
interpreter.run(None)?;
let mut interpreter = Interpreter::new(initial_offset, initial_stack, 0);
interpreter.run()?;
Ok(interpreter)
}

Expand All @@ -121,11 +123,11 @@ pub(crate) fn simulate_cpu_and_get_user_jumps<F: Field>(
let halt_pc = KERNEL.global_labels[final_label];
let initial_context = state.registers.context;
let mut interpreter =
Interpreter::new_with_state_and_halt_condition(state, halt_pc, initial_context);
Interpreter::new_with_state_and_halt_condition(state, halt_pc, initial_context, 0);

log::debug!("Simulating CPU for jumpdest analysis.");

interpreter.run(None);
interpreter.run();

log::trace!("jumpdest table = {:?}", interpreter.jumpdest_table);

Expand All @@ -146,8 +148,12 @@ pub(crate) fn generate_segment<F: Field>(
let init_label = KERNEL.global_labels["init"];
let initial_registers = RegistersState::new_with_main_label();
let interpreter_inputs = GenerationInputs { ..inputs.clone() };
let mut interpreter =
Interpreter::<F>::new_with_generation_inputs(init_label, vec![], interpreter_inputs);
let mut interpreter = Interpreter::<F>::new_with_generation_inputs(
init_label,
vec![],
interpreter_inputs,
max_cpu_len,
);

let (mut registers_before, mut registers_after, mut before_mem_values, mut after_mem_values) = (
initial_registers,
Expand Down Expand Up @@ -188,7 +194,7 @@ pub(crate) fn generate_segment<F: Field>(
interpreter.generation_state.registers.is_kernel = true;
interpreter.clock = 1;

let (updated_registers_after, opt_after_mem_values) = interpreter.run(Some(max_cpu_len))?;
let (updated_registers_after, opt_after_mem_values) = interpreter.run()?;
registers_after = updated_registers_after;
after_mem_values = opt_after_mem_values
.expect("We are in the interpreter: the run should return a memory state");
Expand All @@ -204,13 +210,14 @@ impl<F: Field> Interpreter<F> {
initial_offset: usize,
initial_stack: Vec<U256>,
inputs: GenerationInputs,
max_cpu_len: usize,
) -> Self {
let mut result = Self::new(initial_offset, initial_stack);
let mut result = Self::new(initial_offset, initial_stack, max_cpu_len);
result.initialize_interpreter_state(inputs);
result
}

pub(crate) fn new(initial_offset: usize, initial_stack: Vec<U256>) -> Self {
pub(crate) fn new(initial_offset: usize, initial_stack: Vec<U256>, max_cpu_len: usize) -> Self {
let mut interpreter = Self {
generation_state: GenerationState::new(GenerationInputs::default(), &KERNEL.code)
.expect("Default inputs are known-good"),
Expand All @@ -222,6 +229,11 @@ impl<F: Field> Interpreter<F> {
jumpdest_table: HashMap::new(),
is_jumpdest_analysis: false,
clock: 1,
max_cpu_len: if max_cpu_len > 0 {
Some(max_cpu_len)
} else {
None
},
};
interpreter.generation_state.registers.program_counter = initial_offset;
let initial_stack_len = initial_stack.len();
Expand All @@ -242,7 +254,13 @@ impl<F: Field> Interpreter<F> {
state: &GenerationState<F>,
halt_offset: usize,
halt_context: usize,
max_cpu_len: usize,
) -> Self {
let max_cpu_len = if max_cpu_len > 0 {
Some(max_cpu_len)
} else {
None
};
Self {
generation_state: state.soft_clone(),
halt_offsets: vec![halt_offset],
Expand All @@ -251,6 +269,7 @@ impl<F: Field> Interpreter<F> {
jumpdest_table: HashMap::new(),
is_jumpdest_analysis: true,
clock: 1,
max_cpu_len,
}
}

Expand Down Expand Up @@ -435,11 +454,8 @@ impl<F: Field> Interpreter<F> {
Ok(())
}

pub(crate) fn run(
&mut self,
max_cpu_len: Option<usize>,
) -> Result<(RegistersState, Option<MemoryState>), anyhow::Error> {
let (final_registers, final_mem) = self.run_cpu(max_cpu_len)?;
pub(crate) fn run(&mut self) -> Result<(RegistersState, Option<MemoryState>), anyhow::Error> {
let (final_registers, final_mem) = self.run_cpu(self.max_cpu_len)?;

#[cfg(debug_assertions)]
{
Expand Down Expand Up @@ -1258,7 +1274,7 @@ mod tests {
0x60, 0xff, 0x60, 0x0, 0x52, 0x60, 0, 0x51, 0x60, 0x1, 0x51, 0x60, 0x42, 0x60, 0x27,
0x53,
];
let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![], 0);

interpreter.set_code(1, code.to_vec());

Expand Down Expand Up @@ -1286,7 +1302,7 @@ mod tests {
U256::one() << CONTEXT_SCALING_FACTOR,
);

interpreter.run(None)?;
interpreter.run()?;

// sys_stop returns `success` and `cum_gas_used`, that we need to pop.
interpreter.pop().expect("Stack should not be empty");
Expand Down
30 changes: 15 additions & 15 deletions evm_arithmetization/src/cpu/kernel/tests/account_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn prepare_interpreter<F: Field>(
.push(k.try_into_u256().unwrap())
.expect("The stack should not overflow"); // key

interpreter.run(None)?;
interpreter.run()?;
assert_eq!(
interpreter.stack().len(),
0,
Expand All @@ -135,7 +135,7 @@ fn prepare_interpreter<F: Field>(
interpreter
.push(1.into()) // Initial length of the trie data segment, unused.
.expect("The stack should not overflow");
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(
interpreter.stack().len(),
Expand All @@ -157,7 +157,7 @@ fn test_extcodesize() -> Result<()> {
let code = random_code();
let account = test_account(&code);

let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![], 0);
let address: Address = thread_rng().gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand All @@ -177,7 +177,7 @@ fn test_extcodesize() -> Result<()> {
.expect("The stack should not overflow");
interpreter.generation_state.inputs.contract_code =
HashMap::from([(keccak(&code), code.clone())]);
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(interpreter.stack(), vec![code.len().into()]);

Expand All @@ -189,7 +189,7 @@ fn test_extcodecopy() -> Result<()> {
let code = random_code();
let account = test_account(&code);

let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![], 0);
let address: Address = thread_rng().gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand All @@ -203,7 +203,7 @@ fn test_extcodecopy() -> Result<()> {
let init_accessed_addresses = KERNEL.global_labels["init_access_lists"];
interpreter.generation_state.registers.program_counter = init_accessed_addresses;
interpreter.push(0xdeadbeefu32.into());
interpreter.run(None)?;
interpreter.run()?;

let extcodecopy = KERNEL.global_labels["sys_extcodecopy"];

Expand Down Expand Up @@ -246,7 +246,7 @@ fn test_extcodecopy() -> Result<()> {
.expect("The stack should not overflow"); // kexit_info
interpreter.generation_state.inputs.contract_code =
HashMap::from([(keccak(&code), code.clone())]);
interpreter.run(None)?;
interpreter.run()?;

assert!(interpreter.stack().is_empty());
// Check that the code was correctly copied to memory.
Expand Down Expand Up @@ -332,18 +332,18 @@ fn sstore() -> Result<()> {
};

let initial_stack = vec![];
let mut interpreter: Interpreter<F> = Interpreter::new(0, initial_stack);
let mut interpreter: Interpreter<F> = Interpreter::new(0, initial_stack, 0);

// Pre-initialize the accessed addresses list.
let init_accessed_addresses = KERNEL.global_labels["init_access_lists"];
interpreter.generation_state.registers.program_counter = init_accessed_addresses;
interpreter.push(0xdeadbeefu32.into());
interpreter.run(None)?;
interpreter.run()?;

// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?;

interpreter.run(None)?;
interpreter.run()?;

// The first two elements in the stack are `success` and `leftover_gas`,
// returned by the `sys_stop` opcode.
Expand Down Expand Up @@ -373,7 +373,7 @@ fn sstore() -> Result<()> {
interpreter
.push(1.into()) // Initial length of the trie data segment, unused.
.expect("The stack should not overflow");
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(
interpreter.stack().len(),
Expand Down Expand Up @@ -428,17 +428,17 @@ fn sload() -> Result<()> {
};

let initial_stack = vec![];
let mut interpreter: Interpreter<F> = Interpreter::new(0, initial_stack);
let mut interpreter: Interpreter<F> = Interpreter::new(0, initial_stack, 0);

// Pre-initialize the accessed addresses list.
let init_accessed_addresses = KERNEL.global_labels["init_access_lists"];
interpreter.generation_state.registers.program_counter = init_accessed_addresses;
interpreter.push(0xdeadbeefu32.into());
interpreter.run(None)?;
interpreter.run()?;

// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?;
interpreter.run(None)?;
interpreter.run()?;

// The first two elements in the stack are `success` and `leftover_gas`,
// returned by the `sys_stop` opcode.
Expand Down Expand Up @@ -471,7 +471,7 @@ fn sload() -> Result<()> {
interpreter
.push(1.into()) // Initial length of the trie data segment, unused.
.expect("The stack should not overflow.");
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(
interpreter.stack().len(),
Expand Down
8 changes: 4 additions & 4 deletions evm_arithmetization/src/cpu/kernel/tests/add11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ fn test_add11_yml() {

let initial_stack = vec![];
let mut interpreter: Interpreter<F> =
Interpreter::new_with_generation_inputs(0, initial_stack, tries_inputs);
Interpreter::new_with_generation_inputs(0, initial_stack, tries_inputs, 0);

let route_txn_label = KERNEL.global_labels["init"];
// Switch context and initialize memory with the data we need for the tests.
interpreter.generation_state.registers.program_counter = route_txn_label;
interpreter.set_context_metadata_field(0, ContextMetadata::GasLimit, 1_000_000.into());
interpreter.set_is_kernel(true);
interpreter.run(None).expect("Proving add11 failed.");
interpreter.run().expect("Proving add11 failed.");
}

#[test]
Expand Down Expand Up @@ -311,14 +311,14 @@ fn test_add11_yml_with_exception() {

let initial_stack = vec![];
let mut interpreter: Interpreter<F> =
Interpreter::new_with_generation_inputs(0, initial_stack, tries_inputs);
Interpreter::new_with_generation_inputs(0, initial_stack, tries_inputs, 0);

let route_txn_label = KERNEL.global_labels["init"];
// Switch context and initialize memory with the data we need for the tests.
interpreter.generation_state.registers.program_counter = route_txn_label;
interpreter.set_context_metadata_field(0, ContextMetadata::GasLimit, 1_000_000.into());
interpreter.set_is_kernel(true);
interpreter
.run(None)
.run()
.expect("Proving add11 with exception failed.");
}
8 changes: 4 additions & 4 deletions evm_arithmetization/src/cpu/kernel/tests/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn prepare_interpreter<F: Field>(
.push(k.try_into_u256().unwrap())
.expect("The stack should not overflow"); // key

interpreter.run(None)?;
interpreter.run()?;
assert_eq!(
interpreter.stack().len(),
0,
Expand All @@ -86,7 +86,7 @@ fn prepare_interpreter<F: Field>(
interpreter
.push(1.into()) // Initial trie data segment size, unused.
.expect("The stack should not overflow");
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(
interpreter.stack().len(),
Expand All @@ -109,7 +109,7 @@ fn test_balance() -> Result<()> {
let balance = U256(rng.gen());
let account = test_account(balance);

let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new(0, vec![], 0);
let address: Address = rng.gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand All @@ -125,7 +125,7 @@ fn test_balance() -> Result<()> {
interpreter
.push(U256::from_big_endian(address.as_bytes()))
.expect("The stack should not overflow");
interpreter.run(None)?;
interpreter.run()?;

assert_eq!(interpreter.stack(), vec![balance]);

Expand Down
4 changes: 2 additions & 2 deletions evm_arithmetization/src/cpu/kernel/tests/bignum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ fn run_test(fn_label: &str, memory: Vec<U256>, stack: Vec<U256>) -> Result<(Vec<
initial_stack.push(retdest);
initial_stack.reverse();

let mut interpreter: Interpreter<F> = Interpreter::new(fn_label, initial_stack);
let mut interpreter: Interpreter<F> = Interpreter::new(fn_label, initial_stack, 0);
interpreter.set_current_general_memory(memory);
interpreter.run(None)?;
interpreter.run()?;

let new_memory = interpreter.get_current_general_memory();

Expand Down
Loading