Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
Simulate jumpdest data with the interpreter (0xPolygonZero#1489)
Browse files Browse the repository at this point in the history
* Simulate jumpdest data with the interpreter

* Fix mising type paramenter on some tests

* Refactor simulation and fix some intepreter bugs

* Fix bug in interpreter

* Apply suggestions from code review

Co-authored-by: Robin Salen <[email protected]>

* Address remaining reviews

* [WIP] Fixing memory issue

* [WIP] Fixed memory issue but erc20 failing

* Fix interpreter halting issue

* Restore transition.rs

* Minor

* Adress reviews

* Address reviews

* Missing fix

---------

Co-authored-by: Robin Salen <[email protected]>
  • Loading branch information
4l0n50 and Nashtare authored Feb 13, 2024
1 parent 3ec1bfd commit 710225c
Show file tree
Hide file tree
Showing 34 changed files with 511 additions and 312 deletions.
231 changes: 175 additions & 56 deletions evm/src/cpu/kernel/interpreter.rs

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions evm/src/cpu/kernel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ mod parser;
pub mod stack;
mod utils;

#[cfg(test)]
mod interpreter;
pub(crate) mod interpreter;
#[cfg(test)]
mod tests;

Expand Down
23 changes: 14 additions & 9 deletions evm/src/cpu/kernel/tests/account_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, BigEndianHash, H256, U256};
use hex_literal::hex;
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField as F;
use plonky2::field::types::Field;
use rand::{thread_rng, Rng};

use crate::cpu::kernel::aggregator::KERNEL;
Expand All @@ -20,7 +22,10 @@ use crate::witness::memory::MemoryAddress;
use crate::witness::operation::CONTEXT_SCALING_FACTOR;
use crate::Node;

