Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tender-ties-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nomicfoundation/edr": minor
---

Removed total difficulty from RPC block responses following https://github.com/ethereum/execution-apis/pull/570
41 changes: 9 additions & 32 deletions crates/edr_evm/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -63,40 +63,19 @@ where
{
}

/// The result returned by requesting a block by number.
#[derive(Debug)]
pub struct BlockAndTotalDifficulty<ChainSpecT: ChainSpec, BlockchainErrorT> {
/// The block
pub block: Arc<dyn SyncBlock<ChainSpecT, Error = BlockchainErrorT>>,
/// The total difficulty with the block
pub total_difficulty: Option<U256>,
}

impl<BlockchainErrorT, ChainSpecT: ChainSpec> Clone
for BlockAndTotalDifficulty<ChainSpecT, BlockchainErrorT>
{
fn clone(&self) -> Self {
Self {
block: self.block.clone(),
total_difficulty: self.total_difficulty,
}
}
}

impl<BlockchainErrorT, ChainSpecT: ChainSpec>
From<BlockAndTotalDifficulty<ChainSpecT, BlockchainErrorT>> for edr_rpc_eth::Block<B256>
From<&dyn SyncBlock<ChainSpecT, Error = BlockchainErrorT>> for edr_rpc_eth::Block<B256>
{
fn from(value: BlockAndTotalDifficulty<ChainSpecT, BlockchainErrorT>) -> Self {
let transactions = value
.block
fn from(block: &dyn SyncBlock<ChainSpecT, Error = BlockchainErrorT>) -> 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,
Expand All @@ -109,16 +88,14 @@ impl<BlockchainErrorT, ChainSpecT: ChainSpec>
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,
Expand Down
13 changes: 2 additions & 11 deletions crates/edr_evm/src/block/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<TransactionT> EthRpcBlock for edr_rpc_eth::Block<TransactionT> {
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.
Expand Down
17 changes: 7 additions & 10 deletions crates/edr_evm/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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.
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -177,9 +177,6 @@ where
// Block number -> state overrides
state_overrides: &BTreeMap<u64, StateOverride>,
) -> Result<Box<dyn SyncState<Self::StateError>>, Self::BlockchainError>;

/// Retrieves the total difficulty at the block with the provided hash.
fn total_difficulty_by_hash(&self, hash: &B256) -> Result<Option<U256>, Self::BlockchainError>;
}

/// Trait for implementations of a mutable Ethereum blockchain
Expand All @@ -193,7 +190,7 @@ pub trait BlockchainMut<ChainSpecT: ChainSpec> {
&mut self,
block: LocalBlock<ChainSpecT>,
state_diff: StateDiff,
) -> Result<BlockAndTotalDifficulty<ChainSpecT, Self::Error>, Self::Error>;
) -> Result<Arc<dyn SyncBlock<ChainSpecT, Error = Self::Error>>, Self::Error>;

/// Reserves the provided number of blocks, starting from the next block
/// number.
Expand Down
39 changes: 5 additions & 34 deletions crates/edr_evm/src/blockchain/forked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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`].
Expand Down Expand Up @@ -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<Option<U256>, 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<ChainSpecT> BlockchainMut<ChainSpecT> for ForkedBlockchain<ChainSpecT>
Expand All @@ -554,26 +541,14 @@ where
&mut self,
block: LocalBlock<ChainSpecT>,
state_diff: StateDiff,
) -> Result<BlockAndTotalDifficulty<ChainSpecT, Self::Error>, Self::Error> {
) -> Result<Arc<dyn SyncBlock<ChainSpecT, Error = Self::Error>>, 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))]
Expand All @@ -585,17 +560,13 @@ 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(
additional,
interval,
last_header.base_fee_per_gas,
last_header.state_root,
previous_total_difficulty,
self.spec_id,
);

Expand Down
38 changes: 6 additions & 32 deletions crates/edr_evm/src/blockchain/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
Expand Down Expand Up @@ -200,12 +200,8 @@ where
let genesis_block: Arc<dyn SyncBlock<ChainSpecT, Error = BlockchainError>> =
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,
Expand Down Expand Up @@ -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<Option<U256>, Self::BlockchainError> {
Ok(self.storage.total_difficulty_by_hash(hash))
}
}

impl<ChainSpecT> BlockchainMut<ChainSpecT> for LocalBlockchain<ChainSpecT>
Expand All @@ -347,26 +338,14 @@ where
&mut self,
block: LocalBlock<ChainSpecT>,
state_diff: StateDiff,
) -> Result<BlockAndTotalDifficulty<ChainSpecT, Self::Error>, Self::Error> {
) -> Result<Arc<dyn SyncBlock<ChainSpecT, Error = Self::Error>>, 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))]
Expand All @@ -378,18 +357,13 @@ 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(
additional,
interval,
last_header.base_fee_per_gas,
last_header.state_root,
previous_total_difficulty,
self.spec_id,
);

Expand Down
Loading