Skip to content

Commit cd521ce

Browse files
authored
perf: remove some clones around eth_call (#16665)
1 parent 717449b commit cd521ce

File tree

3 files changed

+44
-64
lines changed

3 files changed

+44
-64
lines changed

crates/rpc/rpc-eth-api/src/helpers/call.rs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
215215
overrides: EvmOverrides,
216216
) -> impl Future<Output = Result<Bytes, Self::Error>> + Send {
217217
async move {
218-
let (res, _env) =
218+
let res =
219219
self.transact_call_at(request, block_number.unwrap_or_default(), overrides).await?;
220220

221221
ensure_success(res.result)
@@ -288,7 +288,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
288288
let block_transactions = block.transactions_recovered().take(num_txs);
289289
for tx in block_transactions {
290290
let tx_env = RpcNodeCore::evm_config(&this).tx_env(tx);
291-
let (res, _) = this.transact(&mut db, evm_env.clone(), tx_env)?;
291+
let res = this.transact(&mut db, evm_env.clone(), tx_env)?;
292292
db.commit(res.state);
293293
}
294294
}
@@ -313,7 +313,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
313313

314314
let (current_evm_env, prepared_tx) =
315315
this.prepare_call_env(evm_env.clone(), tx, &mut db, overrides)?;
316-
let (res, _) = this.transact(&mut db, current_evm_env, prepared_tx)?;
316+
let res = this.transact(&mut db, current_evm_env, prepared_tx)?;
317317

318318
match ensure_success::<_, Self::Error>(res.result) {
319319
Ok(output) => {
@@ -426,11 +426,11 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
426426
};
427427

428428
// transact again to get the exact gas used
429-
let (result, (_, tx_env)) = self.transact(&mut db, evm_env, tx_env)?;
429+
let gas_limit = tx_env.gas_limit();
430+
let result = self.transact(&mut db, evm_env, tx_env)?;
430431
let res = match result.result {
431432
ExecutionResult::Halt { reason, gas_used } => {
432-
let error =
433-
Some(Self::Error::from_evm_halt(reason, tx_env.gas_limit()).to_string());
433+
let error = Some(Self::Error::from_evm_halt(reason, gas_limit).to_string());
434434
AccessListResult { access_list, gas_used: U256::from(gas_used), error }
435435
}
436436
ExecutionResult::Revert { output, gas_used } => {
@@ -477,61 +477,47 @@ pub trait Call:
477477

478478
/// Executes the `TxEnv` against the given [Database] without committing state
479479
/// changes.
480-
#[expect(clippy::type_complexity)]
481480
fn transact<DB>(
482481
&self,
483482
db: DB,
484483
evm_env: EvmEnvFor<Self::Evm>,
485484
tx_env: TxEnvFor<Self::Evm>,
486-
) -> Result<
487-
(ResultAndState<HaltReasonFor<Self::Evm>>, (EvmEnvFor<Self::Evm>, TxEnvFor<Self::Evm>)),
488-
Self::Error,
489-
>
485+
) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
490486
where
491487
DB: Database<Error = ProviderError>,
492488
{
493-
let mut evm = self.evm_config().evm_with_env(db, evm_env.clone());
494-
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
489+
let mut evm = self.evm_config().evm_with_env(db, evm_env);
490+
let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
495491

496-
Ok((res, (evm_env, tx_env)))
492+
Ok(res)
497493
}
498494

499495
/// Executes the [`EvmEnv`] against the given [Database] without committing state
500496
/// changes.
501-
#[expect(clippy::type_complexity)]
502497
fn transact_with_inspector<DB, I>(
503498
&self,
504499
db: DB,
505500
evm_env: EvmEnvFor<Self::Evm>,
506501
tx_env: TxEnvFor<Self::Evm>,
507502
inspector: I,
508-
) -> Result<
509-
(ResultAndState<HaltReasonFor<Self::Evm>>, (EvmEnvFor<Self::Evm>, TxEnvFor<Self::Evm>)),
510-
Self::Error,
511-
>
503+
) -> Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>
512504
where
513505
DB: Database<Error = ProviderError>,
514506
I: InspectorFor<Self::Evm, DB>,
515507
{
516-
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env.clone(), inspector);
517-
let res = evm.transact(tx_env.clone()).map_err(Self::Error::from_evm_err)?;
508+
let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector);
509+
let res = evm.transact(tx_env).map_err(Self::Error::from_evm_err)?;
518510

519-
Ok((res, (evm_env, tx_env)))
511+
Ok(res)
520512
}
521513

522514
/// Executes the call request at the given [`BlockId`].
523-
#[expect(clippy::type_complexity)]
524515
fn transact_call_at(
525516
&self,
526517
request: TransactionRequest,
527518
at: BlockId,
528519
overrides: EvmOverrides,
529-
) -> impl Future<
530-
Output = Result<
531-
(ResultAndState<HaltReasonFor<Self::Evm>>, (EvmEnvFor<Self::Evm>, TxEnvFor<Self::Evm>)),
532-
Self::Error,
533-
>,
534-
> + Send
520+
) -> impl Future<Output = Result<ResultAndState<HaltReasonFor<Self::Evm>>, Self::Error>> + Send
535521
where
536522
Self: LoadPendingBlock,
537523
{
@@ -655,7 +641,7 @@ pub trait Call:
655641

656642
let tx_env = RpcNodeCore::evm_config(&this).tx_env(tx);
657643

658-
let (res, _) = this.transact(&mut db, evm_env, tx_env)?;
644+
let res = this.transact(&mut db, evm_env, tx_env)?;
659645
f(tx_info, res, db)
660646
})
661647
.await