pub(crate) fn initialize_mpts(interpreter: &mut Interpreter, trie_inputs: &TrieInputs) {
pub(crate) fn initialize_mpts<F: Field>(
interpreter: &mut Interpreter<F>,
trie_inputs: &TrieInputs,
) {
// Load all MPTs.
let (trie_root_ptrs, trie_data) =
load_all_mpts(trie_inputs).expect("Invalid MPT data for preinitialization");
Expand Down Expand Up @@ -70,8 +75,8 @@ fn random_code() -> Vec<u8> {

// Stolen from `tests/mpt/insert.rs`
// Prepare the interpreter by inserting the account in the state trie.
fn prepare_interpreter(
interpreter: &mut Interpreter,
fn prepare_interpreter<F: Field>(
interpreter: &mut Interpreter<F>,
address: Address,
account: &AccountRlp,
) -> Result<()> {
Expand Down Expand Up @@ -151,7 +156,7 @@ fn test_extcodesize() -> Result<()> {
let code = random_code();
let account = test_account(&code);

let mut interpreter = Interpreter::new_with_kernel(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new_with_kernel(0, vec![]);
let address: Address = thread_rng().gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand Down Expand Up @@ -183,7 +188,7 @@ fn test_extcodecopy() -> Result<()> {
let code = random_code();
let account = test_account(&code);

let mut interpreter = Interpreter::new_with_kernel(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new_with_kernel(0, vec![]);
let address: Address = thread_rng().gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand Down Expand Up @@ -252,8 +257,8 @@ fn test_extcodecopy() -> Result<()> {

/// Prepare the interpreter for storage tests by inserting all necessary accounts
/// in the state trie, adding the code we want to context 1 and switching the context.
fn prepare_interpreter_all_accounts(
interpreter: &mut Interpreter,
fn prepare_interpreter_all_accounts<F: Field>(
interpreter: &mut Interpreter<F>,
trie_inputs: TrieInputs,
addr: [u8; 20],
code: &[u8],
Expand Down Expand Up @@ -318,7 +323,7 @@ fn sstore() -> Result<()> {
};

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

// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?;
Expand Down Expand Up @@ -407,7 +412,7 @@ fn sload() -> Result<()> {
};

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

// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?;
Expand Down
5 changes: 3 additions & 2 deletions evm/src/cpu/kernel/tests/add11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use eth_trie_utils::partial_trie::{HashedPartialTrie, Node, PartialTrie};
use ethereum_types::{Address, BigEndianHash, H256};
use hex_literal::hex;
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField as F;

use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::constants::context_metadata::ContextMetadata;
Expand Down Expand Up @@ -155,7 +156,7 @@ fn test_add11_yml() {
};

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

let route_txn_label = KERNEL.global_labels["main"];
Expand Down Expand Up @@ -297,7 +298,7 @@ fn test_add11_yml_with_exception() {
};

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

let route_txn_label = KERNEL.global_labels["main"];
Expand Down
8 changes: 5 additions & 3 deletions evm/src/cpu/kernel/tests/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use anyhow::Result;
use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie};
use ethereum_types::{Address, BigEndianHash, H256, U256};
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField as F;
use plonky2::field::types::Field;
use rand::{thread_rng, Rng};

use crate::cpu::kernel::aggregator::KERNEL;
Expand All @@ -24,8 +26,8 @@ fn test_account(balance: U256) -> AccountRlp {

// Stolen from `tests/mpt/insert.rs`
// Prepare the interpreter by inserting the account in the state trie.
fn prepare_interpreter(
interpreter: &mut Interpreter,
fn prepare_interpreter<F: Field>(
interpreter: &mut Interpreter<F>,
address: Address,
account: &AccountRlp,
) -> Result<()> {
Expand Down Expand Up @@ -107,7 +109,7 @@ fn test_balance() -> Result<()> {
let balance = U256(rng.gen());
let account = test_account(balance);

let mut interpreter = Interpreter::new_with_kernel(0, vec![]);
let mut interpreter: Interpreter<F> = Interpreter::new_with_kernel(0, vec![]);
let address: Address = rng.gen();
// Prepare the interpreter by inserting the account in the state trie.
prepare_interpreter(&mut interpreter, address, &account)?;
Expand Down
3 changes: 2 additions & 1 deletion evm/src/cpu/kernel/tests/bignum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use ethereum_types::U256;
use itertools::Itertools;
use num::{BigUint, One, Zero};
use num_bigint::RandBigInt;
use plonky2::field::goldilocks_field::GoldilocksField as F;
use plonky2_util::ceil_div_usize;
use rand::Rng;

Expand Down Expand Up @@ -99,7 +100,7 @@ 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::new_with_kernel(fn_label, initial_stack);
let mut interpreter: Interpreter<F> = Interpreter::new_with_kernel(fn_label, initial_stack);
interpreter.set_current_general_memory(memory);
interpreter.run()?;

Expand Down
3 changes: 2 additions & 1 deletion evm/src/cpu/kernel/tests/blake2_f.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::Result;
use plonky2::field::goldilocks_field::GoldilocksField as F;

use crate::cpu::kernel::interpreter::{
run_interpreter_with_memory, InterpreterMemoryInitialization,
Expand Down Expand Up @@ -71,7 +72,7 @@ fn run_blake2_f(
memory: vec![],
};

let result = run_interpreter_with_memory(interpreter_setup).unwrap();
let result = run_interpreter_with_memory::<F>(interpreter_setup).unwrap();
let mut hash = result.stack().to_vec();
hash.reverse();

Expand Down
13 changes: 9 additions & 4 deletions evm/src/cpu/kernel/tests/block_hash.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use ethereum_types::{H256, U256};
use plonky2::field::goldilocks_field::GoldilocksField as F;
use rand::{thread_rng, Rng};

use crate::cpu::kernel::aggregator::KERNEL;
Expand All @@ -19,7 +20,8 @@ fn test_correct_block_hash() -> Result<()> {

let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];

let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, 256.into());
Expand Down Expand Up @@ -48,7 +50,8 @@ fn test_big_index_block_hash() -> Result<()> {

let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];

let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
Expand Down Expand Up @@ -78,7 +81,8 @@ fn test_small_index_block_hash() -> Result<()> {

let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];

let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
Expand Down Expand Up @@ -106,7 +110,8 @@ fn test_block_hash_with_overflow() -> Result<()> {

let hashes: Vec<U256> = vec![U256::from_big_endian(&thread_rng().gen::<H256>().0); 257];

let mut interpreter = Interpreter::new_with_kernel(blockhash_label, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(blockhash_label, initial_stack);
interpreter.set_memory_segment(Segment::BlockHashes, hashes[0..256].to_vec());
interpreter.set_global_metadata_field(GlobalMetadata::BlockCurrentHash, hashes[256]);
interpreter.set_global_metadata_field(GlobalMetadata::BlockNumber, cur_block_number.into());
Expand Down
3 changes: 2 additions & 1 deletion evm/src/cpu/kernel/tests/bls381.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use ethereum_types::U256;
use plonky2::field::goldilocks_field::GoldilocksField as F;
use rand::Rng;

use crate::cpu::kernel::interpreter::{
Expand All @@ -23,7 +24,7 @@ fn test_bls_fp2_mul() -> Result<()> {
segment: KernelGeneral,
memory: vec![],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter = run_interpreter_with_memory::<F>(setup).unwrap();
let stack: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
let output = Fp2::<BLS381>::from_stack(&stack);

Expand Down
17 changes: 9 additions & 8 deletions evm/src/cpu/kernel/tests/bn254.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use ethereum_types::U256;
use plonky2::field::goldilocks_field::GoldilocksField as F;
use rand::Rng;

use crate::cpu::kernel::interpreter::{
Expand All @@ -23,7 +24,7 @@ fn run_bn_mul_fp6(f: Fp6<BN254>, g: Fp6<BN254>, label: &str) -> Fp6<BN254> {
segment: BnPairing,
memory: vec![],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter = run_interpreter_with_memory::<F>(setup).unwrap();
let output: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
Fp6::<BN254>::from_stack(&output)
}
Expand Down Expand Up @@ -63,7 +64,7 @@ fn run_bn_mul_fp12(f: Fp12<BN254>, g: Fp12<BN254>, label: &str) -> Fp12<BN254> {
segment: BnPairing,
memory: vec![(in0, f.to_stack().to_vec()), (in1, g.to_stack().to_vec())],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter = run_interpreter_with_memory::<F>(setup).unwrap();
let output = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
Fp12::<BN254>::from_stack(&output)
}
Expand Down Expand Up @@ -93,7 +94,7 @@ fn run_bn_frob_fp6(n: usize, f: Fp6<BN254>) -> Fp6<BN254> {
segment: BnPairing,
memory: vec![],
};
let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter: Interpreter<F> = run_interpreter_with_memory(setup).unwrap();
let output: Vec<U256> = interpreter.stack().iter().rev().cloned().collect();
Fp6::<BN254>::from_stack(&output)
}
Expand All @@ -117,7 +118,7 @@ fn run_bn_frob_fp12(f: Fp12<BN254>, n: usize) -> Fp12<BN254> {
segment: BnPairing,
memory: vec![(ptr, f.to_stack().to_vec())],
};
let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter: Interpreter<F> = run_interpreter_with_memory(setup).unwrap();
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, ptr..ptr + 12);
Fp12::<BN254>::from_stack(&output)
}
Expand Down Expand Up @@ -147,7 +148,7 @@ fn test_bn_inv_fp12() -> Result<()> {
segment: BnPairing,
memory: vec![(ptr, f.to_stack().to_vec())],
};
let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter: Interpreter<F> = run_interpreter_with_memory(setup).unwrap();
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, inv..inv + 12);
let output = Fp12::<BN254>::from_stack(&output);

Expand Down Expand Up @@ -175,7 +176,7 @@ fn test_bn_final_exponent() -> Result<()> {
memory: vec![(ptr, f.to_stack().to_vec())],
};

let interpreter: Interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter: Interpreter<F> = run_interpreter_with_memory(setup).unwrap();
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, ptr..ptr + 12);
let expected: Vec<U256> = bn_final_exponent(f).to_stack();

Expand All @@ -202,7 +203,7 @@ fn test_bn_miller() -> Result<()> {
segment: BnPairing,
memory: vec![(ptr, input)],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter = run_interpreter_with_memory::<F>(setup).unwrap();
let output: Vec<U256> = interpreter.extract_kernel_memory(BnPairing, out..out + 12);
let expected = bn_miller_loop(p, q).to_stack();

Expand Down Expand Up @@ -246,7 +247,7 @@ fn test_bn_pairing() -> Result<()> {
segment: BnPairing,
memory: vec![(ptr, input)],
};
let interpreter = run_interpreter_with_memory(setup).unwrap();
let interpreter = run_interpreter_with_memory::<F>(setup).unwrap();
assert_eq!(interpreter.stack()[0], U256::one());
Ok(())
}
13 changes: 9 additions & 4 deletions evm/src/cpu/kernel/tests/core/access_lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::HashSet;

use anyhow::Result;
use ethereum_types::{Address, U256};
use plonky2::field::goldilocks_field::GoldilocksField as F;
use rand::{thread_rng, Rng};

use crate::cpu::kernel::aggregator::KERNEL;
Expand Down Expand Up @@ -33,7 +34,8 @@ fn test_insert_accessed_addresses() -> Result<()> {

// Test for address already in list.
let initial_stack = vec![retaddr, U256::from(addr_in_list.0.as_slice())];
let mut interpreter = Interpreter::new_with_kernel(insert_accessed_addresses, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(insert_accessed_addresses, initial_stack);
for i in 0..n {
let addr = U256::from(addresses[i].0.as_slice());
interpreter
Expand All @@ -57,7 +59,8 @@ fn test_insert_accessed_addresses() -> Result<()> {

// Test for address not in list.
let initial_stack = vec![retaddr, U256::from(addr_not_in_list.0.as_slice())];
let mut interpreter = Interpreter::new_with_kernel(insert_accessed_addresses, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(insert_accessed_addresses, initial_stack);
for i in 0..n {
let addr = U256::from(addresses[i].0.as_slice());
interpreter
Expand Down Expand Up @@ -115,7 +118,8 @@ fn test_insert_accessed_storage_keys() -> Result<()> {
storage_key_in_list.1,
U256::from(storage_key_in_list.0 .0.as_slice()),
];
let mut interpreter = Interpreter::new_with_kernel(insert_accessed_storage_keys, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(insert_accessed_storage_keys, initial_stack);
for i in 0..n {
let addr = U256::from(storage_keys[i].0 .0.as_slice());
interpreter
Expand Down Expand Up @@ -152,7 +156,8 @@ fn test_insert_accessed_storage_keys() -> Result<()> {
storage_key_not_in_list.1,
U256::from(storage_key_not_in_list.0 .0.as_slice()),
];
let mut interpreter = Interpreter::new_with_kernel(insert_accessed_storage_keys, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(insert_accessed_storage_keys, initial_stack);
for i in 0..n {
let addr = U256::from(storage_keys[i].0 .0.as_slice());
interpreter
Expand Down
7 changes: 5 additions & 2 deletions evm/src/cpu/kernel/tests/core/create_addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use anyhow::Result;
use ethereum_types::{H256, U256};
use hex_literal::hex;
use keccak_hash::keccak;
use plonky2::field::goldilocks_field::GoldilocksField as F;

use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::interpreter::Interpreter;
Expand All @@ -19,7 +20,8 @@ fn test_get_create_address() -> Result<()> {
let expected_addr = U256::from_big_endian(&hex!("3f09c73a5ed19289fb9bdc72f1742566df146f56"));

let initial_stack = vec![retaddr, nonce, sender];
let mut interpreter = Interpreter::new_with_kernel(get_create_address, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(get_create_address, initial_stack);
interpreter.run()?;

assert_eq!(interpreter.stack(), &[expected_addr]);
Expand Down Expand Up @@ -105,7 +107,8 @@ fn test_get_create2_address() -> Result<()> {
} in create2_test_cases()
{
let initial_stack = vec![retaddr, salt, U256::from(code_hash.0), sender];
let mut interpreter = Interpreter::new_with_kernel(get_create2_address, initial_stack);
let mut interpreter: Interpreter<F> =
Interpreter::new_with_kernel(get_create2_address, initial_stack);
interpreter.run()?;

assert_eq!(interpreter.stack(), &[expected_addr]);
Expand Down
Loading

0 comments on commit 710225c

Please sign in to comment.