diff --git a/Cargo.lock b/Cargo.lock index 2389ae8b75..4447e5a43c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5161,7 +5161,7 @@ dependencies = [ [[package]] name = "revm" version = "3.0.0" -source = "git+https://github.com/bluealloy/revm#7bb73da23d0278829f9669f175a6eede247c0538" +source = "git+https://github.com/bluealloy/revm#f2656b7eac6fab1cb872268bb7d0dda4b5d3aa85" dependencies = [ "auto_impl", "revm-interpreter", @@ -5171,7 +5171,7 @@ dependencies = [ [[package]] name = "revm-interpreter" version = "1.0.0" -source = "git+https://github.com/bluealloy/revm#7bb73da23d0278829f9669f175a6eede247c0538" +source = "git+https://github.com/bluealloy/revm#f2656b7eac6fab1cb872268bb7d0dda4b5d3aa85" dependencies = [ "bitvec 1.0.1", "derive_more", @@ -5183,7 +5183,7 @@ dependencies = [ [[package]] name = "revm-precompile" version = "2.0.0" -source = "git+https://github.com/bluealloy/revm#7bb73da23d0278829f9669f175a6eede247c0538" +source = "git+https://github.com/bluealloy/revm#f2656b7eac6fab1cb872268bb7d0dda4b5d3aa85" dependencies = [ "k256", "num", @@ -5199,7 +5199,7 @@ dependencies = [ [[package]] name = "revm-primitives" version = "1.0.0" -source = "git+https://github.com/bluealloy/revm#7bb73da23d0278829f9669f175a6eede247c0538" +source = "git+https://github.com/bluealloy/revm#f2656b7eac6fab1cb872268bb7d0dda4b5d3aa85" dependencies = [ "arbitrary", "auto_impl", diff --git a/bin/reth/src/test_eth_chain/runner.rs b/bin/reth/src/test_eth_chain/runner.rs index cae43ba4ef..61025f6fa6 100644 --- a/bin/reth/src/test_eth_chain/runner.rs +++ b/bin/reth/src/test_eth_chain/runner.rs @@ -10,8 +10,8 @@ use reth_db::{ Error as DbError, }; use reth_primitives::{ - keccak256, Account as RethAccount, Address, ChainSpec, ForkCondition, Hardfork, JsonU256, - SealedBlock, SealedHeader, StorageEntry, H256, U256, + keccak256, Account as RethAccount, Address, Bytecode, ChainSpec, ForkCondition, Hardfork, + JsonU256, SealedBlock, SealedHeader, StorageEntry, H256, U256, }; use reth_provider::Transaction; use reth_rlp::Decodable; @@ -162,7 +162,7 @@ pub async fn run_test(path: PathBuf) -> eyre::Result { }, )?; if let Some(code_hash) = code_hash { - tx.put::(code_hash, account.code.to_vec())?; + tx.put::(code_hash, Bytecode::new_raw(account.code.0))?; } account.storage.iter().try_for_each(|(k, v)| { trace!(target: "reth::cli", ?address, key = ?k.0, value = ?v.0, "Update storage"); diff --git a/crates/executor/src/executor.rs b/crates/executor/src/executor.rs index 03d28ee9c9..9f9ed262d2 100644 --- a/crates/executor/src/executor.rs +++ b/crates/executor/src/executor.rs @@ -533,8 +533,8 @@ pub fn verify_receipt<'a>( mod tests { use super::*; use reth_primitives::{ - hex_literal::hex, keccak256, Account, Address, Bytes, ChainSpecBuilder, ForkCondition, - StorageKey, H256, MAINNET, U256, + hex_literal::hex, keccak256, Account, Address, Bytecode, Bytes, ChainSpecBuilder, + ForkCondition, StorageKey, H256, MAINNET, U256, }; use reth_provider::{AccountProvider, BlockHashProvider, StateProvider}; use reth_revm::database::State; @@ -544,7 +544,7 @@ mod tests { #[derive(Debug, Default, Clone, Eq, PartialEq)] struct StateProviderTest { accounts: HashMap, Account)>, - contracts: HashMap, + contracts: HashMap, block_hash: HashMap, } @@ -560,7 +560,7 @@ mod tests { if let Some(bytecode) = bytecode { let hash = keccak256(&bytecode); account.bytecode_hash = Some(hash); - self.contracts.insert(hash, bytecode); + self.contracts.insert(hash, Bytecode::new_raw(bytecode.into())); } self.accounts.insert(address, (storage, account)); } @@ -591,7 +591,7 @@ mod tests { .and_then(|(storage, _)| storage.get(&storage_key).cloned())) } - fn bytecode_by_hash(&self, code_hash: H256) -> reth_interfaces::Result> { + fn bytecode_by_hash(&self, code_hash: H256) -> reth_interfaces::Result> { Ok(self.contracts.get(&code_hash).cloned()) } } diff --git a/crates/primitives/src/account.rs b/crates/primitives/src/account.rs index eb77388a3f..e822bc449e 100644 --- a/crates/primitives/src/account.rs +++ b/crates/primitives/src/account.rs @@ -1,5 +1,10 @@ use crate::{H256, KECCAK_EMPTY, U256}; +use bytes::{Buf, BufMut, Bytes}; +use fixed_hash::byteorder::{BigEndian, ReadBytesExt}; use reth_codecs::{main_codec, Compact}; +use revm_primitives::{Bytecode as RevmBytecode, BytecodeState, JumpMap}; +use serde::{Deserialize, Serialize}; +use std::ops::Deref; /// An Ethereum account. #[main_codec] @@ -31,10 +36,97 @@ impl Account { } } +/// Bytecode for an account. +/// +/// A wrapper around [`revm::primitives::Bytecode`][RevmBytecode] with encoding/decoding support. +/// +/// Note: Upon decoding bytecode from the database, you *should* set the code hash using +/// [`Self::with_code_hash`]. +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct Bytecode(pub RevmBytecode); + +impl Bytecode { + /// Create new bytecode from raw bytes. + /// + /// No analysis will be performed. + pub fn new_raw(bytes: Bytes) -> Self { + Self(RevmBytecode::new_raw(bytes)) + } + + /// Set the hash of the inner bytecode. + pub fn with_code_hash(mut self, code_hash: H256) -> Self { + self.0.hash = code_hash; + self + } +} + +impl Deref for Bytecode { + type Target = RevmBytecode; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Compact for Bytecode { + fn to_compact(self, buf: &mut impl BufMut) -> usize { + buf.put_u32(self.0.bytecode.len() as u32); + buf.put_slice(self.0.bytecode.as_ref()); + let len = match self.0.state() { + BytecodeState::Raw => { + buf.put_u8(0); + 1 + } + BytecodeState::Checked { len } => { + buf.put_u8(1); + buf.put_u64(*len as u64); + 9 + } + BytecodeState::Analysed { len, jump_map } => { + buf.put_u8(2); + buf.put_u64(*len as u64); + let map = jump_map.as_slice(); + buf.put_slice(map); + 9 + map.len() + } + }; + len + self.0.bytecode.len() + 4 + } + + fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) + where + Self: Sized, + { + let len = buf.read_u32::().expect("could not read bytecode length"); + let bytes = buf.copy_to_bytes(len as usize); + let variant = buf.read_u8().expect("could not read bytecode variant"); + let decoded = match variant { + 0 => Bytecode(RevmBytecode::new_raw(bytes)), + 1 => Bytecode(unsafe { + RevmBytecode::new_checked( + bytes, + buf.read_u64::().unwrap() as usize, + None, + ) + }), + 2 => Bytecode(RevmBytecode { + bytecode: bytes, + hash: KECCAK_EMPTY, + state: BytecodeState::Analysed { + len: buf.read_u64::().unwrap() as usize, + jump_map: JumpMap::from_slice(buf), + }, + }), + _ => unreachable!(), + }; + (decoded, &[]) + } +} + #[cfg(test)] mod tests { - use crate::{Account, U256}; - use reth_codecs::Compact; + use super::*; + use hex_literal::hex; #[test] fn test_account() { @@ -51,4 +143,26 @@ mod tests { let len = acc.to_compact(&mut buf); assert_eq!(len, 4); } + + #[test] + fn test_bytecode() { + let mut buf = vec![]; + let mut bytecode = Bytecode(RevmBytecode::new_raw(Bytes::default())); + let len = bytecode.clone().to_compact(&mut buf); + assert_eq!(len, 5); + + let mut buf = vec![]; + bytecode.0.bytecode = Bytes::from(hex!("ffff").as_ref()); + let len = bytecode.clone().to_compact(&mut buf); + assert_eq!(len, 7); + + let mut buf = vec![]; + bytecode.0.state = BytecodeState::Analysed { len: 2, jump_map: JumpMap::from_slice(&[0]) }; + let len = bytecode.clone().to_compact(&mut buf); + assert_eq!(len, 16); + + let (decoded, remainder) = Bytecode::from_compact(&buf, len); + assert_eq!(decoded, bytecode); + assert!(remainder.is_empty()); + } } diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 52f349c3af..59f969e184 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -35,7 +35,7 @@ mod withdrawal; /// Helper function for calculating Merkle proofs and hashes pub mod proofs; -pub use account::Account; +pub use account::{Account, Bytecode}; pub use bits::H512; pub use block::{Block, BlockHashOrNumber, BlockId, BlockNumberOrTag, SealedBlock}; pub use bloom::Bloom; @@ -56,6 +56,7 @@ pub use log::Log; pub use net::NodeRecord; pub use peer::{PeerId, WithPeerId}; pub use receipt::Receipt; +pub use revm_primitives::JumpMap; pub use serde_helper::JsonU256; pub use storage::{StorageEntry, StorageTrieEntry}; pub use transaction::{ diff --git a/crates/revm/revm-primitives/src/env.rs b/crates/revm/revm-primitives/src/env.rs index 470684a760..84465494ef 100644 --- a/crates/revm/revm-primitives/src/env.rs +++ b/crates/revm/revm-primitives/src/env.rs @@ -39,7 +39,7 @@ pub fn fill_cfg_env( cfg_env.chain_id = U256::from(chain_spec.chain().id()); cfg_env.spec_id = spec_id; cfg_env.perf_all_precompiles_have_balance = false; - cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Raw; + cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse; } /// Fill block environment from Block. pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header, after_merge: bool) { diff --git a/crates/revm/revm-primitives/src/lib.rs b/crates/revm/revm-primitives/src/lib.rs index a989c0b65e..8053704946 100644 --- a/crates/revm/revm-primitives/src/lib.rs +++ b/crates/revm/revm-primitives/src/lib.rs @@ -6,7 +6,6 @@ ))] //! revm utils and implementations specific to reth. - pub mod config; /// Helpers for configuring revm [Env](revm::primitives::Env) diff --git a/crates/revm/src/database.rs b/crates/revm/src/database.rs index c90a7b111b..d18d872f2c 100644 --- a/crates/revm/src/database.rs +++ b/crates/revm/src/database.rs @@ -49,19 +49,9 @@ impl DatabaseRef for State { fn code_by_hash(&self, code_hash: H256) -> Result { 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) }) + Ok(bytecode.with_code_hash(code_hash).0) } 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()) } } diff --git a/crates/rpc/rpc/src/eth/api/state.rs b/crates/rpc/rpc/src/eth/api/state.rs index 935615ea4d..fce654d13c 100644 --- a/crates/rpc/rpc/src/eth/api/state.rs +++ b/crates/rpc/rpc/src/eth/api/state.rs @@ -15,7 +15,7 @@ where let state = self.state_at_block_id_or_latest(block_id)?.ok_or(EthApiError::UnknownBlockNumber)?; let code = state.account_code(address)?.unwrap_or_default(); - Ok(code) + Ok(code.original_bytes().into()) } pub(crate) fn balance(&self, address: Address, block_id: Option) -> EthResult { diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 4312a3ca05..0f28ce87b4 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -293,8 +293,8 @@ mod tests { }; use reth_executor::Factory; use reth_primitives::{ - hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, StorageEntry, H160, - H256, U256, + hex_literal::hex, keccak256, Account, Bytecode, ChainSpecBuilder, SealedBlock, + StorageEntry, H160, H256, U256, }; use reth_provider::insert_canonical_block; use reth_rlp::Decodable; @@ -347,7 +347,7 @@ mod tests { Account { nonce: 0, balance, bytecode_hash: None }, ) .unwrap(); - db_tx.put::(code_hash, code.to_vec()).unwrap(); + db_tx.put::(code_hash, Bytecode::new_raw(code.to_vec().into())).unwrap(); tx.commit().unwrap(); let mut execution_stage = stage(); @@ -430,7 +430,7 @@ mod tests { db_tx.put::(acc1, acc1_info).unwrap(); db_tx.put::(acc2, acc2_info).unwrap(); - db_tx.put::(code_hash, code.to_vec()).unwrap(); + db_tx.put::(code_hash, Bytecode::new_raw(code.to_vec().into())).unwrap(); tx.commit().unwrap(); // execute @@ -502,7 +502,7 @@ mod tests { // set account db_tx.put::(caller_address, caller_info).unwrap(); db_tx.put::(destroyed_address, destroyed_info).unwrap(); - db_tx.put::(code_hash, code.to_vec()).unwrap(); + db_tx.put::(code_hash, Bytecode::new_raw(code.to_vec().into())).unwrap(); // set storage to check when account gets destroyed. db_tx .put::( diff --git a/crates/storage/db/src/tables/codecs/compact.rs b/crates/storage/db/src/tables/codecs/compact.rs index a43fe7d76e..4c0a413641 100644 --- a/crates/storage/db/src/tables/codecs/compact.rs +++ b/crates/storage/db/src/tables/codecs/compact.rs @@ -43,7 +43,8 @@ impl_compression_for_compact!( StorageTrieEntry, StoredBlockBody, StoredBlockOmmers, - StoredBlockWithdrawals + StoredBlockWithdrawals, + Bytecode ); impl_compression_for_compact!(AccountBeforeTx, TransactionSigned); impl_compression_for_compact!(CompactU256); diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index 43904cf483..16fb6ac49b 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -18,7 +18,7 @@ use crate::{ }, }; use reth_primitives::{ - Account, Address, BlockHash, BlockNumber, Header, IntegerList, Receipt, StorageEntry, + Account, Address, BlockHash, BlockNumber, Bytecode, Header, IntegerList, Receipt, StorageEntry, StorageTrieEntry, TransactionSigned, TransitionId, TxHash, TxNumber, H256, }; @@ -304,6 +304,3 @@ pub type StageId = Vec; // // TODO: Temporary types, until they're properly defined alongside with the Encode and Decode Trait // - -/// Temporary placeholder type for DB. -pub type Bytecode = Vec; diff --git a/crates/storage/provider/src/providers/state/historical.rs b/crates/storage/provider/src/providers/state/historical.rs index b533946912..214f0ba2eb 100644 --- a/crates/storage/provider/src/providers/state/historical.rs +++ b/crates/storage/provider/src/providers/state/historical.rs @@ -10,7 +10,7 @@ use reth_db::{ }; use reth_interfaces::Result; use reth_primitives::{ - Account, Address, Bytes, StorageKey, StorageValue, TransitionId, H256, U256, + Account, Address, Bytecode, StorageKey, StorageValue, TransitionId, H256, U256, }; use std::marker::PhantomData; @@ -116,8 +116,8 @@ impl<'a, 'b, TX: DbTx<'a>> StateProvider for HistoricalStateProviderRef<'a, 'b, } /// Get account code by its hash - fn bytecode_by_hash(&self, code_hash: H256) -> Result> { - self.tx.get::(code_hash).map_err(Into::into).map(|r| r.map(Bytes::from)) + fn bytecode_by_hash(&self, code_hash: H256) -> Result> { + self.tx.get::(code_hash).map_err(Into::into) } } diff --git a/crates/storage/provider/src/providers/state/latest.rs b/crates/storage/provider/src/providers/state/latest.rs index b1e5ea4833..311f37e415 100644 --- a/crates/storage/provider/src/providers/state/latest.rs +++ b/crates/storage/provider/src/providers/state/latest.rs @@ -4,7 +4,7 @@ use crate::{ }; use reth_db::{cursor::DbDupCursorRO, tables, transaction::DbTx}; use reth_interfaces::Result; -use reth_primitives::{Account, Address, Bytes, StorageKey, StorageValue, H256, U256}; +use reth_primitives::{Account, Address, Bytecode, StorageKey, StorageValue, H256, U256}; use std::marker::PhantomData; /// State provider over latest state that takes tx reference. @@ -49,8 +49,8 @@ impl<'a, 'b, TX: DbTx<'a>> StateProvider for LatestStateProviderRef<'a, 'b, TX> } /// Get account code by its hash - fn bytecode_by_hash(&self, code_hash: H256) -> Result> { - self.db.get::(code_hash).map_err(Into::into).map(|r| r.map(Bytes::from)) + fn bytecode_by_hash(&self, code_hash: H256) -> Result> { + self.db.get::(code_hash).map_err(Into::into) } } diff --git a/crates/storage/provider/src/providers/state/macros.rs b/crates/storage/provider/src/providers/state/macros.rs index b7d9a775a2..d488010d71 100644 --- a/crates/storage/provider/src/providers/state/macros.rs +++ b/crates/storage/provider/src/providers/state/macros.rs @@ -38,7 +38,7 @@ macro_rules! delegate_provider_impls { } StateProvider $(where [$($generics)*])?{ fn storage(&self, account: reth_primitives::Address, storage_key: reth_primitives::StorageKey) -> reth_interfaces::Result>; - fn bytecode_by_hash(&self, code_hash: reth_primitives::H256) -> reth_interfaces::Result>; + fn bytecode_by_hash(&self, code_hash: reth_primitives::H256) -> reth_interfaces::Result>; } ); } diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index f6946f95ef..7d448fd2a9 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -5,8 +5,9 @@ use crate::{ use parking_lot::Mutex; use reth_interfaces::Result; use reth_primitives::{ - keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumber, BlockNumberOrTag, Bytes, - ChainInfo, Header, StorageKey, StorageValue, TransactionSigned, TxHash, H256, U256, + keccak256, Account, Address, Block, BlockHash, BlockId, BlockNumber, BlockNumberOrTag, + Bytecode, Bytes, ChainInfo, Header, StorageKey, StorageValue, TransactionSigned, TxHash, H256, + U256, }; use revm_primitives::{BlockEnv, CfgEnv}; use std::{collections::HashMap, ops::RangeBounds, sync::Arc}; @@ -26,7 +27,7 @@ pub struct MockEthProvider { #[derive(Debug, Clone)] pub struct ExtendedAccount { account: Account, - bytecode: Option, + bytecode: Option, storage: HashMap, } @@ -44,7 +45,7 @@ impl ExtendedAccount { pub fn with_bytecode(mut self, bytecode: Bytes) -> Self { let hash = keccak256(&bytecode); self.account.bytecode_hash = Some(hash); - self.bytecode = Some(bytecode); + self.bytecode = Some(Bytecode::new_raw(bytecode.into())); self } } @@ -226,7 +227,7 @@ impl StateProvider for MockEthProvider { Ok(lock.get(&account).and_then(|account| account.storage.get(&storage_key)).cloned()) } - fn bytecode_by_hash(&self, code_hash: H256) -> Result> { + fn bytecode_by_hash(&self, code_hash: H256) -> Result> { let lock = self.accounts.lock(); Ok(lock.values().find_map(|account| { match (account.account.bytecode_hash.as_ref(), account.bytecode.as_ref()) { diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 28eba66138..c9f86b0caf 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -4,8 +4,8 @@ use crate::{ }; use reth_interfaces::Result; use reth_primitives::{ - Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytes, ChainInfo, Header, StorageKey, - StorageValue, TransactionSigned, TxHash, TxNumber, H256, U256, + Account, Address, Block, BlockHash, BlockId, BlockNumber, Bytecode, ChainInfo, Header, + StorageKey, StorageValue, TransactionSigned, TxHash, TxNumber, H256, U256, }; use revm_primitives::{BlockEnv, CfgEnv}; use std::ops::RangeBounds; @@ -96,7 +96,7 @@ impl StateProvider for NoopProvider { Ok(None) } - fn bytecode_by_hash(&self, _code_hash: H256) -> Result> { + fn bytecode_by_hash(&self, _code_hash: H256) -> Result> { Ok(None) } } diff --git a/crates/storage/provider/src/traits/state.rs b/crates/storage/provider/src/traits/state.rs index dd050c6332..f82f2ad548 100644 --- a/crates/storage/provider/src/traits/state.rs +++ b/crates/storage/provider/src/traits/state.rs @@ -3,7 +3,7 @@ use crate::BlockHashProvider; use auto_impl::auto_impl; use reth_interfaces::Result; use reth_primitives::{ - Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, H256, KECCAK_EMPTY, U256, + Address, BlockHash, BlockNumber, Bytecode, StorageKey, StorageValue, H256, KECCAK_EMPTY, U256, }; /// An abstraction for a type that provides state data. @@ -13,12 +13,12 @@ pub trait StateProvider: BlockHashProvider + AccountProvider + Send + Sync { fn storage(&self, account: Address, storage_key: StorageKey) -> Result>; /// Get account code by its hash - fn bytecode_by_hash(&self, code_hash: H256) -> Result>; + 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> { + 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)? { diff --git a/crates/storage/provider/src/transaction.rs b/crates/storage/provider/src/transaction.rs index 5da17221cf..b3aabfa304 100644 --- a/crates/storage/provider/src/transaction.rs +++ b/crates/storage/provider/src/transaction.rs @@ -14,8 +14,8 @@ use reth_db::{ }; use reth_interfaces::{db::Error as DbError, provider::ProviderError}; use reth_primitives::{ - keccak256, Account, Address, BlockHash, BlockNumber, ChainSpec, Hardfork, Header, SealedBlock, - StorageEntry, TransitionId, TxNumber, H256, U256, + keccak256, Account, Address, BlockHash, BlockNumber, Bytecode, ChainSpec, Hardfork, Header, + SealedBlock, StorageEntry, TransitionId, TxNumber, H256, U256, }; use reth_tracing::tracing::{info, trace}; use std::{ @@ -710,10 +710,9 @@ where for (hash, bytecode) in result.new_bytecodes.into_iter() { // make different types of bytecode. Checked and maybe even analyzed (needs to // be packed). Currently save only raw bytes. - let bytecode = bytecode.bytes(); - trace!(target: "sync::stages::execution", ?hash, ?bytecode, len = bytecode.len(), "Inserting bytecode"); - self.put::(hash, bytecode[..bytecode.len()].to_vec())?; - + let bytes = bytecode.bytes(); + trace!(target: "sync::stages::execution", ?hash, ?bytes, len = bytes.len(), "Inserting bytecode"); + self.put::(hash, Bytecode(bytecode))?; // NOTE: bytecode bytes are not inserted in change set and can be found in // separate table }