From 5e97b4e28e83955da7497f1b283a626f6f3c46b2 Mon Sep 17 00:00:00 2001 From: Chirag Baghasingh <76247491+chirag-bgh@users.noreply.github.com> Date: Mon, 6 Feb 2023 19:36:08 +0530 Subject: [PATCH] feat: Add account_code helper function to AccountProvider (#1169) Co-authored-by: Matthias Seitz --- crates/storage/provider/src/traits/state.rs | 27 ++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/crates/storage/provider/src/traits/state.rs b/crates/storage/provider/src/traits/state.rs index dd6c223fab..6db63cfeb9 100644 --- a/crates/storage/provider/src/traits/state.rs +++ b/crates/storage/provider/src/traits/state.rs @@ -2,7 +2,9 @@ use super::AccountProvider; use crate::BlockHashProvider; use auto_impl::auto_impl; use reth_interfaces::Result; -use reth_primitives::{Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, H256}; +use reth_primitives::{ + Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, H256, KECCAK_EMPTY, +}; /// An abstraction for a type that provides state data. #[auto_impl(&)] @@ -12,6 +14,29 @@ pub trait StateProvider: BlockHashProvider + AccountProvider + Send + Sync { /// Get account code by its hash fn bytecode_by_hash(&self, code_hash: H256) -> Result>; + + /// Get account code by its address. + /// + /// Returns `None` if the account doesn't exist or account is not a contract + fn account_code(&self, addr: Address) -> Result> { + // Get basic account information + // Returns None if acc doesn't exist + let acc = match self.basic_account(addr)? { + Some(acc) => acc, + None => return Ok(None), + }; + + if let Some(code_hash) = acc.bytecode_hash { + if code_hash == KECCAK_EMPTY { + return Ok(None) + } + // Get the code from the code hash + return self.bytecode_by_hash(code_hash) + } + + // Return `None` if no code hash is set + Ok(None) + } } /// Light wrapper that returns `StateProvider` implementations that correspond to the given