mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-08 23:08:19 -05:00
Pre-calculate keccak hashes
This commit is contained in:
@@ -43,7 +43,7 @@ use reth_revm::db::State;
|
||||
use reth_storage_errors::db::DatabaseError;
|
||||
use reth_trie::{updates::TrieUpdates, HashedPostState, StateRoot, TrieInputSorted};
|
||||
use reth_trie_parallel::root::{ParallelStateRoot, ParallelStateRootError};
|
||||
use revm_primitives::Address;
|
||||
use revm_primitives::{keccak256, Address};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
panic::{self, AssertUnwindSafe},
|
||||
@@ -206,6 +206,63 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Warms the keccak cache by pre-computing hashes for transaction addresses.
|
||||
#[instrument(level = "trace", target = "engine::tree::payload_validator", skip_all)]
|
||||
fn warm_keccak_cache<T>(&self, input: &BlockOrPayload<T>)
|
||||
where
|
||||
T: PayloadTypes<BuiltPayload: BuiltPayload<Primitives = N>>,
|
||||
V: PayloadValidator<T, Block = N::Block>,
|
||||
Evm: ConfigureEngineEvm<T::ExecutionData, Primitives = N>,
|
||||
{
|
||||
use alloy_consensus::Transaction as _;
|
||||
use alloy_evm::RecoveredTx;
|
||||
use alloy_primitives::TxKind;
|
||||
use rayon::iter::ParallelIterator;
|
||||
use reth_primitives_traits::SignerRecoverable;
|
||||
|
||||
match input {
|
||||
BlockOrPayload::Payload(payload) => {
|
||||
// Get transaction bytes iterator and conversion function
|
||||
if let Ok((txs, convert)) =
|
||||
self.evm_config.tx_iterator_for_payload(payload).map(|iter| iter.into())
|
||||
{
|
||||
// Use parallel iterator to warm cache for all transactions
|
||||
use rayon::iter::IntoParallelIterator;
|
||||
txs.into_par_iter().for_each(|tx_bytes| {
|
||||
if let Ok(recovered_tx) = convert(tx_bytes) {
|
||||
// Warm cache for sender address
|
||||
let sender = recovered_tx.signer();
|
||||
let _ = keccak256(sender);
|
||||
|
||||
// Unwrap to get the inner transaction for recipient
|
||||
let tx = recovered_tx.tx();
|
||||
|
||||
// Warm cache for recipient address (skip contract creations)
|
||||
if let TxKind::Call(to) = tx.kind() {
|
||||
let _ = keccak256(to);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
BlockOrPayload::Block(block) => {
|
||||
// For blocks, transactions are already decoded
|
||||
for tx in block.body().transactions() {
|
||||
// Warm cache for sender address (skip if recovery fails)
|
||||
if let Ok(sender) = tx.recover_signer() {
|
||||
let _ = keccak256(sender);
|
||||
}
|
||||
|
||||
// Warm cache for recipient address
|
||||
if let TxKind::Call(to) = tx.kind() {
|
||||
let _ = keccak256(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns [`ExecutableTxIterator`] for the given payload or block.
|
||||
pub fn tx_iterator_for<'a, T: PayloadTypes<BuiltPayload: BuiltPayload<Primitives = N>>>(
|
||||
&'a self,
|
||||
@@ -401,6 +458,9 @@ where
|
||||
"Decided which state root algorithm to run"
|
||||
);
|
||||
|
||||
// Warm keccak cache before spawning parallel tasks
|
||||
self.warm_keccak_cache(&input);
|
||||
|
||||
// Get an iterator over the transactions in the payload
|
||||
let txs = self.tx_iterator_for(&input)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user