mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: reduce number of Evm monomorphizations (#8030)
This commit is contained in:
@ -61,10 +61,13 @@ impl CachedReads {
|
||||
}
|
||||
}
|
||||
|
||||
/// A [Database] that caches reads inside [CachedReads].
|
||||
#[derive(Debug)]
|
||||
struct CachedReadsDbMut<'a, DB> {
|
||||
cached: &'a mut CachedReads,
|
||||
db: DB,
|
||||
pub struct CachedReadsDbMut<'a, DB> {
|
||||
/// The cache of reads.
|
||||
pub cached: &'a mut CachedReads,
|
||||
/// The underlying database.
|
||||
pub db: DB,
|
||||
}
|
||||
|
||||
impl<'a, DB: DatabaseRef> Database for CachedReadsDbMut<'a, DB> {
|
||||
@ -126,7 +129,8 @@ impl<'a, DB: DatabaseRef> Database for CachedReadsDbMut<'a, DB> {
|
||||
/// `revm::db::State` for repeated payload build jobs.
|
||||
#[derive(Debug)]
|
||||
pub struct CachedReadsDBRef<'a, DB> {
|
||||
inner: RefCell<CachedReadsDbMut<'a, DB>>,
|
||||
/// The inner cache reads db mut.
|
||||
pub inner: RefCell<CachedReadsDbMut<'a, DB>>,
|
||||
}
|
||||
|
||||
impl<'a, DB: DatabaseRef> DatabaseRef for CachedReadsDBRef<'a, DB> {
|
||||
|
||||
@ -73,36 +73,54 @@ where
|
||||
debug!(target: "payload_builder", parent_hash = ?parent_block.hash(), parent_number = parent_block.number, "building empty payload");
|
||||
|
||||
let state = client.state_by_block_hash(parent_block.hash()).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to get state for empty payload");
|
||||
err
|
||||
})?;
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to get state for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
let mut db = State::builder()
|
||||
.with_database_boxed(Box::new(StateProviderDatabase::new(&state)))
|
||||
.with_database(StateProviderDatabase::new(state))
|
||||
.with_bundle_update()
|
||||
.build();
|
||||
|
||||
let base_fee = initialized_block_env.basefee.to::<u64>();
|
||||
let block_number = initialized_block_env.number.to::<u64>();
|
||||
let block_gas_limit: u64 = initialized_block_env.gas_limit.try_into().unwrap_or(u64::MAX);
|
||||
let block_gas_limit = initialized_block_env.gas_limit.try_into().unwrap_or(u64::MAX);
|
||||
|
||||
// apply eip-4788 pre block contract call
|
||||
pre_block_beacon_root_contract_call(
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
block_number,
|
||||
&initialized_cfg,
|
||||
&initialized_block_env,
|
||||
&attributes,
|
||||
).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to apply beacon root contract call for empty payload");
|
||||
err
|
||||
})?;
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
block_number,
|
||||
&initialized_cfg,
|
||||
&initialized_block_env,
|
||||
&attributes,
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to apply beacon root contract call for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
let WithdrawalsOutcome { withdrawals_root, withdrawals } =
|
||||
commit_withdrawals(&mut db, &chain_spec, attributes.timestamp, attributes.withdrawals.clone()).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to commit withdrawals for empty payload");
|
||||
err
|
||||
})?;
|
||||
let WithdrawalsOutcome { withdrawals_root, withdrawals } = commit_withdrawals(
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
attributes.timestamp,
|
||||
attributes.withdrawals.clone(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to commit withdrawals for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
// merge all transitions into bundle state, this would apply the withdrawal balance
|
||||
// changes and 4788 contract call
|
||||
@ -110,10 +128,14 @@ where
|
||||
|
||||
// calculate the state root
|
||||
let bundle_state = db.take_bundle();
|
||||
let state_root = state.state_root(&bundle_state).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to calculate state root for empty payload");
|
||||
err
|
||||
})?;
|
||||
let state_root = db.database.state_root(&bundle_state).map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to calculate state root for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
let mut excess_blob_gas = None;
|
||||
let mut blob_gas_used = None;
|
||||
@ -178,9 +200,9 @@ where
|
||||
let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args;
|
||||
|
||||
let state_provider = client.state_by_block_hash(config.parent_block.hash())?;
|
||||
let state = StateProviderDatabase::new(&state_provider);
|
||||
let state = StateProviderDatabase::new(state_provider);
|
||||
let mut db =
|
||||
State::builder().with_database_ref(cached_reads.as_db(&state)).with_bundle_update().build();
|
||||
State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build();
|
||||
let extra_data = config.extra_data();
|
||||
let PayloadConfig {
|
||||
initialized_block_env,
|
||||
@ -349,7 +371,10 @@ where
|
||||
let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range");
|
||||
|
||||
// calculate the state root
|
||||
let state_root = state_provider.state_root(bundle.state())?;
|
||||
let state_root = {
|
||||
let state_provider = db.database.0.inner.borrow_mut();
|
||||
state_provider.db.state_root(bundle.state())?
|
||||
};
|
||||
|
||||
// create the block header
|
||||
let transactions_root = proofs::calculate_transaction_root(&executed_txs);
|
||||
|
||||
@ -123,7 +123,7 @@ where
|
||||
err
|
||||
})?;
|
||||
let mut db = State::builder()
|
||||
.with_database_boxed(Box::new(StateProviderDatabase::new(&state)))
|
||||
.with_database(StateProviderDatabase::new(state))
|
||||
.with_bundle_update()
|
||||
.build();
|
||||
|
||||
@ -133,22 +133,36 @@ where
|
||||
|
||||
// apply eip-4788 pre block contract call
|
||||
pre_block_beacon_root_contract_call(
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
block_number,
|
||||
&initialized_cfg,
|
||||
&initialized_block_env,
|
||||
&attributes,
|
||||
).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to apply beacon root contract call for empty payload");
|
||||
err
|
||||
})?;
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
block_number,
|
||||
&initialized_cfg,
|
||||
&initialized_block_env,
|
||||
&attributes,
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to apply beacon root contract call for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
let WithdrawalsOutcome { withdrawals_root, withdrawals } =
|
||||
commit_withdrawals(&mut db, &chain_spec, attributes.payload_attributes.timestamp, attributes.payload_attributes.withdrawals.clone()).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to commit withdrawals for empty payload");
|
||||
err
|
||||
})?;
|
||||
let WithdrawalsOutcome { withdrawals_root, withdrawals } = commit_withdrawals(
|
||||
&mut db,
|
||||
&chain_spec,
|
||||
attributes.payload_attributes.timestamp,
|
||||
attributes.payload_attributes.withdrawals.clone(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to commit withdrawals for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
// merge all transitions into bundle state, this would apply the withdrawal balance
|
||||
// changes and 4788 contract call
|
||||
@ -156,10 +170,14 @@ where
|
||||
|
||||
// calculate the state root
|
||||
let bundle_state = db.take_bundle();
|
||||
let state_root = state.state_root(&bundle_state).map_err(|err| {
|
||||
warn!(target: "payload_builder", parent_hash=%parent_block.hash(), %err, "failed to calculate state root for empty payload");
|
||||
err
|
||||
})?;
|
||||
let state_root = db.database.state_root(&bundle_state).map_err(|err| {
|
||||
warn!(target: "payload_builder",
|
||||
parent_hash=%parent_block.hash(),
|
||||
%err,
|
||||
"failed to calculate state root for empty payload"
|
||||
);
|
||||
err
|
||||
})?;
|
||||
|
||||
let mut excess_blob_gas = None;
|
||||
let mut blob_gas_used = None;
|
||||
@ -236,9 +254,9 @@ where
|
||||
let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args;
|
||||
|
||||
let state_provider = client.state_by_block_hash(config.parent_block.hash())?;
|
||||
let state = StateProviderDatabase::new(&state_provider);
|
||||
let state = StateProviderDatabase::new(state_provider);
|
||||
let mut db =
|
||||
State::builder().with_database_ref(cached_reads.as_db(&state)).with_bundle_update().build();
|
||||
State::builder().with_database_ref(cached_reads.as_db(state)).with_bundle_update().build();
|
||||
let extra_data = config.extra_data();
|
||||
let PayloadConfig {
|
||||
initialized_block_env,
|
||||
@ -510,7 +528,10 @@ where
|
||||
let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range");
|
||||
|
||||
// calculate the state root
|
||||
let state_root = state_provider.state_root(bundle.state())?;
|
||||
let state_root = {
|
||||
let state_provider = db.database.0.inner.borrow_mut();
|
||||
state_provider.db.state_root(bundle.state())?
|
||||
};
|
||||
|
||||
// create the block header
|
||||
let transactions_root = proofs::calculate_transaction_root(&executed_txs);
|
||||
|
||||
@ -323,14 +323,11 @@ where
|
||||
self.inner
|
||||
.eth_api
|
||||
.spawn_with_call_at(call, at, overrides, move |db, env| {
|
||||
let (res, _, db) = this.eth_api().inspect_and_return_db(
|
||||
db,
|
||||
env,
|
||||
&mut inspector,
|
||||
)?;
|
||||
let (res, _) =
|
||||
this.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
let frame = inspector
|
||||
.into_geth_builder()
|
||||
.geth_prestate_traces(&res, prestate_config, &db)?;
|
||||
.geth_prestate_traces(&res, prestate_config, db)?;
|
||||
Ok(frame)
|
||||
})
|
||||
.await?;
|
||||
@ -348,12 +345,9 @@ where
|
||||
.inner
|
||||
.eth_api
|
||||
.spawn_with_call_at(call, at, overrides, move |db, env| {
|
||||
let (res, _, db) = this.eth_api().inspect_and_return_db(
|
||||
db,
|
||||
env,
|
||||
&mut inspector,
|
||||
)?;
|
||||
let frame = inspector.try_into_mux_frame(&res, &db)?;
|
||||
let (res, _) =
|
||||
this.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
let frame = inspector.try_into_mux_frame(&res, db)?;
|
||||
Ok(frame.into())
|
||||
})
|
||||
.await?;
|
||||
@ -370,12 +364,9 @@ where
|
||||
.eth_api
|
||||
.spawn_with_call_at(call, at, overrides, move |db, env| {
|
||||
let mut inspector = JsInspector::new(code, config)?;
|
||||
let (res, _, db) = this.eth_api().inspect_and_return_db(
|
||||
db,
|
||||
env.clone(),
|
||||
&mut inspector,
|
||||
)?;
|
||||
Ok(inspector.json_result(res, &env, &db)?)
|
||||
let (res, _) =
|
||||
this.eth_api().inspect(&mut *db, env.clone(), &mut inspector)?;
|
||||
Ok(inspector.json_result(res, &env, db)?)
|
||||
})
|
||||
.await?;
|
||||
|
||||
@ -564,8 +555,7 @@ where
|
||||
let mut inspector = TracingInspector::new(
|
||||
TracingInspectorConfig::from_geth_prestate_config(&prestate_config),
|
||||
);
|
||||
let (res, _, db) =
|
||||
self.eth_api().inspect_and_return_db(db, env, &mut inspector)?;
|
||||
let (res, _) = self.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
|
||||
let frame = inspector.into_geth_builder().geth_prestate_traces(
|
||||
&res,
|
||||
@ -585,8 +575,7 @@ where
|
||||
|
||||
let mut inspector = MuxInspector::try_from_config(mux_config)?;
|
||||
|
||||
let (res, _, db) =
|
||||
self.eth_api().inspect_and_return_db(db, env, &mut inspector)?;
|
||||
let (res, _) = self.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
let frame = inspector.try_into_mux_frame(&res, db)?;
|
||||
return Ok((frame.into(), res.state))
|
||||
}
|
||||
@ -598,8 +587,7 @@ where
|
||||
config,
|
||||
transaction_context.unwrap_or_default(),
|
||||
)?;
|
||||
let (res, env, db) =
|
||||
self.eth_api().inspect_and_return_db(db, env, &mut inspector)?;
|
||||
let (res, env) = self.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
|
||||
let state = res.state.clone();
|
||||
let result = inspector.json_result(res, &env, db)?;
|
||||
|
||||
@ -451,14 +451,14 @@ where
|
||||
&self,
|
||||
env_gas_limit: U256,
|
||||
mut env: EnvWithHandlerCfg,
|
||||
mut db: &mut CacheDB<StateProviderDatabase<S>>,
|
||||
db: &mut CacheDB<StateProviderDatabase<S>>,
|
||||
) -> EthApiError
|
||||
where
|
||||
S: StateProvider,
|
||||
{
|
||||
let req_gas_limit = env.tx.gas_limit;
|
||||
env.tx.gas_limit = env_gas_limit.try_into().unwrap_or(u64::MAX);
|
||||
let (res, _) = match self.transact(&mut db, env) {
|
||||
let (res, _) = match self.transact(db, env) {
|
||||
Ok(res) => res,
|
||||
Err(err) => return err,
|
||||
};
|
||||
|
||||
@ -52,8 +52,8 @@ impl PendingBlockEnv {
|
||||
|
||||
let parent_hash = origin.build_target_hash();
|
||||
let state_provider = client.history_by_block_hash(parent_hash)?;
|
||||
let state = StateProviderDatabase::new(&state_provider);
|
||||
let mut db = State::builder().with_database(Box::new(state)).with_bundle_update().build();
|
||||
let state = StateProviderDatabase::new(state_provider);
|
||||
let mut db = State::builder().with_database(state).with_bundle_update().build();
|
||||
|
||||
let mut cumulative_gas_used = 0;
|
||||
let mut sum_blob_gas_used = 0;
|
||||
@ -230,6 +230,7 @@ impl PendingBlockEnv {
|
||||
let logs_bloom = bundle.block_logs_bloom(block_number).expect("Block is present");
|
||||
|
||||
// calculate the state root
|
||||
let state_provider = &db.database;
|
||||
let state_root = state_provider.state_root(bundle.state())?;
|
||||
|
||||
// create the block header
|
||||
|
||||
@ -287,7 +287,7 @@ pub trait EthTransactions: Send + Sync {
|
||||
f: F,
|
||||
) -> EthResult<R>
|
||||
where
|
||||
F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
F: FnOnce(&mut StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
R: Send + 'static;
|
||||
|
||||
/// Executes the call request at the given [BlockId].
|
||||
@ -308,7 +308,7 @@ pub trait EthTransactions: Send + Sync {
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
I: Inspector<StateCacheDB> + Send + 'static;
|
||||
I: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static;
|
||||
|
||||
/// Executes the transaction on top of the given [BlockId] with a tracer configured by the
|
||||
/// config.
|
||||
@ -571,10 +571,7 @@ where
|
||||
<DB as Database>::Error: Into<EthApiError>,
|
||||
I: GetInspector<DB>,
|
||||
{
|
||||
let mut evm = self.inner.evm_config.evm_with_env_and_inspector(db, env, inspector);
|
||||
let res = evm.transact()?;
|
||||
let (_, env) = evm.into_db_and_env_with_handler_cfg();
|
||||
Ok((res, env))
|
||||
self.inspect_and_return_db(db, env, inspector).map(|(res, env, _)| (res, env))
|
||||
}
|
||||
|
||||
fn inspect_and_return_db<DB, I>(
|
||||
@ -1066,7 +1063,7 @@ where
|
||||
f: F,
|
||||
) -> EthResult<R>
|
||||
where
|
||||
F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
F: FnOnce(&mut StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (cfg, block_env, at) = self.evm_env_at(at).await?;
|
||||
@ -1085,7 +1082,7 @@ where
|
||||
&mut db,
|
||||
overrides,
|
||||
)?;
|
||||
f(db, env)
|
||||
f(&mut db, env)
|
||||
})
|
||||
.await
|
||||
.map_err(|_| EthApiError::InternalBlockingTaskError)?
|
||||
@ -1098,10 +1095,7 @@ where
|
||||
overrides: EvmOverrides,
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> {
|
||||
let this = self.clone();
|
||||
self.spawn_with_call_at(request, at, overrides, move |mut db, env| {
|
||||
this.transact(&mut db, env)
|
||||
})
|
||||
.await
|
||||
self.spawn_with_call_at(request, at, overrides, move |db, env| this.transact(db, env)).await
|
||||
}
|
||||
|
||||
async fn spawn_inspect_call_at<I>(
|
||||
@ -1112,7 +1106,7 @@ where
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
I: Inspector<StateCacheDB> + Send + 'static,
|
||||
I: for<'a> Inspector<&'a mut StateCacheDB> + Send + 'static,
|
||||
{
|
||||
let this = self.clone();
|
||||
self.spawn_with_call_at(request, at, overrides, move |db, env| {
|
||||
@ -1133,11 +1127,9 @@ where
|
||||
{
|
||||
let this = self.clone();
|
||||
self.with_state_at_block(at, |state| {
|
||||
let db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
|
||||
let mut db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let (res, _) = this.inspect(db, env, &mut inspector)?;
|
||||
|
||||
let (res, _) = this.inspect(&mut db, env, &mut inspector)?;
|
||||
f(inspector, res)
|
||||
})
|
||||
}
|
||||
@ -1155,10 +1147,9 @@ where
|
||||
{
|
||||
let this = self.clone();
|
||||
self.spawn_with_state_at_block(at, move |state| {
|
||||
let db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
let mut db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let (res, _, db) = this.inspect_and_return_db(db, env, &mut inspector)?;
|
||||
|
||||
let (res, _) = this.inspect(&mut db, env, &mut inspector)?;
|
||||
f(inspector, res, db)
|
||||
})
|
||||
.await
|
||||
|
||||
@ -278,7 +278,10 @@ pub(crate) fn create_txn_env(
|
||||
}
|
||||
|
||||
/// Caps the configured [TxEnv] `gas_limit` with the allowance of the caller.
|
||||
pub(crate) fn cap_tx_gas_limit_with_caller_allowance<DB>(db: DB, env: &mut TxEnv) -> EthResult<()>
|
||||
pub(crate) fn cap_tx_gas_limit_with_caller_allowance<DB>(
|
||||
db: &mut DB,
|
||||
env: &mut TxEnv,
|
||||
) -> EthResult<()>
|
||||
where
|
||||
DB: Database,
|
||||
EthApiError: From<<DB as Database>::Error>,
|
||||
@ -296,7 +299,7 @@ where
|
||||
///
|
||||
/// Returns an error if the caller has insufficient funds.
|
||||
/// Caution: This assumes non-zero `env.gas_price`. Otherwise, zero allowance will be returned.
|
||||
pub(crate) fn caller_gas_allowance<DB>(mut db: DB, env: &TxEnv) -> EthResult<U256>
|
||||
pub(crate) fn caller_gas_allowance<DB>(db: &mut DB, env: &TxEnv) -> EthResult<U256>
|
||||
where
|
||||
DB: Database,
|
||||
EthApiError: From<<DB as Database>::Error>,
|
||||
|
||||
@ -86,7 +86,7 @@ where
|
||||
let this = self.clone();
|
||||
self.eth_api()
|
||||
.spawn_with_call_at(trace_request.call, at, overrides, move |db, env| {
|
||||
let (res, _, db) = this.eth_api().inspect_and_return_db(db, env, &mut inspector)?;
|
||||
let (res, _) = this.eth_api().inspect(&mut *db, env, &mut inspector)?;
|
||||
let trace_res = inspector.into_parity_builder().into_trace_results_with_state(
|
||||
&res,
|
||||
&trace_request.trace_types,
|
||||
|
||||
Reference in New Issue
Block a user