mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-27 16:18:08 -05:00
refactor: Add AccessList result type to eth_createAccessList (#9811)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@@ -3,6 +3,20 @@
|
||||
/// Re-export from `alloy_eips`.
|
||||
#[doc(inline)]
|
||||
pub use alloy_eips::eip2930::{AccessList, AccessListItem};
|
||||
use revm_primitives::U256;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// `AccessListResult` for handling errors from `eth_createAccessList`
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct AccessListResult {
|
||||
/// List with accounts accessed during transaction.
|
||||
pub access_list: AccessList,
|
||||
/// Estimated gas used with access list.
|
||||
pub gas_used: U256,
|
||||
/// Optional error message if the transaction failed.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -15,7 +15,7 @@ use once_cell::sync::Lazy;
|
||||
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use access_list::{AccessList, AccessListItem};
|
||||
pub use access_list::{AccessList, AccessListItem, AccessListResult};
|
||||
pub use eip1559::TxEip1559;
|
||||
pub use eip2930::TxEip2930;
|
||||
pub use eip4844::TxEip4844;
|
||||
@@ -41,7 +41,7 @@ pub use tx_type::{
|
||||
};
|
||||
pub use variant::TransactionSignedVariant;
|
||||
|
||||
mod access_list;
|
||||
pub(crate) mod access_list;
|
||||
mod compat;
|
||||
mod eip1559;
|
||||
mod eip2930;
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
|
||||
use alloy_dyn_abi::TypedData;
|
||||
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
|
||||
use reth_primitives::{Account, Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64};
|
||||
use reth_primitives::{
|
||||
transaction::AccessListResult, Account, Address, BlockId, BlockNumberOrTag, Bytes, B256, B64,
|
||||
U256, U64,
|
||||
};
|
||||
use reth_rpc_server_types::{result::internal_rpc_err, ToRpcResult};
|
||||
use reth_rpc_types::{
|
||||
serde_helpers::JsonStorageKey,
|
||||
state::{EvmOverrides, StateOverride},
|
||||
AccessListWithGasUsed, AnyTransactionReceipt, BlockOverrides, Bundle,
|
||||
EIP1186AccountProofResponse, EthCallResponse, FeeHistory, Header, Index, RichBlock,
|
||||
StateContext, SyncStatus, Transaction, TransactionRequest, Work,
|
||||
AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse,
|
||||
FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction,
|
||||
TransactionRequest, Work,
|
||||
};
|
||||
use tracing::trace;
|
||||
|
||||
@@ -229,7 +232,7 @@ pub trait EthApi {
|
||||
&self,
|
||||
request: TransactionRequest,
|
||||
block_number: Option<BlockId>,
|
||||
) -> RpcResult<AccessListWithGasUsed>;
|
||||
) -> RpcResult<AccessListResult>;
|
||||
|
||||
/// Generates and returns an estimate of how much gas is necessary to allow the transaction to
|
||||
/// complete.
|
||||
@@ -594,7 +597,7 @@ where
|
||||
&self,
|
||||
request: TransactionRequest,
|
||||
block_number: Option<BlockId>,
|
||||
) -> RpcResult<AccessListWithGasUsed> {
|
||||
) -> RpcResult<AccessListResult> {
|
||||
trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_createAccessList");
|
||||
Ok(EthCall::create_access_list_at(self, request, block_number).await?)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use reth_primitives::{
|
||||
BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, HaltReason,
|
||||
ResultAndState, TransactTo, TxEnv,
|
||||
},
|
||||
transaction::AccessListResult,
|
||||
Bytes, TransactionSignedEcRecovered, TxKind, B256, U256,
|
||||
};
|
||||
use reth_provider::{ChainSpecProvider, StateProvider};
|
||||
@@ -26,8 +27,7 @@ use reth_rpc_server_types::constants::gas_oracle::{
|
||||
};
|
||||
use reth_rpc_types::{
|
||||
state::{EvmOverrides, StateOverride},
|
||||
AccessListWithGasUsed, BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo,
|
||||
TransactionRequest,
|
||||
BlockId, Bundle, EthCallResponse, StateContext, TransactionInfo, TransactionRequest,
|
||||
};
|
||||
use revm::{Database, DatabaseCommit};
|
||||
use revm_inspectors::access_list::AccessListInspector;
|
||||
@@ -179,13 +179,13 @@ pub trait EthCall: Call + LoadPendingBlock {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates [`AccessListWithGasUsed`] for the [`TransactionRequest`] at the given
|
||||
/// Creates [`AccessListResult`] for the [`TransactionRequest`] at the given
|
||||
/// [`BlockId`], or latest block.
|
||||
fn create_access_list_at(
|
||||
&self,
|
||||
request: TransactionRequest,
|
||||
block_number: Option<BlockId>,
|
||||
) -> impl Future<Output = Result<AccessListWithGasUsed, Self::Error>> + Send
|
||||
) -> impl Future<Output = Result<AccessListResult, Self::Error>> + Send
|
||||
where
|
||||
Self: Trace,
|
||||
{
|
||||
@@ -200,7 +200,7 @@ pub trait EthCall: Call + LoadPendingBlock {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates [`AccessListWithGasUsed`] for the [`TransactionRequest`] at the given
|
||||
/// Creates [`AccessListResult`] for the [`TransactionRequest`] at the given
|
||||
/// [`BlockId`].
|
||||
fn create_access_list_with(
|
||||
&self,
|
||||
@@ -208,7 +208,7 @@ pub trait EthCall: Call + LoadPendingBlock {
|
||||
block: BlockEnv,
|
||||
at: BlockId,
|
||||
mut request: TransactionRequest,
|
||||
) -> Result<AccessListWithGasUsed, Self::Error>
|
||||
) -> Result<AccessListResult, Self::Error>
|
||||
where
|
||||
Self: Trace,
|
||||
{
|
||||
@@ -246,21 +246,22 @@ pub trait EthCall: Call + LoadPendingBlock {
|
||||
|
||||
let precompiles = get_precompiles(env.handler_cfg.spec_id);
|
||||
let mut inspector = AccessListInspector::new(initial, from, to, precompiles);
|
||||
|
||||
let (result, env) = self.inspect(&mut db, env, &mut inspector)?;
|
||||
let access_list = inspector.into_access_list();
|
||||
|
||||
match result.result {
|
||||
ExecutionResult::Halt { reason, .. } => Err(match reason {
|
||||
HaltReason::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue,
|
||||
halt => RpcInvalidTransactionError::EvmHalt(halt),
|
||||
}),
|
||||
ExecutionResult::Revert { output, .. } => {
|
||||
Err(RpcInvalidTransactionError::Revert(RevertError::new(output)))
|
||||
ExecutionResult::Halt { reason, gas_used } => {
|
||||
let error =
|
||||
Some(RpcInvalidTransactionError::halt(reason, env.tx.gas_limit).to_string());
|
||||
return Ok(AccessListResult { access_list, gas_used: U256::from(gas_used), error })
|
||||
}
|
||||
ExecutionResult::Success { .. } => Ok(()),
|
||||
}
|
||||
.map_err(Self::Error::from_eth_err)?;
|
||||
|
||||
let access_list = inspector.into_access_list();
|
||||
ExecutionResult::Revert { output, gas_used } => {
|
||||
let error = Some(RevertError::new(output).to_string());
|
||||
return Ok(AccessListResult { access_list, gas_used: U256::from(gas_used), error })
|
||||
}
|
||||
ExecutionResult::Success { .. } => {}
|
||||
};
|
||||
|
||||
let cfg_with_spec_id =
|
||||
CfgEnvWithHandlerCfg { cfg_env: env.cfg.clone(), handler_cfg: env.handler_cfg };
|
||||
@@ -270,7 +271,7 @@ pub trait EthCall: Call + LoadPendingBlock {
|
||||
let gas_used =
|
||||
self.estimate_gas_with(cfg_with_spec_id, env.block.clone(), request, &*db.db, None)?;
|
||||
|
||||
Ok(AccessListWithGasUsed { access_list, gas_used })
|
||||
Ok(AccessListResult { access_list, gas_used, error: None })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user