mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-28 16:48:13 -05:00
feat: persist contract analysis in db (#1640)
This commit is contained in:
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -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<TestOutcome> {
|
||||
},
|
||||
)?;
|
||||
if let Some(code_hash) = code_hash {
|
||||
tx.put::<tables::Bytecodes>(code_hash, account.code.to_vec())?;
|
||||
tx.put::<tables::Bytecodes>(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");
|
||||
|
||||
@@ -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<Address, (HashMap<StorageKey, U256>, Account)>,
|
||||
contracts: HashMap<H256, Bytes>,
|
||||
contracts: HashMap<H256, Bytecode>,
|
||||
block_hash: HashMap<U256, H256>,
|
||||
}
|
||||
|
||||
@@ -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<Option<Bytes>> {
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> reth_interfaces::Result<Option<Bytecode>> {
|
||||
Ok(self.contracts.get(&code_hash).cloned())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::<BigEndian>().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::<BigEndian>().unwrap() as usize,
|
||||
None,
|
||||
)
|
||||
}),
|
||||
2 => Bytecode(RevmBytecode {
|
||||
bytecode: bytes,
|
||||
hash: KECCAK_EMPTY,
|
||||
state: BytecodeState::Analysed {
|
||||
len: buf.read_u64::<BigEndian>().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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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::{
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
))]
|
||||
|
||||
//! revm utils and implementations specific to reth.
|
||||
|
||||
pub mod config;
|
||||
|
||||
/// Helpers for configuring revm [Env](revm::primitives::Env)
|
||||
|
||||
@@ -49,19 +49,9 @@ impl<DB: StateProvider> DatabaseRef for State<DB> {
|
||||
fn code_by_hash(&self, code_hash: H256) -> Result<Bytecode, Self::Error> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BlockId>) -> EthResult<U256> {
|
||||
|
||||
@@ -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::<tables::Bytecodes>(code_hash, code.to_vec()).unwrap();
|
||||
db_tx.put::<tables::Bytecodes>(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::<tables::PlainAccountState>(acc1, acc1_info).unwrap();
|
||||
db_tx.put::<tables::PlainAccountState>(acc2, acc2_info).unwrap();
|
||||
db_tx.put::<tables::Bytecodes>(code_hash, code.to_vec()).unwrap();
|
||||
db_tx.put::<tables::Bytecodes>(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::<tables::PlainAccountState>(caller_address, caller_info).unwrap();
|
||||
db_tx.put::<tables::PlainAccountState>(destroyed_address, destroyed_info).unwrap();
|
||||
db_tx.put::<tables::Bytecodes>(code_hash, code.to_vec()).unwrap();
|
||||
db_tx.put::<tables::Bytecodes>(code_hash, Bytecode::new_raw(code.to_vec().into())).unwrap();
|
||||
// set storage to check when account gets destroyed.
|
||||
db_tx
|
||||
.put::<tables::PlainStorageState>(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<u8>;
|
||||
//
|
||||
// TODO: Temporary types, until they're properly defined alongside with the Encode and Decode Trait
|
||||
//
|
||||
|
||||
/// Temporary placeholder type for DB.
|
||||
pub type Bytecode = Vec<u8>;
|
||||
|
||||
@@ -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<Option<Bytes>> {
|
||||
self.tx.get::<tables::Bytecodes>(code_hash).map_err(Into::into).map(|r| r.map(Bytes::from))
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> Result<Option<Bytecode>> {
|
||||
self.tx.get::<tables::Bytecodes>(code_hash).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Option<Bytes>> {
|
||||
self.db.get::<tables::Bytecodes>(code_hash).map_err(Into::into).map(|r| r.map(Bytes::from))
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> Result<Option<Bytecode>> {
|
||||
self.db.get::<tables::Bytecodes>(code_hash).map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Option<reth_primitives::StorageValue>>;
|
||||
fn bytecode_by_hash(&self, code_hash: reth_primitives::H256) -> reth_interfaces::Result<Option<reth_primitives::Bytes>>;
|
||||
fn bytecode_by_hash(&self, code_hash: reth_primitives::H256) -> reth_interfaces::Result<Option<reth_primitives::Bytecode>>;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<Bytes>,
|
||||
bytecode: Option<Bytecode>,
|
||||
storage: HashMap<StorageKey, StorageValue>,
|
||||
}
|
||||
|
||||
@@ -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<Option<Bytes>> {
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> Result<Option<Bytecode>> {
|
||||
let lock = self.accounts.lock();
|
||||
Ok(lock.values().find_map(|account| {
|
||||
match (account.account.bytecode_hash.as_ref(), account.bytecode.as_ref()) {
|
||||
|
||||
@@ -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<Option<Bytes>> {
|
||||
fn bytecode_by_hash(&self, _code_hash: H256) -> Result<Option<Bytecode>> {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Option<StorageValue>>;
|
||||
|
||||
/// Get account code by its hash
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> Result<Option<Bytes>>;
|
||||
fn bytecode_by_hash(&self, code_hash: H256) -> Result<Option<Bytecode>>;
|
||||
|
||||
/// 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<Option<Bytes>> {
|
||||
fn account_code(&self, addr: Address) -> Result<Option<Bytecode>> {
|
||||
// Get basic account information
|
||||
// Returns None if acc doesn't exist
|
||||
let acc = match self.basic_account(addr)? {
|
||||
|
||||
@@ -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::<tables::Bytecodes>(hash, bytecode[..bytecode.len()].to_vec())?;
|
||||
|
||||
let bytes = bytecode.bytes();
|
||||
trace!(target: "sync::stages::execution", ?hash, ?bytes, len = bytes.len(), "Inserting bytecode");
|
||||
self.put::<tables::Bytecodes>(hash, Bytecode(bytecode))?;
|
||||
// NOTE: bytecode bytes are not inserted in change set and can be found in
|
||||
// separate table
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user