refactor: Add AccessList result type to eth_createAccessList (#9811)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
c0np4nn4
2024-07-30 03:06:40 +09:00
committed by GitHub
parent 0b91e03ff4
commit f43fd7bd61
4 changed files with 44 additions and 26 deletions

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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?)
}

View File

@@ -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 })
}
}