use reth_evm::ConfigureEvm; use reth_node_api::FullNodeComponents; use reth_primitives::{ revm_primitives::{BlockEnv, OptimismFields, TxEnv}, Bytes, TxKind, U256, }; use reth_rpc_eth_api::{ helpers::{Call, EthCall, LoadState, SpawnBlocking}, FromEthApiError, IntoEthApiError, }; use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError}; use reth_rpc_types::TransactionRequest; use crate::{OpEthApi, OpEthApiError}; impl EthCall for OpEthApi where Self: Call, N: FullNodeComponents, { } impl Call for OpEthApi where Self: LoadState + SpawnBlocking, Self::Error: From, N: FullNodeComponents, { #[inline] fn call_gas_limit(&self) -> u64 { self.inner.gas_cap() } #[inline] fn evm_config(&self) -> &impl ConfigureEvm { self.inner.evm_config() } fn create_txn_env( &self, block_env: &BlockEnv, request: TransactionRequest, ) -> Result { // Ensure that if versioned hashes are set, they're not empty if request.blob_versioned_hashes.as_ref().map_or(false, |hashes| hashes.is_empty()) { return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into_eth_err()) } let TransactionRequest { from, to, gas_price, max_fee_per_gas, max_priority_fee_per_gas, gas, value, input, nonce, access_list, chain_id, blob_versioned_hashes, max_fee_per_blob_gas, // authorization_list, .. } = request; let CallFees { max_priority_fee_per_gas, gas_price, max_fee_per_blob_gas } = CallFees::ensure_fees( gas_price.map(U256::from), max_fee_per_gas.map(U256::from), max_priority_fee_per_gas.map(U256::from), block_env.basefee, blob_versioned_hashes.as_deref(), max_fee_per_blob_gas.map(U256::from), block_env.get_blob_gasprice().map(U256::from), )?; let gas_limit = gas.unwrap_or_else(|| block_env.gas_limit.min(U256::from(u64::MAX)).to()); #[allow(clippy::needless_update)] let env = TxEnv { gas_limit: gas_limit .try_into() .map_err(|_| RpcInvalidTransactionError::GasUintOverflow) .map_err(Self::Error::from_eth_err)?, nonce, caller: from.unwrap_or_default(), gas_price, gas_priority_fee: max_priority_fee_per_gas, transact_to: to.unwrap_or(TxKind::Create), value: value.unwrap_or_default(), data: input .try_into_unique_input() .map_err(Self::Error::from_eth_err)? .unwrap_or_default(), chain_id, access_list: access_list.unwrap_or_default().into(), // EIP-4844 fields blob_hashes: blob_versioned_hashes.unwrap_or_default(), max_fee_per_blob_gas, authorization_list: Default::default(), optimism: OptimismFields { enveloped_tx: Some(Bytes::new()), ..Default::default() }, }; Ok(env) } }