mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
perf: reduce overhead with open state (#5416)
This commit is contained in:
@ -329,15 +329,11 @@ where
|
|||||||
F: FnOnce(StateProviderBox<'_>) -> EthResult<T> + Send + 'static,
|
F: FnOnce(StateProviderBox<'_>) -> EthResult<T> + Send + 'static,
|
||||||
T: Send + 'static,
|
T: Send + 'static,
|
||||||
{
|
{
|
||||||
let this = self.clone();
|
self.spawn_tracing_task_with(move |this| {
|
||||||
self.inner
|
let state = this.state_at(at)?;
|
||||||
.blocking_task_pool
|
f(state)
|
||||||
.spawn(move || {
|
})
|
||||||
let state = this.state_at(at)?;
|
.await
|
||||||
f(state)
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
.map_err(|_| EthApiError::InternalBlockingTaskError)?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
|
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
|
||||||
@ -803,34 +799,48 @@ where
|
|||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
// we need to get the state of the parent block because we're replaying this block on top of
|
|
||||||
// its parent block's state
|
|
||||||
let state_at = block.parent_hash;
|
|
||||||
|
|
||||||
let block_hash = block.hash;
|
|
||||||
let transactions = block.body;
|
|
||||||
|
|
||||||
// replay all transactions of the block
|
// replay all transactions of the block
|
||||||
self.spawn_with_state_at_block(state_at.into(), move |state| {
|
self.spawn_tracing_task_with(move |this| {
|
||||||
|
// we need to get the state of the parent block because we're replaying this block on
|
||||||
|
// top of its parent block's state
|
||||||
|
let state_at = block.parent_hash;
|
||||||
|
let block_hash = block.hash;
|
||||||
|
|
||||||
|
let block_number = block_env.number.saturating_to::<u64>();
|
||||||
|
let base_fee = block_env.basefee.saturating_to::<u64>();
|
||||||
|
|
||||||
|
// prepare transactions, we do everything upfront to reduce time spent with open state
|
||||||
|
let max_transactions =
|
||||||
|
highest_index.map_or(block.body.len(), |highest| highest as usize);
|
||||||
|
let transactions = block
|
||||||
|
.body
|
||||||
|
.into_iter()
|
||||||
|
.take(max_transactions)
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, tx)| -> EthResult<_> {
|
||||||
|
let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?;
|
||||||
|
let tx_info = TransactionInfo {
|
||||||
|
hash: Some(tx.hash()),
|
||||||
|
index: Some(idx as u64),
|
||||||
|
block_hash: Some(block_hash),
|
||||||
|
block_number: Some(block_number),
|
||||||
|
base_fee: Some(base_fee),
|
||||||
|
};
|
||||||
|
let tx_env = tx_env_with_recovered(&tx);
|
||||||
|
|
||||||
|
Ok((tx_info, tx_env))
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
let mut results = Vec::with_capacity(transactions.len());
|
let mut results = Vec::with_capacity(transactions.len());
|
||||||
|
|
||||||
|
// now get the state
|
||||||
|
let state = this.state_at(state_at.into())?;
|
||||||
let mut db = CacheDB::new(StateProviderDatabase::new(state));
|
let mut db = CacheDB::new(StateProviderDatabase::new(state));
|
||||||
|
|
||||||
let max_transactions =
|
let mut transactions = transactions.into_iter().peekable();
|
||||||
highest_index.map_or(transactions.len(), |highest| highest as usize);
|
|
||||||
let mut transactions =
|
|
||||||
transactions.into_iter().take(max_transactions).enumerate().peekable();
|
|
||||||
|
|
||||||
while let Some((idx, tx)) = transactions.next() {
|
while let Some((tx_info, tx)) = transactions.next() {
|
||||||
let tx = tx.into_ecrecovered().ok_or(BlockError::InvalidSignature)?;
|
|
||||||
let tx_info = TransactionInfo {
|
|
||||||
hash: Some(tx.hash()),
|
|
||||||
index: Some(idx as u64),
|
|
||||||
block_hash: Some(block_hash),
|
|
||||||
block_number: Some(block_env.number.try_into().unwrap_or(u64::MAX)),
|
|
||||||
base_fee: Some(block_env.basefee.try_into().unwrap_or(u64::MAX)),
|
|
||||||
};
|
|
||||||
|
|
||||||
let tx = tx_env_with_recovered(&tx);
|
|
||||||
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
||||||
|
|
||||||
let mut inspector = TracingInspector::new(config);
|
let mut inspector = TracingInspector::new(config);
|
||||||
@ -856,6 +866,28 @@ where
|
|||||||
|
|
||||||
// === impl EthApi ===
|
// === impl EthApi ===
|
||||||
|
|
||||||
|
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||||
|
where
|
||||||
|
Pool: TransactionPool + Clone + 'static,
|
||||||
|
Provider:
|
||||||
|
BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static,
|
||||||
|
Network: NetworkInfo + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
/// Spawns the given closure on a new blocking tracing task
|
||||||
|
async fn spawn_tracing_task_with<F, T>(&self, f: F) -> EthResult<T>
|
||||||
|
where
|
||||||
|
F: FnOnce(Self) -> EthResult<T> + Send + 'static,
|
||||||
|
T: Send + 'static,
|
||||||
|
{
|
||||||
|
let this = self.clone();
|
||||||
|
self.inner
|
||||||
|
.blocking_task_pool
|
||||||
|
.spawn(move || f(this))
|
||||||
|
.await
|
||||||
|
.map_err(|_| EthApiError::InternalBlockingTaskError)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
impl<Provider, Pool, Network> EthApi<Provider, Pool, Network>
|
||||||
where
|
where
|
||||||
Provider:
|
Provider:
|
||||||
|
|||||||
Reference in New Issue
Block a user