crates/rpc/rpc-eth-api/src/helpers/estimate.rs

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub trait EstimateCall: Call {
9494
// with the minimum gas limit to make sure.
9595
let mut tx_env = tx_env.clone();
9696
tx_env.set_gas_limit(MIN_TRANSACTION_GAS);
97-
if let Ok((res, _)) = self.transact(&mut db, evm_env.clone(), tx_env) {
97+
if let Ok(res) = self.transact(&mut db, evm_env.clone(), tx_env) {
9898
if res.result.is_success() {
9999
return Ok(U256::from(MIN_TRANSACTION_GAS))
100100
}
@@ -119,36 +119,30 @@ pub trait EstimateCall: Call {
119119
trace!(target: "rpc::eth::estimate", ?evm_env, ?tx_env, "Starting gas estimation");
120120

121121
// Execute the transaction with the highest possible gas limit.
122-
let (mut res, (mut evm_env, mut tx_env)) =
123-
match self.transact(&mut db, evm_env.clone(), tx_env.clone()) {
124-
// Handle the exceptional case where the transaction initialization uses too much
125-
// gas. If the gas price or gas limit was specified in the request,
126-
// retry the transaction with the block's gas limit to determine if
127-
// the failure was due to insufficient gas.
128-
Err(err)
129-
if err.is_gas_too_high() &&
130-
(tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) =>
131-
{
132-
return Err(self.map_out_of_gas_err(
133-
block_env_gas_limit,
134-
evm_env,
135-
tx_env,
136-
&mut db,
137-
))
138-
}
139-
Err(err) if err.is_gas_too_low() => {
140-
// This failed because the configured gas cost of the tx was lower than what
141-
// actually consumed by the tx This can happen if the
142-
// request provided fee values manually and the resulting gas cost exceeds the
143-
// sender's allowance, so we return the appropriate error here
144-
return Err(RpcInvalidTransactionError::GasRequiredExceedsAllowance {
145-
gas_limit: tx_env.gas_limit(),
146-
}
147-
.into_eth_err())
122+
let mut res = match self.transact(&mut db, evm_env.clone(), tx_env.clone()) {
123+
// Handle the exceptional case where the transaction initialization uses too much
124+
// gas. If the gas price or gas limit was specified in the request,
125+
// retry the transaction with the block's gas limit to determine if
126+
// the failure was due to insufficient gas.
127+
Err(err)
128+
if err.is_gas_too_high() &&
129+
(tx_request_gas_limit.is_some() || tx_request_gas_price.is_some()) =>
130+
{
131+
return Err(self.map_out_of_gas_err(block_env_gas_limit, evm_env, tx_env, &mut db))
132+
}
133+
Err(err) if err.is_gas_too_low() => {
134+
// This failed because the configured gas cost of the tx was lower than what
135+
// actually consumed by the tx This can happen if the
136+
// request provided fee values manually and the resulting gas cost exceeds the
137+
// sender's allowance, so we return the appropriate error here
138+
return Err(RpcInvalidTransactionError::GasRequiredExceedsAllowance {
139+
gas_limit: tx_env.gas_limit(),
148140
}
149-
// Propagate other results (successful or other errors).
150-
ethres => ethres?,
151-
};
141+
.into_eth_err())
142+
}
143+
// Propagate other results (successful or other errors).
144+
ethres => ethres?,
145+
};
152146

153147
let gas_refund = match res.result {
154148
ExecutionResult::Success { gas_refunded, .. } => gas_refunded,
@@ -194,7 +188,7 @@ pub trait EstimateCall: Call {
194188
tx_env.set_gas_limit(optimistic_gas_limit);
195189
// Re-execute the transaction with the new gas limit and update the result and
196190
// environment.
197-
(res, (evm_env, tx_env)) = self.transact(&mut db, evm_env, tx_env)?;
191+
res = self.transact(&mut db, evm_env.clone(), tx_env.clone())?;
198192
// Update the gas used based on the new result.
199193
gas_used = res.result.gas_used();
200194
// Update the gas limit estimates (highest and lowest) based on the execution result.
@@ -241,7 +235,7 @@ pub trait EstimateCall: Call {
241235
// Handle other cases, including successful transactions.
242236
ethres => {
243237
// Unpack the result and environment if the transaction was successful.
244-
(res, (evm_env, tx_env)) = ethres?;
238+
res = ethres?;
245239
// Update the estimated gas range based on the transaction result.
246240
update_estimated_gas_range(
247241
res.result,
@@ -296,7 +290,7 @@ pub trait EstimateCall: Call {
296290
{
297291
let req_gas_limit = tx_env.gas_limit();
298292
tx_env.set_gas_limit(env_gas_limit);
299-
let (res, _) = match self.transact(db, evm_env, tx_env) {
293+
let res = match self.transact(db, evm_env, tx_env) {
300294
Ok(res) => res,
301295
Err(err) => return err,
302296
};

crates/rpc/rpc/src/debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ where
528528
// Execute all transactions until index
529529
for tx in transactions {
530530
let tx_env = this.eth_api().evm_config().tx_env(tx);
531-
let (res, _) = this.eth_api().transact(&mut db, evm_env.clone(), tx_env)?;
531+
let res = this.eth_api().transact(&mut db, evm_env.clone(), tx_env)?;
532532
db.commit(res.state);
533533
}
534534
}

0 commit comments

Comments
 (0)