perf: don't execute empty blocks (#2064)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
Bjerg
2023-03-31 19:22:59 +02:00
committed by GitHub
parent 5900a7e1be
commit 8eba4cad2c
2 changed files with 15 additions and 6 deletions

View File

@ -381,6 +381,10 @@ where
total_difficulty: U256,
senders: Option<Vec<Address>>,
) -> Result<(PostState, u64), Error> {
// perf: do not execute empty blocks
if block.body.is_empty() {
return Ok((PostState::default(), 0))
}
let senders = self.recover_senders(&block.body, senders)?;
self.init_env(&block.header, total_difficulty);
@ -447,12 +451,14 @@ where
return Err(Error::BlockGasUsed { got: cumulative_gas_used, expected: block.gas_used })
}
// Add block rewards
let balance_increments = self.post_block_balance_increments(block, total_difficulty)?;
let mut includes_block_transition = !balance_increments.is_empty();
for (address, increment) in balance_increments.into_iter() {
self.increment_account_balance(address, increment, &mut post_state)?;
}
// Perform DAO irregular state change
if self.chain_spec.fork(Hardfork::Dao).transitions_at_block(block.number) {
includes_block_transition = true;
self.apply_dao_fork_changes(&mut post_state)?;
@ -461,7 +467,6 @@ where
if includes_block_transition {
post_state.finish_transition();
}
Ok(post_state)
}
@ -473,6 +478,10 @@ where
) -> Result<PostState, Error> {
let post_state = self.execute(block, total_difficulty, senders)?;
// TODO Before Byzantium, receipts contained state root that would mean that expensive
// operation as hashing that is needed for state root got calculated in every
// transaction This was replaced with is_success flag.
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
if self.chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) {
verify_receipt(
block.header.receipts_root,
@ -481,11 +490,6 @@ where
)?;
}
// TODO Before Byzantium, receipts contained state root that would mean that expensive
// operation as hashing that is needed for state root got calculated in every
// transaction This was replaced with is_success flag.
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
Ok(post_state)
}
}

View File

@ -16,6 +16,7 @@ use reth_primitives::{Address, Block, U256};
use reth_provider::{
post_state::PostState, BlockExecutor, ExecutorFactory, LatestStateProviderRef, Transaction,
};
use std::time::Instant;
use tracing::*;
/// The [`StageId`] of the execution stage.
@ -182,7 +183,11 @@ impl<EF: ExecutorFactory> ExecutionStage<EF> {
// put execution results to database
let first_transition_id = tx.get_block_transition(last_block)?;
let start = Instant::now();
trace!(target: "sync::stages::execution", changes = state.changes().len(), accounts = state.accounts().len(), "Writing updated state to database");
state.write_to_db(&**tx, first_transition_id)?;
trace!(target: "sync::stages::execution", took = ?Instant::now().duration_since(start), "Wrote state");
let done = !capped;
info!(target: "sync::stages::execution", stage_progress = end_block, done, "Sync iteration finished");