diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8d762fac..47fc7671 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,10 +35,12 @@ jobs: GITHUB_TOKEN: ${{ github.token }} - name: run tests v0 run: | + set -o pipefail make vm-tests-v0-ci | tee test_v0.out - name: run tests v1 run: | make vm-tests-v1-ci | tee test_v1.out + set +o pipefail - name: Retrieve ef-tests execution resources run: python scripts/compute_resources.py env: diff --git a/crates/ef-testing/src/evm_sequencer/account/mod.rs b/crates/ef-testing/src/evm_sequencer/account/mod.rs index a2d49e70..9de1dc4a 100644 --- a/crates/ef-testing/src/evm_sequencer/account/mod.rs +++ b/crates/ef-testing/src/evm_sequencer/account/mod.rs @@ -8,6 +8,7 @@ use starknet_api::{ hash::StarkFelt, state::StorageKey, }; +use starknet_crypto::FieldElement; #[macro_export] macro_rules! starknet_storage { @@ -77,3 +78,29 @@ pub mod kkrt_account { } } } + +/// Splits a byte array into 31-byte chunks and converts each chunk to a StarkFelt. +pub fn split_bytecode_to_starkfelt(bytecode: &[u8]) -> impl Iterator + '_ { + bytecode.chunks(31).filter_map(|bytes| { + let f = FieldElement::from_byte_slice_be(bytes); + f.map(StarkFelt::from).ok() + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use reth_primitives::Bytes; + + #[test] + fn test_split_bytecode_to_starkfelt() { + // Given + let bytes = Bytes::from([0x01, 0x02, 0x03, 0x04, 0x05]); + + // When + let result: Vec<_> = split_bytecode_to_starkfelt(&bytes).collect(); + + // Then + assert_eq!(result, vec![StarkFelt::from(0x0102030405u64)]); + } +} diff --git a/crates/ef-testing/src/evm_sequencer/account/v0.rs b/crates/ef-testing/src/evm_sequencer/account/v0.rs index bbef66a0..f32676f1 100644 --- a/crates/ef-testing/src/evm_sequencer/account/v0.rs +++ b/crates/ef-testing/src/evm_sequencer/account/v0.rs @@ -8,7 +8,7 @@ use starknet_api::{ StarknetApiError, }; -use super::{AccountType, KakarotAccount}; +use super::{split_bytecode_to_starkfelt, AccountType, KakarotAccount}; use crate::evm_sequencer::{ constants::{ kkrt_constants_v0::{CONTRACT_ACCOUNT_CLASS_HASH, EOA_CLASS_HASH}, @@ -64,7 +64,7 @@ impl KakarotAccount { // Initialize the bytecode storage var. let mut bytecode_storage = split_bytecode_to_starkfelt(code) .enumerate() - .map(|(i, bytes)| starknet_storage!("bytecode_", [StarkFelt::from(i as u32)], bytes)) + .map(|(i, bytes)| (StorageKey::from(i as u32), bytes)) .collect(); storage.append(&mut bytecode_storage); @@ -90,12 +90,3 @@ impl KakarotAccount { }) } } - -/// Splits a byte array into 16-byte chunks and converts each chunk to a StarkFelt. -pub fn split_bytecode_to_starkfelt(bytecode: &Bytes) -> impl Iterator + '_ { - bytecode.chunks(16).map(|x| { - let mut storage_value = [0u8; 16]; - storage_value[..x.len()].copy_from_slice(x); - StarkFelt::from(u128::from_be_bytes(storage_value)) - }) -} diff --git a/crates/ef-testing/src/evm_sequencer/account/v1.rs b/crates/ef-testing/src/evm_sequencer/account/v1.rs index 5b5ac47b..3523553b 100644 --- a/crates/ef-testing/src/evm_sequencer/account/v1.rs +++ b/crates/ef-testing/src/evm_sequencer/account/v1.rs @@ -9,6 +9,7 @@ use starknet_api::{ }; use starknet_crypto::{poseidon_hash_many, FieldElement}; +use super::split_bytecode_to_starkfelt; use super::{AccountType, KakarotAccount}; use crate::evm_sequencer::{ constants::CHAIN_ID, @@ -131,26 +132,3 @@ impl KakarotAccount { }) } } - -fn split_bytecode_to_starkfelt(bytecode: &[u8]) -> impl Iterator + '_ { - bytecode - .chunks(31) - .map(|bytes| StarkFelt::from(FieldElement::from_byte_slice_be(bytes).unwrap())) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_split_bytecode_to_starkfelt() { - // Given - let bytes = Bytes::from([0x01, 0x02, 0x03, 0x04, 0x05]); - - // When - let result: Vec<_> = split_bytecode_to_starkfelt(&bytes).collect(); - - // Then - assert_eq!(result, vec![StarkFelt::from(0x0102030405u64)]); - } -} diff --git a/crates/ef-testing/src/evm_sequencer/evm_state/v0.rs b/crates/ef-testing/src/evm_sequencer/evm_state/v0.rs index 0c423ed3..14ea20fb 100644 --- a/crates/ef-testing/src/evm_sequencer/evm_state/v0.rs +++ b/crates/ef-testing/src/evm_sequencer/evm_state/v0.rs @@ -10,6 +10,7 @@ use sequencer::execution::Execution as _; use sequencer::transaction::BroadcastedTransactionWrapper; use starknet::core::types::{BroadcastedTransaction, FieldElement}; use starknet_api::hash::StarkFelt; +use starknet_api::state::StorageKey; use super::Evm; use crate::evm_sequencer::account::{AccountType, KakarotAccount}; @@ -20,8 +21,7 @@ use crate::evm_sequencer::constants::KAKAROT_ADDRESS; use crate::evm_sequencer::constants::{CHAIN_ID, ETH_FEE_TOKEN_ADDRESS}; use crate::evm_sequencer::sequencer::KakarotSequencer; use crate::evm_sequencer::utils::{ - compute_starknet_address, high_16_bytes_of_felt_to_bytes, split_u256, - to_broadcasted_starknet_transaction, + compute_starknet_address, felt_to_bytes, split_u256, to_broadcasted_starknet_transaction, }; impl Evm for KakarotSequencer { @@ -133,7 +133,7 @@ impl Evm for KakarotSequencer { /// Returns the bytecode of the given address. For an EOA, the bytecode_len_ storage variable will return 0, /// and the function will return an empty vector. For a contract account, the function will return the bytecode - /// stored in the bytecode_ storage variables. The function assumes that the bytecode is stored in 16 byte big-endian chunks. + /// stored in the bytecode_ storage variables. The function assumes that the bytecode is stored in 31 byte big-endian chunks. fn code_at(&mut self, evm_address: &Address) -> StateResult { let starknet_address = compute_starknet_address(evm_address); @@ -146,21 +146,20 @@ impl Evm for KakarotSequencer { return Ok(Bytes::default()); } - // Assumes that the bytecode is stored in 16 byte chunks. - let num_chunks = bytecode_len / 16; + // Assumes that the bytecode is stored in 31 byte chunks. + let num_chunks = bytecode_len / 31; let mut bytecode: Vec = Vec::new(); for chunk_index in 0..num_chunks { - let key = get_storage_var_address("bytecode_", &[StarkFelt::from(chunk_index)]); + let key = StorageKey::from(chunk_index); let code = (&mut self.state).get_storage_at(starknet_address.try_into()?, key)?; - bytecode.append(&mut high_16_bytes_of_felt_to_bytes(&code.into(), 16).to_vec()); + bytecode.append(&mut felt_to_bytes(&code.into(), 1).to_vec()); } - let remainder = bytecode_len % 16; - let key = get_storage_var_address("bytecode_", &[StarkFelt::from(num_chunks)]); + let remainder = bytecode_len % 31; + let key = StorageKey::from(num_chunks); let code = (&mut self.state).get_storage_at(starknet_address.try_into()?, key)?; - bytecode - .append(&mut high_16_bytes_of_felt_to_bytes(&code.into(), remainder as usize).to_vec()); + bytecode.append(&mut felt_to_bytes(&code.into(), (32 - remainder) as usize).to_vec()); Ok(Bytes::from(bytecode)) } diff --git a/crates/ef-testing/src/evm_sequencer/utils.rs b/crates/ef-testing/src/evm_sequencer/utils.rs index ea97d417..0911e4d1 100644 --- a/crates/ef-testing/src/evm_sequencer/utils.rs +++ b/crates/ef-testing/src/evm_sequencer/utils.rs @@ -57,9 +57,9 @@ pub fn split_u256(value: U256) -> [u128; 2] { ] } -/// Converts the high 16 bytes of a FieldElement to a byte array. -pub fn high_16_bytes_of_felt_to_bytes(felt: &FieldElement, len: usize) -> Bytes { - Bytes::from(&felt.to_bytes_be()[16..len + 16]) +/// Converts a FieldElement to a byte array. +pub fn felt_to_bytes(felt: &FieldElement, start: usize) -> Bytes { + Bytes::from(&felt.to_bytes_be()[start..]) } /// Converts an signed transaction and a signature to a Starknet-rs transaction. @@ -138,14 +138,14 @@ mod tests { use super::*; macro_rules! test_felt_to_bytes { - ($input: expr, $output: expr, $len: expr, $test_name: ident) => { + ($input: expr, $output: expr, $start: expr, $test_name: ident) => { #[test] fn $test_name() { // Given let felt = FieldElement::from_hex_be($input).unwrap(); // When - let bytes = high_16_bytes_of_felt_to_bytes(&felt, $len); + let bytes = felt_to_bytes(&felt, $start); // Then let expected = Bytes::from($output); @@ -155,26 +155,27 @@ mod tests { } test_felt_to_bytes!( - "0x1234567890abcdef1234567890abcdef", + "0x34567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", vec![ - 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, - 0xcd, 0xef + 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, + 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x90, + 0xab, 0xcd, 0xef ], - 16, + 1, test_felt_to_bytes_full ); test_felt_to_bytes!( - "0x12345678900000000000000000000000", + "0x00000000000000000000000000000000000000000000000000001234567890", vec![0x12, 0x34, 0x56, 0x78, 0x90], - 5, + 27, test_felt_to_bytes_partial ); test_felt_to_bytes!( "0x12345678900000000000000000000000", vec![], - 0, + 32, test_felt_to_bytes_empty ); }