diff --git a/crates/revm/src/database.rs b/crates/revm/src/database.rs index 9740f6475..c90a7b111 100644 --- a/crates/revm/src/database.rs +++ b/crates/revm/src/database.rs @@ -47,8 +47,23 @@ impl DatabaseRef for State { } fn code_by_hash(&self, code_hash: H256) -> Result { - let bytecode = self.0.bytecode_by_hash(code_hash)?.unwrap_or_default(); - Ok(Bytecode::new_raw(bytecode.0)) + let bytecode = self.0.bytecode_by_hash(code_hash)?; + + // SAFETY: We are requesting the code by its hash, so it is almost tautological why this + // would be safe. If the bytecode is not found, we return an empty bytecode with the + // appropriate hash. + // + // In an ideal world we would return analysed bytecode here, but analysed bytecode in revm + // depends on the current active hard fork, since it calculates gas blocks... + if let Some(bytecode) = bytecode { + Ok(unsafe { Bytecode::new_raw_with_hash(bytecode.0, code_hash) }) + } else { + // NOTE(onbjerg): This corresponds to an empty analysed bytecode with a hash of + // `KECCAK_EMPTY`. In the case where the bytecode is not found, we would + // return empty bytes anyway: this simply skips the hashing and analysis steps, which + // would otherwise be present if we simply did an `.unwrap_or_default()` above. + Ok(Bytecode::new()) + } } fn storage(&self, address: H160, index: U256) -> Result {