diff --git a/etherlink/kernel_latest/revm/src/code_storage.rs b/etherlink/kernel_latest/revm/src/code_storage.rs index 3a134cbce168715d31a7d3ad10019abc60c6d25a..7e4ca9cc18872caaf8f9bfe17512b5fc6c58c895 100644 --- a/etherlink/kernel_latest/revm/src/code_storage.rs +++ b/etherlink/kernel_latest/revm/src/code_storage.rs @@ -92,8 +92,11 @@ impl CodeStorage { Bytecode::new_raw_checked(Bytes::from(host.store_read_all(&code_path)?)) .map_err(|err| Error::Custom(err.to_string())) } else { - // TODO: Double check that legacy code with one STOP instruction - // is ok here. + // `Bytecode::new()` creates a new legacy analyzed bytecode with exactly + // one STOP (`0x00`) opcode. + // This is a bit counter-intuitive as if the code doesn't exist we would + // expect the code to be empty to match the code hash (KECCAK_EMPTY). + // This is an internal mechanism of REVM needed for `LegacyAnalyzedBytecode`. Ok(Bytecode::new()) } } @@ -126,7 +129,7 @@ mod test { use crate::storage_helpers::{concat, read_u64_le}; use revm::{ - primitives::{alloy_primitives::KECCAK256_EMPTY, Bytes}, + primitives::{Bytes, KECCAK_EMPTY}, state::Bytecode, }; use tezos_evm_runtime::runtime::MockKernelHost; @@ -139,7 +142,7 @@ mod test { let found_code_hash = CodeStorage::add(&mut host, &empty_code) .expect("Could not create code storage"); - assert_eq!(found_code_hash, KECCAK256_EMPTY); + assert_eq!(found_code_hash, KECCAK_EMPTY); } #[test] @@ -193,7 +196,7 @@ mod test { let mut host = MockKernelHost::default(); let code_storage = - CodeStorage::new(&KECCAK256_EMPTY).expect("Could not find code storage"); + CodeStorage::new(&KECCAK_EMPTY).expect("Could not find code storage"); let exists = code_storage .exists(&host) @@ -218,7 +221,7 @@ mod test { .expect("Could not check if contract exists"); assert!(exists, "code storage should exist"); - let () = CodeStorage::delete(&mut host, &KECCAK256_EMPTY) + let () = CodeStorage::delete(&mut host, &KECCAK_EMPTY) .expect("Could not delete code storage"); let exists = code_storage @@ -226,7 +229,7 @@ mod test { .expect("Could not check if contract exists"); assert!(exists, "code storage should exist"); - let () = CodeStorage::delete(&mut host, &KECCAK256_EMPTY) + let () = CodeStorage::delete(&mut host, &KECCAK_EMPTY) .expect("Could not delete code storage"); let exists = code_storage @@ -234,4 +237,19 @@ mod test { .expect("Could not check if contract exist"); assert!(!exists, "code storage should not exists"); } + + #[test] + fn test_get_code_from_non_existing_code() { + let mut host = MockKernelHost::default(); + + let code: Vec = (0..100).collect(); + let code_hash = CodeStorage::add(&mut host, &code).unwrap(); + let code_storage = CodeStorage::new(&code_hash).unwrap(); + CodeStorage::delete(&mut host, &code_hash).unwrap(); + let empty_code = code_storage.get_code(&host).unwrap(); + let empty_hash = empty_code.hash_slow(); + + assert_eq!(empty_code, Bytecode::new()); + assert_eq!(empty_hash, KECCAK_EMPTY); + } }