From fdd6ca2706c308658f01d18b3661e258ed066acc Mon Sep 17 00:00:00 2001 From: Agost Biro Date: Mon, 14 Oct 2024 13:30:23 +0000 Subject: [PATCH 1/2] fix: remove total difficulty from block --- .changeset/tender-ties-retire.md | 5 + crates/edr_evm/src/block.rs | 41 ++---- crates/edr_evm/src/block/remote.rs | 13 +- crates/edr_evm/src/blockchain.rs | 17 +-- crates/edr_evm/src/blockchain/forked.rs | 39 +---- crates/edr_evm/src/blockchain/local.rs | 38 +---- crates/edr_evm/src/blockchain/remote.rs | 38 +---- .../src/blockchain/storage/contiguous.rs | 43 +----- .../src/blockchain/storage/reservable.rs | 20 +-- .../edr_evm/src/blockchain/storage/sparse.rs | 27 +--- crates/edr_evm/tests/blockchain.rs | 136 +++--------------- crates/edr_napi/src/subscribe.rs | 2 +- crates/edr_provider/src/data.rs | 37 ++--- crates/edr_provider/src/pending.rs | 21 +-- .../edr_provider/src/requests/eth/blocks.rs | 54 ++----- crates/edr_provider/src/subscribe.rs | 6 +- crates/edr_rpc_eth/src/block.rs | 2 - .../modules/eth/methods/getBlockByNumber.ts | 51 ------- .../provider/modules/hardhat.ts | 32 +---- 19 files changed, 95 insertions(+), 527 deletions(-) create mode 100644 .changeset/tender-ties-retire.md diff --git a/.changeset/tender-ties-retire.md b/.changeset/tender-ties-retire.md new file mode 100644 index 0000000000..1ca253474b --- /dev/null +++ b/.changeset/tender-ties-retire.md @@ -0,0 +1,5 @@ +--- +"@nomicfoundation/edr": minor +--- + +Removed total difficulty from RPC block responses following https://github.com/ethereum/execution-apis/pull/570 diff --git a/crates/edr_evm/src/block.rs b/crates/edr_evm/src/block.rs index 9e9a441842..51dd84f9a3 100644 --- a/crates/edr_evm/src/block.rs +++ b/crates/edr_evm/src/block.rs @@ -6,7 +6,7 @@ use std::{fmt::Debug, sync::Arc}; use auto_impl::auto_impl; use edr_eth::{ - block, receipt::BlockReceipt, transaction::Transaction, withdrawal::Withdrawal, B256, U256, + block, receipt::BlockReceipt, transaction::Transaction, withdrawal::Withdrawal, B256, }; pub use self::{ @@ -63,40 +63,19 @@ where { } -/// The result returned by requesting a block by number. -#[derive(Debug)] -pub struct BlockAndTotalDifficulty { - /// The block - pub block: Arc>, - /// The total difficulty with the block - pub total_difficulty: Option, -} - -impl Clone - for BlockAndTotalDifficulty -{ - fn clone(&self) -> Self { - Self { - block: self.block.clone(), - total_difficulty: self.total_difficulty, - } - } -} - impl - From> for edr_rpc_eth::Block + From<&dyn SyncBlock> for edr_rpc_eth::Block { - fn from(value: BlockAndTotalDifficulty) -> Self { - let transactions = value - .block + fn from(block: &dyn SyncBlock) -> Self { + let transactions = block .transactions() .iter() .map(|tx| *tx.transaction_hash()) .collect(); - let header = value.block.header(); + let header = block.header(); edr_rpc_eth::Block { - hash: Some(*value.block.hash()), + hash: Some(*block.hash()), parent_hash: header.parent_hash, sha3_uncles: header.ommers_hash, state_root: header.state_root, @@ -109,16 +88,14 @@ impl logs_bloom: header.logs_bloom, timestamp: header.timestamp, difficulty: header.difficulty, - total_difficulty: value.total_difficulty, - uncles: value.block.ommer_hashes().to_vec(), + uncles: block.ommer_hashes().to_vec(), transactions, - size: value.block.rlp_size(), + size: block.rlp_size(), mix_hash: Some(header.mix_hash), nonce: Some(header.nonce), base_fee_per_gas: header.base_fee_per_gas, miner: Some(header.beneficiary), - withdrawals: value - .block + withdrawals: block .withdrawals() .map(<[edr_eth::withdrawal::Withdrawal]>::to_vec), withdrawals_root: header.withdrawals_root, diff --git a/crates/edr_evm/src/block/remote.rs b/crates/edr_evm/src/block/remote.rs index d22bec6e39..9de79962ea 100644 --- a/crates/edr_evm/src/block/remote.rs +++ b/crates/edr_evm/src/block/remote.rs @@ -5,7 +5,7 @@ use edr_eth::{ receipt::BlockReceipt, transaction::{self, Transaction}, withdrawal::Withdrawal, - B256, U256, + B256, }; use edr_rpc_eth::{client::EthRpcClient, TransactionConversionError}; use tokio::runtime; @@ -126,25 +126,16 @@ where } } -/// Trait that provides access to the state root and total difficulty of an -/// Ethereum-based block. +/// Trait that provides access to the state root of an Ethereum-based block. pub trait EthRpcBlock { /// Returns the root of the block's state trie. fn state_root(&self) -> &B256; - - /// Returns the total difficulty of the chain until this block for finalised - /// blocks. For pending blocks, returns `None`. - fn total_difficulty(&self) -> Option<&U256>; } impl EthRpcBlock for edr_rpc_eth::Block { fn state_root(&self) -> &B256 { &self.state_root } - - fn total_difficulty(&self) -> Option<&U256> { - self.total_difficulty.as_ref() - } } /// Trait for types that can be converted into a remote Ethereum block. diff --git a/crates/edr_evm/src/blockchain.rs b/crates/edr_evm/src/blockchain.rs index 67221f913e..8fbbd490e9 100644 --- a/crates/edr_evm/src/blockchain.rs +++ b/crates/edr_evm/src/blockchain.rs @@ -7,9 +7,7 @@ pub mod storage; use std::{collections::BTreeMap, fmt::Debug, ops::Bound::Included, sync::Arc}; use auto_impl::auto_impl; -use edr_eth::{ - log::FilterLog, receipt::BlockReceipt, spec::HardforkActivations, Address, B256, U256, -}; +use edr_eth::{log::FilterLog, receipt::BlockReceipt, spec::HardforkActivations, Address, B256}; use revm::{ db::BlockHashRef, primitives::{HashSet, SpecId}, @@ -24,7 +22,7 @@ pub use self::{ use crate::{ chain_spec::{ChainSpec, SyncChainSpec}, state::{StateDiff, StateOverride, SyncState}, - Block, BlockAndTotalDifficulty, LocalBlock, SyncBlock, + Block, LocalBlock, SyncBlock, }; /// Combinatorial error for the blockchain API. @@ -53,7 +51,8 @@ pub enum BlockchainError { expected: B256, }, /// Missing hardfork activation history - #[error("No known hardfork for execution on historical block {block_number} (relative to fork block number {fork_block_number}) in chain with id {chain_id}. The node was not configured with a hardfork activation history.")] + #[error("No known hardfork for execution on historical block {block_number} (relative to fork block number {fork_block_number}) in chain with id {chain_id}. The node was not configured with a hardfork activation history." + )] MissingHardforkActivations { /// Block number block_number: u64, @@ -69,7 +68,8 @@ pub enum BlockchainError { #[error("Unknown block number")] UnknownBlockNumber, /// No hardfork found for block - #[error("Could not find a hardfork to run for block {block_number}, after having looked for one in the hardfork activation history, which was: {hardfork_activations:?}.")] + #[error("Could not find a hardfork to run for block {block_number}, after having looked for one in the hardfork activation history, which was: {hardfork_activations:?}." + )] UnknownBlockSpec { /// Block number block_number: u64, @@ -177,9 +177,6 @@ where // Block number -> state overrides state_overrides: &BTreeMap, ) -> Result>, Self::BlockchainError>; - - /// Retrieves the total difficulty at the block with the provided hash. - fn total_difficulty_by_hash(&self, hash: &B256) -> Result, Self::BlockchainError>; } /// Trait for implementations of a mutable Ethereum blockchain @@ -193,7 +190,7 @@ pub trait BlockchainMut { &mut self, block: LocalBlock, state_diff: StateDiff, - ) -> Result, Self::Error>; + ) -> Result>, Self::Error>; /// Reserves the provided number of blocks, starting from the next block /// number. diff --git a/crates/edr_evm/src/blockchain/forked.rs b/crates/edr_evm/src/blockchain/forked.rs index 302c617e9b..e8983bcdce 100644 --- a/crates/edr_evm/src/blockchain/forked.rs +++ b/crates/edr_evm/src/blockchain/forked.rs @@ -6,7 +6,7 @@ use edr_eth::{ log::FilterLog, receipt::BlockReceipt, spec::{chain_hardfork_activations, chain_name, HardforkActivations}, - AccountInfo, Address, BlockSpec, Bytes, B256, U256, + AccountInfo, Address, BlockSpec, Bytes, B256, }; use edr_rpc_eth::{ client::{EthRpcClient, RpcClientError}, @@ -29,8 +29,7 @@ use super::{ use crate::{ chain_spec::SyncChainSpec, state::{ForkState, IrregularState, StateDiff, StateError, StateOverride, SyncState}, - Block, BlockAndTotalDifficulty, LocalBlock, RandomHashGenerator, RemoteBlockCreationError, - SyncBlock, + Block, LocalBlock, RandomHashGenerator, RemoteBlockCreationError, SyncBlock, }; /// An error that occurs upon creation of a [`ForkedBlockchain`]. @@ -529,18 +528,6 @@ where Ok(Box::new(state)) } - - #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - fn total_difficulty_by_hash(&self, hash: &B256) -> Result, Self::BlockchainError> { - if let Some(difficulty) = self.local_storage.total_difficulty_by_hash(hash) { - Ok(Some(difficulty)) - } else { - Ok(tokio::task::block_in_place(move || { - self.runtime() - .block_on(self.remote.total_difficulty_by_hash(hash)) - })?) - } - } } impl BlockchainMut for ForkedBlockchain @@ -554,26 +541,14 @@ where &mut self, block: LocalBlock, state_diff: StateDiff, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { let last_block = self.last_block()?; validate_next_block(self.spec_id, &last_block, &block)?; - let previous_total_difficulty = self - .total_difficulty_by_hash(last_block.hash()) - .expect("No error can occur as it is stored locally") - .expect("Must exist as its block is stored"); - - let total_difficulty = previous_total_difficulty + block.header().difficulty; + let block = self.local_storage.insert_block(block, state_diff)?; - let block = self - .local_storage - .insert_block(block, state_diff, total_difficulty)?; - - Ok(BlockAndTotalDifficulty { - block: block.clone(), - total_difficulty: Some(total_difficulty), - }) + Ok(Arc::clone(block)) } #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -585,9 +560,6 @@ where }; let last_block = self.last_block()?; - let previous_total_difficulty = self - .total_difficulty_by_hash(last_block.hash())? - .expect("Must exist as its block is stored"); let last_header = last_block.header(); self.local_storage.reserve_blocks( @@ -595,7 +567,6 @@ where interval, last_header.base_fee_per_gas, last_header.state_root, - previous_total_difficulty, self.spec_id, ); diff --git a/crates/edr_evm/src/blockchain/local.rs b/crates/edr_evm/src/blockchain/local.rs index 9ba25ce6ce..0804771184 100644 --- a/crates/edr_evm/src/blockchain/local.rs +++ b/crates/edr_evm/src/blockchain/local.rs @@ -26,7 +26,7 @@ use super::{ use crate::{ chain_spec::SyncChainSpec, state::{StateDebug, StateDiff, StateError, StateOverride, SyncState, TrieState}, - Block, BlockAndTotalDifficulty, LocalBlock, SyncBlock, + Block, LocalBlock, SyncBlock, }; /// An error that occurs upon creation of a [`LocalBlockchain`]. @@ -200,12 +200,8 @@ where let genesis_block: Arc> = Arc::new(genesis_block); - let total_difficulty = genesis_block.header().difficulty; - let storage = ReservableSparseBlockchainStorage::with_genesis_block( - genesis_block, - genesis_diff, - total_difficulty, - ); + let storage = + ReservableSparseBlockchainStorage::with_genesis_block(genesis_block, genesis_diff); Self { storage, @@ -329,11 +325,6 @@ where Ok(Box::new(state)) } - - #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - fn total_difficulty_by_hash(&self, hash: &B256) -> Result, Self::BlockchainError> { - Ok(self.storage.total_difficulty_by_hash(hash)) - } } impl BlockchainMut for LocalBlockchain @@ -347,26 +338,14 @@ where &mut self, block: LocalBlock, state_diff: StateDiff, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { let last_block = self.last_block()?; validate_next_block(self.spec_id, &last_block, &block)?; - let previous_total_difficulty = self - .total_difficulty_by_hash(last_block.hash()) - .expect("No error can occur as it is stored locally") - .expect("Must exist as its block is stored"); + let block = self.storage.insert_block(block, state_diff)?; - let total_difficulty = previous_total_difficulty + block.header().difficulty; - - let block = self - .storage - .insert_block(block, state_diff, total_difficulty)?; - - Ok(BlockAndTotalDifficulty { - block: block.clone(), - total_difficulty: Some(total_difficulty), - }) + Ok(Arc::clone(block)) } #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -378,10 +357,6 @@ where }; let last_block = self.last_block()?; - let previous_total_difficulty = self - .total_difficulty_by_hash(last_block.hash())? - .expect("Must exist as its block is stored"); - let last_header = last_block.header(); self.storage.reserve_blocks( @@ -389,7 +364,6 @@ where interval, last_header.base_fee_per_gas, last_header.state_root, - previous_total_difficulty, self.spec_id, ); diff --git a/crates/edr_evm/src/blockchain/remote.rs b/crates/edr_evm/src/blockchain/remote.rs index aadc111692..49132f714f 100644 --- a/crates/edr_evm/src/blockchain/remote.rs +++ b/crates/edr_evm/src/blockchain/remote.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use async_rwlock::{RwLock, RwLockUpgradableReadGuard}; use edr_eth::{ filter::OneOrMore, log::FilterLog, receipt::BlockReceipt, Address, BlockSpec, - PreEip1898BlockSpec, B256, U256, + PreEip1898BlockSpec, B256, }; use edr_rpc_eth::client::EthRpcClient; use revm::primitives::HashSet; @@ -12,8 +12,7 @@ use tokio::runtime; use super::storage::SparseBlockchainStorage; use crate::{ blockchain::ForkedBlockchainError, chain_spec::ChainSpec, - transaction::remote::EthRpcTransaction as _, Block, EthRpcBlock as _, IntoRemoteBlock, - RemoteBlock, + transaction::remote::EthRpcTransaction as _, Block, IntoRemoteBlock, RemoteBlock, }; #[derive(Debug)] @@ -193,33 +192,6 @@ where &self.runtime } - /// Retrieves the total difficulty at the block with the provided hash. - #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub async fn total_difficulty_by_hash( - &self, - hash: &B256, - ) -> Result, ForkedBlockchainError> { - let cache = self.cache.upgradable_read().await; - - if let Some(difficulty) = cache.total_difficulty_by_hash(hash).cloned() { - Ok(Some(difficulty)) - } else if let Some(block) = self - .client - .get_block_by_hash_with_transaction_data(*hash) - .await? - { - let total_difficulty = *block - .total_difficulty() - .expect("Must be present as this is not a pending transaction"); - - self.fetch_and_cache_block(cache, block).await?; - - Ok(Some(total_difficulty)) - } else { - Ok(None) - } - } - /// Fetches detailed block information and caches the block. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] async fn fetch_and_cache_block( @@ -227,10 +199,6 @@ where cache: RwLockUpgradableReadGuard<'_, SparseBlockchainStorage>, block: ChainSpecT::RpcBlock, ) -> Result { - let total_difficulty = *block - .total_difficulty() - .expect("Must be present as this is not a pending block"); - let block: RemoteBlock = block.into_remote_block(self.client.clone(), self.runtime.clone())?; @@ -245,7 +213,7 @@ where if is_cacheable { let mut remote_cache = RwLockUpgradableReadGuard::upgrade(cache).await; - Ok(remote_cache.insert_block(block, total_difficulty)?.clone()) + Ok(remote_cache.insert_block(block)?.clone()) } else { Ok(block) } diff --git a/crates/edr_evm/src/blockchain/storage/contiguous.rs b/crates/edr_evm/src/blockchain/storage/contiguous.rs index b6f7830e30..524fa2d520 100644 --- a/crates/edr_evm/src/blockchain/storage/contiguous.rs +++ b/crates/edr_evm/src/blockchain/storage/contiguous.rs @@ -23,7 +23,6 @@ where { blocks: Vec, hash_to_block: HashMap, - total_difficulties: Vec, transaction_hash_to_block: HashMap, transaction_hash_to_receipt: HashMap>, phantom: PhantomData, @@ -82,7 +81,6 @@ where return false; } - self.total_difficulties.truncate(block_index + 1); let removed_blocks = self.blocks.split_off(block_index + 1); for block in removed_blocks { @@ -95,29 +93,6 @@ where true } - - /// Retrieves the instance's total difficulties. - pub fn total_difficulties(&self) -> &[U256] { - &self.total_difficulties - } - - /// Retrieves the total difficulty of the block with the provided hash. - pub fn total_difficulty_by_hash(&self, hash: &B256) -> Option<&U256> { - self.hash_to_block.get(hash).map(|block| { - let first_block_number = self - .blocks - .first() - .expect("A block must exist since we found one") - .header() - .number; - - let local_block_number = usize::try_from(block.header().number - first_block_number) - .expect("No blocks with a number larger than usize::MAX are inserted"); - - // SAFETY: A total difficulty is inserted for each block - unsafe { self.total_difficulties.get_unchecked(local_block_number) } - }) - } } impl ContiguousBlockchainStorage @@ -126,7 +101,7 @@ where ChainSpecT: ChainSpec, { /// Constructs a new instance with the provided block. - pub fn with_block(block: LocalBlock, total_difficulty: U256) -> Self { + pub fn with_block(block: LocalBlock) -> Self { let block_hash = *block.hash(); let transaction_hash_to_receipt = block @@ -147,7 +122,6 @@ where hash_to_block.insert(block_hash, block.clone()); Self { - total_difficulties: vec![total_difficulty], blocks: vec![block], hash_to_block, transaction_hash_to_block, @@ -157,11 +131,7 @@ where } /// Inserts a block, failing if a block with the same hash already exists. - pub fn insert_block( - &mut self, - block: LocalBlock, - total_difficulty: U256, - ) -> Result<&BlockT, InsertError> { + pub fn insert_block(&mut self, block: LocalBlock) -> Result<&BlockT, InsertError> { let block_hash = block.hash(); // As blocks are contiguous, we are guaranteed that the block number won't exist @@ -183,7 +153,7 @@ where } // SAFETY: We checked that block hash doesn't exist yet - Ok(unsafe { self.insert_block_unchecked(block, total_difficulty) }) + Ok(unsafe { self.insert_block_unchecked(block) }) } /// Inserts a block without checking its validity. @@ -192,11 +162,7 @@ where /// /// Ensure that the instance does not contain a block with the same hash, /// nor any transactions with the same hash. - pub unsafe fn insert_block_unchecked( - &mut self, - block: LocalBlock, - total_difficulty: U256, - ) -> &BlockT { + pub unsafe fn insert_block_unchecked(&mut self, block: LocalBlock) -> &BlockT { self.transaction_hash_to_receipt.extend( block .transaction_receipts() @@ -214,7 +180,6 @@ where ); self.blocks.push(block.clone()); - self.total_difficulties.push(total_difficulty); self.hash_to_block .insert_unique_unchecked(*block.hash(), block) .1 diff --git a/crates/edr_evm/src/blockchain/storage/reservable.rs b/crates/edr_evm/src/blockchain/storage/reservable.rs index 185311e2a4..0e6998b274 100644 --- a/crates/edr_evm/src/blockchain/storage/reservable.rs +++ b/crates/edr_evm/src/blockchain/storage/reservable.rs @@ -16,7 +16,6 @@ struct Reservation { interval: u64, previous_base_fee_per_gas: Option, previous_state_root: B256, - previous_total_difficulty: U256, previous_diff_index: usize, spec_id: SpecId, } @@ -47,10 +46,10 @@ where { /// Constructs a new instance with the provided block as genesis block. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub fn with_genesis_block(block: BlockT, diff: StateDiff, total_difficulty: U256) -> Self { + pub fn with_genesis_block(block: BlockT, diff: StateDiff) -> Self { Self { reservations: RwLock::new(Vec::new()), - storage: RwLock::new(SparseBlockchainStorage::with_block(block, total_difficulty)), + storage: RwLock::new(SparseBlockchainStorage::with_block(block)), state_diffs: vec![(0, diff)], number_to_diff_index: std::iter::once((0, 0)).collect(), last_block_number: 0, @@ -149,7 +148,6 @@ where interval: u64, previous_base_fee: Option, previous_state_root: B256, - previous_total_difficulty: U256, spec_id: SpecId, ) { let reservation = Reservation { @@ -158,7 +156,6 @@ where interval, previous_base_fee_per_gas: previous_base_fee, previous_state_root, - previous_total_difficulty, previous_diff_index: self.state_diffs.len() - 1, spec_id, }; @@ -223,12 +220,6 @@ where true } - - /// Retrieves the total difficulty of the block with the provided hash. - #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub fn total_difficulty_by_hash(&self, hash: &B256) -> Option { - self.storage.read().total_difficulty_by_hash(hash).cloned() - } } impl ReservableSparseBlockchainStorage @@ -251,7 +242,6 @@ where &mut self, block: LocalBlock, state_diff: StateDiff, - total_difficulty: U256, ) -> Result<&BlockT, InsertError> { self.last_block_number = block.header().number; self.number_to_diff_index @@ -264,7 +254,7 @@ where self.storage.get_mut().insert_receipts(receipts)?; - self.storage.get_mut().insert_block(block, total_difficulty) + self.storage.get_mut().insert_block(block) } #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] @@ -324,9 +314,7 @@ where { let mut storage = RwLockUpgradableReadGuard::upgrade(storage); - Ok(storage - .insert_block(block.into(), reservation.previous_total_difficulty)? - .clone()) + Ok(storage.insert_block(block.into())?.clone()) } }) .transpose() diff --git a/crates/edr_evm/src/blockchain/storage/sparse.rs b/crates/edr_evm/src/blockchain/storage/sparse.rs index 5e3b624ac2..bd098ef57a 100644 --- a/crates/edr_evm/src/blockchain/storage/sparse.rs +++ b/crates/edr_evm/src/blockchain/storage/sparse.rs @@ -4,7 +4,7 @@ use edr_eth::{ log::{matches_address_filter, matches_topics_filter}, receipt::BlockReceipt, transaction::Transaction, - Address, B256, U256, + Address, B256, }; use revm::primitives::{HashMap, HashSet}; @@ -19,7 +19,6 @@ where ChainSpecT: ChainSpec, { hash_to_block: HashMap, - hash_to_total_difficulty: HashMap, number_to_block: HashMap, transaction_hash_to_block: HashMap, transaction_hash_to_receipt: HashMap>, @@ -33,7 +32,7 @@ where { /// Constructs a new instance with the provided block. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub fn with_block(block: BlockT, total_difficulty: U256) -> Self { + pub fn with_block(block: BlockT) -> Self { let block_hash = block.hash(); let transaction_hash_to_block = block @@ -45,15 +44,11 @@ where let mut hash_to_block = HashMap::new(); hash_to_block.insert(*block_hash, block.clone()); - let mut hash_to_total_difficulty = HashMap::new(); - hash_to_total_difficulty.insert(*block_hash, total_difficulty); - let mut number_to_block = HashMap::new(); number_to_block.insert(block.header().number, block); Self { hash_to_block, - hash_to_total_difficulty, number_to_block, transaction_hash_to_block, transaction_hash_to_receipt: HashMap::new(), @@ -108,7 +103,6 @@ where let block_hash = block.hash(); self.hash_to_block.remove(block_hash); - self.hash_to_total_difficulty.remove(block_hash); for transaction in block.transactions() { let transaction_hash = transaction.transaction_hash(); @@ -119,25 +113,14 @@ where } } - /// Retrieves the total difficulty of the block with the provided hash. - #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub fn total_difficulty_by_hash(&self, hash: &B256) -> Option<&U256> { - self.hash_to_total_difficulty.get(hash) - } - /// Inserts a block. Errors if a block with the same hash or number already /// exists. #[cfg_attr(feature = "tracing", tracing::instrument(skip_all))] - pub fn insert_block( - &mut self, - block: BlockT, - total_difficulty: U256, - ) -> Result<&BlockT, InsertError> { + pub fn insert_block(&mut self, block: BlockT) -> Result<&BlockT, InsertError> { let block_hash = block.hash(); let block_header = block.header(); if self.hash_to_block.contains_key(block_hash) - || self.hash_to_total_difficulty.contains_key(block_hash) || self.number_to_block.contains_key(&block_header.number) { return Err(InsertError::DuplicateBlock { @@ -167,9 +150,6 @@ where self.hash_to_block .insert_unique_unchecked(*block_hash, block.clone()); - self.hash_to_total_difficulty - .insert_unique_unchecked(*block_hash, total_difficulty); - Ok(self .number_to_block .insert_unique_unchecked(block.header().number, block) @@ -226,7 +206,6 @@ where fn default() -> Self { Self { hash_to_block: HashMap::default(), - hash_to_total_difficulty: HashMap::default(), number_to_block: HashMap::default(), transaction_hash_to_block: HashMap::default(), transaction_hash_to_receipt: HashMap::default(), diff --git a/crates/edr_evm/tests/blockchain.rs b/crates/edr_evm/tests/blockchain.rs index bfd0f3680c..c2e18cc542 100644 --- a/crates/edr_evm/tests/blockchain.rs +++ b/crates/edr_evm/tests/blockchain.rs @@ -115,27 +115,6 @@ fn create_dummy_block_with_number( create_dummy_block_with_hash(blockchain.spec_id(), number, parent_hash) } -fn create_dummy_block_with_difficulty( - blockchain: &dyn SyncBlockchain, - number: u64, - difficulty: u64, -) -> LocalBlock { - let parent_hash = *blockchain - .last_block() - .expect("Failed to retrieve last block") - .hash(); - - create_dummy_block_with_header( - blockchain.spec_id(), - PartialHeader { - number, - parent_hash, - difficulty: U256::from(difficulty), - ..PartialHeader::default() - }, - ) -} - fn create_dummy_block_with_hash( spec_id: SpecId, number: u64, @@ -209,10 +188,10 @@ fn insert_dummy_block_with_transaction( Some(Vec::new()), ); let block = blockchain.insert_block(block, StateDiff::default())?; - assert_eq!(block.block.transactions().len(), 1); + assert_eq!(block.transactions().len(), 1); Ok(DummyBlockAndTransaction { - block: block.block, + block, transaction_hash, transaction_receipt, }) @@ -232,7 +211,7 @@ async fn get_last_block() -> anyhow::Result<()> { let next_block = create_dummy_block(blockchain.as_ref()); let expected = blockchain.insert_block(next_block, StateDiff::default())?; - assert_eq!(blockchain.last_block()?.hash(), expected.block.hash()); + assert_eq!(blockchain.last_block()?.hash(), expected.hash()); } Ok(()) @@ -251,11 +230,11 @@ async fn block_by_hash_some() { assert_eq!( blockchain - .block_by_hash(expected.block.hash()) + .block_by_hash(expected.hash()) .unwrap() .unwrap() .hash(), - expected.block.hash() + expected.hash() ); } } @@ -311,11 +290,11 @@ async fn block_by_number_some() { assert_eq!( blockchain - .block_by_number(expected.block.header().number) + .block_by_number(expected.header().number) .unwrap() .unwrap() .hash(), - expected.block.hash(), + expected.hash(), ); } } @@ -431,14 +410,14 @@ async fn insert_block_multiple() -> anyhow::Result<()> { assert_eq!( blockchain - .block_by_number(one.block.header().number)? + .block_by_number(one.header().number)? .unwrap() .hash(), - one.block.hash() + one.hash() ); assert_eq!( - blockchain.block_by_hash(two.block.hash())?.unwrap().hash(), - two.block.hash() + blockchain.block_by_hash(two.hash())?.unwrap().hash(), + two.hash() ); } @@ -637,22 +616,18 @@ async fn revert_to_block_local() -> anyhow::Result<()> { ); // Blocks 1 and 2 are gone - assert!(blockchain - .block_by_number(one.block.header().number)? - .is_none()); + assert!(blockchain.block_by_number(one.header().number)?.is_none()); - assert!(blockchain - .block_by_number(two.block.header().number)? - .is_none()); + assert!(blockchain.block_by_number(two.header().number)?.is_none()); - assert!(blockchain.block_by_hash(one.block.hash())?.is_none()); - assert!(blockchain.block_by_hash(two.block.hash())?.is_none()); + assert!(blockchain.block_by_hash(one.hash())?.is_none()); + assert!(blockchain.block_by_hash(two.hash())?.is_none()); // Can insert a new block after reverting let new = create_dummy_block(blockchain.as_ref()); let new = blockchain.insert_block(new.clone(), StateDiff::default())?; - assert_eq!(blockchain.last_block()?.hash(), new.block.hash()); + assert_eq!(blockchain.last_block()?.hash(), new.hash()); } Ok(()) @@ -694,85 +669,6 @@ async fn revert_to_block_invalid_number() { } } -#[tokio::test(flavor = "multi_thread")] -#[serial] -async fn block_total_difficulty_by_hash() { - let blockchains: Vec>> = - create_dummy_blockchains().await; - - for mut blockchain in blockchains { - let last_block = blockchain.last_block().unwrap(); - let last_block_header = last_block.header(); - - let one = create_dummy_block_with_difficulty( - blockchain.as_ref(), - last_block_header.number + 1, - 1000, - ); - let one = blockchain.insert_block(one, StateDiff::default()).unwrap(); - - let two = create_dummy_block_with_difficulty( - blockchain.as_ref(), - last_block_header.number + 2, - 2000, - ); - let two = blockchain.insert_block(two, StateDiff::default()).unwrap(); - - let last_block_difficulty = blockchain - .total_difficulty_by_hash(last_block.hash()) - .unwrap() - .expect("total difficulty must exist"); - - assert_eq!( - blockchain - .total_difficulty_by_hash(one.block.hash()) - .unwrap(), - Some(last_block_difficulty + one.block.header().difficulty) - ); - - assert_eq!( - blockchain - .total_difficulty_by_hash(two.block.hash()) - .unwrap(), - Some( - last_block_difficulty - + one.block.header().difficulty - + two.block.header().difficulty - ) - ); - - blockchain - .revert_to_block(one.block.header().number) - .unwrap(); - - // Block 1 has a total difficulty - assert_eq!( - blockchain - .total_difficulty_by_hash(one.block.hash()) - .unwrap(), - Some(last_block_difficulty + one.block.header().difficulty) - ); - - // Block 2 no longer stores a total difficulty - assert!(blockchain - .total_difficulty_by_hash(two.block.hash()) - .unwrap() - .is_none()); - } -} - -#[tokio::test(flavor = "multi_thread")] -#[serial] -async fn block_total_difficulty_by_hash_invalid_hash() { - let blockchains = create_dummy_blockchains().await; - - for blockchain in blockchains { - let difficulty = blockchain.total_difficulty_by_hash(&B256::ZERO).unwrap(); - - assert!(difficulty.is_none()); - } -} - #[tokio::test(flavor = "multi_thread")] #[serial] async fn block_by_transaction_hash_local() -> anyhow::Result<()> { diff --git a/crates/edr_napi/src/subscribe.rs b/crates/edr_napi/src/subscribe.rs index 476e5747c9..7f4e6273ac 100644 --- a/crates/edr_napi/src/subscribe.rs +++ b/crates/edr_napi/src/subscribe.rs @@ -28,7 +28,7 @@ impl SubscriberCallback { let result = match ctx.value.result { edr_provider::SubscriptionEventData::Logs(logs) => ctx.env.to_js_value(&logs), edr_provider::SubscriptionEventData::NewHeads(block) => { - let block = edr_rpc_eth::Block::::from(block); + let block = edr_rpc_eth::Block::::from(block.as_ref()); ctx.env.to_js_value(&block) } edr_provider::SubscriptionEventData::NewPendingTransactions(tx_hash) => { diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index 2d00315367..1388e9c1f9 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -42,11 +42,11 @@ use edr_evm::{ }, trace::Trace, transaction::{self, SignedTransaction as _}, - Account, AccountInfo, BlobExcessGasAndPrice, Block as _, BlockAndTotalDifficulty, BlockEnv, - Bytecode, CfgEnv, CfgEnvWithHandlerCfg, DebugContext, DebugTraceConfig, - DebugTraceResultWithTraces, Eip3155AndRawTracers, EvmStorageSlot, ExecutionResult, HashMap, - HashSet, IntoRemoteBlock, MemPool, MineBlockResultAndState, OrderedTransaction, Precompile, - RandomHashGenerator, RemoteBlockCreationError, SyncBlock, TxEnv, KECCAK_EMPTY, + Account, AccountInfo, BlobExcessGasAndPrice, Block as _, BlockEnv, Bytecode, CfgEnv, + CfgEnvWithHandlerCfg, DebugContext, DebugTraceConfig, DebugTraceResultWithTraces, + Eip3155AndRawTracers, EvmStorageSlot, ExecutionResult, HashMap, HashSet, IntoRemoteBlock, + MemPool, MineBlockResultAndState, OrderedTransaction, Precompile, RandomHashGenerator, + RemoteBlockCreationError, SyncBlock, TxEnv, KECCAK_EMPTY, }; use edr_rpc_eth::{ client::{EthRpcClient, HeaderMap, RpcClientError}, @@ -1145,7 +1145,7 @@ impl ProviderData ProviderData ProviderData Result, ProviderError> { - self.blockchain - .total_difficulty_by_hash(hash) - .map_err(ProviderError::Blockchain) - } - /// Get a transaction by hash from the blockchain or from the mempool if /// it's not mined yet. pub fn transaction_by_hash( @@ -2351,9 +2339,8 @@ impl ProviderData, + block: &Arc>, ) -> Result<(), BlockchainError> { - let block = &block_and_total_difficulty.block; for (filter_id, filter) in self.filters.iter_mut() { match &mut filter.data { FilterData::Logs { criteria, logs } => { @@ -2377,9 +2364,7 @@ impl ProviderData Blockchain for BlockchainWithPending<'blockchain> .state_at_block_number(block_number, state_overrides) } } - - fn total_difficulty_by_hash(&self, hash: &B256) -> Result, Self::BlockchainError> { - if hash == self.pending_block.hash() { - let previous_total_difficulty = self - .blockchain - .total_difficulty_by_hash(&self.pending_block.header().parent_hash)? - .expect("At least one block should exist before the pending block."); - - Ok(Some( - previous_total_difficulty + self.pending_block.header().difficulty, - )) - } else { - self.blockchain.total_difficulty_by_hash(hash) - } - } } impl<'blockchain> BlockchainMut for BlockchainWithPending<'blockchain> { @@ -201,7 +186,7 @@ impl<'blockchain> BlockchainMut for BlockchainWithPending<'blockcha &mut self, _block: LocalBlock, _state_diff: StateDiff, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { panic!("Inserting blocks into a pending blockchain is not supported."); } diff --git a/crates/edr_provider/src/requests/eth/blocks.rs b/crates/edr_provider/src/requests/eth/blocks.rs index 4c5a6cc52e..eadd7aef29 100644 --- a/crates/edr_provider/src/requests/eth/blocks.rs +++ b/crates/edr_provider/src/requests/eth/blocks.rs @@ -1,9 +1,7 @@ use core::fmt::Debug; use std::sync::Arc; -use edr_eth::{ - transaction::Transaction as _, BlockSpec, PreEip1898BlockSpec, SpecId, B256, U256, U64, -}; +use edr_eth::{transaction::Transaction as _, BlockSpec, PreEip1898BlockSpec, SpecId, B256, U64}; use edr_evm::{blockchain::BlockchainError, chain_spec::L1ChainSpec, SyncBlock}; use crate::{ @@ -27,15 +25,8 @@ pub fn handle_get_block_by_hash_request Result>, ProviderError> { data.block_by_hash(&block_hash)? .map(|block| { - let total_difficulty = data.total_difficulty_by_hash(block.hash())?; let pending = false; - block_to_rpc_output( - data.spec_id(), - block, - pending, - total_difficulty, - transaction_detail_flag, - ) + block_to_rpc_output(data.spec_id(), block, pending, transaction_detail_flag) }) .transpose() } @@ -46,21 +37,9 @@ pub fn handle_get_block_by_number_request Result>, ProviderError> { block_by_number(data, &block_spec.into())? - .map( - |BlockByNumberResult { - block, - pending, - total_difficulty, - }| { - block_to_rpc_output( - data.spec_id(), - block, - pending, - total_difficulty, - transaction_detail_flag, - ) - }, - ) + .map(|BlockByNumberResult { block, pending }| { + block_to_rpc_output(data.spec_id(), block, pending, transaction_detail_flag) + }) .transpose() } @@ -94,8 +73,6 @@ struct BlockByNumberResult { pub block: Arc>, /// Whether the block is a pending block. pub pending: bool, - /// The total difficulty with the block - pub total_difficulty: Option, } fn block_by_number( @@ -105,30 +82,19 @@ fn block_by_number( validate_post_merge_block_tags(data.spec_id(), block_spec)?; match data.block_by_block_spec(block_spec) { - Ok(Some(block)) => { - let total_difficulty = data.total_difficulty_by_hash(block.hash())?; - Ok(Some(BlockByNumberResult { - block, - pending: false, - total_difficulty, - })) - } + Ok(Some(block)) => Ok(Some(BlockByNumberResult { + block, + pending: false, + })), // Pending block Ok(None) => { let result = data.mine_pending_block()?; let block: Arc> = Arc::new(result.block); - let last_block = data.last_block()?; - let previous_total_difficulty = data - .total_difficulty_by_hash(last_block.hash())? - .expect("last block has total difficulty"); - let total_difficulty = previous_total_difficulty + block.header().difficulty; - Ok(Some(BlockByNumberResult { block, pending: true, - total_difficulty: Some(total_difficulty), })) } Err(ProviderError::InvalidBlockNumberOrHash { .. }) => Ok(None), @@ -140,7 +106,6 @@ fn block_to_rpc_output( spec_id: SpecId, block: Arc>, pending: bool, - total_difficulty: Option, transaction_detail_flag: bool, ) -> Result, ProviderError> { let header = block.header(); @@ -186,7 +151,6 @@ fn block_to_rpc_output( logs_bloom: header.logs_bloom, timestamp: header.timestamp, difficulty: header.difficulty, - total_difficulty, uncles: block.ommer_hashes().to_vec(), transactions, size: block.rlp_size(), diff --git a/crates/edr_provider/src/subscribe.rs b/crates/edr_provider/src/subscribe.rs index f154a79076..b20895ba1a 100644 --- a/crates/edr_provider/src/subscribe.rs +++ b/crates/edr_provider/src/subscribe.rs @@ -1,6 +1,8 @@ +use std::sync::Arc; + use dyn_clone::DynClone; use edr_eth::{filter::LogOutput, B256, U256}; -use edr_evm::{blockchain::BlockchainError, chain_spec::L1ChainSpec, BlockAndTotalDifficulty}; +use edr_evm::{blockchain::BlockchainError, chain_spec::L1ChainSpec, SyncBlock}; /// Subscription event. #[derive(Clone, Debug)] @@ -13,7 +15,7 @@ pub struct SubscriptionEvent { #[derive(Clone, Debug)] pub enum SubscriptionEventData { Logs(Vec), - NewHeads(BlockAndTotalDifficulty), + NewHeads(Arc>), NewPendingTransactions(B256), } diff --git a/crates/edr_rpc_eth/src/block.rs b/crates/edr_rpc_eth/src/block.rs index 327236ec38..5a79c2cead 100644 --- a/crates/edr_rpc_eth/src/block.rs +++ b/crates/edr_rpc_eth/src/block.rs @@ -39,8 +39,6 @@ pub struct Block { pub timestamp: u64, /// integer of the difficulty for this blocket pub difficulty: U256, - /// integer of the total difficulty of the chain until this block - pub total_difficulty: Option, /// Array of uncle hashes #[serde(default)] pub uncles: Vec, diff --git a/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts b/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts index 922b3948f1..14545018b7 100644 --- a/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts +++ b/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts @@ -150,57 +150,6 @@ describe("Eth module", function () { await this.provider.send("eth_getTransactionByHash", [txHash]) ); }); - - it( - "should return the right block total difficulty", - isFork ? testTotalDifficultyFork : testTotalDifficulty - ); - - async function testTotalDifficultyFork(this: Context) { - const forkBlockNumber: number = rpcQuantityToNumber( - await this.provider.send("eth_blockNumber") - ); - - const forkBlock: RpcBlockOutput = await this.provider.send( - "eth_getBlockByNumber", - [numberToRpcQuantity(forkBlockNumber), false] - ); - - await sendTxToZeroAddress(this.provider); - - const block: RpcBlockOutput = await this.provider.send( - "eth_getBlockByNumber", - [numberToRpcQuantity(forkBlockNumber + 1), false] - ); - - assertQuantity( - block.totalDifficulty, - rpcQuantityToBigInt(forkBlock.totalDifficulty) + - rpcQuantityToBigInt(block.difficulty) - ); - } - - async function testTotalDifficulty(this: Context) { - const genesisBlock: RpcBlockOutput = await this.provider.send( - "eth_getBlockByNumber", - [numberToRpcQuantity(0), false] - ); - - assertQuantity(genesisBlock.totalDifficulty, 1); - assertQuantity(genesisBlock.difficulty, 1); - - await sendTxToZeroAddress(this.provider); - - const block: RpcBlockOutput = await this.provider.send( - "eth_getBlockByNumber", - [numberToRpcQuantity(1), false] - ); - - assertQuantity( - block.totalDifficulty, - rpcQuantityToNumber(block.difficulty) + 1 - ); - } }); }); }); diff --git a/hardhat-tests/test/internal/hardhat-network/provider/modules/hardhat.ts b/hardhat-tests/test/internal/hardhat-network/provider/modules/hardhat.ts index 8ac2057bd9..52040038c6 100644 --- a/hardhat-tests/test/internal/hardhat-network/provider/modules/hardhat.ts +++ b/hardhat-tests/test/internal/hardhat-network/provider/modules/hardhat.ts @@ -1256,17 +1256,14 @@ describe("Hardhat module", function () { }); }); - describe("difficulty and totalDifficulty", function () { + describe("difficulty", function () { const getBlockDifficulty = async (blockNumber: number) => { const block = await this.ctx.provider.send("eth_getBlockByNumber", [ numberToRpcQuantity(blockNumber), false, ]); - return { - difficulty: rpcQuantityToBigInt(block.difficulty), - totalDifficulty: rpcQuantityToBigInt(block.totalDifficulty), - }; + return rpcQuantityToBigInt(block.difficulty); }; it("reserved blocks should have a difficulty of 0", async function () { @@ -1280,30 +1277,7 @@ describe("Hardhat module", function () { previousBlockNumber + 10 ); - assert.equal(middleBlockDifficulty.difficulty, 0n); - }); - - it("reserved blocks should have consistent difficulty values", async function () { - const previousBlockNumber = await getLatestBlockNumber(); - - await this.provider.send("hardhat_mine", [numberToRpcQuantity(20)]); - - let previousBlockDifficulty = - await getBlockDifficulty(previousBlockNumber); - - for (let i = 1; i <= 20; i++) { - const blockDifficulty = await getBlockDifficulty( - previousBlockNumber + i - ); - - assert.equal( - blockDifficulty.totalDifficulty, - previousBlockDifficulty.totalDifficulty + - blockDifficulty.difficulty - ); - - previousBlockDifficulty = blockDifficulty; - } + assert.equal(middleBlockDifficulty, 0n); }); }); }); From 3bc7ea01f3907319130710ca1e19c3cdbf9bbe5a Mon Sep 17 00:00:00 2001 From: Agost Biro Date: Mon, 14 Oct 2024 14:40:36 +0000 Subject: [PATCH 2/2] Fix unused imports --- .../provider/modules/eth/methods/getBlockByNumber.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts b/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts index 14545018b7..2954a4b8c7 100644 --- a/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts +++ b/hardhat-tests/test/internal/hardhat-network/provider/modules/eth/methods/getBlockByNumber.ts @@ -1,7 +1,6 @@ import { assert } from "chai"; import { numberToRpcQuantity, - rpcQuantityToBigInt, rpcQuantityToNumber, } from "hardhat/internal/core/jsonrpc/types/base-types"; import { @@ -9,7 +8,6 @@ import { RpcTransactionOutput, } from "hardhat/internal/hardhat-network/provider/output"; import { DEFAULT_COINBASE } from "hardhat/internal/hardhat-network/provider/provider"; -import { Context } from "mocha"; import { workaroundWindowsCiFailures } from "../../../../../../utils/workaround-windows-ci-failures"; import { assertQuantity } from "../../../../helpers/assertions";