From 926c86f8c98cdd99301378ebe864c3c9e93a2332 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 14 Jun 2024 17:12:31 +0200 Subject: [PATCH 01/16] Move EthApi trait to own crate --- Cargo.lock | 12 +++++++++- Cargo.toml | 2 ++ crates/rpc/rpc-api/Cargo.toml | 8 +++++-- crates/rpc/rpc-api/src/lib.rs | 5 ++-- crates/rpc/rpc-eth-api/Cargo.toml | 24 +++++++++++++++++++ .../src/eth.rs => rpc-eth-api/src/lib.rs} | 14 +++++++++++ 6 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 crates/rpc/rpc-eth-api/Cargo.toml rename crates/rpc/{rpc-api/src/eth.rs => rpc-eth-api/src/lib.rs} (96%) diff --git a/Cargo.lock b/Cargo.lock index 872ef282647..ab07f8aa34b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7951,9 +7951,9 @@ dependencies = [ "reth-engine-primitives", "reth-network-peers", "reth-primitives", + "reth-rpc-eth-api", "reth-rpc-types", "serde", - "serde_json", ] [[package]] @@ -8043,6 +8043,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "reth-rpc-eth-api" +version = "1.0.0-rc.1" +dependencies = [ + "jsonrpsee", + "reth-primitives", + "reth-rpc-types", + "serde_json", +] + [[package]] name = "reth-rpc-layer" version = "1.0.0-rc.1" diff --git a/Cargo.toml b/Cargo.toml index 3ee6f0a2e59..c370f2f0394 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ members = [ "crates/rpc/rpc-api/", "crates/rpc/rpc-builder/", "crates/rpc/rpc-engine-api/", + "crates/rpc/rpc-eth-api/", "crates/rpc/rpc-layer", "crates/rpc/rpc-testing-util/", "crates/rpc/rpc-types-compat/", @@ -317,6 +318,7 @@ reth-rpc-api = { path = "crates/rpc/rpc-api" } reth-rpc-api-testing-util = { path = "crates/rpc/rpc-testing-util" } reth-rpc-builder = { path = "crates/rpc/rpc-builder" } reth-rpc-engine-api = { path = "crates/rpc/rpc-engine-api" } +reth-rpc-eth-api = { path = "crates/rpc/rpc-eth-api" } reth-rpc-layer = { path = "crates/rpc/rpc-layer" } reth-rpc-server-types = { path = "crates/rpc/rpc-server-types" } reth-rpc-types = { path = "crates/rpc/rpc-types" } diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index 00581a1a16f..67665774910 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -15,13 +15,17 @@ workspace = true # reth reth-primitives.workspace = true reth-rpc-types.workspace = true +reth-rpc-eth-api.workspace = true reth-engine-primitives.workspace = true reth-network-peers.workspace = true # misc jsonrpsee = { workspace = true, features = ["server", "macros"] } -serde_json.workspace = true serde = { workspace = true, features = ["derive"] } [features] -client = ["jsonrpsee/client", "jsonrpsee/async-client"] +client = [ + "jsonrpsee/client", + "jsonrpsee/async-client", + "reth-rpc-eth-api/client" +] diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index 82af34a86d7..86eb14a230b 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -19,7 +19,6 @@ mod anvil; mod bundle; mod debug; mod engine; -mod eth; mod eth_filter; mod eth_pubsub; mod ganache; @@ -45,7 +44,6 @@ pub mod servers { bundle::{EthBundleApiServer, EthCallBundleApiServer}, debug::DebugApiServer, engine::{EngineApiServer, EngineEthApiServer}, - eth::EthApiServer, eth_filter::EthFilterApiServer, eth_pubsub::EthPubSubApiServer, mev::MevApiServer, @@ -58,6 +56,7 @@ pub mod servers { validation::BlockSubmissionValidationApiServer, web3::Web3ApiServer, }; + pub use reth_rpc_eth_api::EthApiServer; } /// re-export of all client traits @@ -73,7 +72,6 @@ pub mod clients { bundle::{EthBundleApiClient, EthCallBundleApiClient}, debug::DebugApiClient, engine::{EngineApiClient, EngineEthApiClient}, - eth::EthApiClient, eth_filter::EthFilterApiClient, ganache::GanacheApiClient, hardhat::HardhatApiClient, @@ -86,4 +84,5 @@ pub mod clients { validation::BlockSubmissionValidationApiClient, web3::Web3ApiClient, }; + pub use reth_rpc_eth_api::EthApiClient; } diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml new file mode 100644 index 00000000000..9368646eb67 --- /dev/null +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "reth-rpc-eth-api" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "Reth RPC `eth_` API implementation" + +[lints] +workspace = true + +[dependencies] +# reth +reth-rpc-types.workspace = true +reth-primitives.workspace = true + +# rpc +jsonrpsee.workspace = true +serde_json.workspace = true + +[features] +client = ["jsonrpsee/client", "jsonrpsee/async-client"] \ No newline at end of file diff --git a/crates/rpc/rpc-api/src/eth.rs b/crates/rpc/rpc-eth-api/src/lib.rs similarity index 96% rename from crates/rpc/rpc-api/src/eth.rs rename to crates/rpc/rpc-eth-api/src/lib.rs index 44b5df58a0a..fa8d4ca01cb 100644 --- a/crates/rpc/rpc-api/src/eth.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -1,3 +1,17 @@ +//! Reth RPC `eth_` API implementation +//! +//! ## Feature Flags +//! +//! - `client`: Enables JSON-RPC client support. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; use reth_rpc_types::{ From 2c78d296626d3527c4f44addf9587b967f847862 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 14 Jun 2024 17:27:21 +0200 Subject: [PATCH 02/16] Impl EthApiServer for generic type --- crates/rpc/rpc-eth-api/src/server.rs | 711 +++++++++++++++++++++++++++ 1 file changed, 711 insertions(+) create mode 100644 crates/rpc/rpc-eth-api/src/server.rs diff --git a/crates/rpc/rpc-eth-api/src/server.rs b/crates/rpc/rpc-eth-api/src/server.rs new file mode 100644 index 00000000000..d8deefc07e7 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/server.rs @@ -0,0 +1,711 @@ +//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`](crate::EthApi) trait +//! Handles RPC requests for the `eth_` namespace. + +use jsonrpsee::core::RpcResult as Result; +use reth_network_api::NetworkInfo; +use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; +use reth_rpc_types::{ + serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, + AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, + FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, TransactionRequest, Work, +}; +use serde_json::Value; +use tracing::trace; + +use reth_rpc::{ + eth::{ + api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, + error::EthApiError, + revm_utils::EvmOverrides, + EthApi, + }, + result::{internal_rpc_err, ToRpcResult}, +}; + +#[async_trait::async_trait] +impl EthApiServer for EthApi +where + Self: EthApiSpec + EthTransactions + EthBlocks + EthState + EthCall + EthFees, +{ + /// Handler for: `eth_protocolVersion` + async fn protocol_version(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_protocolVersion"); + EthApiSpec::protocol_version(self).await.to_rpc_result() + } + + /// Handler for: `eth_syncing` + fn syncing(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_syncing"); + EthApiSpec::sync_status(self).to_rpc_result() + } + + /// Handler for: `eth_coinbase` + async fn author(&self) -> Result
{ + Err(internal_rpc_err("unimplemented")) + } + + /// Handler for: `eth_accounts` + fn accounts(&self) -> Result> { + trace!(target: "rpc::eth", "Serving eth_accounts"); + Ok(EthApiSpec::accounts(self)) + } + + /// Handler for: `eth_blockNumber` + fn block_number(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_blockNumber"); + Ok(U256::from( + EthApiSpec::chain_info(self).with_message("failed to read chain info")?.best_number, + )) + } + + /// Handler for: `eth_chainId` + async fn chain_id(&self) -> Result> { + trace!(target: "rpc::eth", "Serving eth_chainId"); + Ok(Some(EthApiSpec::chain_id(self))) + } + + /// Handler for: `eth_getBlockByHash` + async fn block_by_hash(&self, hash: B256, full: bool) -> Result> { + trace!(target: "rpc::eth", ?hash, ?full, "Serving eth_getBlockByHash"); + Ok(EthBlocks::rpc_block(self, hash, full).await?) + } + + /// Handler for: `eth_getBlockByNumber` + async fn block_by_number( + &self, + number: BlockNumberOrTag, + full: bool, + ) -> Result> { + trace!(target: "rpc::eth", ?number, ?full, "Serving eth_getBlockByNumber"); + Ok(EthBlocks::rpc_block(self, number, full).await?) + } + + /// Handler for: `eth_getBlockTransactionCountByHash` + async fn block_transaction_count_by_hash(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getBlockTransactionCountByHash"); + Ok(EthBlocks::block_transaction_count(self, hash).await?.map(U256::from)) + } + + /// Handler for: `eth_getBlockTransactionCountByNumber` + async fn block_transaction_count_by_number( + &self, + number: BlockNumberOrTag, + ) -> Result> { + trace!(target: "rpc::eth", ?number, "Serving eth_getBlockTransactionCountByNumber"); + Ok(EthBlocks::block_transaction_count(self, number).await?.map(U256::from)) + } + + /// Handler for: `eth_getUncleCountByBlockHash` + async fn block_uncles_count_by_hash(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getUncleCountByBlockHash"); + Ok(EthBlocks::ommers(self, hash)?.map(|ommers| U256::from(ommers.len()))) + } + + /// Handler for: `eth_getUncleCountByBlockNumber` + async fn block_uncles_count_by_number(&self, number: BlockNumberOrTag) -> Result> { + trace!(target: "rpc::eth", ?number, "Serving eth_getUncleCountByBlockNumber"); + Ok(EthBlocks::ommers(self, number)?.map(|ommers| U256::from(ommers.len()))) + } + + /// Handler for: `eth_getBlockReceipts` + async fn block_receipts( + &self, + block_id: BlockId, + ) -> Result>> { + trace!(target: "rpc::eth", ?block_id, "Serving eth_getBlockReceipts"); + Ok(EthBlocks::block_receipts(self, block_id).await?) + } + + /// Handler for: `eth_getUncleByBlockHashAndIndex` + async fn uncle_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getUncleByBlockHashAndIndex"); + Ok(EthBlocks::ommer_by_block_and_index(self, hash, index).await?) + } + + /// Handler for: `eth_getUncleByBlockNumberAndIndex` + async fn uncle_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getUncleByBlockNumberAndIndex"); + Ok(EthBlocks::ommer_by_block_and_index(self, number, index).await?) + } + + /// Handler for: `eth_getRawTransactionByHash` + async fn raw_transaction_by_hash(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getRawTransactionByHash"); + Ok(EthTransactions::raw_transaction_by_hash(self, hash).await?) + } + + /// Handler for: `eth_getTransactionByHash` + async fn transaction_by_hash(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); + Ok(EthTransactions::transaction_by_hash(self, hash).await?.map(Into::into)) + } + + /// Handler for: `eth_getRawTransactionByBlockHashAndIndex` + async fn raw_transaction_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getRawTransactionByBlockHashAndIndex"); + Ok(EthTransactions::raw_transaction_by_block_and_tx_index(self, hash, index).await?) + } + + /// Handler for: `eth_getTransactionByBlockHashAndIndex` + async fn transaction_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getTransactionByBlockHashAndIndex"); + Ok(EthTransactions::transaction_by_block_and_tx_index(self, hash, index).await?) + } + + /// Handler for: `eth_getRawTransactionByBlockNumberAndIndex` + async fn raw_transaction_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getRawTransactionByBlockNumberAndIndex"); + Ok(EthTransactions::raw_transaction_by_block_and_tx_index(self, number, index).await?) + } + + /// Handler for: `eth_getTransactionByBlockNumberAndIndex` + async fn transaction_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> Result> { + trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getTransactionByBlockNumberAndIndex"); + Ok(EthTransactions::transaction_by_block_and_tx_index(self, number, index).await?) + } + + /// Handler for: `eth_getTransactionReceipt` + async fn transaction_receipt(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionReceipt"); + Ok(EthTransactions::transaction_receipt(self, hash).await?) + } + + /// Handler for: `eth_getBalance` + async fn balance(&self, address: Address, block_number: Option) -> Result { + trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getBalance"); + Ok(EthState::balance(self, address, block_number).await?) + } + + /// Handler for: `eth_getStorageAt` + async fn storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option, + ) -> Result { + trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getStorageAt"); + let res: B256 = EthState::storage_at(self, address, index, block_number).await?; + Ok(res) + } + + /// Handler for: `eth_getTransactionCount` + async fn transaction_count( + &self, + address: Address, + block_number: Option, + ) -> Result { + trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getTransactionCount"); + Ok(EthState::transaction_count(self, address, block_number).await?) + } + + /// Handler for: `eth_getCode` + async fn get_code(&self, address: Address, block_number: Option) -> Result { + trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getCode"); + Ok(EthState::get_code(self, address, block_number).await?) + } + + /// Handler for: `eth_getHeaderByNumber` + async fn header_by_number(&self, block_number: BlockNumberOrTag) -> Result> { + trace!(target: "rpc::eth", ?block_number, "Serving eth_getHeaderByNumber"); + Ok(EthBlocks::rpc_block_header(self, block_number).await?) + } + + /// Handler for: `eth_getHeaderByHash` + async fn header_by_hash(&self, hash: B256) -> Result> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getHeaderByHash"); + Ok(EthBlocks::rpc_block_header(self, hash).await?) + } + + /// Handler for: `eth_call` + async fn call( + &self, + request: TransactionRequest, + block_number: Option, + state_overrides: Option, + block_overrides: Option>, + ) -> Result { + trace!(target: "rpc::eth", ?request, ?block_number, ?state_overrides, ?block_overrides, "Serving eth_call"); + Ok(EthCall::call( + self, + request, + block_number, + EvmOverrides::new(state_overrides, block_overrides), + ) + .await?) + } + + /// Handler for: `eth_callMany` + async fn call_many( + &self, + bundle: Bundle, + state_context: Option, + state_override: Option, + ) -> Result> { + trace!(target: "rpc::eth", ?bundle, ?state_context, ?state_override, "Serving eth_callMany"); + Ok(EthCall::call_many(self, bundle, state_context, state_override).await?) + } + + /// Handler for: `eth_createAccessList` + async fn create_access_list( + &self, + request: TransactionRequest, + block_number: Option, + ) -> Result { + trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_createAccessList"); + let access_list_with_gas_used = + EthCall::create_access_list_at(self, request, block_number).await?; + + Ok(access_list_with_gas_used) + } + + /// Handler for: `eth_estimateGas` + async fn estimate_gas( + &self, + request: TransactionRequest, + block_number: Option, + state_override: Option, + ) -> Result { + trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_estimateGas"); + Ok(EthCall::estimate_gas_at( + self, + request, + block_number.unwrap_or_default(), + state_override, + ) + .await?) + } + + /// Handler for: `eth_gasPrice` + async fn gas_price(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_gasPrice"); + return Ok(EthFees::gas_price(self).await?) + } + + /// Handler for: `eth_maxPriorityFeePerGas` + async fn max_priority_fee_per_gas(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_maxPriorityFeePerGas"); + return Ok(EthFees::suggested_priority_fee(self).await?) + } + + /// Handler for: `eth_blobBaseFee` + async fn blob_base_fee(&self) -> Result { + trace!(target: "rpc::eth", "Serving eth_blobBaseFee"); + return Ok(EthFees::blob_base_fee(self).await?) + } + + // FeeHistory is calculated based on lazy evaluation of fees for historical blocks, and further + // caching of it in the LRU cache. + // When new RPC call is executed, the cache gets locked, we check it for the historical fees + // according to the requested block range, and fill any cache misses (in both RPC response + // and cache itself) with the actual data queried from the database. + // To minimize the number of database seeks required to query the missing data, we calculate the + // first non-cached block number and last non-cached block number. After that, we query this + // range of consecutive blocks from the database. + /// Handler for: `eth_feeHistory` + async fn fee_history( + &self, + block_count: U64, + newest_block: BlockNumberOrTag, + reward_percentiles: Option>, + ) -> Result { + trace!(target: "rpc::eth", ?block_count, ?newest_block, ?reward_percentiles, "Serving eth_feeHistory"); + return Ok( + EthFees::fee_history(self, block_count.to(), newest_block, reward_percentiles).await? + ) + } + + /// Handler for: `eth_mining` + async fn is_mining(&self) -> Result { + Err(internal_rpc_err("unimplemented")) + } + + /// Handler for: `eth_hashrate` + async fn hashrate(&self) -> Result { + Ok(U256::ZERO) + } + + /// Handler for: `eth_getWork` + async fn get_work(&self) -> Result { + Err(internal_rpc_err("unimplemented")) + } + + /// Handler for: `eth_submitHashrate` + async fn submit_hashrate(&self, _hashrate: U256, _id: B256) -> Result { + Ok(false) + } + + /// Handler for: `eth_submitWork` + async fn submit_work(&self, _nonce: B64, _pow_hash: B256, _mix_digest: B256) -> Result { + Err(internal_rpc_err("unimplemented")) + } + + /// Handler for: `eth_sendTransaction` + async fn send_transaction(&self, request: TransactionRequest) -> Result { + trace!(target: "rpc::eth", ?request, "Serving eth_sendTransaction"); + Ok(EthTransactions::send_transaction(self, request).await?) + } + + /// Handler for: `eth_sendRawTransaction` + async fn send_raw_transaction(&self, tx: Bytes) -> Result { + trace!(target: "rpc::eth", ?tx, "Serving eth_sendRawTransaction"); + Ok(EthTransactions::send_raw_transaction(self, tx).await?) + } + + /// Handler for: `eth_sign` + async fn sign(&self, address: Address, message: Bytes) -> Result { + trace!(target: "rpc::eth", ?address, ?message, "Serving eth_sign"); + Ok(EthTransactions::sign(self, address, message).await?) + } + + /// Handler for: `eth_signTransaction` + async fn sign_transaction(&self, _transaction: TransactionRequest) -> Result { + Err(internal_rpc_err("unimplemented")) + } + + /// Handler for: `eth_signTypedData` + async fn sign_typed_data(&self, address: Address, data: Value) -> Result { + trace!(target: "rpc::eth", ?address, ?data, "Serving eth_signTypedData"); + Ok(EthTransactions::sign_typed_data(self, data, address)?) + } + + /// Handler for: `eth_getProof` + async fn get_proof( + &self, + address: Address, + keys: Vec, + block_number: Option, + ) -> Result { + trace!(target: "rpc::eth", ?address, ?keys, ?block_number, "Serving eth_getProof"); + let res = EthState::get_proof(self, address, keys, block_number)?.await; + + Ok(res.map_err(|e| match e { + EthApiError::InvalidBlockRange => { + internal_rpc_err("eth_getProof is unimplemented for historical blocks") + } + _ => e.into(), + })?) + } +} + +#[cfg(test)] +mod tests { + use crate::{ + eth::{ + cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, + FeeHistoryCacheConfig, + }, + EthApi, + }; + use jsonrpsee::types::error::INVALID_PARAMS_CODE; + use reth_evm_ethereum::EthEvmConfig; + use reth_network_api::noop::NoopNetwork; + use reth_primitives::{ + constants::ETHEREUM_BLOCK_GAS_LIMIT, BaseFeeParams, Block, BlockNumberOrTag, Header, + TransactionSigned, B256, U64, + }; + use reth_provider::{ + test_utils::{MockEthProvider, NoopProvider}, + BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory, + }; + use reth_rpc_api::EthApiServer; + use reth_rpc_types::FeeHistory; + use reth_tasks::pool::BlockingTaskPool; + use reth_testing_utils::{generators, generators::Rng}; + use reth_transaction_pool::test_utils::{testing_pool, TestPool}; + + fn build_test_eth_api< + P: BlockReaderIdExt + + BlockReader + + ChainSpecProvider + + EvmEnvProvider + + StateProviderFactory + + Unpin + + Clone + + 'static, + >( + provider: P, + ) -> EthApi { + let evm_config = EthEvmConfig::default(); + let cache = EthStateCache::spawn(provider.clone(), Default::default(), evm_config); + let fee_history_cache = + FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default()); + + EthApi::new( + provider.clone(), + testing_pool(), + NoopNetwork::default(), + cache.clone(), + GasPriceOracle::new(provider, Default::default(), cache), + ETHEREUM_BLOCK_GAS_LIMIT, + BlockingTaskPool::build().expect("failed to build tracing pool"), + fee_history_cache, + evm_config, + None, + ) + } + + // Function to prepare the EthApi with mock data + fn prepare_eth_api( + newest_block: u64, + mut oldest_block: Option, + block_count: u64, + mock_provider: MockEthProvider, + ) -> (EthApi, Vec, Vec) { + let mut rng = generators::rng(); + + // Build mock data + let mut gas_used_ratios = Vec::new(); + let mut base_fees_per_gas = Vec::new(); + let mut last_header = None; + let mut parent_hash = B256::default(); + + for i in (0..block_count).rev() { + let hash = rng.gen(); + let gas_limit: u64 = rng.gen(); + let gas_used: u64 = rng.gen(); + // Note: Generates a u32 to avoid overflows later + let base_fee_per_gas: Option = rng.gen::().then(|| rng.gen::() as u64); + + let header = Header { + number: newest_block - i, + gas_limit, + gas_used, + base_fee_per_gas, + parent_hash, + ..Default::default() + }; + last_header = Some(header.clone()); + parent_hash = hash; + + let mut transactions = vec![]; + for _ in 0..100 { + let random_fee: u128 = rng.gen(); + + if let Some(base_fee_per_gas) = header.base_fee_per_gas { + let transaction = TransactionSigned { + transaction: reth_primitives::Transaction::Eip1559( + reth_primitives::TxEip1559 { + max_priority_fee_per_gas: random_fee, + max_fee_per_gas: random_fee + base_fee_per_gas as u128, + ..Default::default() + }, + ), + ..Default::default() + }; + + transactions.push(transaction); + } else { + let transaction = TransactionSigned { + transaction: reth_primitives::Transaction::Legacy(Default::default()), + ..Default::default() + }; + + transactions.push(transaction); + } + } + + mock_provider.add_block( + hash, + Block { header: header.clone(), body: transactions, ..Default::default() }, + ); + mock_provider.add_header(hash, header); + + oldest_block.get_or_insert(hash); + gas_used_ratios.push(gas_used as f64 / gas_limit as f64); + base_fees_per_gas.push(base_fee_per_gas.map(|fee| fee as u128).unwrap_or_default()); + } + + // Add final base fee (for the next block outside of the request) + let last_header = last_header.unwrap(); + base_fees_per_gas.push(BaseFeeParams::ethereum().next_block_base_fee( + last_header.gas_used as u128, + last_header.gas_limit as u128, + last_header.base_fee_per_gas.unwrap_or_default() as u128, + )); + + let eth_api = build_test_eth_api(mock_provider); + + (eth_api, base_fees_per_gas, gas_used_ratios) + } + + /// Invalid block range + #[tokio::test] + async fn test_fee_history_empty() { + let response = as EthApiServer>::fee_history( + &build_test_eth_api(NoopProvider::default()), + U64::from(1), + BlockNumberOrTag::Latest, + None, + ) + .await; + assert!(response.is_err()); + let error_object = response.unwrap_err(); + assert_eq!(error_object.code(), INVALID_PARAMS_CODE); + } + + #[tokio::test] + /// Invalid block range (request is before genesis) + async fn test_fee_history_invalid_block_range_before_genesis() { + let block_count = 10; + let newest_block = 1337; + let oldest_block = None; + + let (eth_api, _, _) = + prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); + + let response = as EthApiServer>::fee_history( + ð_api, + U64::from(newest_block + 1), + newest_block.into(), + Some(vec![10.0]), + ) + .await; + + assert!(response.is_err()); + let error_object = response.unwrap_err(); + assert_eq!(error_object.code(), INVALID_PARAMS_CODE); + } + + #[tokio::test] + /// Invalid block range (request is in the future) + async fn test_fee_history_invalid_block_range_in_future() { + let block_count = 10; + let newest_block = 1337; + let oldest_block = None; + + let (eth_api, _, _) = + prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); + + let response = as EthApiServer>::fee_history( + ð_api, + U64::from(1), + (newest_block + 1000).into(), + Some(vec![10.0]), + ) + .await; + + assert!(response.is_err()); + let error_object = response.unwrap_err(); + assert_eq!(error_object.code(), INVALID_PARAMS_CODE); + } + + #[tokio::test] + /// Requesting no block should result in a default response + async fn test_fee_history_no_block_requested() { + let block_count = 10; + let newest_block = 1337; + let oldest_block = None; + + let (eth_api, _, _) = + prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); + + let response = as EthApiServer>::fee_history( + ð_api, + U64::from(0), + newest_block.into(), + None, + ) + .await + .unwrap(); + assert_eq!( + response, + FeeHistory::default(), + "none: requesting no block should yield a default response" + ); + } + + #[tokio::test] + /// Requesting a single block should return 1 block (+ base fee for the next block over) + async fn test_fee_history_single_block() { + let block_count = 10; + let newest_block = 1337; + let oldest_block = None; + + let (eth_api, base_fees_per_gas, gas_used_ratios) = + prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); + + let fee_history = + eth_api.fee_history(U64::from(1), newest_block.into(), None).await.unwrap(); + assert_eq!( + fee_history.base_fee_per_gas, + &base_fees_per_gas[base_fees_per_gas.len() - 2..], + "one: base fee per gas is incorrect" + ); + assert_eq!( + fee_history.base_fee_per_gas.len(), + 2, + "one: should return base fee of the next block as well" + ); + assert_eq!( + &fee_history.gas_used_ratio, + &gas_used_ratios[gas_used_ratios.len() - 1..], + "one: gas used ratio is incorrect" + ); + assert_eq!(fee_history.oldest_block, newest_block, "one: oldest block is incorrect"); + assert!( + fee_history.reward.is_none(), + "one: no percentiles were requested, so there should be no rewards result" + ); + } + + /// Requesting all blocks should be ok + #[tokio::test] + async fn test_fee_history_all_blocks() { + let block_count = 10; + let newest_block = 1337; + let oldest_block = None; + + let (eth_api, base_fees_per_gas, gas_used_ratios) = + prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); + + let fee_history = + eth_api.fee_history(U64::from(block_count), newest_block.into(), None).await.unwrap(); + + assert_eq!( + &fee_history.base_fee_per_gas, &base_fees_per_gas, + "all: base fee per gas is incorrect" + ); + assert_eq!( + fee_history.base_fee_per_gas.len() as u64, + block_count + 1, + "all: should return base fee of the next block as well" + ); + assert_eq!( + &fee_history.gas_used_ratio, &gas_used_ratios, + "all: gas used ratio is incorrect" + ); + assert_eq!( + fee_history.oldest_block, + newest_block - block_count + 1, + "all: oldest block is incorrect" + ); + assert!( + fee_history.reward.is_none(), + "all: no percentiles were requested, so there should be no rewards result" + ); + } +} From f6fe8b56d61cd47966be5e00a37260548327fa4d Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 14 Jun 2024 17:27:33 +0200 Subject: [PATCH 03/16] Move eth api trait and impl into reth-rpc-eth-api --- Cargo.lock | 35 + crates/rpc/rpc-api/Cargo.toml | 1 + crates/rpc/rpc-builder/src/eth.rs | 4 +- crates/rpc/rpc-eth-api/Cargo.toml | 46 +- .../{rpc => rpc-eth-api}/src/eth/api/block.rs | 2 +- .../{rpc => rpc-eth-api}/src/eth/api/call.rs | 2 +- .../src/eth/api/fee_history.rs | 0 .../{rpc => rpc-eth-api}/src/eth/api/fees.rs | 2 +- .../{rpc => rpc-eth-api}/src/eth/api/mod.rs | 2 +- .../src/eth/api/optimism.rs | 0 .../src/eth/api/pending_block.rs | 3 +- .../src/eth/api/receipt.rs | 2 +- crates/rpc/rpc-eth-api/src/eth/api/server.rs | 29 + .../{rpc => rpc-eth-api}/src/eth/api/sign.rs | 2 +- .../{rpc => rpc-eth-api}/src/eth/api/state.rs | 2 +- .../{rpc => rpc-eth-api}/src/eth/api/trace.rs | 2 +- .../src/eth/api/traits/block.rs | 2 +- .../src/eth/api/traits/blocking_task.rs | 0 .../src/eth/api/traits/call.rs | 2 +- .../src/eth/api/traits/fee.rs | 2 +- .../src/eth/api/traits/mod.rs | 2 +- .../src/eth/api/traits/pending_block.rs | 0 .../src/eth/api/traits/receipt.rs | 0 .../src/eth/api/traits/state.rs | 2 +- .../src/eth/api/traits/trace.rs | 0 .../src/eth/api/traits/transaction.rs | 2 +- .../src/eth/api/transactions.rs | 2 +- .../src/eth/cache/config.rs | 0 .../src/eth/cache/metrics.rs | 0 .../{rpc => rpc-eth-api}/src/eth/cache/mod.rs | 0 .../src/eth/cache/multi_consumer.rs | 0 .../rpc/{rpc => rpc-eth-api}/src/eth/error.rs | 0 .../src/eth/gas_oracle.rs | 0 crates/rpc/rpc-eth-api/src/eth/mod.rs | 16 + .../src/eth/revm_utils.rs | 2 +- .../{rpc => rpc-eth-api}/src/eth/signer.rs | 0 .../rpc/{rpc => rpc-eth-api}/src/eth/utils.rs | 2 +- crates/rpc/rpc-eth-api/src/lib.rs | 6 + crates/rpc/{rpc => rpc-eth-api}/src/result.rs | 11 +- crates/rpc/rpc-eth-api/src/server.rs | 15 +- crates/rpc/rpc-testing-util/Cargo.toml | 1 + crates/rpc/rpc-testing-util/tests/it/trace.rs | 2 +- crates/rpc/rpc/Cargo.toml | 3 + crates/rpc/rpc/src/debug.rs | 19 +- crates/rpc/rpc/src/eth/api/server.rs | 726 ------------------ crates/rpc/rpc/src/eth/bundle.rs | 11 +- crates/rpc/rpc/src/eth/filter.rs | 32 +- crates/rpc/rpc/src/eth/mod.rs | 26 +- crates/rpc/rpc/src/lib.rs | 6 +- crates/rpc/rpc/src/net.rs | 2 +- crates/rpc/rpc/src/otterscan.rs | 9 +- crates/rpc/rpc/src/reth.rs | 2 +- crates/rpc/rpc/src/trace.rs | 13 +- 53 files changed, 222 insertions(+), 830 deletions(-) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/block.rs (98%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/call.rs (98%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/fee_history.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/fees.rs (98%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/mod.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/optimism.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/pending_block.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/receipt.rs (99%) create mode 100644 crates/rpc/rpc-eth-api/src/eth/api/server.rs rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/sign.rs (89%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/state.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/trace.rs (96%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/block.rs (98%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/blocking_task.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/call.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/fee.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/mod.rs (93%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/pending_block.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/receipt.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/state.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/trace.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/traits/transaction.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/api/transactions.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/cache/config.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/cache/metrics.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/cache/mod.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/cache/multi_consumer.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/error.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/gas_oracle.rs (100%) create mode 100644 crates/rpc/rpc-eth-api/src/eth/mod.rs rename crates/rpc/{rpc => rpc-eth-api}/src/eth/revm_utils.rs (99%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/signer.rs (100%) rename crates/rpc/{rpc => rpc-eth-api}/src/eth/utils.rs (95%) rename crates/rpc/{rpc => rpc-eth-api}/src/result.rs (97%) delete mode 100644 crates/rpc/rpc/src/eth/api/server.rs diff --git a/Cargo.lock b/Cargo.lock index ab07f8aa34b..4f1a773d9db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7920,6 +7920,7 @@ dependencies = [ "reth-revm", "reth-rpc-api", "reth-rpc-engine-api", + "reth-rpc-eth-api", "reth-rpc-server-types", "reth-rpc-types", "reth-rpc-types-compat", @@ -7964,6 +7965,7 @@ dependencies = [ "jsonrpsee", "reth-primitives", "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-types", "serde_json", "similar-asserts", @@ -8047,10 +8049,43 @@ dependencies = [ name = "reth-rpc-eth-api" version = "1.0.0-rc.1" dependencies = [ + "alloy-dyn-abi", + "alloy-sol-types", + "async-trait", + "auto_impl", + "derive_more", + "dyn-clone", + "futures", "jsonrpsee", + "metrics", + "parking_lot 0.12.3", + "rand 0.8.5", + "reth-errors", + "reth-evm", + "reth-evm-ethereum", + "reth-metrics", + "reth-network-api", "reth-primitives", + "reth-provider", + "reth-revm", + "reth-rpc-server-types", "reth-rpc-types", + "reth-rpc-types-compat", + "reth-tasks", + "reth-testing-utils", + "reth-transaction-pool", + "reth-trie", + "revm", + "revm-inspectors", + "revm-primitives", + "schnellru", + "secp256k1 0.28.2", + "serde", "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", ] [[package]] diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index 67665774910..a0d03a4039a 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -29,3 +29,4 @@ client = [ "jsonrpsee/async-client", "reth-rpc-eth-api/client" ] +optimism = ["reth-rpc-eth-api/optimism"] \ No newline at end of file diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index 5d0d064247a..ece57a46076 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -2,9 +2,9 @@ use reth_rpc::{ eth::{ cache::{EthStateCache, EthStateCacheConfig}, gas_oracle::GasPriceOracleConfig, - EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, + EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, EthApi }, - EthApi, EthFilter, EthPubSub, + EthFilter, EthPubSub, }; use reth_rpc_server_types::constants::{ default_max_tracing_requests, DEFAULT_MAX_BLOCKS_PER_FILTER, DEFAULT_MAX_LOGS_PER_RESPONSE, diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index 9368646eb67..b37680c5dcb 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -13,12 +13,54 @@ workspace = true [dependencies] # reth -reth-rpc-types.workspace = true +revm.workspace = true +revm-inspectors.workspace = true +revm-primitives.workspace = true +reth-errors.workspace = true +reth-evm.workspace = true +reth-metrics.workspace = true +reth-network-api.workspace = true reth-primitives.workspace = true +reth-provider.workspace = true +reth-revm.workspace = true +reth-rpc-server-types.workspace = true +reth-rpc-types.workspace = true +reth-rpc-types-compat.workspace = true +reth-tasks.workspace = true +reth-trie.workspace = true +reth-transaction-pool.workspace = true + +# ethereum +alloy-dyn-abi.workspace = true +alloy-sol-types.workspace = true +secp256k1.workspace = true # rpc jsonrpsee.workspace = true serde_json.workspace = true +# async +async-trait.workspace = true +futures.workspace = true +parking_lot.workspace = true +tokio.workspace = true +tokio-stream.workspace = true + +# misc +auto_impl.workspace = true +derive_more.workspace = true +dyn-clone.workspace = true +metrics.workspace = true +rand.workspace = true +schnellru.workspace = true +serde.workspace = true +thiserror.workspace = true +tracing.workspace = true + +[dev-dependencies] +reth-evm-ethereum.workspace = true +reth-testing-utils.workspace = true + [features] -client = ["jsonrpsee/client", "jsonrpsee/async-client"] \ No newline at end of file +client = ["jsonrpsee/client", "jsonrpsee/async-client"] +optimism = ["reth-primitives/optimism"] \ No newline at end of file diff --git a/crates/rpc/rpc/src/eth/api/block.rs b/crates/rpc/rpc-eth-api/src/eth/api/block.rs similarity index 98% rename from crates/rpc/rpc/src/eth/api/block.rs rename to crates/rpc/rpc-eth-api/src/eth/api/block.rs index 4c16a7c8c2e..c5df169d99e 100644 --- a/crates/rpc/rpc/src/eth/api/block.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/block.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to blocks. -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`EthBlocks`](crate::eth::api::EthBlocks) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc-eth-api/src/eth/api/call.rs similarity index 98% rename from crates/rpc/rpc/src/eth/api/call.rs rename to crates/rpc/rpc-eth-api/src/eth/api/call.rs index db68343b531..28d681d8d5e 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/call.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to endpoints that call/execute within evm. -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`EthCall`](crate::eth::api::EthCall) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/api/fee_history.rs b/crates/rpc/rpc-eth-api/src/eth/api/fee_history.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/fee_history.rs rename to crates/rpc/rpc-eth-api/src/eth/api/fee_history.rs diff --git a/crates/rpc/rpc/src/eth/api/fees.rs b/crates/rpc/rpc-eth-api/src/eth/api/fees.rs similarity index 98% rename from crates/rpc/rpc/src/eth/api/fees.rs rename to crates/rpc/rpc-eth-api/src/eth/api/fees.rs index 0392bbc60e1..8cdab100197 100644 --- a/crates/rpc/rpc/src/eth/api/fees.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/fees.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations for fee history. -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`EthFees`](crate::eth::api::EthFees) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/api/mod.rs b/crates/rpc/rpc-eth-api/src/eth/api/mod.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/mod.rs rename to crates/rpc/rpc-eth-api/src/eth/api/mod.rs index 172ed4f62cf..bf66825c2e9 100644 --- a/crates/rpc/rpc/src/eth/api/mod.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/mod.rs @@ -70,7 +70,7 @@ pub trait EthApiSpec: Send + Sync { /// /// This type provides the functionality for handling `eth_` related requests. /// These are implemented two-fold: Core functionality is implemented as [`EthApiSpec`] -/// trait. Additionally, the required server implementations (e.g. [`reth_rpc_api::EthApiServer`]) +/// trait. Additionally, the required server implementations (e.g. [`reth_rpc_eth_api::EthApiServer`]) /// are implemented separately in submodules. The rpc handler implementation can then delegate to /// the main impls. This way [`EthApi`] is not limited to [`jsonrpsee`] and can be used standalone /// or in other network handlers (for example ipc). diff --git a/crates/rpc/rpc/src/eth/api/optimism.rs b/crates/rpc/rpc-eth-api/src/eth/api/optimism.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/optimism.rs rename to crates/rpc/rpc-eth-api/src/eth/api/optimism.rs diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/pending_block.rs rename to crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs index fab17ef7718..604831d3235 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs @@ -13,8 +13,7 @@ use revm::{Database, DatabaseCommit}; use revm_primitives::EnvWithHandlerCfg; use crate::{ - eth::error::{EthApiError, EthResult}, - EthApi, + eth::{EthApi, error::{EthApiError, EthResult}}, }; /// Implements [`LoadPendingBlock`](crate::eth::api::LoadPendingBlock) for a type, that has similar diff --git a/crates/rpc/rpc/src/eth/api/receipt.rs b/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/receipt.rs rename to crates/rpc/rpc-eth-api/src/eth/api/receipt.rs index 27cea387080..aa563dc8335 100644 --- a/crates/rpc/rpc/src/eth/api/receipt.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs @@ -12,11 +12,11 @@ use reth_rpc_types::{ use crate::{ eth::{ + EthApi, api::LoadReceipt, cache::EthStateCache, error::{EthApiError, EthResult}, }, - EthApi, }; impl LoadReceipt for EthApi diff --git a/crates/rpc/rpc-eth-api/src/eth/api/server.rs b/crates/rpc/rpc-eth-api/src/eth/api/server.rs new file mode 100644 index 00000000000..46cee106d79 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/eth/api/server.rs @@ -0,0 +1,29 @@ +//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_eth_api::EthApiServer`] trait +//! Handles RPC requests for the `eth_` namespace. + +use jsonrpsee::core::RpcResult as Result; +use reth_evm::ConfigureEvm; +use reth_network_api::NetworkInfo; +use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; +use reth_provider::{ + BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, HeaderProvider, StateProviderFactory, +}; +use reth_rpc_types::{ + serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, + AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, + FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, TransactionRequest, Work, +}; +use reth_transaction_pool::TransactionPool; +use serde_json::Value; +use tracing::trace; + +use crate::{ + eth::{ + api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, + error::EthApiError, + revm_utils::EvmOverrides, + EthApi, + }, + EthApiServer, + result::{internal_rpc_err, ToRpcResult}, +}; diff --git a/crates/rpc/rpc/src/eth/api/sign.rs b/crates/rpc/rpc-eth-api/src/eth/api/sign.rs similarity index 89% rename from crates/rpc/rpc/src/eth/api/sign.rs rename to crates/rpc/rpc-eth-api/src/eth/api/sign.rs index b6c096084ef..62a30ce8138 100644 --- a/crates/rpc/rpc/src/eth/api/sign.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/sign.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to sign endpoints -use crate::{eth::signer::DevSigner, EthApi}; +use crate::eth::{signer::DevSigner, EthApi}; impl EthApi { /// Generates 20 random developer accounts. diff --git a/crates/rpc/rpc/src/eth/api/state.rs b/crates/rpc/rpc-eth-api/src/eth/api/state.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/state.rs rename to crates/rpc/rpc-eth-api/src/eth/api/state.rs index 49df9989490..2a29db0624c 100644 --- a/crates/rpc/rpc/src/eth/api/state.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/state.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to state. -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`EthState`](crate::eth::api::EthState) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/api/trace.rs b/crates/rpc/rpc-eth-api/src/eth/api/trace.rs similarity index 96% rename from crates/rpc/rpc/src/eth/api/trace.rs rename to crates/rpc/rpc-eth-api/src/eth/api/trace.rs index 9d19d85d5e3..6a1ffa3245a 100644 --- a/crates/rpc/rpc/src/eth/api/trace.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/trace.rs @@ -1,6 +1,6 @@ //! Contains RPC handler implementations specific to tracing. -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`Trace`](crate::eth::api::Trace) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/api/traits/block.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs similarity index 98% rename from crates/rpc/rpc/src/eth/api/traits/block.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs index 2526353e555..249a0f7e6b4 100644 --- a/crates/rpc/rpc/src/eth/api/traits/block.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs @@ -14,7 +14,7 @@ use crate::eth::{ error::{EthApiError, EthResult}, }; -/// Block related functions for the [`EthApiServer`](reth_rpc_api::EthApiServer) trait in the +/// Block related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the /// `eth_` namespace. pub trait EthBlocks: LoadBlock { /// Returns a handle for reading data from disk. diff --git a/crates/rpc/rpc/src/eth/api/traits/blocking_task.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/blocking_task.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/traits/blocking_task.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/blocking_task.rs diff --git a/crates/rpc/rpc/src/eth/api/traits/call.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/traits/call.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs index ea267f00ca0..2a5c9f8fc30 100644 --- a/crates/rpc/rpc/src/eth/api/traits/call.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs @@ -40,7 +40,7 @@ pub const ESTIMATE_GAS_ERROR_RATIO: f64 = 0.015; /// Helper alias type for the state's [`CacheDB`] pub type StateCacheDB<'a> = CacheDB>>; -/// Execution related functions for the [`EthApiServer`](reth_rpc_api::EthApiServer) trait in the +/// Execution related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the /// `eth_` namespace. pub trait EthCall: Call + LoadPendingBlock { /// Estimate gas needed for execution of the `request` at the [`BlockId`]. diff --git a/crates/rpc/rpc/src/eth/api/traits/fee.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/traits/fee.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs index fa7f45c2982..f880105cb7d 100644 --- a/crates/rpc/rpc/src/eth/api/traits/fee.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs @@ -17,7 +17,7 @@ use crate::eth::{ FeeHistoryCache, }; -/// Fee related functions for the [`EthApiServer`](reth_rpc_api::EthApiServer) trait in the +/// Fee related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the /// `eth_` namespace. pub trait EthFees: LoadFee { /// Returns a suggestion for a gas price for legacy transactions. diff --git a/crates/rpc/rpc/src/eth/api/traits/mod.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs similarity index 93% rename from crates/rpc/rpc/src/eth/api/traits/mod.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs index 38b518f6e38..41a0a80e2ae 100644 --- a/crates/rpc/rpc/src/eth/api/traits/mod.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs @@ -11,7 +11,7 @@ //! divided into: [`EthTransactions`], [`EthBlocks`], [`EthFees`], [`EthState`] and [`EthCall`]. //! Default implementation of the `Eth` traits, is done w.r.t. L1. //! -//! [`EthApiServer`](reth_rpc_api::EthApiServer), is implemented for any type that implements all +//! [`EthApiServer`](reth_rpc_eth_api::EthApiServer), is implemented for any type that implements all //! the `Eth` traits, e.g. [`EthApi`](crate::EthApi). pub mod block; diff --git a/crates/rpc/rpc/src/eth/api/traits/pending_block.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/pending_block.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/traits/pending_block.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/pending_block.rs diff --git a/crates/rpc/rpc/src/eth/api/traits/receipt.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/receipt.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/traits/receipt.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/receipt.rs diff --git a/crates/rpc/rpc/src/eth/api/traits/state.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/traits/state.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs index c0637396707..2a76cfa169e 100644 --- a/crates/rpc/rpc/src/eth/api/traits/state.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs @@ -17,8 +17,8 @@ use crate::{ api::{pending_block::PendingBlockEnv, LoadPendingBlock, SpawnBlocking}, cache::EthStateCache, error::{EthApiError, EthResult, RpcInvalidTransactionError}, + EthApiSpec, }, - EthApiSpec, }; /// Helper methods for `eth_` methods relating to state (accounts). diff --git a/crates/rpc/rpc/src/eth/api/traits/trace.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/trace.rs similarity index 100% rename from crates/rpc/rpc/src/eth/api/traits/trace.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/trace.rs diff --git a/crates/rpc/rpc/src/eth/api/traits/transaction.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/traits/transaction.rs rename to crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs index b8f33a346dc..2750f6e1058 100644 --- a/crates/rpc/rpc/src/eth/api/traits/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs @@ -29,7 +29,7 @@ use crate::eth::{ TransactionSource, }; -/// Transaction related functions for the [`EthApiServer`](reth_rpc_api::EthApiServer) trait in +/// Transaction related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in /// the `eth_` namespace. /// /// This includes utilities for transaction tracing, transacting and inspection. diff --git a/crates/rpc/rpc/src/eth/api/transactions.rs b/crates/rpc/rpc-eth-api/src/eth/api/transactions.rs similarity index 99% rename from crates/rpc/rpc/src/eth/api/transactions.rs rename to crates/rpc/rpc-eth-api/src/eth/api/transactions.rs index 180c50ca470..c72e1dfff40 100644 --- a/crates/rpc/rpc/src/eth/api/transactions.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/transactions.rs @@ -4,7 +4,7 @@ use reth_primitives::{TransactionSignedEcRecovered, B256}; use reth_rpc_types::{Transaction, TransactionInfo}; use reth_rpc_types_compat::transaction::from_recovered_with_block_context; -use crate::EthApi; +use crate::eth::EthApi; /// Implements [`EthTransactions`](crate::eth::api::EthTransactions) for a type, that has similar /// data layout to [`EthApi`]. diff --git a/crates/rpc/rpc/src/eth/cache/config.rs b/crates/rpc/rpc-eth-api/src/eth/cache/config.rs similarity index 100% rename from crates/rpc/rpc/src/eth/cache/config.rs rename to crates/rpc/rpc-eth-api/src/eth/cache/config.rs diff --git a/crates/rpc/rpc/src/eth/cache/metrics.rs b/crates/rpc/rpc-eth-api/src/eth/cache/metrics.rs similarity index 100% rename from crates/rpc/rpc/src/eth/cache/metrics.rs rename to crates/rpc/rpc-eth-api/src/eth/cache/metrics.rs diff --git a/crates/rpc/rpc/src/eth/cache/mod.rs b/crates/rpc/rpc-eth-api/src/eth/cache/mod.rs similarity index 100% rename from crates/rpc/rpc/src/eth/cache/mod.rs rename to crates/rpc/rpc-eth-api/src/eth/cache/mod.rs diff --git a/crates/rpc/rpc/src/eth/cache/multi_consumer.rs b/crates/rpc/rpc-eth-api/src/eth/cache/multi_consumer.rs similarity index 100% rename from crates/rpc/rpc/src/eth/cache/multi_consumer.rs rename to crates/rpc/rpc-eth-api/src/eth/cache/multi_consumer.rs diff --git a/crates/rpc/rpc/src/eth/error.rs b/crates/rpc/rpc-eth-api/src/eth/error.rs similarity index 100% rename from crates/rpc/rpc/src/eth/error.rs rename to crates/rpc/rpc-eth-api/src/eth/error.rs diff --git a/crates/rpc/rpc/src/eth/gas_oracle.rs b/crates/rpc/rpc-eth-api/src/eth/gas_oracle.rs similarity index 100% rename from crates/rpc/rpc/src/eth/gas_oracle.rs rename to crates/rpc/rpc-eth-api/src/eth/gas_oracle.rs diff --git a/crates/rpc/rpc-eth-api/src/eth/mod.rs b/crates/rpc/rpc-eth-api/src/eth/mod.rs new file mode 100644 index 00000000000..98337e2a462 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/eth/mod.rs @@ -0,0 +1,16 @@ +//! `eth` namespace handler implementation. + +pub mod api; +pub mod cache; +pub mod error; +pub mod gas_oracle; +pub mod revm_utils; +mod signer; +pub mod utils; + +pub use api::{ + fee_history::{fee_history_cache_new_blocks_task, FeeHistoryCache, FeeHistoryCacheConfig}, + EthApi, EthApiSpec, PendingBlock, TransactionSource, RPC_DEFAULT_GAS_CAP, +}; + +pub use signer::EthSigner; diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc-eth-api/src/eth/revm_utils.rs similarity index 99% rename from crates/rpc/rpc/src/eth/revm_utils.rs rename to crates/rpc/rpc-eth-api/src/eth/revm_utils.rs index 02ddf43b9b5..20b42f5676d 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc-eth-api/src/eth/revm_utils.rs @@ -72,7 +72,7 @@ pub(crate) fn get_precompiles(spec_id: SpecId) -> impl IntoIterator( +pub fn prepare_call_env( mut cfg: CfgEnvWithHandlerCfg, mut block: BlockEnv, request: TransactionRequest, diff --git a/crates/rpc/rpc/src/eth/signer.rs b/crates/rpc/rpc-eth-api/src/eth/signer.rs similarity index 100% rename from crates/rpc/rpc/src/eth/signer.rs rename to crates/rpc/rpc-eth-api/src/eth/signer.rs diff --git a/crates/rpc/rpc/src/eth/utils.rs b/crates/rpc/rpc-eth-api/src/eth/utils.rs similarity index 95% rename from crates/rpc/rpc/src/eth/utils.rs rename to crates/rpc/rpc-eth-api/src/eth/utils.rs index a4291c4b933..a4e92d0b8a9 100644 --- a/crates/rpc/rpc/src/eth/utils.rs +++ b/crates/rpc/rpc-eth-api/src/eth/utils.rs @@ -6,7 +6,7 @@ use reth_primitives::{Bytes, PooledTransactionsElement, PooledTransactionsElemen /// Recovers a [`PooledTransactionsElementEcRecovered`] from an enveloped encoded byte stream. /// /// See [`PooledTransactionsElement::decode_enveloped`] -pub(crate) fn recover_raw_transaction( +pub fn recover_raw_transaction( data: Bytes, ) -> EthResult { if data.is_empty() { diff --git a/crates/rpc/rpc-eth-api/src/lib.rs b/crates/rpc/rpc-eth-api/src/lib.rs index fa8d4ca01cb..b0c9175586d 100644 --- a/crates/rpc/rpc-eth-api/src/lib.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -21,6 +21,12 @@ use reth_rpc_types::{ TransactionRequest, Work, }; +pub mod eth; +pub mod result; +pub mod server; + +pub use eth::EthApiSpec; + /// Eth rpc interface: #[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))] #[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))] diff --git a/crates/rpc/rpc/src/result.rs b/crates/rpc/rpc-eth-api/src/result.rs similarity index 97% rename from crates/rpc/rpc/src/result.rs rename to crates/rpc/rpc-eth-api/src/result.rs index ac654239151..ac55bb3fefe 100644 --- a/crates/rpc/rpc/src/result.rs +++ b/crates/rpc/rpc-eth-api/src/result.rs @@ -1,8 +1,9 @@ //! Additional helpers for converting errors. +use std::fmt::Display; + use jsonrpsee::core::RpcResult; use reth_rpc_types::engine::PayloadError; -use std::fmt::Display; /// Helper trait to easily convert various `Result` types into [`RpcResult`] pub trait ToRpcResult: Sized { @@ -104,7 +105,7 @@ impl_to_rpc_result!(reth_errors::ProviderError); impl_to_rpc_result!(reth_network_api::NetworkError); /// Constructs an invalid params JSON-RPC error. -pub(crate) fn invalid_params_rpc_err( +pub fn invalid_params_rpc_err( msg: impl Into, ) -> jsonrpsee::types::error::ErrorObject<'static> { rpc_err(jsonrpsee::types::error::INVALID_PARAMS_CODE, msg, None) @@ -116,7 +117,7 @@ pub fn internal_rpc_err(msg: impl Into) -> jsonrpsee::types::error::Erro } /// Constructs an internal JSON-RPC error with data -pub(crate) fn internal_rpc_err_with_data( +pub fn internal_rpc_err_with_data( msg: impl Into, data: &[u8], ) -> jsonrpsee::types::error::ErrorObject<'static> { @@ -124,7 +125,7 @@ pub(crate) fn internal_rpc_err_with_data( } /// Constructs an internal JSON-RPC error with code and message -pub(crate) fn rpc_error_with_code( +pub fn rpc_error_with_code( code: i32, msg: impl Into, ) -> jsonrpsee::types::error::ErrorObject<'static> { @@ -132,7 +133,7 @@ pub(crate) fn rpc_error_with_code( } /// Constructs a JSON-RPC error, consisting of `code`, `message` and optional `data`. -pub(crate) fn rpc_err( +pub fn rpc_err( code: i32, msg: impl Into, data: Option<&[u8]>, diff --git a/crates/rpc/rpc-eth-api/src/server.rs b/crates/rpc/rpc-eth-api/src/server.rs index d8deefc07e7..de6036659a8 100644 --- a/crates/rpc/rpc-eth-api/src/server.rs +++ b/crates/rpc/rpc-eth-api/src/server.rs @@ -2,7 +2,6 @@ //! Handles RPC requests for the `eth_` namespace. use jsonrpsee::core::RpcResult as Result; -use reth_network_api::NetworkInfo; use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; use reth_rpc_types::{ serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, @@ -12,20 +11,20 @@ use reth_rpc_types::{ use serde_json::Value; use tracing::trace; -use reth_rpc::{ +use crate::{ + EthApiServer, eth::{ - api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, + api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, Trace, LoadReceipt}, error::EthApiError, revm_utils::EvmOverrides, - EthApi, }, result::{internal_rpc_err, ToRpcResult}, }; #[async_trait::async_trait] -impl EthApiServer for EthApi +impl EthApiServer for T where - Self: EthApiSpec + EthTransactions + EthBlocks + EthState + EthCall + EthFees, + Self: EthApiSpec + EthTransactions + EthBlocks + EthState + EthCall + EthFees + Trace + LoadReceipt, { /// Handler for: `eth_protocolVersion` async fn protocol_version(&self) -> Result { @@ -415,10 +414,11 @@ where mod tests { use crate::{ eth::{ + EthApi, cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, FeeHistoryCacheConfig, }, - EthApi, + EthApiServer, }; use jsonrpsee::types::error::INVALID_PARAMS_CODE; use reth_evm_ethereum::EthEvmConfig; @@ -431,7 +431,6 @@ mod tests { test_utils::{MockEthProvider, NoopProvider}, BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory, }; - use reth_rpc_api::EthApiServer; use reth_rpc_types::FeeHistory; use reth_tasks::pool::BlockingTaskPool; use reth_testing_utils::{generators, generators::Rng}; diff --git a/crates/rpc/rpc-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index b14451969ce..08745e0ca37 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -16,6 +16,7 @@ workspace = true reth-primitives.workspace = true reth-rpc-types.workspace = true reth-rpc-api = { workspace = true, features = ["client"] } +reth-rpc-eth-api = { workspace = true, features = ["client"] } # async futures.workspace = true diff --git a/crates/rpc/rpc-testing-util/tests/it/trace.rs b/crates/rpc/rpc-testing-util/tests/it/trace.rs index a6439f0744c..a132937e888 100644 --- a/crates/rpc/rpc-testing-util/tests/it/trace.rs +++ b/crates/rpc/rpc-testing-util/tests/it/trace.rs @@ -1,6 +1,6 @@ use futures::StreamExt; use jsonrpsee::http_client::HttpClientBuilder; -use reth_rpc_api::EthApiClient; +use reth_rpc_eth_api::EthApiClient; use reth_rpc_api_testing_util::{debug::DebugApiExt, trace::TraceApiExt, utils::parse_env_url}; use reth_rpc_types::trace::{ filter::TraceFilter, parity::TraceType, tracerequest::TraceCallRequest, diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index cab1134a231..fc49087a03a 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -15,6 +15,7 @@ workspace = true # reth reth-primitives.workspace = true reth-rpc-api.workspace = true +reth-rpc-eth-api.workspace = true reth-rpc-server-types.workspace = true reth-rpc-types.workspace = true reth-errors.workspace = true @@ -93,4 +94,6 @@ optimism = [ "reth-primitives/optimism", "reth-rpc-types-compat/optimism", "reth-provider/optimism", + "reth-rpc-api/optimism", + "reth-rpc-eth-api/optimism", ] diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 186adecbd17..4ed2ffc01b0 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -13,6 +13,15 @@ use reth_provider::{ }; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::DebugApiServer; +use reth_rpc_eth_api::{ + eth::{ + api::{EthTransactions, LoadBlock, LoadTransaction, StateCacheDB, TraceExt}, + error::{EthApiError, EthResult}, + revm_utils::{prepare_call_env, EvmOverrides}, + }, + result::{internal_rpc_err, ToRpcResult}, + EthApiSpec, +}; use reth_rpc_types::{ trace::geth::{ BlockTraceResult, FourByteFrame, GethDebugBuiltInTracerType, GethDebugTracerType, @@ -31,16 +40,6 @@ use revm_inspectors::tracing::{ }; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; -use crate::{ - eth::{ - api::{EthTransactions, LoadBlock, LoadTransaction, StateCacheDB, TraceExt}, - error::{EthApiError, EthResult}, - revm_utils::{prepare_call_env, EvmOverrides}, - }, - result::{internal_rpc_err, ToRpcResult}, - EthApiSpec, -}; - /// `debug` API implementation. /// /// This type provides the functionality for handling `debug` related requests. diff --git a/crates/rpc/rpc/src/eth/api/server.rs b/crates/rpc/rpc/src/eth/api/server.rs deleted file mode 100644 index e001784e311..00000000000 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ /dev/null @@ -1,726 +0,0 @@ -//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_api::EthApiServer`] trait -//! Handles RPC requests for the `eth_` namespace. - -use jsonrpsee::core::RpcResult as Result; -use reth_evm::ConfigureEvm; -use reth_network_api::NetworkInfo; -use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; -use reth_provider::{ - BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, HeaderProvider, StateProviderFactory, -}; -use reth_rpc_api::EthApiServer; -use reth_rpc_types::{ - serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, - AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, - FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, TransactionRequest, Work, -}; -use reth_transaction_pool::TransactionPool; -use serde_json::Value; -use tracing::trace; - -use crate::{ - eth::{ - api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, - error::EthApiError, - revm_utils::EvmOverrides, - EthApi, - }, - result::{internal_rpc_err, ToRpcResult}, -}; - -#[async_trait::async_trait] -impl EthApiServer for EthApi -where - Self: EthApiSpec + EthTransactions + EthBlocks + EthState + EthCall + EthFees, - Pool: TransactionPool + 'static, - Provider: BlockReaderIdExt - + ChainSpecProvider - + HeaderProvider - + StateProviderFactory - + EvmEnvProvider - + 'static, - Network: NetworkInfo + Send + Sync + 'static, - EvmConfig: ConfigureEvm, -{ - /// Handler for: `eth_protocolVersion` - async fn protocol_version(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_protocolVersion"); - EthApiSpec::protocol_version(self).await.to_rpc_result() - } - - /// Handler for: `eth_syncing` - fn syncing(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_syncing"); - EthApiSpec::sync_status(self).to_rpc_result() - } - - /// Handler for: `eth_coinbase` - async fn author(&self) -> Result
{ - Err(internal_rpc_err("unimplemented")) - } - - /// Handler for: `eth_accounts` - fn accounts(&self) -> Result> { - trace!(target: "rpc::eth", "Serving eth_accounts"); - Ok(EthApiSpec::accounts(self)) - } - - /// Handler for: `eth_blockNumber` - fn block_number(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_blockNumber"); - Ok(U256::from( - EthApiSpec::chain_info(self).with_message("failed to read chain info")?.best_number, - )) - } - - /// Handler for: `eth_chainId` - async fn chain_id(&self) -> Result> { - trace!(target: "rpc::eth", "Serving eth_chainId"); - Ok(Some(EthApiSpec::chain_id(self))) - } - - /// Handler for: `eth_getBlockByHash` - async fn block_by_hash(&self, hash: B256, full: bool) -> Result> { - trace!(target: "rpc::eth", ?hash, ?full, "Serving eth_getBlockByHash"); - Ok(EthBlocks::rpc_block(self, hash, full).await?) - } - - /// Handler for: `eth_getBlockByNumber` - async fn block_by_number( - &self, - number: BlockNumberOrTag, - full: bool, - ) -> Result> { - trace!(target: "rpc::eth", ?number, ?full, "Serving eth_getBlockByNumber"); - Ok(EthBlocks::rpc_block(self, number, full).await?) - } - - /// Handler for: `eth_getBlockTransactionCountByHash` - async fn block_transaction_count_by_hash(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getBlockTransactionCountByHash"); - Ok(EthBlocks::block_transaction_count(self, hash).await?.map(U256::from)) - } - - /// Handler for: `eth_getBlockTransactionCountByNumber` - async fn block_transaction_count_by_number( - &self, - number: BlockNumberOrTag, - ) -> Result> { - trace!(target: "rpc::eth", ?number, "Serving eth_getBlockTransactionCountByNumber"); - Ok(EthBlocks::block_transaction_count(self, number).await?.map(U256::from)) - } - - /// Handler for: `eth_getUncleCountByBlockHash` - async fn block_uncles_count_by_hash(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getUncleCountByBlockHash"); - Ok(EthBlocks::ommers(self, hash)?.map(|ommers| U256::from(ommers.len()))) - } - - /// Handler for: `eth_getUncleCountByBlockNumber` - async fn block_uncles_count_by_number(&self, number: BlockNumberOrTag) -> Result> { - trace!(target: "rpc::eth", ?number, "Serving eth_getUncleCountByBlockNumber"); - Ok(EthBlocks::ommers(self, number)?.map(|ommers| U256::from(ommers.len()))) - } - - /// Handler for: `eth_getBlockReceipts` - async fn block_receipts( - &self, - block_id: BlockId, - ) -> Result>> { - trace!(target: "rpc::eth", ?block_id, "Serving eth_getBlockReceipts"); - Ok(EthBlocks::block_receipts(self, block_id).await?) - } - - /// Handler for: `eth_getUncleByBlockHashAndIndex` - async fn uncle_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getUncleByBlockHashAndIndex"); - Ok(EthBlocks::ommer_by_block_and_index(self, hash, index).await?) - } - - /// Handler for: `eth_getUncleByBlockNumberAndIndex` - async fn uncle_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getUncleByBlockNumberAndIndex"); - Ok(EthBlocks::ommer_by_block_and_index(self, number, index).await?) - } - - /// Handler for: `eth_getRawTransactionByHash` - async fn raw_transaction_by_hash(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getRawTransactionByHash"); - Ok(EthTransactions::raw_transaction_by_hash(self, hash).await?) - } - - /// Handler for: `eth_getTransactionByHash` - async fn transaction_by_hash(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); - Ok(EthTransactions::transaction_by_hash(self, hash).await?.map(Into::into)) - } - - /// Handler for: `eth_getRawTransactionByBlockHashAndIndex` - async fn raw_transaction_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getRawTransactionByBlockHashAndIndex"); - Ok(EthTransactions::raw_transaction_by_block_and_tx_index(self, hash, index).await?) - } - - /// Handler for: `eth_getTransactionByBlockHashAndIndex` - async fn transaction_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?hash, ?index, "Serving eth_getTransactionByBlockHashAndIndex"); - Ok(EthTransactions::transaction_by_block_and_tx_index(self, hash, index).await?) - } - - /// Handler for: `eth_getRawTransactionByBlockNumberAndIndex` - async fn raw_transaction_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getRawTransactionByBlockNumberAndIndex"); - Ok(EthTransactions::raw_transaction_by_block_and_tx_index(self, number, index).await?) - } - - /// Handler for: `eth_getTransactionByBlockNumberAndIndex` - async fn transaction_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> Result> { - trace!(target: "rpc::eth", ?number, ?index, "Serving eth_getTransactionByBlockNumberAndIndex"); - Ok(EthTransactions::transaction_by_block_and_tx_index(self, number, index).await?) - } - - /// Handler for: `eth_getTransactionReceipt` - async fn transaction_receipt(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionReceipt"); - Ok(EthTransactions::transaction_receipt(self, hash).await?) - } - - /// Handler for: `eth_getBalance` - async fn balance(&self, address: Address, block_number: Option) -> Result { - trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getBalance"); - Ok(EthState::balance(self, address, block_number).await?) - } - - /// Handler for: `eth_getStorageAt` - async fn storage_at( - &self, - address: Address, - index: JsonStorageKey, - block_number: Option, - ) -> Result { - trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getStorageAt"); - let res: B256 = EthState::storage_at(self, address, index, block_number).await?; - Ok(res) - } - - /// Handler for: `eth_getTransactionCount` - async fn transaction_count( - &self, - address: Address, - block_number: Option, - ) -> Result { - trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getTransactionCount"); - Ok(EthState::transaction_count(self, address, block_number).await?) - } - - /// Handler for: `eth_getCode` - async fn get_code(&self, address: Address, block_number: Option) -> Result { - trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getCode"); - Ok(EthState::get_code(self, address, block_number).await?) - } - - /// Handler for: `eth_getHeaderByNumber` - async fn header_by_number(&self, block_number: BlockNumberOrTag) -> Result> { - trace!(target: "rpc::eth", ?block_number, "Serving eth_getHeaderByNumber"); - Ok(EthBlocks::rpc_block_header(self, block_number).await?) - } - - /// Handler for: `eth_getHeaderByHash` - async fn header_by_hash(&self, hash: B256) -> Result> { - trace!(target: "rpc::eth", ?hash, "Serving eth_getHeaderByHash"); - Ok(EthBlocks::rpc_block_header(self, hash).await?) - } - - /// Handler for: `eth_call` - async fn call( - &self, - request: TransactionRequest, - block_number: Option, - state_overrides: Option, - block_overrides: Option>, - ) -> Result { - trace!(target: "rpc::eth", ?request, ?block_number, ?state_overrides, ?block_overrides, "Serving eth_call"); - Ok(EthCall::call( - self, - request, - block_number, - EvmOverrides::new(state_overrides, block_overrides), - ) - .await?) - } - - /// Handler for: `eth_callMany` - async fn call_many( - &self, - bundle: Bundle, - state_context: Option, - state_override: Option, - ) -> Result> { - trace!(target: "rpc::eth", ?bundle, ?state_context, ?state_override, "Serving eth_callMany"); - Ok(EthCall::call_many(self, bundle, state_context, state_override).await?) - } - - /// Handler for: `eth_createAccessList` - async fn create_access_list( - &self, - request: TransactionRequest, - block_number: Option, - ) -> Result { - trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_createAccessList"); - let access_list_with_gas_used = - EthCall::create_access_list_at(self, request, block_number).await?; - - Ok(access_list_with_gas_used) - } - - /// Handler for: `eth_estimateGas` - async fn estimate_gas( - &self, - request: TransactionRequest, - block_number: Option, - state_override: Option, - ) -> Result { - trace!(target: "rpc::eth", ?request, ?block_number, "Serving eth_estimateGas"); - Ok(EthCall::estimate_gas_at( - self, - request, - block_number.unwrap_or_default(), - state_override, - ) - .await?) - } - - /// Handler for: `eth_gasPrice` - async fn gas_price(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_gasPrice"); - return Ok(EthFees::gas_price(self).await?) - } - - /// Handler for: `eth_maxPriorityFeePerGas` - async fn max_priority_fee_per_gas(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_maxPriorityFeePerGas"); - return Ok(EthFees::suggested_priority_fee(self).await?) - } - - /// Handler for: `eth_blobBaseFee` - async fn blob_base_fee(&self) -> Result { - trace!(target: "rpc::eth", "Serving eth_blobBaseFee"); - return Ok(EthFees::blob_base_fee(self).await?) - } - - // FeeHistory is calculated based on lazy evaluation of fees for historical blocks, and further - // caching of it in the LRU cache. - // When new RPC call is executed, the cache gets locked, we check it for the historical fees - // according to the requested block range, and fill any cache misses (in both RPC response - // and cache itself) with the actual data queried from the database. - // To minimize the number of database seeks required to query the missing data, we calculate the - // first non-cached block number and last non-cached block number. After that, we query this - // range of consecutive blocks from the database. - /// Handler for: `eth_feeHistory` - async fn fee_history( - &self, - block_count: U64, - newest_block: BlockNumberOrTag, - reward_percentiles: Option>, - ) -> Result { - trace!(target: "rpc::eth", ?block_count, ?newest_block, ?reward_percentiles, "Serving eth_feeHistory"); - return Ok( - EthFees::fee_history(self, block_count.to(), newest_block, reward_percentiles).await? - ) - } - - /// Handler for: `eth_mining` - async fn is_mining(&self) -> Result { - Err(internal_rpc_err("unimplemented")) - } - - /// Handler for: `eth_hashrate` - async fn hashrate(&self) -> Result { - Ok(U256::ZERO) - } - - /// Handler for: `eth_getWork` - async fn get_work(&self) -> Result { - Err(internal_rpc_err("unimplemented")) - } - - /// Handler for: `eth_submitHashrate` - async fn submit_hashrate(&self, _hashrate: U256, _id: B256) -> Result { - Ok(false) - } - - /// Handler for: `eth_submitWork` - async fn submit_work(&self, _nonce: B64, _pow_hash: B256, _mix_digest: B256) -> Result { - Err(internal_rpc_err("unimplemented")) - } - - /// Handler for: `eth_sendTransaction` - async fn send_transaction(&self, request: TransactionRequest) -> Result { - trace!(target: "rpc::eth", ?request, "Serving eth_sendTransaction"); - Ok(EthTransactions::send_transaction(self, request).await?) - } - - /// Handler for: `eth_sendRawTransaction` - async fn send_raw_transaction(&self, tx: Bytes) -> Result { - trace!(target: "rpc::eth", ?tx, "Serving eth_sendRawTransaction"); - Ok(EthTransactions::send_raw_transaction(self, tx).await?) - } - - /// Handler for: `eth_sign` - async fn sign(&self, address: Address, message: Bytes) -> Result { - trace!(target: "rpc::eth", ?address, ?message, "Serving eth_sign"); - Ok(EthTransactions::sign(self, address, message).await?) - } - - /// Handler for: `eth_signTransaction` - async fn sign_transaction(&self, _transaction: TransactionRequest) -> Result { - Err(internal_rpc_err("unimplemented")) - } - - /// Handler for: `eth_signTypedData` - async fn sign_typed_data(&self, address: Address, data: Value) -> Result { - trace!(target: "rpc::eth", ?address, ?data, "Serving eth_signTypedData"); - Ok(EthTransactions::sign_typed_data(self, data, address)?) - } - - /// Handler for: `eth_getProof` - async fn get_proof( - &self, - address: Address, - keys: Vec, - block_number: Option, - ) -> Result { - trace!(target: "rpc::eth", ?address, ?keys, ?block_number, "Serving eth_getProof"); - let res = EthState::get_proof(self, address, keys, block_number)?.await; - - Ok(res.map_err(|e| match e { - EthApiError::InvalidBlockRange => { - internal_rpc_err("eth_getProof is unimplemented for historical blocks") - } - _ => e.into(), - })?) - } -} - -#[cfg(test)] -mod tests { - use crate::{ - eth::{ - cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, - FeeHistoryCacheConfig, - }, - EthApi, - }; - use jsonrpsee::types::error::INVALID_PARAMS_CODE; - use reth_evm_ethereum::EthEvmConfig; - use reth_network_api::noop::NoopNetwork; - use reth_primitives::{ - constants::ETHEREUM_BLOCK_GAS_LIMIT, BaseFeeParams, Block, BlockNumberOrTag, Header, - TransactionSigned, B256, U64, - }; - use reth_provider::{ - test_utils::{MockEthProvider, NoopProvider}, - BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory, - }; - use reth_rpc_api::EthApiServer; - use reth_rpc_types::FeeHistory; - use reth_tasks::pool::BlockingTaskPool; - use reth_testing_utils::{generators, generators::Rng}; - use reth_transaction_pool::test_utils::{testing_pool, TestPool}; - - fn build_test_eth_api< - P: BlockReaderIdExt - + BlockReader - + ChainSpecProvider - + EvmEnvProvider - + StateProviderFactory - + Unpin - + Clone - + 'static, - >( - provider: P, - ) -> EthApi { - let evm_config = EthEvmConfig::default(); - let cache = EthStateCache::spawn(provider.clone(), Default::default(), evm_config); - let fee_history_cache = - FeeHistoryCache::new(cache.clone(), FeeHistoryCacheConfig::default()); - - EthApi::new( - provider.clone(), - testing_pool(), - NoopNetwork::default(), - cache.clone(), - GasPriceOracle::new(provider, Default::default(), cache), - ETHEREUM_BLOCK_GAS_LIMIT, - BlockingTaskPool::build().expect("failed to build tracing pool"), - fee_history_cache, - evm_config, - None, - ) - } - - // Function to prepare the EthApi with mock data - fn prepare_eth_api( - newest_block: u64, - mut oldest_block: Option, - block_count: u64, - mock_provider: MockEthProvider, - ) -> (EthApi, Vec, Vec) { - let mut rng = generators::rng(); - - // Build mock data - let mut gas_used_ratios = Vec::new(); - let mut base_fees_per_gas = Vec::new(); - let mut last_header = None; - let mut parent_hash = B256::default(); - - for i in (0..block_count).rev() { - let hash = rng.gen(); - let gas_limit: u64 = rng.gen(); - let gas_used: u64 = rng.gen(); - // Note: Generates a u32 to avoid overflows later - let base_fee_per_gas: Option = rng.gen::().then(|| rng.gen::() as u64); - - let header = Header { - number: newest_block - i, - gas_limit, - gas_used, - base_fee_per_gas, - parent_hash, - ..Default::default() - }; - last_header = Some(header.clone()); - parent_hash = hash; - - let mut transactions = vec![]; - for _ in 0..100 { - let random_fee: u128 = rng.gen(); - - if let Some(base_fee_per_gas) = header.base_fee_per_gas { - let transaction = TransactionSigned { - transaction: reth_primitives::Transaction::Eip1559( - reth_primitives::TxEip1559 { - max_priority_fee_per_gas: random_fee, - max_fee_per_gas: random_fee + base_fee_per_gas as u128, - ..Default::default() - }, - ), - ..Default::default() - }; - - transactions.push(transaction); - } else { - let transaction = TransactionSigned { - transaction: reth_primitives::Transaction::Legacy(Default::default()), - ..Default::default() - }; - - transactions.push(transaction); - } - } - - mock_provider.add_block( - hash, - Block { header: header.clone(), body: transactions, ..Default::default() }, - ); - mock_provider.add_header(hash, header); - - oldest_block.get_or_insert(hash); - gas_used_ratios.push(gas_used as f64 / gas_limit as f64); - base_fees_per_gas.push(base_fee_per_gas.map(|fee| fee as u128).unwrap_or_default()); - } - - // Add final base fee (for the next block outside of the request) - let last_header = last_header.unwrap(); - base_fees_per_gas.push(BaseFeeParams::ethereum().next_block_base_fee( - last_header.gas_used as u128, - last_header.gas_limit as u128, - last_header.base_fee_per_gas.unwrap_or_default() as u128, - )); - - let eth_api = build_test_eth_api(mock_provider); - - (eth_api, base_fees_per_gas, gas_used_ratios) - } - - /// Invalid block range - #[tokio::test] - async fn test_fee_history_empty() { - let response = as EthApiServer>::fee_history( - &build_test_eth_api(NoopProvider::default()), - U64::from(1), - BlockNumberOrTag::Latest, - None, - ) - .await; - assert!(response.is_err()); - let error_object = response.unwrap_err(); - assert_eq!(error_object.code(), INVALID_PARAMS_CODE); - } - - #[tokio::test] - /// Invalid block range (request is before genesis) - async fn test_fee_history_invalid_block_range_before_genesis() { - let block_count = 10; - let newest_block = 1337; - let oldest_block = None; - - let (eth_api, _, _) = - prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); - - let response = as EthApiServer>::fee_history( - ð_api, - U64::from(newest_block + 1), - newest_block.into(), - Some(vec![10.0]), - ) - .await; - - assert!(response.is_err()); - let error_object = response.unwrap_err(); - assert_eq!(error_object.code(), INVALID_PARAMS_CODE); - } - - #[tokio::test] - /// Invalid block range (request is in the future) - async fn test_fee_history_invalid_block_range_in_future() { - let block_count = 10; - let newest_block = 1337; - let oldest_block = None; - - let (eth_api, _, _) = - prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); - - let response = as EthApiServer>::fee_history( - ð_api, - U64::from(1), - (newest_block + 1000).into(), - Some(vec![10.0]), - ) - .await; - - assert!(response.is_err()); - let error_object = response.unwrap_err(); - assert_eq!(error_object.code(), INVALID_PARAMS_CODE); - } - - #[tokio::test] - /// Requesting no block should result in a default response - async fn test_fee_history_no_block_requested() { - let block_count = 10; - let newest_block = 1337; - let oldest_block = None; - - let (eth_api, _, _) = - prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); - - let response = as EthApiServer>::fee_history( - ð_api, - U64::from(0), - newest_block.into(), - None, - ) - .await - .unwrap(); - assert_eq!( - response, - FeeHistory::default(), - "none: requesting no block should yield a default response" - ); - } - - #[tokio::test] - /// Requesting a single block should return 1 block (+ base fee for the next block over) - async fn test_fee_history_single_block() { - let block_count = 10; - let newest_block = 1337; - let oldest_block = None; - - let (eth_api, base_fees_per_gas, gas_used_ratios) = - prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); - - let fee_history = - eth_api.fee_history(U64::from(1), newest_block.into(), None).await.unwrap(); - assert_eq!( - fee_history.base_fee_per_gas, - &base_fees_per_gas[base_fees_per_gas.len() - 2..], - "one: base fee per gas is incorrect" - ); - assert_eq!( - fee_history.base_fee_per_gas.len(), - 2, - "one: should return base fee of the next block as well" - ); - assert_eq!( - &fee_history.gas_used_ratio, - &gas_used_ratios[gas_used_ratios.len() - 1..], - "one: gas used ratio is incorrect" - ); - assert_eq!(fee_history.oldest_block, newest_block, "one: oldest block is incorrect"); - assert!( - fee_history.reward.is_none(), - "one: no percentiles were requested, so there should be no rewards result" - ); - } - - /// Requesting all blocks should be ok - #[tokio::test] - async fn test_fee_history_all_blocks() { - let block_count = 10; - let newest_block = 1337; - let oldest_block = None; - - let (eth_api, base_fees_per_gas, gas_used_ratios) = - prepare_eth_api(newest_block, oldest_block, block_count, MockEthProvider::default()); - - let fee_history = - eth_api.fee_history(U64::from(block_count), newest_block.into(), None).await.unwrap(); - - assert_eq!( - &fee_history.base_fee_per_gas, &base_fees_per_gas, - "all: base fee per gas is incorrect" - ); - assert_eq!( - fee_history.base_fee_per_gas.len() as u64, - block_count + 1, - "all: should return base fee of the next block as well" - ); - assert_eq!( - &fee_history.gas_used_ratio, &gas_used_ratios, - "all: gas used ratio is incorrect" - ); - assert_eq!( - fee_history.oldest_block, - newest_block - block_count + 1, - "all: oldest block is incorrect" - ); - assert!( - fee_history.reward.is_none(), - "all: no percentiles were requested, so there should be no rewards result" - ); - } -} diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc/src/eth/bundle.rs index a452f60b6c7..1640b9c7c8f 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc/src/eth/bundle.rs @@ -12,6 +12,11 @@ use reth_primitives::{ }; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::EthCallBundleApiServer; +use reth_rpc_eth_api::eth::{ + api::{Call, EthTransactions, LoadPendingBlock}, + error::{EthApiError, EthResult, RpcInvalidTransactionError}, + utils::recover_raw_transaction, +}; use reth_rpc_types::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use reth_tasks::pool::BlockingTaskGuard; use revm::{ @@ -20,12 +25,6 @@ use revm::{ }; use revm_primitives::{EnvWithHandlerCfg, MAX_BLOB_GAS_PER_BLOCK}; -use crate::eth::{ - api::{Call, EthTransactions, LoadPendingBlock}, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, - utils::recover_raw_transaction, -}; - /// `Eth` bundle implementation. pub struct EthBundle { /// All nested fields bundled together. diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 08b22aa7407..244c1e498dd 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -1,19 +1,24 @@ -use super::cache::EthStateCache; -use crate::{ - eth::{ - error::EthApiError, - logs_utils::{self, append_matching_block_logs}, - }, - result::{rpc_error_with_code, ToRpcResult}, - EthSubscriptionIdProvider, +use std::{ + collections::HashMap, + fmt, + iter::StepBy, + ops::RangeInclusive, + sync::Arc, + time::{Duration, Instant}, }; -use core::fmt; use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_primitives::{ChainInfo, IntoRecoveredTransaction, TxHash}; use reth_provider::{BlockIdReader, BlockReader, EvmEnvProvider, ProviderError}; use reth_rpc_api::EthFilterApiServer; +use reth_rpc_eth_api::{ + eth::{ + cache::EthStateCache, + error::EthApiError, + }, + result::{rpc_error_with_code, ToRpcResult}, +}; use reth_rpc_types::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, PendingTransactionFilterKind, @@ -21,19 +26,14 @@ use reth_rpc_types::{ use reth_tasks::TaskSpawner; use reth_transaction_pool::{NewSubpoolTransactionStream, PoolTransaction, TransactionPool}; -use std::{ - collections::HashMap, - iter::StepBy, - ops::RangeInclusive, - sync::Arc, - time::{Duration, Instant}, -}; use tokio::{ sync::{mpsc::Receiver, Mutex}, time::MissedTickBehavior, }; use tracing::trace; +use crate::{EthSubscriptionIdProvider, eth::logs_utils::{self, append_matching_block_logs}}; + /// The maximum number of headers we read at once when handling a range filter. const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb diff --git a/crates/rpc/rpc/src/eth/mod.rs b/crates/rpc/rpc/src/eth/mod.rs index 79a8028a258..d4bbf04f895 100644 --- a/crates/rpc/rpc/src/eth/mod.rs +++ b/crates/rpc/rpc/src/eth/mod.rs @@ -1,25 +1,13 @@ -//! `eth` namespace handler implementation. - -pub mod api; pub mod bundle; -pub mod cache; -pub mod error; -mod filter; -pub mod gas_oracle; -mod id_provider; -mod logs_utils; -mod pubsub; -pub mod revm_utils; -mod signer; -pub(crate) mod utils; - -pub use api::{ - fee_history::{fee_history_cache_new_blocks_task, FeeHistoryCache, FeeHistoryCacheConfig}, - EthApi, EthApiSpec, PendingBlock, TransactionSource, RPC_DEFAULT_GAS_CAP, -}; +pub mod filter; +pub mod id_provider; +pub mod logs_utils; +pub mod pubsub; pub use bundle::EthBundle; pub use filter::{EthFilter, EthFilterConfig}; pub use id_provider::EthSubscriptionIdProvider; pub use pubsub::EthPubSub; -pub use signer::EthSigner; + + +pub use reth_rpc_eth_api::eth::*; \ No newline at end of file diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index 17dc8fcb809..c5b53d28f86 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -46,7 +46,7 @@ mod web3; pub use admin::AdminApi; pub use debug::DebugApi; pub use engine::{EngineApi, EngineEthApi}; -pub use eth::{EthApi, EthApiSpec, EthFilter, EthPubSub, EthSubscriptionIdProvider}; +pub use eth::{EthFilter, EthPubSub, EthSubscriptionIdProvider}; pub use net::NetApi; pub use otterscan::OtterscanApi; pub use reth::RethApi; @@ -54,4 +54,6 @@ pub use rpc::RPCApi; pub use trace::TraceApi; pub use txpool::TxPoolApi; pub use web3::Web3Api; -pub mod result; + + +pub use reth_rpc_eth_api::{result, eth::EthApi}; \ No newline at end of file diff --git a/crates/rpc/rpc/src/net.rs b/crates/rpc/rpc/src/net.rs index 8e6615a281b..2454e6ee56a 100644 --- a/crates/rpc/rpc/src/net.rs +++ b/crates/rpc/rpc/src/net.rs @@ -1,8 +1,8 @@ -use crate::eth::EthApiSpec; use jsonrpsee::core::RpcResult as Result; use reth_network_api::PeersInfo; use reth_primitives::U64; use reth_rpc_api::NetApiServer; +use reth_rpc_eth_api::eth::EthApiSpec; use reth_rpc_types::PeerCount; /// `Net` API implementation. diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index 6314acd9f7e..c42c205c5d0 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -3,6 +3,10 @@ use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_primitives::{Address, BlockId, BlockNumberOrTag, TxHash, B256}; use reth_rpc_api::{EthApiServer, OtterscanServer}; +use reth_rpc_eth_api::{ + eth::api::{LoadBlock, LoadTransaction, TraceExt}, + result::internal_rpc_err, +}; use reth_rpc_types::{ trace::otterscan::{ BlockDetails, ContractCreator, InternalOperation, OperationType, OtsBlockTransactions, @@ -13,11 +17,6 @@ use reth_rpc_types::{ use revm_inspectors::transfer::{TransferInspector, TransferKind}; use revm_primitives::ExecutionResult; -use crate::{ - eth::api::{LoadBlock, LoadTransaction, TraceExt}, - result::internal_rpc_err, -}; - const API_LEVEL: u64 = 8; /// Otterscan API. diff --git a/crates/rpc/rpc/src/reth.rs b/crates/rpc/rpc/src/reth.rs index 17925b5ab8b..7d5f1e74ba7 100644 --- a/crates/rpc/rpc/src/reth.rs +++ b/crates/rpc/rpc/src/reth.rs @@ -1,10 +1,10 @@ -use crate::eth::error::{EthApiError, EthResult}; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_errors::RethResult; use reth_primitives::{Address, BlockId, U256}; use reth_provider::{BlockReaderIdExt, ChangeSetReader, StateProviderFactory}; use reth_rpc_api::RethApiServer; +use reth_rpc_eth_api::eth::error::{EthApiError, EthResult}; use reth_tasks::TaskSpawner; use std::{collections::HashMap, future::Future, sync::Arc}; use tokio::sync::oneshot; diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 50b6c2bcf22..4b5b38081c5 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -7,6 +7,12 @@ use reth_primitives::{revm::env::tx_env_with_recovered, BlockId, Bytes, SealedHe use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::TraceApiServer; +use reth_rpc_eth_api::eth::{ + api::{LoadBlock, LoadTransaction, TraceExt}, + error::{EthApiError, EthResult}, + revm_utils::{prepare_call_env, EvmOverrides}, + utils::recover_raw_transaction, +}; use reth_rpc_types::{ state::StateOverride, trace::{ @@ -28,13 +34,6 @@ use revm_inspectors::{ }; use tokio::sync::{AcquireError, OwnedSemaphorePermit}; -use crate::eth::{ - api::{LoadBlock, LoadTransaction, TraceExt}, - error::{EthApiError, EthResult}, - revm_utils::{prepare_call_env, EvmOverrides}, - utils::recover_raw_transaction, -}; - /// `trace` API implementation. /// /// This type provides the functionality for handling `trace` related requests. From 53a97b87ca8735537ad059fab59b40a7af47f48e Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Fri, 14 Jun 2024 19:14:49 +0200 Subject: [PATCH 04/16] Run fmt --- crates/rpc/rpc-builder/src/eth.rs | 4 ++-- crates/rpc/rpc-eth-api/src/eth/api/mod.rs | 8 ++++---- .../rpc-eth-api/src/eth/api/pending_block.rs | 5 +++-- crates/rpc/rpc-eth-api/src/eth/api/receipt.rs | 12 +++++------- crates/rpc/rpc-eth-api/src/eth/api/server.rs | 2 +- .../rpc/rpc-eth-api/src/eth/api/traits/call.rs | 4 ++-- .../rpc/rpc-eth-api/src/eth/api/traits/mod.rs | 4 ++-- .../rpc-eth-api/src/eth/api/traits/state.rs | 12 +++++------- crates/rpc/rpc-eth-api/src/eth/utils.rs | 4 +--- crates/rpc/rpc-eth-api/src/server.rs | 18 +++++++++++++----- crates/rpc/rpc-testing-util/tests/it/trace.rs | 2 +- crates/rpc/rpc/src/eth/filter.rs | 10 +++++----- crates/rpc/rpc/src/eth/mod.rs | 3 +-- crates/rpc/rpc/src/lib.rs | 3 +-- 14 files changed, 46 insertions(+), 45 deletions(-) diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index ece57a46076..a2dbbcb4f72 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -2,9 +2,9 @@ use reth_rpc::{ eth::{ cache::{EthStateCache, EthStateCacheConfig}, gas_oracle::GasPriceOracleConfig, - EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, EthApi + EthApi, EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, }, - EthFilter, EthPubSub, + EthFilter, EthPubSub, }; use reth_rpc_server_types::constants::{ default_max_tracing_requests, DEFAULT_MAX_BLOCKS_PER_FILTER, DEFAULT_MAX_LOGS_PER_RESPONSE, diff --git a/crates/rpc/rpc-eth-api/src/eth/api/mod.rs b/crates/rpc/rpc-eth-api/src/eth/api/mod.rs index bf66825c2e9..ce0e970e025 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/mod.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/mod.rs @@ -70,10 +70,10 @@ pub trait EthApiSpec: Send + Sync { /// /// This type provides the functionality for handling `eth_` related requests. /// These are implemented two-fold: Core functionality is implemented as [`EthApiSpec`] -/// trait. Additionally, the required server implementations (e.g. [`reth_rpc_eth_api::EthApiServer`]) -/// are implemented separately in submodules. The rpc handler implementation can then delegate to -/// the main impls. This way [`EthApi`] is not limited to [`jsonrpsee`] and can be used standalone -/// or in other network handlers (for example ipc). +/// trait. Additionally, the required server implementations (e.g. +/// [`reth_rpc_eth_api::EthApiServer`]) are implemented separately in submodules. The rpc handler +/// implementation can then delegate to the main impls. This way [`EthApi`] is not limited to +/// [`jsonrpsee`] and can be used standalone or in other network handlers (for example ipc). pub struct EthApi { /// All nested fields bundled together. inner: Arc>, diff --git a/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs b/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs index 604831d3235..118d3524cba 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs @@ -12,8 +12,9 @@ use reth_revm::state_change::{apply_beacon_root_contract_call, apply_blockhashes use revm::{Database, DatabaseCommit}; use revm_primitives::EnvWithHandlerCfg; -use crate::{ - eth::{EthApi, error::{EthApiError, EthResult}}, +use crate::eth::{ + error::{EthApiError, EthResult}, + EthApi, }; /// Implements [`LoadPendingBlock`](crate::eth::api::LoadPendingBlock) for a type, that has similar diff --git a/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs b/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs index aa563dc8335..6669925a143 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs @@ -10,13 +10,11 @@ use reth_rpc_types::{ TransactionReceipt, WithOtherFields, }; -use crate::{ - eth::{ - EthApi, - api::LoadReceipt, - cache::EthStateCache, - error::{EthApiError, EthResult}, - }, +use crate::eth::{ + api::LoadReceipt, + cache::EthStateCache, + error::{EthApiError, EthResult}, + EthApi, }; impl LoadReceipt for EthApi diff --git a/crates/rpc/rpc-eth-api/src/eth/api/server.rs b/crates/rpc/rpc-eth-api/src/eth/api/server.rs index 46cee106d79..c41a1ae9d9e 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/server.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/server.rs @@ -24,6 +24,6 @@ use crate::{ revm_utils::EvmOverrides, EthApi, }, - EthApiServer, result::{internal_rpc_err, ToRpcResult}, + EthApiServer, }; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs index 2a5c9f8fc30..e6283e7ced2 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs @@ -40,8 +40,8 @@ pub const ESTIMATE_GAS_ERROR_RATIO: f64 = 0.015; /// Helper alias type for the state's [`CacheDB`] pub type StateCacheDB<'a> = CacheDB>>; -/// Execution related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the -/// `eth_` namespace. +/// Execution related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in +/// the `eth_` namespace. pub trait EthCall: Call + LoadPendingBlock { /// Estimate gas needed for execution of the `request` at the [`BlockId`]. fn estimate_gas_at( diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs index 41a0a80e2ae..35c506a325e 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs @@ -11,8 +11,8 @@ //! divided into: [`EthTransactions`], [`EthBlocks`], [`EthFees`], [`EthState`] and [`EthCall`]. //! Default implementation of the `Eth` traits, is done w.r.t. L1. //! -//! [`EthApiServer`](reth_rpc_eth_api::EthApiServer), is implemented for any type that implements all -//! the `Eth` traits, e.g. [`EthApi`](crate::EthApi). +//! [`EthApiServer`](reth_rpc_eth_api::EthApiServer), is implemented for any type that implements +//! all the `Eth` traits, e.g. [`EthApi`](crate::EthApi). pub mod block; pub mod blocking_task; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs b/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs index 2a76cfa169e..7d421e71667 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs +++ b/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs @@ -12,13 +12,11 @@ use reth_rpc_types_compat::proof::from_primitive_account_proof; use reth_transaction_pool::{PoolTransaction, TransactionPool}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}; -use crate::{ - eth::{ - api::{pending_block::PendingBlockEnv, LoadPendingBlock, SpawnBlocking}, - cache::EthStateCache, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, - EthApiSpec, - }, +use crate::eth::{ + api::{pending_block::PendingBlockEnv, LoadPendingBlock, SpawnBlocking}, + cache::EthStateCache, + error::{EthApiError, EthResult, RpcInvalidTransactionError}, + EthApiSpec, }; /// Helper methods for `eth_` methods relating to state (accounts). diff --git a/crates/rpc/rpc-eth-api/src/eth/utils.rs b/crates/rpc/rpc-eth-api/src/eth/utils.rs index a4e92d0b8a9..5aa876c78c8 100644 --- a/crates/rpc/rpc-eth-api/src/eth/utils.rs +++ b/crates/rpc/rpc-eth-api/src/eth/utils.rs @@ -6,9 +6,7 @@ use reth_primitives::{Bytes, PooledTransactionsElement, PooledTransactionsElemen /// Recovers a [`PooledTransactionsElementEcRecovered`] from an enveloped encoded byte stream. /// /// See [`PooledTransactionsElement::decode_enveloped`] -pub fn recover_raw_transaction( - data: Bytes, -) -> EthResult { +pub fn recover_raw_transaction(data: Bytes) -> EthResult { if data.is_empty() { return Err(EthApiError::EmptyRawTransactionData) } diff --git a/crates/rpc/rpc-eth-api/src/server.rs b/crates/rpc/rpc-eth-api/src/server.rs index de6036659a8..1d757cb6805 100644 --- a/crates/rpc/rpc-eth-api/src/server.rs +++ b/crates/rpc/rpc-eth-api/src/server.rs @@ -12,19 +12,28 @@ use serde_json::Value; use tracing::trace; use crate::{ - EthApiServer, eth::{ - api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, Trace, LoadReceipt}, + api::{ + EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, LoadReceipt, Trace, + }, error::EthApiError, revm_utils::EvmOverrides, }, result::{internal_rpc_err, ToRpcResult}, + EthApiServer, }; #[async_trait::async_trait] impl EthApiServer for T where - Self: EthApiSpec + EthTransactions + EthBlocks + EthState + EthCall + EthFees + Trace + LoadReceipt, + Self: EthApiSpec + + EthTransactions + + EthBlocks + + EthState + + EthCall + + EthFees + + Trace + + LoadReceipt, { /// Handler for: `eth_protocolVersion` async fn protocol_version(&self) -> Result { @@ -414,8 +423,7 @@ where mod tests { use crate::{ eth::{ - EthApi, - cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, + cache::EthStateCache, gas_oracle::GasPriceOracle, EthApi, FeeHistoryCache, FeeHistoryCacheConfig, }, EthApiServer, diff --git a/crates/rpc/rpc-testing-util/tests/it/trace.rs b/crates/rpc/rpc-testing-util/tests/it/trace.rs index a132937e888..029e9fbbc8b 100644 --- a/crates/rpc/rpc-testing-util/tests/it/trace.rs +++ b/crates/rpc/rpc-testing-util/tests/it/trace.rs @@ -1,7 +1,7 @@ use futures::StreamExt; use jsonrpsee::http_client::HttpClientBuilder; -use reth_rpc_eth_api::EthApiClient; use reth_rpc_api_testing_util::{debug::DebugApiExt, trace::TraceApiExt, utils::parse_env_url}; +use reth_rpc_eth_api::EthApiClient; use reth_rpc_types::trace::{ filter::TraceFilter, parity::TraceType, tracerequest::TraceCallRequest, }; diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc/src/eth/filter.rs index 244c1e498dd..0a15f905087 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc/src/eth/filter.rs @@ -13,10 +13,7 @@ use reth_primitives::{ChainInfo, IntoRecoveredTransaction, TxHash}; use reth_provider::{BlockIdReader, BlockReader, EvmEnvProvider, ProviderError}; use reth_rpc_api::EthFilterApiServer; use reth_rpc_eth_api::{ - eth::{ - cache::EthStateCache, - error::EthApiError, - }, + eth::{cache::EthStateCache, error::EthApiError}, result::{rpc_error_with_code, ToRpcResult}, }; use reth_rpc_types::{ @@ -32,7 +29,10 @@ use tokio::{ }; use tracing::trace; -use crate::{EthSubscriptionIdProvider, eth::logs_utils::{self, append_matching_block_logs}}; +use crate::{ + eth::logs_utils::{self, append_matching_block_logs}, + EthSubscriptionIdProvider, +}; /// The maximum number of headers we read at once when handling a range filter. const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb diff --git a/crates/rpc/rpc/src/eth/mod.rs b/crates/rpc/rpc/src/eth/mod.rs index d4bbf04f895..df13ea022e1 100644 --- a/crates/rpc/rpc/src/eth/mod.rs +++ b/crates/rpc/rpc/src/eth/mod.rs @@ -9,5 +9,4 @@ pub use filter::{EthFilter, EthFilterConfig}; pub use id_provider::EthSubscriptionIdProvider; pub use pubsub::EthPubSub; - -pub use reth_rpc_eth_api::eth::*; \ No newline at end of file +pub use reth_rpc_eth_api::eth::*; diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index c5b53d28f86..ebb876d3757 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -55,5 +55,4 @@ pub use trace::TraceApi; pub use txpool::TxPoolApi; pub use web3::Web3Api; - -pub use reth_rpc_eth_api::{result, eth::EthApi}; \ No newline at end of file +pub use reth_rpc_eth_api::{eth::EthApi, result}; From 6a3b05903ca9eb4720568c446f8256a5c5c909f5 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 15 Jun 2024 11:55:43 +0200 Subject: [PATCH 05/16] Structure reth-rpc-eth-api fs --- Cargo.lock | 22 +- crates/ethereum/node/tests/e2e/dev.rs | 2 +- crates/node-core/Cargo.toml | 4 +- crates/node-core/src/args/gas_price_oracle.rs | 2 +- crates/node-core/src/args/rpc_server.rs | 2 +- crates/node-core/src/lib.rs | 4 +- crates/optimism/rpc/Cargo.toml | 2 +- crates/optimism/rpc/src/lib.rs | 6 +- crates/rpc/rpc-api/src/lib.rs | 17 +- crates/rpc/rpc-builder/src/auth.rs | 2 +- crates/rpc/rpc-builder/src/config.rs | 2 +- crates/rpc/rpc-builder/src/eth.rs | 10 +- crates/rpc/rpc-builder/src/lib.rs | 12 +- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- .../src => rpc-eth-api/src/api}/bundle.rs | 2 +- .../src/api/filter.rs} | 3 + crates/rpc/rpc-eth-api/src/api/mod.rs | 317 ++++++++++++++++ .../src/api/pubsub.rs} | 2 + .../src/api/servers}/bundle.rs | 12 +- .../src/api/servers}/filter.rs | 112 +++--- .../{eth/api => api/servers/helpers}/block.rs | 16 +- .../{eth/api => api/servers/helpers}/call.rs | 14 +- .../{eth/api => api/servers/helpers}/fees.rs | 23 +- .../src/api/servers/helpers/mod.rs | 15 + .../src/api/servers/helpers/pending_block.rs | 48 +++ .../src/api/servers/helpers/receipt.rs | 13 + .../{eth => api/servers/helpers}/signer.rs | 49 +-- .../src/api/servers/helpers/spec.rs | 63 +++ .../{eth/api => api/servers/helpers}/state.rs | 28 +- .../{eth/api => api/servers/helpers}/trace.rs | 8 +- .../servers/helpers}/traits/block.rs | 7 +- .../servers/helpers}/traits/blocking_task.rs | 2 +- .../servers/helpers}/traits/call.rs | 183 +-------- .../api => api/servers/helpers}/traits/fee.rs | 13 +- .../api => api/servers/helpers}/traits/mod.rs | 15 +- .../servers/helpers}/traits/pending_block.rs | 13 +- .../servers/helpers}/traits/receipt.rs | 6 +- .../src/api/servers/helpers/traits/signer.rs | 40 ++ .../src/api/servers/helpers/traits/spec.rs | 30 ++ .../servers/helpers}/traits/state.rs | 8 +- .../servers/helpers}/traits/trace.rs | 36 +- .../servers/helpers}/traits/transaction.rs | 12 +- .../servers/helpers/transaction.rs} | 125 +----- .../src/{eth/api => api/servers}/mod.rs | 180 ++------- .../src/api/servers}/pubsub.rs | 18 +- .../src/{ => api/servers}/server.rs | 35 +- .../rpc-eth-api/src/{eth => }/cache/config.rs | 0 crates/rpc/rpc-eth-api/src/cache/db.rs | 165 ++++++++ .../src/{eth => }/cache/metrics.rs | 0 .../rpc-eth-api/src/{eth => }/cache/mod.rs | 11 +- .../src/{eth => }/cache/multi_consumer.rs | 0 crates/rpc/rpc-eth-api/src/{eth => }/error.rs | 0 .../rpc/rpc-eth-api/src/eth/api/optimism.rs | 31 -- crates/rpc/rpc-eth-api/src/eth/api/server.rs | 29 -- crates/rpc/rpc-eth-api/src/eth/api/sign.rs | 12 - crates/rpc/rpc-eth-api/src/eth/mod.rs | 16 - .../src/{eth/api => }/fee_history.rs | 2 +- .../rpc-eth-api/src/{eth => }/gas_oracle.rs | 45 ++- .../eth => rpc-eth-api/src}/id_provider.rs | 7 +- crates/rpc/rpc-eth-api/src/lib.rs | 358 +++--------------- .../src/eth => rpc-eth-api/src}/logs_utils.rs | 12 +- .../src/{eth/api => }/pending_block.rs | 67 +--- .../rpc-eth-api/src/{eth/api => }/receipt.rs | 30 +- .../rpc-eth-api/src/{eth => }/revm_utils.rs | 6 +- crates/rpc/rpc-eth-api/src/transaction.rs | 96 +++++ crates/rpc/rpc-eth-api/src/{eth => }/utils.rs | 3 +- crates/rpc/rpc/Cargo.toml | 24 -- crates/rpc/rpc/src/admin.rs | 6 +- crates/rpc/rpc/src/debug.rs | 13 +- crates/rpc/rpc/src/eth/mod.rs | 12 - crates/rpc/rpc/src/lib.rs | 5 +- crates/rpc/rpc/src/net.rs | 2 +- crates/rpc/rpc/src/otterscan.rs | 2 +- crates/rpc/rpc/src/reth.rs | 5 +- crates/rpc/rpc/src/trace.rs | 4 +- crates/rpc/rpc/src/web3.rs | 3 +- crates/storage/nippy-jar/src/error.rs | 2 +- 77 files changed, 1222 insertions(+), 1283 deletions(-) rename crates/rpc/{rpc-api/src => rpc-eth-api/src/api}/bundle.rs (98%) rename crates/rpc/{rpc-api/src/eth_filter.rs => rpc-eth-api/src/api/filter.rs} (97%) create mode 100644 crates/rpc/rpc-eth-api/src/api/mod.rs rename crates/rpc/{rpc-api/src/eth_pubsub.rs => rpc-eth-api/src/api/pubsub.rs} (92%) rename crates/rpc/{rpc/src/eth => rpc-eth-api/src/api/servers}/bundle.rs (98%) rename crates/rpc/{rpc/src/eth => rpc-eth-api/src/api/servers}/filter.rs (94%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/block.rs (61%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/call.rs (60%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/fees.rs (59%) create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/mod.rs create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/pending_block.rs create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/receipt.rs rename crates/rpc/rpc-eth-api/src/{eth => api/servers/helpers}/signer.rs (86%) create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/state.rs (83%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/trace.rs (65%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/block.rs (98%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/blocking_task.rs (97%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/call.rs (84%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/fee.rs (98%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/mod.rs (78%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/pending_block.rs (98%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/receipt.rs (92%) create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/signer.rs create mode 100644 crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/spec.rs rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/state.rs (97%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/trace.rs (94%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers/helpers}/traits/transaction.rs (99%) rename crates/rpc/rpc-eth-api/src/{eth/api/transactions.rs => api/servers/helpers/transaction.rs} (60%) rename crates/rpc/rpc-eth-api/src/{eth/api => api/servers}/mod.rs (66%) rename crates/rpc/{rpc/src/eth => rpc-eth-api/src/api/servers}/pubsub.rs (98%) rename crates/rpc/rpc-eth-api/src/{ => api/servers}/server.rs (97%) rename crates/rpc/rpc-eth-api/src/{eth => }/cache/config.rs (100%) create mode 100644 crates/rpc/rpc-eth-api/src/cache/db.rs rename crates/rpc/rpc-eth-api/src/{eth => }/cache/metrics.rs (100%) rename crates/rpc/rpc-eth-api/src/{eth => }/cache/mod.rs (99%) rename crates/rpc/rpc-eth-api/src/{eth => }/cache/multi_consumer.rs (100%) rename crates/rpc/rpc-eth-api/src/{eth => }/error.rs (100%) delete mode 100644 crates/rpc/rpc-eth-api/src/eth/api/optimism.rs delete mode 100644 crates/rpc/rpc-eth-api/src/eth/api/server.rs delete mode 100644 crates/rpc/rpc-eth-api/src/eth/api/sign.rs delete mode 100644 crates/rpc/rpc-eth-api/src/eth/mod.rs rename crates/rpc/rpc-eth-api/src/{eth/api => }/fee_history.rs (99%) rename crates/rpc/rpc-eth-api/src/{eth => }/gas_oracle.rs (90%) rename crates/rpc/{rpc/src/eth => rpc-eth-api/src}/id_provider.rs (93%) rename crates/rpc/{rpc/src/eth => rpc-eth-api/src}/logs_utils.rs (96%) rename crates/rpc/rpc-eth-api/src/{eth/api => }/pending_block.rs (72%) rename crates/rpc/rpc-eth-api/src/{eth/api => }/receipt.rs (86%) rename crates/rpc/rpc-eth-api/src/{eth => }/revm_utils.rs (99%) create mode 100644 crates/rpc/rpc-eth-api/src/transaction.rs rename crates/rpc/rpc-eth-api/src/{eth => }/utils.rs (93%) delete mode 100644 crates/rpc/rpc/src/eth/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 4f1a773d9db..fdaec31803b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7493,8 +7493,8 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-prune-types", - "reth-rpc", "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-server-types", "reth-rpc-types", "reth-rpc-types-compat", @@ -7658,7 +7658,7 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-rpc", - "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-types", "reth-tasks", "reth-transaction-pool", @@ -7889,30 +7889,20 @@ dependencies = [ name = "reth-rpc" version = "1.0.0-rc.1" dependencies = [ - "alloy-dyn-abi", "alloy-primitives", "alloy-rlp", - "alloy-sol-types", "assert_matches", "async-trait", - "auto_impl", - "derive_more", - "dyn-clone", "futures", "http 1.1.0", "http-body", "hyper", "jsonrpsee", "jsonwebtoken 8.3.0", - "metrics", - "parking_lot 0.12.3", "pin-project", - "rand 0.8.5", "reth-consensus-common", "reth-errors", - "reth-evm", "reth-evm-ethereum", - "reth-metrics", "reth-network-api", "reth-network-peers", "reth-primitives", @@ -7921,24 +7911,16 @@ dependencies = [ "reth-rpc-api", "reth-rpc-engine-api", "reth-rpc-eth-api", - "reth-rpc-server-types", "reth-rpc-types", "reth-rpc-types-compat", "reth-tasks", "reth-testing-utils", "reth-transaction-pool", - "reth-trie", "revm", "revm-inspectors", "revm-primitives", - "schnellru", - "secp256k1 0.28.2", - "serde", - "serde_json", "tempfile", - "thiserror", "tokio", - "tokio-stream", "tower", "tracing", "tracing-futures", diff --git a/crates/ethereum/node/tests/e2e/dev.rs b/crates/ethereum/node/tests/e2e/dev.rs index dcda6929fde..4570a8c0e12 100644 --- a/crates/ethereum/node/tests/e2e/dev.rs +++ b/crates/ethereum/node/tests/e2e/dev.rs @@ -1,6 +1,6 @@ use crate::utils::EthNode; use futures::StreamExt; -use reth::rpc::eth::api::EthTransactions; +use reth::rpc::eth::EthTransactions; use reth_e2e_test_utils::setup; use reth_primitives::{b256, hex, ChainSpec, Genesis}; use reth_provider::CanonStateSubscriptions; diff --git a/crates/node-core/Cargo.toml b/crates/node-core/Cargo.toml index 27271cdc470..018677884f2 100644 --- a/crates/node-core/Cargo.toml +++ b/crates/node-core/Cargo.toml @@ -20,11 +20,11 @@ reth-storage-errors.workspace = true reth-provider.workspace = true reth-network = { workspace = true, features = ["serde"] } reth-network-p2p.workspace = true -reth-rpc.workspace = true reth-rpc-server-types.workspace = true reth-rpc-types.workspace = true reth-rpc-types-compat.workspace = true reth-rpc-api = { workspace = true, features = ["client"] } +reth-rpc-eth-api = { workspace = true, features = ["client"] } reth-transaction-pool.workspace = true reth-tracing.workspace = true reth-config.workspace = true @@ -101,10 +101,10 @@ reth-network-peers.workspace = true [features] optimism = [ "reth-primitives/optimism", - "reth-rpc/optimism", "reth-provider/optimism", "reth-rpc-types-compat/optimism", "reth-beacon-consensus/optimism", + "reth-rpc-eth-api/optimism", ] jemalloc = ["dep:tikv-jemalloc-ctl"] diff --git a/crates/node-core/src/args/gas_price_oracle.rs b/crates/node-core/src/args/gas_price_oracle.rs index 5148fdca34b..c719e9c8a5f 100644 --- a/crates/node-core/src/args/gas_price_oracle.rs +++ b/crates/node-core/src/args/gas_price_oracle.rs @@ -1,6 +1,6 @@ use crate::primitives::U256; use clap::Args; -use reth_rpc::eth::gas_oracle::GasPriceOracleConfig; +use reth_rpc_eth_api::GasPriceOracleConfig; use reth_rpc_server_types::constants::gas_oracle::{ DEFAULT_GAS_PRICE_BLOCKS, DEFAULT_GAS_PRICE_PERCENTILE, DEFAULT_IGNORE_GAS_PRICE, DEFAULT_MAX_GAS_PRICE, diff --git a/crates/node-core/src/args/rpc_server.rs b/crates/node-core/src/args/rpc_server.rs index 7ab2dd268fa..62c675d5077 100644 --- a/crates/node-core/src/args/rpc_server.rs +++ b/crates/node-core/src/args/rpc_server.rs @@ -10,7 +10,7 @@ use clap::{ Arg, Args, Command, }; use rand::Rng; -use reth_rpc::eth::RPC_DEFAULT_GAS_CAP; +use reth_rpc_eth_api::RPC_DEFAULT_GAS_CAP; use reth_rpc_server_types::{constants, RethRpcModule, RpcModuleSelection}; use std::{ diff --git a/crates/node-core/src/lib.rs b/crates/node-core/src/lib.rs index a8761110aea..3ea123098c3 100644 --- a/crates/node-core/src/lib.rs +++ b/crates/node-core/src/lib.rs @@ -39,12 +39,12 @@ pub mod rpc { } /// Re-exported from `reth_rpc::eth`. pub mod eth { - pub use reth_rpc::eth::*; + pub use reth_rpc_eth_api::*; } /// Re-exported from `reth_rpc::rpc`. pub mod result { - pub use reth_rpc::result::*; + pub use reth_rpc_eth_api::result::*; } /// Re-exported from `reth_rpc::eth`. diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 02c5dac47c3..0bc91ed87b8 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -18,7 +18,7 @@ reth-evm-optimism = { workspace = true, features = ["optimism"] } revm = { workspace = true, features = ["optimism"] } reth-network-api.workspace = true reth-rpc = { workspace = true, features = ["optimism"] } -reth-rpc-api.workspace = true +reth-rpc-eth-api = { workspace = true, features = ["optimism"] } reth-rpc-types.workspace = true reth-primitives = { workspace = true, features = ["optimism"] } reth-provider = { workspace = true, features = ["optimism"] } diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index 985b0131637..fab542212a6 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -11,9 +11,9 @@ use std::sync::Arc; -use reth_rpc::{ - call_impl, eth::api::EthApiInner, eth_call_impl, eth_fees_impl, eth_state_impl, - eth_transactions_impl, load_block_impl, load_fee_impl, load_state_impl, load_transaction_impl, +use reth_rpc_eth_api::{ + call_impl, eth_call_impl, eth_fees_impl, eth_state_impl, eth_transactions_impl, + load_block_impl, load_fee_impl, load_state_impl, load_transaction_impl, servers::EthApiInner, spawn_blocking_impl, trace_impl, }; diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index 86eb14a230b..661b7780e18 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -16,11 +16,8 @@ mod admin; mod anvil; -mod bundle; mod debug; mod engine; -mod eth_filter; -mod eth_pubsub; mod ganache; mod hardhat; mod mev; @@ -41,11 +38,8 @@ pub use servers::*; pub mod servers { pub use crate::{ admin::AdminApiServer, - bundle::{EthBundleApiServer, EthCallBundleApiServer}, debug::DebugApiServer, engine::{EngineApiServer, EngineEthApiServer}, - eth_filter::EthFilterApiServer, - eth_pubsub::EthPubSubApiServer, mev::MevApiServer, net::NetApiServer, otterscan::OtterscanServer, @@ -56,7 +50,10 @@ pub mod servers { validation::BlockSubmissionValidationApiServer, web3::Web3ApiServer, }; - pub use reth_rpc_eth_api::EthApiServer; + pub use reth_rpc_eth_api::{ + EthApiServer, EthBundleApiServer, EthCallBundleApiServer, EthFilterApiServer, + EthPubSubApiServer, + }; } /// re-export of all client traits @@ -69,10 +66,8 @@ pub mod clients { pub use crate::{ admin::AdminApiClient, anvil::AnvilApiClient, - bundle::{EthBundleApiClient, EthCallBundleApiClient}, debug::DebugApiClient, engine::{EngineApiClient, EngineEthApiClient}, - eth_filter::EthFilterApiClient, ganache::GanacheApiClient, hardhat::HardhatApiClient, mev::MevApiClient, @@ -84,5 +79,7 @@ pub mod clients { validation::BlockSubmissionValidationApiClient, web3::Web3ApiClient, }; - pub use reth_rpc_eth_api::EthApiClient; + pub use reth_rpc_eth_api::{ + EthApiClient, EthBundleApiClient, EthCallBundleApiClient, EthFilterApiClient, + }; } diff --git a/crates/rpc/rpc-builder/src/auth.rs b/crates/rpc/rpc-builder/src/auth.rs index 62a676eaa94..60dd5780453 100644 --- a/crates/rpc/rpc-builder/src/auth.rs +++ b/crates/rpc/rpc-builder/src/auth.rs @@ -7,7 +7,7 @@ use jsonrpsee::{ Methods, }; use reth_engine_primitives::EngineTypes; -use reth_rpc::EthSubscriptionIdProvider; +use reth_rpc::eth::EthSubscriptionIdProvider; use reth_rpc_api::servers::*; use reth_rpc_layer::{ secret_to_bearer_header, AuthClientLayer, AuthClientService, AuthLayer, JwtAuthValidator, diff --git a/crates/rpc/rpc-builder/src/config.rs b/crates/rpc/rpc-builder/src/config.rs index 45cad81cd7f..89ce742e38e 100644 --- a/crates/rpc/rpc-builder/src/config.rs +++ b/crates/rpc/rpc-builder/src/config.rs @@ -4,7 +4,7 @@ use crate::{ }; use jsonrpsee::server::ServerBuilder; use reth_node_core::{args::RpcServerArgs, utils::get_or_create_jwt_secret_from_path}; -use reth_rpc::eth::{cache::EthStateCacheConfig, gas_oracle::GasPriceOracleConfig}; +use reth_rpc::eth::{EthStateCacheConfig, GasPriceOracleConfig}; use reth_rpc_layer::{JwtError, JwtSecret}; use reth_rpc_server_types::RpcModuleSelection; use std::{net::SocketAddr, path::PathBuf}; diff --git a/crates/rpc/rpc-builder/src/eth.rs b/crates/rpc/rpc-builder/src/eth.rs index a2dbbcb4f72..f2179a3b8fc 100644 --- a/crates/rpc/rpc-builder/src/eth.rs +++ b/crates/rpc/rpc-builder/src/eth.rs @@ -1,10 +1,6 @@ -use reth_rpc::{ - eth::{ - cache::{EthStateCache, EthStateCacheConfig}, - gas_oracle::GasPriceOracleConfig, - EthApi, EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, - }, - EthFilter, EthPubSub, +use reth_rpc::eth::{ + EthApi, EthFilter, EthFilterConfig, EthPubSub, EthStateCache, EthStateCacheConfig, + FeeHistoryCacheConfig, GasPriceOracleConfig, RPC_DEFAULT_GAS_CAP, }; use reth_rpc_server_types::constants::{ default_max_tracing_requests, DEFAULT_MAX_BLOCKS_PER_FILTER, DEFAULT_MAX_LOGS_PER_RESPONSE, diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 5f24cde83b8..5ac1d048d65 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -176,14 +176,12 @@ use reth_provider::{ }; use reth_rpc::{ eth::{ - api::RawTransactionForwarder, - cache::{cache_new_blocks_task, EthStateCache}, - fee_history_cache_new_blocks_task, - gas_oracle::GasPriceOracle, - EthBundle, FeeHistoryCache, + cache::cache_new_blocks_task, fee_history::fee_history_cache_new_blocks_task, + servers::RawTransactionForwarder, EthApi, EthBundle, EthFilter, EthPubSub, EthStateCache, + EthSubscriptionIdProvider, FeeHistoryCache, GasPriceOracle, }, - AdminApi, DebugApi, EngineEthApi, EthApi, EthFilter, EthPubSub, EthSubscriptionIdProvider, - NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, TxPoolApi, Web3Api, + AdminApi, DebugApi, EngineEthApi, NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, TxPoolApi, + Web3Api, }; use reth_rpc_api::servers::*; use reth_rpc_layer::{AuthLayer, Claims, JwtAuthValidator, JwtSecret}; diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index b37680c5dcb..1948f56e473 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -31,7 +31,7 @@ reth-trie.workspace = true reth-transaction-pool.workspace = true # ethereum -alloy-dyn-abi.workspace = true +alloy-dyn-abi = { workspace = true, features = ["eip712"] } alloy-sol-types.workspace = true secp256k1.workspace = true diff --git a/crates/rpc/rpc-api/src/bundle.rs b/crates/rpc/rpc-eth-api/src/api/bundle.rs similarity index 98% rename from crates/rpc/rpc-api/src/bundle.rs rename to crates/rpc/rpc-eth-api/src/api/bundle.rs index 429f6948f8a..f657e30c430 100644 --- a/crates/rpc/rpc-api/src/bundle.rs +++ b/crates/rpc/rpc-eth-api/src/api/bundle.rs @@ -1,4 +1,4 @@ -//! Additional `eth_` functions for bundles +//! Additional `eth_` RPC API for bundles. //! //! See also diff --git a/crates/rpc/rpc-api/src/eth_filter.rs b/crates/rpc/rpc-eth-api/src/api/filter.rs similarity index 97% rename from crates/rpc/rpc-api/src/eth_filter.rs rename to crates/rpc/rpc-eth-api/src/api/filter.rs index 2e395d5bad7..da53b577eec 100644 --- a/crates/rpc/rpc-api/src/eth_filter.rs +++ b/crates/rpc/rpc-eth-api/src/api/filter.rs @@ -1,5 +1,8 @@ +//! `eth_` RPC API for filtering. + use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_rpc_types::{Filter, FilterChanges, FilterId, Log, PendingTransactionFilterKind}; + /// Rpc Interface for poll-based ethereum filter API. #[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))] #[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))] diff --git a/crates/rpc/rpc-eth-api/src/api/mod.rs b/crates/rpc/rpc-eth-api/src/api/mod.rs new file mode 100644 index 00000000000..673a10799f6 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/mod.rs @@ -0,0 +1,317 @@ +//! `eth_` RPC API. + +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; +use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; +use reth_rpc_types::{ + serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, + AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, + FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction, + TransactionRequest, Work, +}; + +pub mod bundle; +pub mod filter; +pub mod pubsub; +pub mod servers; + +/// Eth rpc interface: +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))] +pub trait EthApi { + /// Returns the protocol version encoded as a string. + #[method(name = "protocolVersion")] + async fn protocol_version(&self) -> RpcResult; + + /// Returns an object with data about the sync status or false. + #[method(name = "syncing")] + fn syncing(&self) -> RpcResult; + + /// Returns the client coinbase address. + #[method(name = "coinbase")] + async fn author(&self) -> RpcResult
; + + /// Returns a list of addresses owned by client. + #[method(name = "accounts")] + fn accounts(&self) -> RpcResult>; + + /// Returns the number of most recent block. + #[method(name = "blockNumber")] + fn block_number(&self) -> RpcResult; + + /// Returns the chain ID of the current network. + #[method(name = "chainId")] + async fn chain_id(&self) -> RpcResult>; + + /// Returns information about a block by hash. + #[method(name = "getBlockByHash")] + async fn block_by_hash(&self, hash: B256, full: bool) -> RpcResult>; + + /// Returns information about a block by number. + #[method(name = "getBlockByNumber")] + async fn block_by_number( + &self, + number: BlockNumberOrTag, + full: bool, + ) -> RpcResult>; + + /// Returns the number of transactions in a block from a block matching the given block hash. + #[method(name = "getBlockTransactionCountByHash")] + async fn block_transaction_count_by_hash(&self, hash: B256) -> RpcResult>; + + /// Returns the number of transactions in a block matching the given block number. + #[method(name = "getBlockTransactionCountByNumber")] + async fn block_transaction_count_by_number( + &self, + number: BlockNumberOrTag, + ) -> RpcResult>; + + /// Returns the number of uncles in a block from a block matching the given block hash. + #[method(name = "getUncleCountByBlockHash")] + async fn block_uncles_count_by_hash(&self, hash: B256) -> RpcResult>; + + /// Returns the number of uncles in a block with given block number. + #[method(name = "getUncleCountByBlockNumber")] + async fn block_uncles_count_by_number( + &self, + number: BlockNumberOrTag, + ) -> RpcResult>; + + /// Returns all transaction receipts for a given block. + #[method(name = "getBlockReceipts")] + async fn block_receipts( + &self, + block_id: BlockId, + ) -> RpcResult>>; + + /// Returns an uncle block of the given block and index. + #[method(name = "getUncleByBlockHashAndIndex")] + async fn uncle_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> RpcResult>; + + /// Returns an uncle block of the given block and index. + #[method(name = "getUncleByBlockNumberAndIndex")] + async fn uncle_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> RpcResult>; + + /// Returns the EIP-2718 encoded transaction if it exists. + /// + /// If this is a EIP-4844 transaction that is in the pool it will include the sidecar. + #[method(name = "getRawTransactionByHash")] + async fn raw_transaction_by_hash(&self, hash: B256) -> RpcResult>; + + /// Returns the information about a transaction requested by transaction hash. + #[method(name = "getTransactionByHash")] + async fn transaction_by_hash(&self, hash: B256) -> RpcResult>; + + /// Returns information about a raw transaction by block hash and transaction index position. + #[method(name = "getRawTransactionByBlockHashAndIndex")] + async fn raw_transaction_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> RpcResult>; + + /// Returns information about a transaction by block hash and transaction index position. + #[method(name = "getTransactionByBlockHashAndIndex")] + async fn transaction_by_block_hash_and_index( + &self, + hash: B256, + index: Index, + ) -> RpcResult>; + + /// Returns information about a raw transaction by block number and transaction index + /// position. + #[method(name = "getRawTransactionByBlockNumberAndIndex")] + async fn raw_transaction_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> RpcResult>; + + /// Returns information about a transaction by block number and transaction index position. + #[method(name = "getTransactionByBlockNumberAndIndex")] + async fn transaction_by_block_number_and_index( + &self, + number: BlockNumberOrTag, + index: Index, + ) -> RpcResult>; + + /// Returns the receipt of a transaction by transaction hash. + #[method(name = "getTransactionReceipt")] + async fn transaction_receipt(&self, hash: B256) -> RpcResult>; + + /// Returns the balance of the account of given address. + #[method(name = "getBalance")] + async fn balance(&self, address: Address, block_number: Option) -> RpcResult; + + /// Returns the value from a storage position at a given address + #[method(name = "getStorageAt")] + async fn storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option, + ) -> RpcResult; + + /// Returns the number of transactions sent from an address at given block number. + #[method(name = "getTransactionCount")] + async fn transaction_count( + &self, + address: Address, + block_number: Option, + ) -> RpcResult; + + /// Returns code at a given address at given block number. + #[method(name = "getCode")] + async fn get_code(&self, address: Address, block_number: Option) -> RpcResult; + + /// Returns the block's header at given number. + #[method(name = "getHeaderByNumber")] + async fn header_by_number(&self, hash: BlockNumberOrTag) -> RpcResult>; + + /// Returns the block's header at given hash. + #[method(name = "getHeaderByHash")] + async fn header_by_hash(&self, hash: B256) -> RpcResult>; + + /// Executes a new message call immediately without creating a transaction on the block chain. + #[method(name = "call")] + async fn call( + &self, + request: TransactionRequest, + block_number: Option, + state_overrides: Option, + block_overrides: Option>, + ) -> RpcResult; + + /// Simulate arbitrary number of transactions at an arbitrary blockchain index, with the + /// optionality of state overrides + #[method(name = "callMany")] + async fn call_many( + &self, + bundle: Bundle, + state_context: Option, + state_override: Option, + ) -> RpcResult>; + + /// Generates an access list for a transaction. + /// + /// This method creates an [EIP2930](https://eips.ethereum.org/EIPS/eip-2930) type accessList based on a given Transaction. + /// + /// An access list contains all storage slots and addresses touched by the transaction, except + /// for the sender account and the chain's precompiles. + /// + /// It returns list of addresses and storage keys used by the transaction, plus the gas + /// consumed when the access list is added. That is, it gives you the list of addresses and + /// storage keys that will be used by that transaction, plus the gas consumed if the access + /// list is included. Like eth_estimateGas, this is an estimation; the list could change + /// when the transaction is actually mined. Adding an accessList to your transaction does + /// not necessary result in lower gas usage compared to a transaction without an access + /// list. + #[method(name = "createAccessList")] + async fn create_access_list( + &self, + request: TransactionRequest, + block_number: Option, + ) -> RpcResult; + + /// Generates and returns an estimate of how much gas is necessary to allow the transaction to + /// complete. + #[method(name = "estimateGas")] + async fn estimate_gas( + &self, + request: TransactionRequest, + block_number: Option, + state_override: Option, + ) -> RpcResult; + + /// Returns the current price per gas in wei. + #[method(name = "gasPrice")] + async fn gas_price(&self) -> RpcResult; + + /// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions. + #[method(name = "maxPriorityFeePerGas")] + async fn max_priority_fee_per_gas(&self) -> RpcResult; + + /// Introduced in EIP-4844, returns the current blob base fee in wei. + #[method(name = "blobBaseFee")] + async fn blob_base_fee(&self) -> RpcResult; + + /// Returns the Transaction fee history + /// + /// Introduced in EIP-1559 for getting information on the appropriate priority fee to use. + /// + /// Returns transaction base fee per gas and effective priority fee per gas for the + /// requested/supported block range. The returned Fee history for the returned block range + /// can be a subsection of the requested range if not all blocks are available. + #[method(name = "feeHistory")] + async fn fee_history( + &self, + block_count: U64, + newest_block: BlockNumberOrTag, + reward_percentiles: Option>, + ) -> RpcResult; + + /// Returns whether the client is actively mining new blocks. + #[method(name = "mining")] + async fn is_mining(&self) -> RpcResult; + + /// Returns the number of hashes per second that the node is mining with. + #[method(name = "hashrate")] + async fn hashrate(&self) -> RpcResult; + + /// Returns the hash of the current block, the seedHash, and the boundary condition to be met + /// (“target”) + #[method(name = "getWork")] + async fn get_work(&self) -> RpcResult; + + /// Used for submitting mining hashrate. + /// + /// Can be used for remote miners to submit their hash rate. + /// It accepts the miner hash rate and an identifier which must be unique between nodes. + /// Returns `true` if the block was successfully submitted, `false` otherwise. + #[method(name = "submitHashrate")] + async fn submit_hashrate(&self, hashrate: U256, id: B256) -> RpcResult; + + /// Used for submitting a proof-of-work solution. + #[method(name = "submitWork")] + async fn submit_work(&self, nonce: B64, pow_hash: B256, mix_digest: B256) -> RpcResult; + + /// Sends transaction; will block waiting for signer to return the + /// transaction hash. + #[method(name = "sendTransaction")] + async fn send_transaction(&self, request: TransactionRequest) -> RpcResult; + + /// Sends signed transaction, returning its hash. + #[method(name = "sendRawTransaction")] + async fn send_raw_transaction(&self, bytes: Bytes) -> RpcResult; + + /// Returns an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" + /// + len(message) + message))). + #[method(name = "sign")] + async fn sign(&self, address: Address, message: Bytes) -> RpcResult; + + /// Signs a transaction that can be submitted to the network at a later time using with + /// `sendRawTransaction.` + #[method(name = "signTransaction")] + async fn sign_transaction(&self, transaction: TransactionRequest) -> RpcResult; + + /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md). + #[method(name = "signTypedData")] + async fn sign_typed_data(&self, address: Address, data: serde_json::Value) -> RpcResult; + + /// Returns the account and storage values of the specified account including the Merkle-proof. + /// This call can be used to verify that the data you are pulling from is not tampered with. + #[method(name = "getProof")] + async fn get_proof( + &self, + address: Address, + keys: Vec, + block_number: Option, + ) -> RpcResult; +} diff --git a/crates/rpc/rpc-api/src/eth_pubsub.rs b/crates/rpc/rpc-eth-api/src/api/pubsub.rs similarity index 92% rename from crates/rpc/rpc-api/src/eth_pubsub.rs rename to crates/rpc/rpc-eth-api/src/api/pubsub.rs index eaa1ef2d817..8de12515282 100644 --- a/crates/rpc/rpc-api/src/eth_pubsub.rs +++ b/crates/rpc/rpc-eth-api/src/api/pubsub.rs @@ -1,3 +1,5 @@ +//! `eth_` RPC API for pubsub subscription. + use jsonrpsee::proc_macros::rpc; use reth_rpc_types::pubsub::{Params, SubscriptionKind}; diff --git a/crates/rpc/rpc/src/eth/bundle.rs b/crates/rpc/rpc-eth-api/src/api/servers/bundle.rs similarity index 98% rename from crates/rpc/rpc/src/eth/bundle.rs rename to crates/rpc/rpc-eth-api/src/api/servers/bundle.rs index 1640b9c7c8f..fa768de566b 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/bundle.rs @@ -11,12 +11,6 @@ use reth_primitives::{ PooledTransactionsElement, U256, }; use reth_revm::database::StateProviderDatabase; -use reth_rpc_api::EthCallBundleApiServer; -use reth_rpc_eth_api::eth::{ - api::{Call, EthTransactions, LoadPendingBlock}, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, - utils::recover_raw_transaction, -}; use reth_rpc_types::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use reth_tasks::pool::BlockingTaskGuard; use revm::{ @@ -25,6 +19,12 @@ use revm::{ }; use revm_primitives::{EnvWithHandlerCfg, MAX_BLOB_GAS_PER_BLOCK}; +use crate::{ + servers::{Call, EthTransactions, LoadPendingBlock}, + utils::recover_raw_transaction, + EthApiError, EthCallBundleApiServer, EthResult, RpcInvalidTransactionError, +}; + /// `Eth` bundle implementation. pub struct EthBundle { /// All nested fields bundled together. diff --git a/crates/rpc/rpc/src/eth/filter.rs b/crates/rpc/rpc-eth-api/src/api/servers/filter.rs similarity index 94% rename from crates/rpc/rpc/src/eth/filter.rs rename to crates/rpc/rpc-eth-api/src/api/servers/filter.rs index 0a15f905087..5ca7f7e45c0 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/filter.rs @@ -1,3 +1,5 @@ +//! `eth_` `Filter` RPC handler implementation + use std::{ collections::HashMap, fmt, @@ -11,16 +13,10 @@ use async_trait::async_trait; use jsonrpsee::{core::RpcResult, server::IdProvider}; use reth_primitives::{ChainInfo, IntoRecoveredTransaction, TxHash}; use reth_provider::{BlockIdReader, BlockReader, EvmEnvProvider, ProviderError}; -use reth_rpc_api::EthFilterApiServer; -use reth_rpc_eth_api::{ - eth::{cache::EthStateCache, error::EthApiError}, - result::{rpc_error_with_code, ToRpcResult}, -}; use reth_rpc_types::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, PendingTransactionFilterKind, }; - use reth_tasks::TaskSpawner; use reth_transaction_pool::{NewSubpoolTransactionStream, PoolTransaction, TransactionPool}; use tokio::{ @@ -30,8 +26,9 @@ use tokio::{ use tracing::trace; use crate::{ - eth::logs_utils::{self, append_matching_block_logs}, - EthSubscriptionIdProvider, + logs_utils::{self, append_matching_block_logs}, + result::rpc_error_with_code, + EthApiError, EthFilterApiServer, EthStateCache, EthSubscriptionIdProvider, ToRpcResult, }; /// The maximum number of headers we read at once when handling a range filter. @@ -131,7 +128,7 @@ where ::Transaction: 'static, { /// Returns all the filter changes for the given id, if any - pub async fn filter_changes(&self, id: FilterId) -> Result { + pub async fn filter_changes(&self, id: FilterId) -> Result { let info = self.inner.provider.chain_info()?; let best_number = info.best_number; @@ -139,7 +136,7 @@ where // the last time changes were polled, in other words the best block at last poll + 1 let (start_block, kind) = { let mut filters = self.inner.active_filters.inner.lock().await; - let filter = filters.get_mut(&id).ok_or(FilterError::FilterNotFound(id))?; + let filter = filters.get_mut(&id).ok_or(EthFilterError::FilterNotFound(id))?; if filter.block > best_number { // no new blocks since the last poll @@ -203,16 +200,16 @@ where /// Returns an error if no matching log filter exists. /// /// Handler for `eth_getFilterLogs` - pub async fn filter_logs(&self, id: FilterId) -> Result, FilterError> { + pub async fn filter_logs(&self, id: FilterId) -> Result, EthFilterError> { let filter = { let filters = self.inner.active_filters.inner.lock().await; if let FilterKind::Log(ref filter) = - filters.get(&id).ok_or_else(|| FilterError::FilterNotFound(id.clone()))?.kind + filters.get(&id).ok_or_else(|| EthFilterError::FilterNotFound(id.clone()))?.kind { *filter.clone() } else { // Not a log filter - return Err(FilterError::FilterNotFound(id)) + return Err(EthFilterError::FilterNotFound(id)) } }; @@ -346,7 +343,7 @@ where Pool: TransactionPool + 'static, { /// Returns logs matching given filter object. - async fn logs_for_filter(&self, filter: Filter) -> Result, FilterError> { + async fn logs_for_filter(&self, filter: Filter) -> Result, EthFilterError> { match filter.block_option { FilterBlockOption::AtBlockHash(block_hash) => { // for all matching logs in the block @@ -427,16 +424,16 @@ where from_block: u64, to_block: u64, chain_info: ChainInfo, - ) -> Result, FilterError> { + ) -> Result, EthFilterError> { trace!(target: "rpc::eth::filter", from=from_block, to=to_block, ?filter, "finding logs in range"); let best_number = chain_info.best_number; if to_block < from_block { - return Err(FilterError::InvalidBlockRangeParams) + return Err(EthFilterError::InvalidBlockRangeParams) } if to_block - from_block > self.max_blocks_per_filter { - return Err(FilterError::QueryExceedsMaxBlocks(self.max_blocks_per_filter)) + return Err(EthFilterError::QueryExceedsMaxBlocks(self.max_blocks_per_filter)) } let mut all_logs = Vec::new(); @@ -504,7 +501,7 @@ where // logs of a single block let is_multi_block_range = from_block != to_block; if is_multi_block_range && all_logs.len() > self.max_logs_per_response { - return Err(FilterError::QueryExceedsMaxResults( + return Err(EthFilterError::QueryExceedsMaxResults( self.max_logs_per_response, )) } @@ -681,17 +678,49 @@ enum FilterKind { PendingTransaction(PendingTransactionKind), } +/// An iterator that yields _inclusive_ block ranges of a given step size +#[derive(Debug)] +struct BlockRangeInclusiveIter { + iter: StepBy>, + step: u64, + end: u64, +} + +impl BlockRangeInclusiveIter { + fn new(range: RangeInclusive, step: u64) -> Self { + Self { end: *range.end(), iter: range.step_by(step as usize + 1), step } + } +} + +impl Iterator for BlockRangeInclusiveIter { + type Item = (u64, u64); + + fn next(&mut self) -> Option { + let start = self.iter.next()?; + let end = (start + self.step).min(self.end); + if start > end { + return None + } + Some((start, end)) + } +} + /// Errors that can occur in the handler implementation #[derive(Debug, thiserror::Error)] -pub enum FilterError { +pub enum EthFilterError { + /// Filter not found. #[error("filter not found")] FilterNotFound(FilterId), + /// Invalid block range. #[error("invalid block range params")] InvalidBlockRangeParams, + /// Query scope is too broad. #[error("query exceeds max block range {0}")] QueryExceedsMaxBlocks(u64), + /// Query result is too large. #[error("query exceeds max results {0}")] QueryExceedsMaxResults(usize), + /// Error serving request in `eth_` namespace. #[error(transparent)] EthAPIError(#[from] EthApiError), /// Error thrown when a spawned task failed to deliver a response. @@ -700,59 +729,32 @@ pub enum FilterError { } // convert the error -impl From for jsonrpsee::types::error::ErrorObject<'static> { - fn from(err: FilterError) -> Self { +impl From for jsonrpsee::types::error::ErrorObject<'static> { + fn from(err: EthFilterError) -> Self { match err { - FilterError::FilterNotFound(_) => rpc_error_with_code( + EthFilterError::FilterNotFound(_) => rpc_error_with_code( jsonrpsee::types::error::INVALID_PARAMS_CODE, "filter not found", ), - err @ FilterError::InternalError => { + err @ EthFilterError::InternalError => { rpc_error_with_code(jsonrpsee::types::error::INTERNAL_ERROR_CODE, err.to_string()) } - FilterError::EthAPIError(err) => err.into(), - err @ FilterError::InvalidBlockRangeParams | - err @ FilterError::QueryExceedsMaxBlocks(_) | - err @ FilterError::QueryExceedsMaxResults(_) => { + EthFilterError::EthAPIError(err) => err.into(), + err @ EthFilterError::InvalidBlockRangeParams | + err @ EthFilterError::QueryExceedsMaxBlocks(_) | + err @ EthFilterError::QueryExceedsMaxResults(_) => { rpc_error_with_code(jsonrpsee::types::error::INVALID_PARAMS_CODE, err.to_string()) } } } } -impl From for FilterError { +impl From for EthFilterError { fn from(err: ProviderError) -> Self { Self::EthAPIError(err.into()) } } -/// An iterator that yields _inclusive_ block ranges of a given step size -#[derive(Debug)] -struct BlockRangeInclusiveIter { - iter: StepBy>, - step: u64, - end: u64, -} - -impl BlockRangeInclusiveIter { - fn new(range: RangeInclusive, step: u64) -> Self { - Self { end: *range.end(), iter: range.step_by(step as usize + 1), step } - } -} - -impl Iterator for BlockRangeInclusiveIter { - type Item = (u64, u64); - - fn next(&mut self) -> Option { - let start = self.iter.next()?; - let end = (start + self.step).min(self.end); - if start > end { - return None - } - Some((start, end)) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs similarity index 61% rename from crates/rpc/rpc-eth-api/src/eth/api/block.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs index c5df169d99e..fb714de6ba3 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs @@ -1,15 +1,15 @@ //! Contains RPC handler implementations specific to blocks. -use crate::eth::EthApi; +use crate::EthApi; -/// Implements [`EthBlocks`](crate::eth::api::EthBlocks) for a type, that has similar +/// Implements [`EthBlocks`](crate::servers::EthBlocks) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! eth_blocks_impl { ($network_api:ty) => { - impl $crate::eth::api::EthBlocks for $network_api + impl $crate::servers::EthBlocks for $network_api where - Self: $crate::eth::api::LoadBlock, + Self: $crate::servers::LoadBlock, Provider: reth_provider::HeaderProvider, { #[inline] @@ -20,14 +20,14 @@ macro_rules! eth_blocks_impl { }; } -/// Implements [`LoadBlock`](crate::eth::api::LoadBlock) for a type, that has similar +/// Implements [`LoadBlock`](crate::servers::LoadBlock) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! load_block_impl { ($network_api:ty) => { - impl $crate::eth::api::LoadBlock for $network_api + impl $crate::servers::LoadBlock for $network_api where - Self: $crate::eth::api::LoadPendingBlock + $crate::eth::api::SpawnBlocking, + Self: $crate::servers::LoadPendingBlock + $crate::servers::SpawnBlocking, Provider: reth_provider::BlockReaderIdExt, { #[inline] @@ -36,7 +36,7 @@ macro_rules! load_block_impl { } #[inline] - fn cache(&self) -> &$crate::eth::cache::EthStateCache { + fn cache(&self) -> &$crate::EthStateCache { self.inner.cache() } } diff --git a/crates/rpc/rpc-eth-api/src/eth/api/call.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs similarity index 60% rename from crates/rpc/rpc-eth-api/src/eth/api/call.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs index 28d681d8d5e..981e4a44891 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/call.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs @@ -1,27 +1,27 @@ //! Contains RPC handler implementations specific to endpoints that call/execute within evm. -use crate::eth::EthApi; +use crate::EthApi; -/// Implements [`EthCall`](crate::eth::api::EthCall) for a type, that has similar +/// Implements [`EthCall`](crate::servers::EthCall) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! eth_call_impl { ($network_api:ty) => { - impl $crate::eth::api::EthCall for $network_api where - Self: $crate::eth::api::Call + $crate::eth::api::LoadPendingBlock + impl $crate::servers::EthCall for $network_api where + Self: $crate::servers::Call + $crate::servers::LoadPendingBlock { } }; } -/// Implements [`Call`](crate::eth::api::Call) for a type, that has similar +/// Implements [`Call`](crate::servers::Call) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! call_impl { ($network_api:ty) => { - impl $crate::eth::api::Call for $network_api + impl $crate::servers::Call for $network_api where - Self: $crate::eth::api::LoadState + $crate::eth::api::SpawnBlocking, + Self: $crate::servers::LoadState + $crate::servers::SpawnBlocking, EvmConfig: reth_evm::ConfigureEvm, { #[inline] diff --git a/crates/rpc/rpc-eth-api/src/eth/api/fees.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs similarity index 59% rename from crates/rpc/rpc-eth-api/src/eth/api/fees.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs index 8cdab100197..65fd086403d 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/fees.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs @@ -1,27 +1,27 @@ //! Contains RPC handler implementations for fee history. -use crate::eth::EthApi; +use crate::EthApi; -/// Implements [`EthFees`](crate::eth::api::EthFees) for a type, that has similar +/// Implements [`EthFees`](crate::servers::EthFees) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! eth_fees_impl { ($network_api:ty) => { - impl $crate::eth::api::EthFees for $network_api where - Self: $crate::eth::api::LoadFee + impl $crate::servers::EthFees for $network_api where + Self: $crate::servers::LoadFee { } }; } -/// Implements [`LoadFee`](crate::eth::api::LoadFee) for a type, that has similar +/// Implements [`LoadFee`](crate::servers::LoadFee) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! load_fee_impl { ($network_api:ty) => { - impl $crate::eth::api::LoadFee for $network_api + impl $crate::servers::LoadFee for $network_api where - Self: $crate::eth::api::LoadBlock, + Self: $crate::servers::LoadBlock, Provider: reth_provider::BlockReaderIdExt + reth_provider::HeaderProvider + reth_provider::ChainSpecProvider, @@ -36,20 +36,17 @@ macro_rules! load_fee_impl { } #[inline] - fn cache(&self) -> &$crate::eth::cache::EthStateCache { + fn cache(&self) -> &$crate::EthStateCache { self.inner.cache() } #[inline] - fn gas_oracle( - &self, - ) -> &$crate::eth::gas_oracle::GasPriceOracle - { + fn gas_oracle(&self) -> &$crate::GasPriceOracle { self.inner.gas_oracle() } #[inline] - fn fee_history_cache(&self) -> &$crate::eth::FeeHistoryCache { + fn fee_history_cache(&self) -> &$crate::FeeHistoryCache { self.inner.fee_history_cache() } } diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/mod.rs new file mode 100644 index 00000000000..0ae635dfb9c --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/mod.rs @@ -0,0 +1,15 @@ +//! The entire implementation of the namespace is quite large, hence it is divided across several +//! files. + +pub mod signer; +pub mod traits; + +mod block; +mod call; +mod fees; +mod pending_block; +mod receipt; +mod spec; +mod state; +mod trace; +mod transaction; diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/pending_block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/pending_block.rs new file mode 100644 index 00000000000..92bb5fce125 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/pending_block.rs @@ -0,0 +1,48 @@ +//! Support for building a pending block with transactions from local view of mempool. + +use crate::EthApi; + +/// Implements [`LoadPendingBlock`](crate::servers::LoadPendingBlock) for a type, that has similar +/// data layout to [`EthApi`]. +#[macro_export] +macro_rules! load_pending_block_impl { + ($network_api:ty) => { + impl $crate::servers::LoadPendingBlock for $network_api + where + Self: $crate::servers::SpawnBlocking, + Provider: reth_provider::BlockReaderIdExt + + reth_provider::EvmEnvProvider + + reth_provider::ChainSpecProvider + + reth_provider::StateProviderFactory, + Pool: reth_transaction_pool::TransactionPool, + EvmConfig: reth_evm::ConfigureEvm, + { + #[inline] + fn provider( + &self, + ) -> impl reth_provider::BlockReaderIdExt + + reth_provider::EvmEnvProvider + + reth_provider::ChainSpecProvider + + reth_provider::StateProviderFactory { + self.inner.provider() + } + + #[inline] + fn pool(&self) -> impl reth_transaction_pool::TransactionPool { + self.inner.pool() + } + + #[inline] + fn pending_block(&self) -> &tokio::sync::Mutex> { + self.inner.pending_block() + } + + #[inline] + fn evm_config(&self) -> &impl reth_evm::ConfigureEvm { + self.inner.evm_config() + } + } + }; +} + +load_pending_block_impl!(EthApi); diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/receipt.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/receipt.rs new file mode 100644 index 00000000000..404b526e4a9 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/receipt.rs @@ -0,0 +1,13 @@ +//! Builds an RPC receipt response w.r.t. data layout of network. + +use crate::{servers::LoadReceipt, EthApi, EthStateCache}; + +impl LoadReceipt for EthApi +where + Self: Send + Sync, +{ + #[inline] + fn cache(&self) -> &EthStateCache { + &self.inner.eth_cache + } +} diff --git a/crates/rpc/rpc-eth-api/src/eth/signer.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/signer.rs similarity index 86% rename from crates/rpc/rpc-eth-api/src/eth/signer.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/signer.rs index 7b76794cae4..f28fb745b07 100644 --- a/crates/rpc/rpc-eth-api/src/eth/signer.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/signer.rs @@ -1,49 +1,23 @@ //! An abstraction over ethereum signers. -use crate::eth::error::SignError; +use std::collections::HashMap; + use alloy_dyn_abi::TypedData; use reth_primitives::{ eip191_hash_message, sign_message, Address, Signature, TransactionSigned, B256, }; use reth_rpc_types::TypedTransactionRequest; - -use dyn_clone::DynClone; use reth_rpc_types_compat::transaction::to_primitive_transaction; use secp256k1::SecretKey; -use std::collections::HashMap; - -type Result = std::result::Result; - -/// An Ethereum Signer used via RPC. -#[async_trait::async_trait] -pub trait EthSigner: Send + Sync + DynClone { - /// Returns the available accounts for this signer. - fn accounts(&self) -> Vec
; - - /// Returns `true` whether this signer can sign for this address - fn is_signer_for(&self, addr: &Address) -> bool { - self.accounts().contains(addr) - } - - /// Returns the signature - async fn sign(&self, address: Address, message: &[u8]) -> Result; - - /// signs a transaction request using the given account in request - fn sign_transaction( - &self, - request: TypedTransactionRequest, - address: &Address, - ) -> Result; - /// Encodes and signs the typed data according EIP-712. Payload must implement Eip712 trait. - fn sign_typed_data(&self, address: Address, payload: &TypedData) -> Result; -} - -dyn_clone::clone_trait_object!(EthSigner); +use crate::{ + servers::{helpers::traits::signer::Result, EthSigner}, + SignError, +}; /// Holds developer keys -#[derive(Clone)] -pub(crate) struct DevSigner { +#[derive(Debug, Clone)] +pub struct DevSigner { addresses: Vec
, accounts: HashMap, } @@ -122,9 +96,12 @@ impl EthSigner for DevSigner { #[cfg(test)] mod tests { - use super::*; - use reth_primitives::U256; use std::str::FromStr; + + use reth_primitives::U256; + + use super::*; + fn build_signer() -> DevSigner { let addresses = vec![]; let secret = diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs new file mode 100644 index 00000000000..4627a27b00d --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs @@ -0,0 +1,63 @@ +use reth_errors::{RethError, RethResult}; +use reth_evm::ConfigureEvm; +use reth_network_api::NetworkInfo; +use reth_primitives::{Address, ChainInfo, U256, U64}; +use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; +use reth_rpc_types::{SyncInfo, SyncStatus}; +use reth_transaction_pool::TransactionPool; + +use crate::{servers::EthApiSpec, EthApi}; + +impl EthApiSpec for EthApi +where + Pool: TransactionPool + 'static, + Provider: + BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static, + Network: NetworkInfo + 'static, + EvmConfig: ConfigureEvm, +{ + /// Returns the current ethereum protocol version. + /// + /// Note: This returns an `U64`, since this should return as hex string. + async fn protocol_version(&self) -> RethResult { + let status = self.network().network_status().await.map_err(RethError::other)?; + Ok(U64::from(status.protocol_version)) + } + + /// Returns the chain id + fn chain_id(&self) -> U64 { + U64::from(self.network().chain_id()) + } + + /// Returns the current info for the chain + fn chain_info(&self) -> RethResult { + Ok(self.provider().chain_info()?) + } + + fn accounts(&self) -> Vec
{ + self.inner.signers.read().iter().flat_map(|s| s.accounts()).collect() + } + + fn is_syncing(&self) -> bool { + self.network().is_syncing() + } + + /// Returns the [SyncStatus] of the network + fn sync_status(&self) -> RethResult { + let status = if self.is_syncing() { + let current_block = U256::from( + self.provider().chain_info().map(|info| info.best_number).unwrap_or_default(), + ); + SyncStatus::Info(SyncInfo { + starting_block: self.inner.starting_block, + current_block, + highest_block: current_block, + warp_chunks_amount: None, + warp_chunks_processed: None, + }) + } else { + SyncStatus::None + }; + Ok(status) + } +} diff --git a/crates/rpc/rpc-eth-api/src/eth/api/state.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs similarity index 83% rename from crates/rpc/rpc-eth-api/src/eth/api/state.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs index 2a29db0624c..bc0e15f36fd 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/state.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs @@ -1,25 +1,25 @@ //! Contains RPC handler implementations specific to state. -use crate::eth::EthApi; +use crate::EthApi; -/// Implements [`EthState`](crate::eth::api::EthState) for a type, that has similar +/// Implements [`EthState`](crate::servers::EthState) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! eth_state_impl { ($network_api:ty) => { - impl $crate::eth::api::EthState for $network_api where - Self: $crate::eth::api::LoadState + $crate::eth::api::SpawnBlocking + impl $crate::servers::EthState for $network_api where + Self: $crate::servers::LoadState + $crate::servers::SpawnBlocking { } }; } -/// Implements [`LoadState`](crate::eth::api::LoadState) for a type, that has similar +/// Implements [`LoadState`](crate::servers::LoadState) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! load_state_impl { ($network_api:ty) => { - impl $crate::eth::api::LoadState for $network_api + impl $crate::servers::LoadState for $network_api where Provider: reth_provider::StateProviderFactory, Pool: reth_transaction_pool::TransactionPool, @@ -30,7 +30,7 @@ macro_rules! load_state_impl { } #[inline] - fn cache(&self) -> &$crate::eth::cache::EthStateCache { + fn cache(&self) -> &$crate::EthStateCache { self.inner.cache() } @@ -47,11 +47,8 @@ load_state_impl!(EthApi); #[cfg(test)] mod tests { - use super::*; - use crate::eth::{ - api::EthState, cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, - FeeHistoryCacheConfig, - }; + use std::collections::HashMap; + use reth_evm_ethereum::EthEvmConfig; use reth_primitives::{ constants::ETHEREUM_BLOCK_GAS_LIMIT, Address, StorageKey, StorageValue, U256, @@ -59,7 +56,12 @@ mod tests { use reth_provider::test_utils::{ExtendedAccount, MockEthProvider, NoopProvider}; use reth_tasks::pool::BlockingTaskPool; use reth_transaction_pool::test_utils::testing_pool; - use std::collections::HashMap; + + use crate::{ + servers::EthState, EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, GasPriceOracle, + }; + + use super::*; #[tokio::test] async fn test_storage() { diff --git a/crates/rpc/rpc-eth-api/src/eth/api/trace.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs similarity index 65% rename from crates/rpc/rpc-eth-api/src/eth/api/trace.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs index 6a1ffa3245a..43fa1c1f4ac 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/trace.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs @@ -1,15 +1,15 @@ //! Contains RPC handler implementations specific to tracing. -use crate::eth::EthApi; +use crate::EthApi; -/// Implements [`Trace`](crate::eth::api::Trace) for a type, that has similar +/// Implements [`Trace`](crate::servers::Trace) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! trace_impl { ($network_api:ty) => { - impl $crate::eth::api::Trace for $network_api + impl $crate::servers::Trace for $network_api where - Self: $crate::eth::api::LoadState, + Self: $crate::servers::LoadState, EvmConfig: reth_evm::ConfigureEvm, { #[inline] diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs similarity index 98% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs index 249a0f7e6b4..7e0027ef528 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs @@ -8,10 +8,9 @@ use reth_provider::{BlockIdReader, BlockReader, BlockReaderIdExt, HeaderProvider use reth_rpc_types::{AnyTransactionReceipt, Header, Index, RichBlock}; use reth_rpc_types_compat::block::{from_block, uncle_block_from_header}; -use crate::eth::{ - api::{LoadPendingBlock, LoadReceipt, ReceiptBuilder, SpawnBlocking}, - cache::EthStateCache, - error::{EthApiError, EthResult}, +use crate::{ + servers::{LoadPendingBlock, LoadReceipt, SpawnBlocking}, + EthApiError, EthResult, EthStateCache, ReceiptBuilder, }; /// Block related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/blocking_task.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/blocking_task.rs similarity index 97% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/blocking_task.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/blocking_task.rs index 90255c97741..1dae8dc6bb1 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/blocking_task.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/blocking_task.rs @@ -5,7 +5,7 @@ use futures::Future; use reth_tasks::{pool::BlockingTaskPool, TaskSpawner}; use tokio::sync::oneshot; -use crate::eth::error::{EthApiError, EthResult}; +use crate::{EthApiError, EthResult}; /// Executes code on a blocking thread. pub trait SpawnBlocking: Clone + Send + Sync + 'static { diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs similarity index 84% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs index e6283e7ced2..4882b983360 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/call.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs @@ -21,25 +21,18 @@ use revm::{Database, DatabaseCommit}; use revm_inspectors::access_list::AccessListInspector; use tracing::trace; -use crate::eth::{ - api::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace}, - error::{ensure_success, EthApiError, EthResult, RevertError, RpcInvalidTransactionError}, +use crate::{ + cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, + error::ensure_success, revm_utils::{ apply_state_overrides, build_call_evm_env, caller_gas_allowance, cap_tx_gas_limit_with_caller_allowance, get_precompiles, prepare_call_env, EvmOverrides, }, + servers::{LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, SpawnBlocking, Trace}, + EthApiError, EthResult, RevertError, RpcInvalidTransactionError, StateCacheDb, + ESTIMATE_GAS_ERROR_RATIO, MIN_TRANSACTION_GAS, }; -/// Gas per transaction not creating a contract. -pub const MIN_TRANSACTION_GAS: u64 = 21_000u64; -/// Allowed error ratio for gas estimation -/// Taken from Geth's implementation in order to pass the hive tests -/// -pub const ESTIMATE_GAS_ERROR_RATIO: f64 = 0.015; - -/// Helper alias type for the state's [`CacheDB`] -pub type StateCacheDB<'a> = CacheDB>>; - /// Execution related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in /// the `eth_` namespace. pub trait EthCall: Call + LoadPendingBlock { @@ -351,7 +344,7 @@ pub trait Call: LoadState + SpawnBlocking { ) -> impl Future> + Send where Self: LoadPendingBlock, - F: FnOnce(StateCacheDBRefMutWrapper<'_, '_>, EnvWithHandlerCfg) -> EthResult + F: FnOnce(StateCacheDbRefMutWrapper<'_, '_>, EnvWithHandlerCfg) -> EthResult + Send + 'static, R: Send + 'static, @@ -373,7 +366,7 @@ pub trait Call: LoadState + SpawnBlocking { overrides, )?; - f(StateCacheDBRefMutWrapper(&mut db), env) + f(StateCacheDbRefMutWrapper(&mut db), env) }) .await .map_err(|_| EthApiError::InternalBlockingTaskError) @@ -396,7 +389,7 @@ pub trait Call: LoadState + SpawnBlocking { ) -> impl Future>> + Send where Self: LoadBlock + LoadPendingBlock + LoadTransaction, - F: FnOnce(TransactionInfo, ResultAndState, StateCacheDB<'_>) -> EthResult + F: FnOnce(TransactionInfo, ResultAndState, StateCacheDb<'_>) -> EthResult + Send + 'static, R: Send + 'static, @@ -779,161 +772,3 @@ pub trait Call: LoadState + SpawnBlocking { } } } - -/// Hack to get around 'higher-ranked lifetime error', see -/// -#[allow(missing_debug_implementations)] -pub struct StateProviderTraitObjWrapper<'a>(pub &'a dyn StateProvider); - -impl<'a> reth_provider::StateRootProvider for StateProviderTraitObjWrapper<'a> { - fn state_root( - &self, - bundle_state: &revm::db::BundleState, - ) -> reth_errors::ProviderResult { - self.0.state_root(bundle_state) - } - - fn state_root_with_updates( - &self, - bundle_state: &revm::db::BundleState, - ) -> reth_errors::ProviderResult<(B256, reth_trie::updates::TrieUpdates)> { - self.0.state_root_with_updates(bundle_state) - } -} - -impl<'a> reth_provider::AccountReader for StateProviderTraitObjWrapper<'a> { - fn basic_account( - &self, - address: revm_primitives::Address, - ) -> reth_errors::ProviderResult> { - self.0.basic_account(address) - } -} - -impl<'a> reth_provider::BlockHashReader for StateProviderTraitObjWrapper<'a> { - fn block_hash( - &self, - block_number: reth_primitives::BlockNumber, - ) -> reth_errors::ProviderResult> { - self.0.block_hash(block_number) - } - - fn canonical_hashes_range( - &self, - start: reth_primitives::BlockNumber, - end: reth_primitives::BlockNumber, - ) -> reth_errors::ProviderResult> { - self.0.canonical_hashes_range(start, end) - } - - fn convert_block_hash( - &self, - hash_or_number: reth_rpc_types::BlockHashOrNumber, - ) -> reth_errors::ProviderResult> { - self.0.convert_block_hash(hash_or_number) - } -} - -impl<'a> StateProvider for StateProviderTraitObjWrapper<'a> { - fn account_balance( - &self, - addr: revm_primitives::Address, - ) -> reth_errors::ProviderResult> { - self.0.account_balance(addr) - } - - fn account_code( - &self, - addr: revm_primitives::Address, - ) -> reth_errors::ProviderResult> { - self.0.account_code(addr) - } - - fn account_nonce( - &self, - addr: revm_primitives::Address, - ) -> reth_errors::ProviderResult> { - self.0.account_nonce(addr) - } - - fn bytecode_by_hash( - &self, - code_hash: B256, - ) -> reth_errors::ProviderResult> { - self.0.bytecode_by_hash(code_hash) - } - - fn proof( - &self, - address: revm_primitives::Address, - keys: &[B256], - ) -> reth_errors::ProviderResult { - self.0.proof(address, keys) - } - - fn storage( - &self, - account: revm_primitives::Address, - storage_key: reth_primitives::StorageKey, - ) -> reth_errors::ProviderResult> { - self.0.storage(account, storage_key) - } -} - -/// Hack to get around 'higher-ranked lifetime error', see -/// -#[allow(missing_debug_implementations)] -pub struct StateCacheDBRefMutWrapper<'a, 'b>(pub &'b mut StateCacheDB<'a>); - -impl<'a, 'b> Database for StateCacheDBRefMutWrapper<'a, 'b> { - type Error = as Database>::Error; - fn basic( - &mut self, - address: revm_primitives::Address, - ) -> Result, Self::Error> { - self.0.basic(address) - } - - fn block_hash(&mut self, number: U256) -> Result { - self.0.block_hash(number) - } - - fn code_by_hash(&mut self, code_hash: B256) -> Result { - self.0.code_by_hash(code_hash) - } - - fn storage( - &mut self, - address: revm_primitives::Address, - index: U256, - ) -> Result { - self.0.storage(address, index) - } -} - -impl<'a, 'b> DatabaseRef for StateCacheDBRefMutWrapper<'a, 'b> { - type Error = as Database>::Error; - - fn basic_ref( - &self, - address: revm_primitives::Address, - ) -> Result, Self::Error> { - self.0.basic_ref(address) - } - - fn block_hash_ref(&self, number: U256) -> Result { - self.0.block_hash_ref(number) - } - - fn code_by_hash_ref(&self, code_hash: B256) -> Result { - self.0.code_by_hash_ref(code_hash) - } - - fn storage_ref( - &self, - address: revm_primitives::Address, - index: U256, - ) -> Result { - self.0.storage_ref(address, index) - } -} diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs similarity index 98% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs index f880105cb7d..b0ae9a638c4 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/fee.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs @@ -6,15 +6,10 @@ use reth_provider::{BlockIdReader, BlockReaderIdExt, ChainSpecProvider, HeaderPr use reth_rpc_types::{BlockNumberOrTag, FeeHistory}; use tracing::debug; -use crate::eth::{ - api::{ - fee_history::{calculate_reward_percentiles_for_block, FeeHistoryEntry}, - LoadBlock, - }, - cache::EthStateCache, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, - gas_oracle::GasPriceOracle, - FeeHistoryCache, +use crate::{ + fee_history::calculate_reward_percentiles_for_block, servers::LoadBlock, EthApiError, + EthResult, EthStateCache, FeeHistoryCache, FeeHistoryEntry, GasPriceOracle, + RpcInvalidTransactionError, }; /// Fee related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs similarity index 78% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs index 35c506a325e..66d6c6f1567 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/mod.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs @@ -20,19 +20,16 @@ pub mod call; pub mod fee; pub mod pending_block; pub mod receipt; +pub mod signer; +pub mod spec; pub mod state; pub mod trace; pub mod transaction; -pub use block::{EthBlocks, LoadBlock}; -pub use blocking_task::SpawnBlocking; -pub use call::{Call, EthCall, StateCacheDB}; -pub use fee::{EthFees, LoadFee}; -pub use pending_block::LoadPendingBlock; -pub use receipt::LoadReceipt; -pub use state::{EthState, LoadState}; -pub use trace::Trace; -pub use transaction::{EthTransactions, LoadTransaction, RawTransactionForwarder}; +use blocking_task::SpawnBlocking; +use call::Call; +use pending_block::LoadPendingBlock; +use trace::Trace; /// Extension trait that bundles traits needed for tracing transactions. pub trait TraceExt: LoadPendingBlock + SpawnBlocking + Trace + Call {} diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/pending_block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/pending_block.rs similarity index 98% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/pending_block.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/pending_block.rs index aa9fe28fb85..c6ccb9ca7c7 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/pending_block.rs @@ -29,15 +29,10 @@ use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State}; use tokio::sync::Mutex; use tracing::debug; -use crate::eth::{ - api::{ - pending_block::{ - pre_block_beacon_root_contract_call, pre_block_blockhashes_update, PendingBlock, - PendingBlockEnv, PendingBlockEnvOrigin, - }, - SpawnBlocking, - }, - error::{EthApiError, EthResult}, +use crate::{ + pending_block::{pre_block_beacon_root_contract_call, pre_block_blockhashes_update}, + servers::SpawnBlocking, + EthApiError, EthResult, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin, }; /// Loads a pending block from database. diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/receipt.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/receipt.rs similarity index 92% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/receipt.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/receipt.rs index e8fabee0d86..83c4b9d03d8 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/receipt.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/receipt.rs @@ -5,11 +5,7 @@ use futures::Future; use reth_primitives::{Receipt, TransactionMeta, TransactionSigned}; use reth_rpc_types::AnyTransactionReceipt; -use crate::eth::{ - api::ReceiptBuilder, - cache::EthStateCache, - error::{EthApiError, EthResult}, -}; +use crate::{EthApiError, EthResult, EthStateCache, ReceiptBuilder}; /// Assembles transaction receipt data w.r.t to network. /// diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/signer.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/signer.rs new file mode 100644 index 00000000000..637708eb7c4 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/signer.rs @@ -0,0 +1,40 @@ +//! An abstraction over ethereum signers. + +use std::result; + +use alloy_dyn_abi::TypedData; +use dyn_clone::DynClone; +use reth_primitives::{Address, Signature, TransactionSigned}; +use reth_rpc_types::TypedTransactionRequest; + +use crate::SignError; + +/// Result returned by [`EthSigner`] methods. +pub type Result = result::Result; + +/// An Ethereum Signer used via RPC. +#[async_trait::async_trait] +pub trait EthSigner: Send + Sync + DynClone { + /// Returns the available accounts for this signer. + fn accounts(&self) -> Vec
; + + /// Returns `true` whether this signer can sign for this address + fn is_signer_for(&self, addr: &Address) -> bool { + self.accounts().contains(addr) + } + + /// Returns the signature + async fn sign(&self, address: Address, message: &[u8]) -> Result; + + /// signs a transaction request using the given account in request + fn sign_transaction( + &self, + request: TypedTransactionRequest, + address: &Address, + ) -> Result; + + /// Encodes and signs the typed data according EIP-712. Payload must implement Eip712 trait. + fn sign_typed_data(&self, address: Address, payload: &TypedData) -> Result; +} + +dyn_clone::clone_trait_object!(EthSigner); diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/spec.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/spec.rs new file mode 100644 index 00000000000..45d8483b393 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/spec.rs @@ -0,0 +1,30 @@ +//! Loads chain metadata. + +use futures::Future; +use reth_errors::RethResult; +use reth_primitives::{Address, ChainInfo, U64}; +use reth_rpc_types::SyncStatus; + +/// `Eth` API trait. +/// +/// Defines core functionality of the `eth` API implementation. +#[auto_impl::auto_impl(&, Arc)] +pub trait EthApiSpec: Send + Sync { + /// Returns the current ethereum protocol version. + fn protocol_version(&self) -> impl Future> + Send; + + /// Returns the chain id + fn chain_id(&self) -> U64; + + /// Returns provider chain info + fn chain_info(&self) -> RethResult; + + /// Returns a list of addresses owned by provider. + fn accounts(&self) -> Vec
; + + /// Returns `true` if the network is undergoing sync. + fn is_syncing(&self) -> bool; + + /// Returns the [`SyncStatus`] of the network + fn sync_status(&self) -> RethResult; +} diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/state.rs similarity index 97% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/state.rs index 7d421e71667..220a33e9168 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/state.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/state.rs @@ -12,11 +12,9 @@ use reth_rpc_types_compat::proof::from_primitive_account_proof; use reth_transaction_pool::{PoolTransaction, TransactionPool}; use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId}; -use crate::eth::{ - api::{pending_block::PendingBlockEnv, LoadPendingBlock, SpawnBlocking}, - cache::EthStateCache, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, - EthApiSpec, +use crate::{ + servers::{EthApiSpec, LoadPendingBlock, SpawnBlocking}, + EthApiError, EthResult, EthStateCache, PendingBlockEnv, RpcInvalidTransactionError, }; /// Helper methods for `eth_` methods relating to state (accounts). diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/trace.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/trace.rs similarity index 94% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/trace.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/trace.rs index 39d54d9abde..a1eedf5dc1b 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/trace.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/trace.rs @@ -9,12 +9,10 @@ use revm::{db::CacheDB, Database, DatabaseCommit, GetInspector, Inspector}; use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig}; use revm_primitives::{EnvWithHandlerCfg, EvmState, ExecutionResult, ResultAndState}; -use crate::eth::{ - api::{ - traits::call::{StateCacheDBRefMutWrapper, StateProviderTraitObjWrapper}, - Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction, StateCacheDB, - }, - error::{EthApiError, EthResult}, +use crate::{ + cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper}, + servers::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction}, + EthApiError, EthResult, StateCacheDb, }; /// Executes CPU heavy tasks. @@ -104,7 +102,7 @@ pub trait Trace: LoadState { ) -> impl Future> + Send where Self: LoadPendingBlock + Call, - F: FnOnce(TracingInspector, ResultAndState, StateCacheDB<'_>) -> EthResult + F: FnOnce(TracingInspector, ResultAndState, StateCacheDb<'_>) -> EthResult + Send + 'static, R: Send + 'static, @@ -113,7 +111,7 @@ pub trait Trace: LoadState { self.spawn_with_state_at_block(at, move |state| { let mut db = CacheDB::new(StateProviderDatabase::new(state)); let mut inspector = TracingInspector::new(config); - let (res, _) = this.inspect(StateCacheDBRefMutWrapper(&mut db), env, &mut inspector)?; + let (res, _) = this.inspect(StateCacheDbRefMutWrapper(&mut db), env, &mut inspector)?; f(inspector, res, db) }) } @@ -139,7 +137,7 @@ pub trait Trace: LoadState { TransactionInfo, TracingInspector, ResultAndState, - StateCacheDB<'_>, + StateCacheDb<'_>, ) -> EthResult + Send + 'static, @@ -165,10 +163,10 @@ pub trait Trace: LoadState { ) -> impl Future>> + Send where Self: LoadPendingBlock + LoadTransaction + Call, - F: FnOnce(TransactionInfo, Insp, ResultAndState, StateCacheDB<'_>) -> EthResult + F: FnOnce(TransactionInfo, Insp, ResultAndState, StateCacheDb<'_>) -> EthResult + Send + 'static, - Insp: for<'a, 'b> Inspector> + Send + 'static, + Insp: for<'a, 'b> Inspector> + Send + 'static, R: Send + 'static, { async move { @@ -201,7 +199,7 @@ pub trait Trace: LoadState { let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, tx_env_with_recovered(&tx)); let (res, _) = - this.inspect(StateCacheDBRefMutWrapper(&mut db), env, &mut inspector)?; + this.inspect(StateCacheDbRefMutWrapper(&mut db), env, &mut inspector)?; f(tx_info, inspector, res, db) }) .await @@ -229,7 +227,7 @@ pub trait Trace: LoadState { TracingInspector, ExecutionResult, &EvmState, - &StateCacheDB<'_>, + &StateCacheDb<'_>, ) -> EthResult + Send + 'static, @@ -262,11 +260,11 @@ pub trait Trace: LoadState { ) -> impl Future>>> + Send where Self: LoadBlock, - F: Fn(TransactionInfo, Insp, ExecutionResult, &EvmState, &StateCacheDB<'_>) -> EthResult + F: Fn(TransactionInfo, Insp, ExecutionResult, &EvmState, &StateCacheDb<'_>) -> EthResult + Send + 'static, Setup: FnMut() -> Insp + Send + 'static, - Insp: for<'a, 'b> Inspector> + Send + 'static, + Insp: for<'a, 'b> Inspector> + Send + 'static, R: Send + 'static, { async move { @@ -326,7 +324,7 @@ pub trait Trace: LoadState { let mut inspector = inspector_setup(); let (res, _) = - this.inspect(StateCacheDBRefMutWrapper(&mut db), env, &mut inspector)?; + this.inspect(StateCacheDbRefMutWrapper(&mut db), env, &mut inspector)?; let ResultAndState { result, state } = res; results.push(f(tx_info, inspector, result, &state, &db)?); @@ -369,7 +367,7 @@ pub trait Trace: LoadState { TracingInspector, ExecutionResult, &EvmState, - &StateCacheDB<'_>, + &StateCacheDb<'_>, ) -> EthResult + Send + 'static, @@ -402,11 +400,11 @@ pub trait Trace: LoadState { Self: LoadBlock, // This is the callback that's invoked for each transaction with the inspector, the result, // state and db - F: Fn(TransactionInfo, Insp, ExecutionResult, &EvmState, &StateCacheDB<'_>) -> EthResult + F: Fn(TransactionInfo, Insp, ExecutionResult, &EvmState, &StateCacheDb<'_>) -> EthResult + Send + 'static, Setup: FnMut() -> Insp + Send + 'static, - Insp: for<'a, 'b> Inspector> + Send + 'static, + Insp: for<'a, 'b> Inspector> + Send + 'static, R: Send + 'static, { self.trace_block_until_with_inspector(block_id, None, insp_setup, f) diff --git a/crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs similarity index 99% rename from crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs index 2750f6e1058..221aab91b32 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/traits/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs @@ -20,13 +20,13 @@ use reth_rpc_types::{ use reth_rpc_types_compat::transaction::from_recovered_with_block_context; use reth_transaction_pool::{TransactionOrigin, TransactionPool}; -use crate::eth::{ - api::{Call, EthApiSpec, LoadBlock, LoadFee, LoadPendingBlock, LoadReceipt, SpawnBlocking}, - cache::EthStateCache, - error::{EthApiError, EthResult, SignError}, - signer::EthSigner, +use crate::{ + servers::{ + Call, EthApiSpec, EthSigner, LoadBlock, LoadFee, LoadPendingBlock, LoadReceipt, + SpawnBlocking, + }, utils::recover_raw_transaction, - TransactionSource, + EthApiError, EthResult, EthStateCache, SignError, TransactionSource, }; /// Transaction related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in diff --git a/crates/rpc/rpc-eth-api/src/eth/api/transactions.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/transaction.rs similarity index 60% rename from crates/rpc/rpc-eth-api/src/eth/api/transactions.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/transaction.rs index c72e1dfff40..3f5551d682e 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/transactions.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/transaction.rs @@ -1,19 +1,15 @@ //! Contains RPC handler implementations specific to transactions -use reth_primitives::{TransactionSignedEcRecovered, B256}; -use reth_rpc_types::{Transaction, TransactionInfo}; -use reth_rpc_types_compat::transaction::from_recovered_with_block_context; +use crate::EthApi; -use crate::eth::EthApi; - -/// Implements [`EthTransactions`](crate::eth::api::EthTransactions) for a type, that has similar +/// Implements [`EthTransactions`](crate::servers::EthTransactions) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! eth_transactions_impl { ($network_api:ty) => { - impl $crate::eth::api::EthTransactions for $network_api + impl $crate::servers::EthTransactions for $network_api where - Self: $crate::eth::api::LoadTransaction, + Self: $crate::servers::LoadTransaction, Pool: reth_transaction_pool::TransactionPool + 'static, Provider: reth_provider::BlockReaderIdExt, { @@ -25,26 +21,26 @@ macro_rules! eth_transactions_impl { #[inline] fn raw_tx_forwarder( &self, - ) -> Option> { + ) -> Option> { self.inner.raw_tx_forwarder() } #[inline] - fn signers(&self) -> &parking_lot::RwLock>> { + fn signers(&self) -> &parking_lot::RwLock>> { self.inner.signers() } } }; } -/// Implements [`LoadTransaction`](crate::eth::api::LoadTransaction) for a type, that has similar +/// Implements [`LoadTransaction`](crate::servers::LoadTransaction) for a type, that has similar /// data layout to [`EthApi`]. #[macro_export] macro_rules! load_transaction_impl { ($network_api:ty) => { - impl $crate::eth::api::LoadTransaction for $network_api + impl $crate::servers::LoadTransaction for $network_api where - Self: $crate::eth::api::SpawnBlocking, + Self: $crate::servers::SpawnBlocking, Provider: reth_provider::TransactionsProvider, Pool: reth_transaction_pool::TransactionPool, { @@ -56,7 +52,7 @@ macro_rules! load_transaction_impl { } #[inline] - fn cache(&self) -> &$crate::eth::cache::EthStateCache { + fn cache(&self) -> &$crate::EthStateCache { self.inner.cache() } @@ -71,102 +67,8 @@ macro_rules! load_transaction_impl { eth_transactions_impl!(EthApi); load_transaction_impl!(EthApi); -/// Represents from where a transaction was fetched. -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum TransactionSource { - /// Transaction exists in the pool (Pending) - Pool(TransactionSignedEcRecovered), - /// Transaction already included in a block - /// - /// This can be a historical block or a pending block (received from the CL) - Block { - /// Transaction fetched via provider - transaction: TransactionSignedEcRecovered, - /// Index of the transaction in the block - index: u64, - /// Hash of the block. - block_hash: B256, - /// Number of the block. - block_number: u64, - /// base fee of the block. - base_fee: Option, - }, -} - -// === impl TransactionSource === - -impl TransactionSource { - /// Consumes the type and returns the wrapped transaction. - pub fn into_recovered(self) -> TransactionSignedEcRecovered { - self.into() - } - - /// Returns the transaction and block related info, if not pending - pub fn split(self) -> (TransactionSignedEcRecovered, TransactionInfo) { - match self { - Self::Pool(tx) => { - let hash = tx.hash(); - ( - tx, - TransactionInfo { - hash: Some(hash), - index: None, - block_hash: None, - block_number: None, - base_fee: None, - }, - ) - } - Self::Block { transaction, index, block_hash, block_number, base_fee } => { - let hash = transaction.hash(); - ( - transaction, - TransactionInfo { - hash: Some(hash), - index: Some(index), - block_hash: Some(block_hash), - block_number: Some(block_number), - base_fee: base_fee.map(u128::from), - }, - ) - } - } - } -} - -impl From for TransactionSignedEcRecovered { - fn from(value: TransactionSource) -> Self { - match value { - TransactionSource::Pool(tx) => tx, - TransactionSource::Block { transaction, .. } => transaction, - } - } -} - -impl From for Transaction { - fn from(value: TransactionSource) -> Self { - match value { - TransactionSource::Pool(tx) => reth_rpc_types_compat::transaction::from_recovered(tx), - TransactionSource::Block { transaction, index, block_hash, block_number, base_fee } => { - from_recovered_with_block_context( - transaction, - block_hash, - block_number, - base_fee, - index as usize, - ) - } - } - } -} - #[cfg(test)] mod tests { - use super::*; - use crate::eth::{ - api::EthTransactions, cache::EthStateCache, gas_oracle::GasPriceOracle, FeeHistoryCache, - FeeHistoryCacheConfig, - }; use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; use reth_primitives::{constants::ETHEREUM_BLOCK_GAS_LIMIT, hex_literal::hex, Bytes}; @@ -174,6 +76,13 @@ mod tests { use reth_tasks::pool::BlockingTaskPool; use reth_transaction_pool::{test_utils::testing_pool, TransactionPool}; + use crate::{ + servers::EthTransactions, EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, + GasPriceOracle, + }; + + use super::*; + #[tokio::test] async fn send_raw_transaction() { let noop_provider = NoopProvider::default(); diff --git a/crates/rpc/rpc-eth-api/src/eth/api/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs similarity index 66% rename from crates/rpc/rpc-eth-api/src/eth/api/mod.rs rename to crates/rpc/rpc-eth-api/src/api/servers/mod.rs index ce0e970e025..ad8187cac8d 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/mod.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs @@ -1,70 +1,39 @@ -//! The entire implementation of the namespace is quite large, hence it is divided across several -//! files. - -use std::{fmt::Debug, sync::Arc}; - -use async_trait::async_trait; -use reth_errors::{RethError, RethResult}; -use reth_evm::ConfigureEvm; -use reth_network_api::NetworkInfo; -use reth_primitives::{Address, BlockNumberOrTag, ChainInfo, U256, U64}; -use reth_provider::{BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; -use reth_rpc_types::{SyncInfo, SyncStatus}; -use reth_tasks::{pool::BlockingTaskPool, TaskSpawner, TokioTaskExecutor}; -use reth_transaction_pool::TransactionPool; -use tokio::sync::Mutex; - -use crate::eth::{ - api::fee_history::FeeHistoryCache, cache::EthStateCache, gas_oracle::GasPriceOracle, - signer::EthSigner, -}; - -pub mod block; -mod call; -pub(crate) mod fee_history; -mod fees; -pub mod pending_block; -pub mod receipt; -mod server; -mod sign; -mod state; -pub mod trace; -pub mod traits; -pub mod transactions; - -pub use pending_block::PendingBlock; -pub use receipt::ReceiptBuilder; -pub use traits::{ - Call, EthBlocks, EthCall, EthFees, EthState, EthTransactions, LoadBlock, LoadFee, - LoadPendingBlock, LoadReceipt, LoadState, LoadTransaction, RawTransactionForwarder, - SpawnBlocking, StateCacheDB, Trace, TraceExt, -}; -pub use transactions::TransactionSource; +//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`](crate::EthApi) trait +//! Handles RPC requests for the `eth_` namespace. -/// `Eth` API trait. -/// -/// Defines core functionality of the `eth` API implementation. -#[async_trait] -#[auto_impl::auto_impl(&, Arc)] -pub trait EthApiSpec: Send + Sync { - /// Returns the current ethereum protocol version. - async fn protocol_version(&self) -> RethResult; +use std::sync::Arc; - /// Returns the chain id - fn chain_id(&self) -> U64; +use reth_primitives::{BlockNumberOrTag, U256}; +use reth_provider::{BlockReaderIdExt, ChainSpecProvider}; - /// Returns provider chain info - fn chain_info(&self) -> RethResult; +pub mod bundle; +pub mod filter; +pub mod helpers; +pub mod pubsub; - /// Returns a list of addresses owned by provider. - fn accounts(&self) -> Vec
; +mod server; - /// Returns `true` if the network is undergoing sync. - fn is_syncing(&self) -> bool; +pub use helpers::{ + signer::DevSigner, + traits::{ + block::{EthBlocks, LoadBlock}, + blocking_task::SpawnBlocking, + call::{Call, EthCall}, + fee::{EthFees, LoadFee}, + pending_block::LoadPendingBlock, + receipt::LoadReceipt, + signer::EthSigner, + spec::EthApiSpec, + state::{EthState, LoadState}, + trace::Trace, + transaction::{EthTransactions, LoadTransaction, RawTransactionForwarder}, + TraceExt, + }, +}; +use reth_tasks::{pool::BlockingTaskPool, TaskSpawner, TokioTaskExecutor}; +use tokio::sync::Mutex; - /// Returns the [SyncStatus] of the network - fn sync_status(&self) -> RethResult; -} +use crate::{EthStateCache, FeeHistoryCache, GasCap, GasPriceOracle, PendingBlock}; /// `Eth` API implementation. /// @@ -214,66 +183,11 @@ impl Clone for EthApi EthApiSpec for EthApi -where - Pool: TransactionPool + 'static, - Provider: - BlockReaderIdExt + ChainSpecProvider + StateProviderFactory + EvmEnvProvider + 'static, - Network: NetworkInfo + 'static, - EvmConfig: ConfigureEvm, -{ - /// Returns the current ethereum protocol version. - /// - /// Note: This returns an `U64`, since this should return as hex string. - async fn protocol_version(&self) -> RethResult { - let status = self.network().network_status().await.map_err(RethError::other)?; - Ok(U64::from(status.protocol_version)) - } - - /// Returns the chain id - fn chain_id(&self) -> U64 { - U64::from(self.network().chain_id()) - } - - /// Returns the current info for the chain - fn chain_info(&self) -> RethResult { - Ok(self.provider().chain_info()?) - } - - fn accounts(&self) -> Vec
{ - self.inner.signers.read().iter().flat_map(|s| s.accounts()).collect() - } - - fn is_syncing(&self) -> bool { - self.network().is_syncing() - } - - /// Returns the [SyncStatus] of the network - fn sync_status(&self) -> RethResult { - let status = if self.is_syncing() { - let current_block = U256::from( - self.provider().chain_info().map(|info| info.best_number).unwrap_or_default(), - ); - SyncStatus::Info(SyncInfo { - starting_block: self.inner.starting_block, - current_block, - highest_block: current_block, - warp_chunks_amount: None, - warp_chunks_processed: None, - }) - } else { - SyncStatus::None - }; - Ok(status) - } -} - /// Implements [`SpawnBlocking`] for a type, that has similar data layout to [`EthApi`]. #[macro_export] macro_rules! spawn_blocking_impl { ($network_api:ty) => { - impl $crate::eth::api::SpawnBlocking for $network_api + impl $crate::servers::SpawnBlocking for $network_api where Self: Clone + Send + Sync + 'static, { @@ -292,32 +206,12 @@ macro_rules! spawn_blocking_impl { spawn_blocking_impl!(EthApi); -/// The default gas limit for `eth_call` and adjacent calls. -/// -/// This is different from the default to regular 30M block gas limit -/// [`ETHEREUM_BLOCK_GAS_LIMIT`](reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT) to allow for -/// more complex calls. -pub const RPC_DEFAULT_GAS_CAP: GasCap = GasCap(50_000_000); - -/// The wrapper type for gas limit -#[derive(Debug, Clone, Copy)] -pub struct GasCap(u64); - -impl Default for GasCap { - fn default() -> Self { - RPC_DEFAULT_GAS_CAP - } -} - -impl From for GasCap { - fn from(gas_cap: u64) -> Self { - Self(gas_cap) - } -} - -impl From for u64 { - fn from(gas_cap: GasCap) -> Self { - gas_cap.0 +impl EthApi { + /// Generates 20 random developer accounts. + /// Used in DEV mode. + pub fn with_dev_accounts(&self) { + let mut signers = self.inner.signers.write(); + *signers = DevSigner::random_signers(20); } } diff --git a/crates/rpc/rpc/src/eth/pubsub.rs b/crates/rpc/rpc-eth-api/src/api/servers/pubsub.rs similarity index 98% rename from crates/rpc/rpc/src/eth/pubsub.rs rename to crates/rpc/rpc-eth-api/src/api/servers/pubsub.rs index fdfa836b91f..a0e886f6d94 100644 --- a/crates/rpc/rpc/src/eth/pubsub.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/pubsub.rs @@ -1,9 +1,7 @@ //! `eth_` `PubSub` RPC handler implementation -use crate::{ - eth::logs_utils, - result::{internal_rpc_err, invalid_params_rpc_err}, -}; +use std::sync::Arc; + use futures::StreamExt; use jsonrpsee::{ server::SubscriptionMessage, types::ErrorObject, PendingSubscriptionSink, SubscriptionSink, @@ -11,7 +9,6 @@ use jsonrpsee::{ use reth_network_api::NetworkInfo; use reth_primitives::{IntoRecoveredTransaction, TxHash}; use reth_provider::{BlockReader, CanonStateSubscriptions, EvmEnvProvider}; -use reth_rpc_api::EthPubSubApiServer; use reth_rpc_types::{ pubsub::{ Params, PubSubSyncStatus, SubscriptionKind, SubscriptionResult as EthSubscriptionResult, @@ -22,12 +19,17 @@ use reth_rpc_types::{ use reth_tasks::{TaskSpawner, TokioTaskExecutor}; use reth_transaction_pool::{NewTransactionEvent, TransactionPool}; use serde::Serialize; -use std::sync::Arc; use tokio_stream::{ wrappers::{BroadcastStream, ReceiverStream}, Stream, }; +use crate::{ + logs_utils, + result::{internal_rpc_err, invalid_params_rpc_err}, + EthPubSubApiServer, +}; + /// `Eth` pubsub RPC implementation. /// /// This handles `eth_subscribe` RPC calls. @@ -197,10 +199,10 @@ where /// Helper to convert a serde error into an [`ErrorObject`] #[derive(Debug, thiserror::Error)] #[error("Failed to serialize subscription item: {0}")] -pub(crate) struct SubscriptionSerializeError(#[from] serde_json::Error); +pub struct SubscriptionSerializeError(#[from] serde_json::Error); impl SubscriptionSerializeError { - pub(crate) const fn new(err: serde_json::Error) -> Self { + const fn new(err: serde_json::Error) -> Self { Self(err) } } diff --git a/crates/rpc/rpc-eth-api/src/server.rs b/crates/rpc/rpc-eth-api/src/api/servers/server.rs similarity index 97% rename from crates/rpc/rpc-eth-api/src/server.rs rename to crates/rpc/rpc-eth-api/src/api/servers/server.rs index 1d757cb6805..b5380046df9 100644 --- a/crates/rpc/rpc-eth-api/src/server.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/server.rs @@ -1,26 +1,20 @@ -//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`](crate::EthApi) trait -//! Handles RPC requests for the `eth_` namespace. - use jsonrpsee::core::RpcResult as Result; use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; use reth_rpc_types::{ serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, - FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, TransactionRequest, Work, + FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction, + TransactionRequest, Work, }; -use serde_json::Value; use tracing::trace; use crate::{ - eth::{ - api::{ - EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, LoadReceipt, Trace, - }, - error::EthApiError, - revm_utils::EvmOverrides, + result::internal_rpc_err, + revm_utils::EvmOverrides, + servers::{ + EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, LoadReceipt, Trace, }, - result::{internal_rpc_err, ToRpcResult}, - EthApiServer, + EthApiError, EthApiServer, ToRpcResult, }; #[async_trait::async_trait] @@ -151,7 +145,7 @@ where } /// Handler for: `eth_getTransactionByHash` - async fn transaction_by_hash(&self, hash: B256) -> Result> { + async fn transaction_by_hash(&self, hash: B256) -> Result> { trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash"); Ok(EthTransactions::transaction_by_hash(self, hash).await?.map(Into::into)) } @@ -395,7 +389,7 @@ where } /// Handler for: `eth_signTypedData` - async fn sign_typed_data(&self, address: Address, data: Value) -> Result { + async fn sign_typed_data(&self, address: Address, data: serde_json::Value) -> Result { trace!(target: "rpc::eth", ?address, ?data, "Serving eth_signTypedData"); Ok(EthTransactions::sign_typed_data(self, data, address)?) } @@ -421,13 +415,6 @@ where #[cfg(test)] mod tests { - use crate::{ - eth::{ - cache::EthStateCache, gas_oracle::GasPriceOracle, EthApi, FeeHistoryCache, - FeeHistoryCacheConfig, - }, - EthApiServer, - }; use jsonrpsee::types::error::INVALID_PARAMS_CODE; use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; @@ -444,6 +431,10 @@ mod tests { use reth_testing_utils::{generators, generators::Rng}; use reth_transaction_pool::test_utils::{testing_pool, TestPool}; + use crate::{ + EthApi, EthApiServer, EthStateCache, FeeHistoryCache, FeeHistoryCacheConfig, GasPriceOracle, + }; + fn build_test_eth_api< P: BlockReaderIdExt + BlockReader diff --git a/crates/rpc/rpc-eth-api/src/eth/cache/config.rs b/crates/rpc/rpc-eth-api/src/cache/config.rs similarity index 100% rename from crates/rpc/rpc-eth-api/src/eth/cache/config.rs rename to crates/rpc/rpc-eth-api/src/cache/config.rs diff --git a/crates/rpc/rpc-eth-api/src/cache/db.rs b/crates/rpc/rpc-eth-api/src/cache/db.rs new file mode 100644 index 00000000000..55629c602ef --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/cache/db.rs @@ -0,0 +1,165 @@ +use reth_primitives::{B256, U256}; +use reth_provider::StateProvider; +use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; +use revm::Database; + +/// Helper alias type for the state's [`CacheDB`] +pub type StateCacheDb<'a> = CacheDB>>; + +/// Hack to get around 'higher-ranked lifetime error', see +/// +#[allow(missing_debug_implementations)] +pub struct StateProviderTraitObjWrapper<'a>(pub &'a dyn StateProvider); + +impl<'a> reth_provider::StateRootProvider for StateProviderTraitObjWrapper<'a> { + fn state_root( + &self, + bundle_state: &revm::db::BundleState, + ) -> reth_errors::ProviderResult { + self.0.state_root(bundle_state) + } + + fn state_root_with_updates( + &self, + bundle_state: &revm::db::BundleState, + ) -> reth_errors::ProviderResult<(B256, reth_trie::updates::TrieUpdates)> { + self.0.state_root_with_updates(bundle_state) + } +} + +impl<'a> reth_provider::AccountReader for StateProviderTraitObjWrapper<'a> { + fn basic_account( + &self, + address: revm_primitives::Address, + ) -> reth_errors::ProviderResult> { + self.0.basic_account(address) + } +} + +impl<'a> reth_provider::BlockHashReader for StateProviderTraitObjWrapper<'a> { + fn block_hash( + &self, + block_number: reth_primitives::BlockNumber, + ) -> reth_errors::ProviderResult> { + self.0.block_hash(block_number) + } + + fn canonical_hashes_range( + &self, + start: reth_primitives::BlockNumber, + end: reth_primitives::BlockNumber, + ) -> reth_errors::ProviderResult> { + self.0.canonical_hashes_range(start, end) + } + + fn convert_block_hash( + &self, + hash_or_number: reth_rpc_types::BlockHashOrNumber, + ) -> reth_errors::ProviderResult> { + self.0.convert_block_hash(hash_or_number) + } +} + +impl<'a> StateProvider for StateProviderTraitObjWrapper<'a> { + fn account_balance( + &self, + addr: revm_primitives::Address, + ) -> reth_errors::ProviderResult> { + self.0.account_balance(addr) + } + + fn account_code( + &self, + addr: revm_primitives::Address, + ) -> reth_errors::ProviderResult> { + self.0.account_code(addr) + } + + fn account_nonce( + &self, + addr: revm_primitives::Address, + ) -> reth_errors::ProviderResult> { + self.0.account_nonce(addr) + } + + fn bytecode_by_hash( + &self, + code_hash: B256, + ) -> reth_errors::ProviderResult> { + self.0.bytecode_by_hash(code_hash) + } + + fn proof( + &self, + address: revm_primitives::Address, + keys: &[B256], + ) -> reth_errors::ProviderResult { + self.0.proof(address, keys) + } + + fn storage( + &self, + account: revm_primitives::Address, + storage_key: reth_primitives::StorageKey, + ) -> reth_errors::ProviderResult> { + self.0.storage(account, storage_key) + } +} + +/// Hack to get around 'higher-ranked lifetime error', see +/// +#[allow(missing_debug_implementations)] +pub struct StateCacheDbRefMutWrapper<'a, 'b>(pub &'b mut StateCacheDb<'a>); + +impl<'a, 'b> Database for StateCacheDbRefMutWrapper<'a, 'b> { + type Error = as Database>::Error; + fn basic( + &mut self, + address: revm_primitives::Address, + ) -> Result, Self::Error> { + self.0.basic(address) + } + + fn block_hash(&mut self, number: U256) -> Result { + self.0.block_hash(number) + } + + fn code_by_hash(&mut self, code_hash: B256) -> Result { + self.0.code_by_hash(code_hash) + } + + fn storage( + &mut self, + address: revm_primitives::Address, + index: U256, + ) -> Result { + self.0.storage(address, index) + } +} + +impl<'a, 'b> DatabaseRef for StateCacheDbRefMutWrapper<'a, 'b> { + type Error = as Database>::Error; + + fn basic_ref( + &self, + address: revm_primitives::Address, + ) -> Result, Self::Error> { + self.0.basic_ref(address) + } + + fn block_hash_ref(&self, number: U256) -> Result { + self.0.block_hash_ref(number) + } + + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + self.0.code_by_hash_ref(code_hash) + } + + fn storage_ref( + &self, + address: revm_primitives::Address, + index: U256, + ) -> Result { + self.0.storage_ref(address, index) + } +} diff --git a/crates/rpc/rpc-eth-api/src/eth/cache/metrics.rs b/crates/rpc/rpc-eth-api/src/cache/metrics.rs similarity index 100% rename from crates/rpc/rpc-eth-api/src/eth/cache/metrics.rs rename to crates/rpc/rpc-eth-api/src/cache/metrics.rs diff --git a/crates/rpc/rpc-eth-api/src/eth/cache/mod.rs b/crates/rpc/rpc-eth-api/src/cache/mod.rs similarity index 99% rename from crates/rpc/rpc-eth-api/src/eth/cache/mod.rs rename to crates/rpc/rpc-eth-api/src/cache/mod.rs index 95c1669a280..32c97f51e85 100644 --- a/crates/rpc/rpc-eth-api/src/eth/cache/mod.rs +++ b/crates/rpc/rpc-eth-api/src/cache/mod.rs @@ -26,13 +26,12 @@ use tokio::sync::{ }; use tokio_stream::wrappers::UnboundedReceiverStream; -mod config; -pub use config::*; +use crate::{EthStateCacheConfig, MultiConsumerLruCache}; -mod metrics; - -mod multi_consumer; -pub use multi_consumer::MultiConsumerLruCache; +pub mod config; +pub mod db; +pub mod metrics; +pub mod multi_consumer; /// The type that can send the response to a requested [Block] type BlockTransactionsResponseSender = diff --git a/crates/rpc/rpc-eth-api/src/eth/cache/multi_consumer.rs b/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs similarity index 100% rename from crates/rpc/rpc-eth-api/src/eth/cache/multi_consumer.rs rename to crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs diff --git a/crates/rpc/rpc-eth-api/src/eth/error.rs b/crates/rpc/rpc-eth-api/src/error.rs similarity index 100% rename from crates/rpc/rpc-eth-api/src/eth/error.rs rename to crates/rpc/rpc-eth-api/src/error.rs diff --git a/crates/rpc/rpc-eth-api/src/eth/api/optimism.rs b/crates/rpc/rpc-eth-api/src/eth/api/optimism.rs deleted file mode 100644 index af58450145b..00000000000 --- a/crates/rpc/rpc-eth-api/src/eth/api/optimism.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Optimism helpers. - -use revm::L1BlockInfo; - -/// Optimism Transaction Metadata -/// -/// Includes the L1 fee and data gas for the tx along with the L1 -/// block info. In order to pass the [`OptimismTxMeta`] into the -/// async colored `build_transaction_receipt_with_block_receipts` -/// function, a reference counter for the L1 block info is -/// used so the L1 block info can be shared between receipts. -#[derive(Debug, Default, Clone)] -pub(crate) struct OptimismTxMeta { - /// The L1 block info. - pub(crate) l1_block_info: Option, - /// The L1 fee for the block. - pub(crate) l1_fee: Option, - /// The L1 data gas for the block. - pub(crate) l1_data_gas: Option, -} - -impl OptimismTxMeta { - /// Creates a new [`OptimismTxMeta`]. - pub(crate) const fn new( - l1_block_info: Option, - l1_fee: Option, - l1_data_gas: Option, - ) -> Self { - Self { l1_block_info, l1_fee, l1_data_gas } - } -} diff --git a/crates/rpc/rpc-eth-api/src/eth/api/server.rs b/crates/rpc/rpc-eth-api/src/eth/api/server.rs deleted file mode 100644 index c41a1ae9d9e..00000000000 --- a/crates/rpc/rpc-eth-api/src/eth/api/server.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_eth_api::EthApiServer`] trait -//! Handles RPC requests for the `eth_` namespace. - -use jsonrpsee::core::RpcResult as Result; -use reth_evm::ConfigureEvm; -use reth_network_api::NetworkInfo; -use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; -use reth_provider::{ - BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, HeaderProvider, StateProviderFactory, -}; -use reth_rpc_types::{ - serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, - AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, - FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, TransactionRequest, Work, -}; -use reth_transaction_pool::TransactionPool; -use serde_json::Value; -use tracing::trace; - -use crate::{ - eth::{ - api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, - error::EthApiError, - revm_utils::EvmOverrides, - EthApi, - }, - result::{internal_rpc_err, ToRpcResult}, - EthApiServer, -}; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/sign.rs b/crates/rpc/rpc-eth-api/src/eth/api/sign.rs deleted file mode 100644 index 62a30ce8138..00000000000 --- a/crates/rpc/rpc-eth-api/src/eth/api/sign.rs +++ /dev/null @@ -1,12 +0,0 @@ -//! Contains RPC handler implementations specific to sign endpoints - -use crate::eth::{signer::DevSigner, EthApi}; - -impl EthApi { - /// Generates 20 random developer accounts. - /// Used in DEV mode. - pub fn with_dev_accounts(&self) { - let mut signers = self.inner.signers.write(); - *signers = DevSigner::random_signers(20); - } -} diff --git a/crates/rpc/rpc-eth-api/src/eth/mod.rs b/crates/rpc/rpc-eth-api/src/eth/mod.rs deleted file mode 100644 index 98337e2a462..00000000000 --- a/crates/rpc/rpc-eth-api/src/eth/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! `eth` namespace handler implementation. - -pub mod api; -pub mod cache; -pub mod error; -pub mod gas_oracle; -pub mod revm_utils; -mod signer; -pub mod utils; - -pub use api::{ - fee_history::{fee_history_cache_new_blocks_task, FeeHistoryCache, FeeHistoryCacheConfig}, - EthApi, EthApiSpec, PendingBlock, TransactionSource, RPC_DEFAULT_GAS_CAP, -}; - -pub use signer::EthSigner; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/fee_history.rs b/crates/rpc/rpc-eth-api/src/fee_history.rs similarity index 99% rename from crates/rpc/rpc-eth-api/src/eth/api/fee_history.rs rename to crates/rpc/rpc-eth-api/src/fee_history.rs index 4b03bec9d81..0b4d98b84cc 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/fee_history.rs +++ b/crates/rpc/rpc-eth-api/src/fee_history.rs @@ -22,7 +22,7 @@ use reth_rpc_types::TxGasAndReward; use serde::{Deserialize, Serialize}; use tracing::trace; -use crate::eth::{cache::EthStateCache, error::EthApiError}; +use crate::{EthApiError, EthStateCache}; /// Contains cached fee history entries for blocks. /// diff --git a/crates/rpc/rpc-eth-api/src/eth/gas_oracle.rs b/crates/rpc/rpc-eth-api/src/gas_oracle.rs similarity index 90% rename from crates/rpc/rpc-eth-api/src/eth/gas_oracle.rs rename to crates/rpc/rpc-eth-api/src/gas_oracle.rs index 346f7852f54..3cc55eb2b34 100644 --- a/crates/rpc/rpc-eth-api/src/eth/gas_oracle.rs +++ b/crates/rpc/rpc-eth-api/src/gas_oracle.rs @@ -1,20 +1,33 @@ //! An implementation of the eth gas price oracle, used for providing gas price estimates based on //! previous blocks. -use crate::eth::{ - cache::EthStateCache, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, -}; +use std::fmt::{self, Debug, Formatter}; + use derive_more::{Deref, DerefMut}; use reth_primitives::{constants::GWEI_TO_WEI, BlockNumberOrTag, B256, U256}; use reth_provider::BlockReaderIdExt; use reth_rpc_server_types::constants::gas_oracle::*; use schnellru::{ByLength, LruMap}; use serde::{Deserialize, Serialize}; -use std::fmt::{self, Debug, Formatter}; use tokio::sync::Mutex; use tracing::warn; +use crate::{EthApiError, EthResult, EthStateCache, RpcInvalidTransactionError}; + +/// The default gas limit for `eth_call` and adjacent calls. +/// +/// This is different from the default to regular 30M block gas limit +/// [`ETHEREUM_BLOCK_GAS_LIMIT`](reth_primitives::constants::ETHEREUM_BLOCK_GAS_LIMIT) to allow for +/// more complex calls. +pub const RPC_DEFAULT_GAS_CAP: GasCap = GasCap(50_000_000); + +/// Gas per transaction not creating a contract. +pub const MIN_TRANSACTION_GAS: u64 = 21_000u64; +/// Allowed error ratio for gas estimation +/// Taken from Geth's implementation in order to pass the hive tests +/// +pub const ESTIMATE_GAS_ERROR_RATIO: f64 = 0.015; + /// Settings for the [`GasPriceOracle`] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -286,6 +299,28 @@ impl Default for GasPriceOracleResult { } } +/// The wrapper type for gas limit +#[derive(Debug, Clone, Copy)] +pub struct GasCap(u64); + +impl Default for GasCap { + fn default() -> Self { + RPC_DEFAULT_GAS_CAP + } +} + +impl From for GasCap { + fn from(gas_cap: u64) -> Self { + Self(gas_cap) + } +} + +impl From for u64 { + fn from(gas_cap: GasCap) -> Self { + gas_cap.0 + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc/rpc/src/eth/id_provider.rs b/crates/rpc/rpc-eth-api/src/id_provider.rs similarity index 93% rename from crates/rpc/rpc/src/eth/id_provider.rs rename to crates/rpc/rpc-eth-api/src/id_provider.rs index 6691e13a9f4..e3960d7c265 100644 --- a/crates/rpc/rpc/src/eth/id_provider.rs +++ b/crates/rpc/rpc-eth-api/src/id_provider.rs @@ -1,6 +1,11 @@ -use jsonrpsee::types::SubscriptionId; +//! Helper type for [`EthPubSubApiServer`](crate::api::pubsub::EthPubSubApi) implementation. +//! +//! Generates IDs for tracking subscriptions. + use std::fmt::Write; +use jsonrpsee::types::SubscriptionId; + /// An [`IdProvider`](jsonrpsee::core::traits::IdProvider) for ethereum subscription ids. /// /// Returns new hex-string [QUANTITY](https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding) ids diff --git a/crates/rpc/rpc-eth-api/src/lib.rs b/crates/rpc/rpc-eth-api/src/lib.rs index b0c9175586d..e70bd8efd52 100644 --- a/crates/rpc/rpc-eth-api/src/lib.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -12,319 +12,47 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use jsonrpsee::{core::RpcResult, proc_macros::rpc}; -use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; -use reth_rpc_types::{ - serde_helpers::JsonStorageKey, state::StateOverride, AccessListWithGasUsed, - AnyTransactionReceipt, BlockOverrides, Bundle, EIP1186AccountProofResponse, EthCallResponse, - FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction, - TransactionRequest, Work, -}; - -pub mod eth; +pub mod api; +pub mod cache; +pub mod error; +pub mod fee_history; +pub mod gas_oracle; +pub mod id_provider; +pub mod logs_utils; +pub mod pending_block; +pub mod receipt; pub mod result; -pub mod server; - -pub use eth::EthApiSpec; - -/// Eth rpc interface: -#[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))] -#[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))] -pub trait EthApi { - /// Returns the protocol version encoded as a string. - #[method(name = "protocolVersion")] - async fn protocol_version(&self) -> RpcResult; - - /// Returns an object with data about the sync status or false. - #[method(name = "syncing")] - fn syncing(&self) -> RpcResult; - - /// Returns the client coinbase address. - #[method(name = "coinbase")] - async fn author(&self) -> RpcResult
; - - /// Returns a list of addresses owned by client. - #[method(name = "accounts")] - fn accounts(&self) -> RpcResult>; - - /// Returns the number of most recent block. - #[method(name = "blockNumber")] - fn block_number(&self) -> RpcResult; - - /// Returns the chain ID of the current network. - #[method(name = "chainId")] - async fn chain_id(&self) -> RpcResult>; - - /// Returns information about a block by hash. - #[method(name = "getBlockByHash")] - async fn block_by_hash(&self, hash: B256, full: bool) -> RpcResult>; - - /// Returns information about a block by number. - #[method(name = "getBlockByNumber")] - async fn block_by_number( - &self, - number: BlockNumberOrTag, - full: bool, - ) -> RpcResult>; - - /// Returns the number of transactions in a block from a block matching the given block hash. - #[method(name = "getBlockTransactionCountByHash")] - async fn block_transaction_count_by_hash(&self, hash: B256) -> RpcResult>; - - /// Returns the number of transactions in a block matching the given block number. - #[method(name = "getBlockTransactionCountByNumber")] - async fn block_transaction_count_by_number( - &self, - number: BlockNumberOrTag, - ) -> RpcResult>; - - /// Returns the number of uncles in a block from a block matching the given block hash. - #[method(name = "getUncleCountByBlockHash")] - async fn block_uncles_count_by_hash(&self, hash: B256) -> RpcResult>; - - /// Returns the number of uncles in a block with given block number. - #[method(name = "getUncleCountByBlockNumber")] - async fn block_uncles_count_by_number( - &self, - number: BlockNumberOrTag, - ) -> RpcResult>; - - /// Returns all transaction receipts for a given block. - #[method(name = "getBlockReceipts")] - async fn block_receipts( - &self, - block_id: BlockId, - ) -> RpcResult>>; - - /// Returns an uncle block of the given block and index. - #[method(name = "getUncleByBlockHashAndIndex")] - async fn uncle_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> RpcResult>; - - /// Returns an uncle block of the given block and index. - #[method(name = "getUncleByBlockNumberAndIndex")] - async fn uncle_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> RpcResult>; - - /// Returns the EIP-2718 encoded transaction if it exists. - /// - /// If this is a EIP-4844 transaction that is in the pool it will include the sidecar. - #[method(name = "getRawTransactionByHash")] - async fn raw_transaction_by_hash(&self, hash: B256) -> RpcResult>; - - /// Returns the information about a transaction requested by transaction hash. - #[method(name = "getTransactionByHash")] - async fn transaction_by_hash(&self, hash: B256) -> RpcResult>; - - /// Returns information about a raw transaction by block hash and transaction index position. - #[method(name = "getRawTransactionByBlockHashAndIndex")] - async fn raw_transaction_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> RpcResult>; - - /// Returns information about a transaction by block hash and transaction index position. - #[method(name = "getTransactionByBlockHashAndIndex")] - async fn transaction_by_block_hash_and_index( - &self, - hash: B256, - index: Index, - ) -> RpcResult>; - - /// Returns information about a raw transaction by block number and transaction index - /// position. - #[method(name = "getRawTransactionByBlockNumberAndIndex")] - async fn raw_transaction_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> RpcResult>; - - /// Returns information about a transaction by block number and transaction index position. - #[method(name = "getTransactionByBlockNumberAndIndex")] - async fn transaction_by_block_number_and_index( - &self, - number: BlockNumberOrTag, - index: Index, - ) -> RpcResult>; - - /// Returns the receipt of a transaction by transaction hash. - #[method(name = "getTransactionReceipt")] - async fn transaction_receipt(&self, hash: B256) -> RpcResult>; - - /// Returns the balance of the account of given address. - #[method(name = "getBalance")] - async fn balance(&self, address: Address, block_number: Option) -> RpcResult; - - /// Returns the value from a storage position at a given address - #[method(name = "getStorageAt")] - async fn storage_at( - &self, - address: Address, - index: JsonStorageKey, - block_number: Option, - ) -> RpcResult; - - /// Returns the number of transactions sent from an address at given block number. - #[method(name = "getTransactionCount")] - async fn transaction_count( - &self, - address: Address, - block_number: Option, - ) -> RpcResult; - - /// Returns code at a given address at given block number. - #[method(name = "getCode")] - async fn get_code(&self, address: Address, block_number: Option) -> RpcResult; - - /// Returns the block's header at given number. - #[method(name = "getHeaderByNumber")] - async fn header_by_number(&self, hash: BlockNumberOrTag) -> RpcResult>; - - /// Returns the block's header at given hash. - #[method(name = "getHeaderByHash")] - async fn header_by_hash(&self, hash: B256) -> RpcResult>; - - /// Executes a new message call immediately without creating a transaction on the block chain. - #[method(name = "call")] - async fn call( - &self, - request: TransactionRequest, - block_number: Option, - state_overrides: Option, - block_overrides: Option>, - ) -> RpcResult; - - /// Simulate arbitrary number of transactions at an arbitrary blockchain index, with the - /// optionality of state overrides - #[method(name = "callMany")] - async fn call_many( - &self, - bundle: Bundle, - state_context: Option, - state_override: Option, - ) -> RpcResult>; - - /// Generates an access list for a transaction. - /// - /// This method creates an [EIP2930](https://eips.ethereum.org/EIPS/eip-2930) type accessList based on a given Transaction. - /// - /// An access list contains all storage slots and addresses touched by the transaction, except - /// for the sender account and the chain's precompiles. - /// - /// It returns list of addresses and storage keys used by the transaction, plus the gas - /// consumed when the access list is added. That is, it gives you the list of addresses and - /// storage keys that will be used by that transaction, plus the gas consumed if the access - /// list is included. Like eth_estimateGas, this is an estimation; the list could change - /// when the transaction is actually mined. Adding an accessList to your transaction does - /// not necessary result in lower gas usage compared to a transaction without an access - /// list. - #[method(name = "createAccessList")] - async fn create_access_list( - &self, - request: TransactionRequest, - block_number: Option, - ) -> RpcResult; - - /// Generates and returns an estimate of how much gas is necessary to allow the transaction to - /// complete. - #[method(name = "estimateGas")] - async fn estimate_gas( - &self, - request: TransactionRequest, - block_number: Option, - state_override: Option, - ) -> RpcResult; - - /// Returns the current price per gas in wei. - #[method(name = "gasPrice")] - async fn gas_price(&self) -> RpcResult; - - /// Introduced in EIP-1559, returns suggestion for the priority for dynamic fee transactions. - #[method(name = "maxPriorityFeePerGas")] - async fn max_priority_fee_per_gas(&self) -> RpcResult; - - /// Introduced in EIP-4844, returns the current blob base fee in wei. - #[method(name = "blobBaseFee")] - async fn blob_base_fee(&self) -> RpcResult; - - /// Returns the Transaction fee history - /// - /// Introduced in EIP-1559 for getting information on the appropriate priority fee to use. - /// - /// Returns transaction base fee per gas and effective priority fee per gas for the - /// requested/supported block range. The returned Fee history for the returned block range - /// can be a subsection of the requested range if not all blocks are available. - #[method(name = "feeHistory")] - async fn fee_history( - &self, - block_count: U64, - newest_block: BlockNumberOrTag, - reward_percentiles: Option>, - ) -> RpcResult; - - /// Returns whether the client is actively mining new blocks. - #[method(name = "mining")] - async fn is_mining(&self) -> RpcResult; - - /// Returns the number of hashes per second that the node is mining with. - #[method(name = "hashrate")] - async fn hashrate(&self) -> RpcResult; - - /// Returns the hash of the current block, the seedHash, and the boundary condition to be met - /// (“target”) - #[method(name = "getWork")] - async fn get_work(&self) -> RpcResult; - - /// Used for submitting mining hashrate. - /// - /// Can be used for remote miners to submit their hash rate. - /// It accepts the miner hash rate and an identifier which must be unique between nodes. - /// Returns `true` if the block was successfully submitted, `false` otherwise. - #[method(name = "submitHashrate")] - async fn submit_hashrate(&self, hashrate: U256, id: B256) -> RpcResult; - - /// Used for submitting a proof-of-work solution. - #[method(name = "submitWork")] - async fn submit_work(&self, nonce: B64, pow_hash: B256, mix_digest: B256) -> RpcResult; - - /// Sends transaction; will block waiting for signer to return the - /// transaction hash. - #[method(name = "sendTransaction")] - async fn send_transaction(&self, request: TransactionRequest) -> RpcResult; - - /// Sends signed transaction, returning its hash. - #[method(name = "sendRawTransaction")] - async fn send_raw_transaction(&self, bytes: Bytes) -> RpcResult; - - /// Returns an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" - /// + len(message) + message))). - #[method(name = "sign")] - async fn sign(&self, address: Address, message: Bytes) -> RpcResult; - - /// Signs a transaction that can be submitted to the network at a later time using with - /// `sendRawTransaction.` - #[method(name = "signTransaction")] - async fn sign_transaction(&self, transaction: TransactionRequest) -> RpcResult; - - /// Signs data via [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md). - #[method(name = "signTypedData")] - async fn sign_typed_data(&self, address: Address, data: serde_json::Value) -> RpcResult; - - /// Returns the account and storage values of the specified account including the Merkle-proof. - /// This call can be used to verify that the data you are pulling from is not tampered with. - #[method(name = "getProof")] - async fn get_proof( - &self, - address: Address, - keys: Vec, - block_number: Option, - ) -> RpcResult; -} +pub mod revm_utils; +pub mod transaction; +pub mod utils; + +pub use api::{ + bundle::{ + EthBundleApiClient, EthBundleApiServer, EthCallBundleApiClient, EthCallBundleApiServer, + }, + filter::{EthFilterApiClient, EthFilterApiServer}, + pubsub::EthPubSubApiServer, + servers::{ + self, + bundle::EthBundle, + filter::{EthFilter, EthFilterConfig}, + pubsub::EthPubSub, + EthApi, + }, + EthApiClient, EthApiServer, +}; +pub use cache::{ + config::EthStateCacheConfig, db::StateCacheDb, multi_consumer::MultiConsumerLruCache, + EthStateCache, +}; +pub use error::{EthApiError, EthResult, RevertError, RpcInvalidTransactionError, SignError}; +pub use fee_history::{FeeHistoryCache, FeeHistoryCacheConfig, FeeHistoryEntry}; +pub use gas_oracle::{ + GasCap, GasPriceOracle, GasPriceOracleConfig, GasPriceOracleResult, ESTIMATE_GAS_ERROR_RATIO, + MIN_TRANSACTION_GAS, RPC_DEFAULT_GAS_CAP, +}; +pub use id_provider::EthSubscriptionIdProvider; +pub use pending_block::{PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin}; +pub use receipt::ReceiptBuilder; +pub use result::ToRpcResult; +pub use transaction::TransactionSource; diff --git a/crates/rpc/rpc/src/eth/logs_utils.rs b/crates/rpc/rpc-eth-api/src/logs_utils.rs similarity index 96% rename from crates/rpc/rpc/src/eth/logs_utils.rs rename to crates/rpc/rpc-eth-api/src/logs_utils.rs index 4fdf9b3a704..12fae5fcf6f 100644 --- a/crates/rpc/rpc/src/eth/logs_utils.rs +++ b/crates/rpc/rpc-eth-api/src/logs_utils.rs @@ -1,9 +1,13 @@ -use super::filter::FilterError; -use alloy_primitives::TxHash; -use reth_primitives::{BlockNumHash, ChainInfo, Receipt}; +//! Helper functions for [`EthFilterApiServer`](crate::api::filter::EthFilterApi) implementation. +//! +//! Log parsing for building filter. + +use reth_primitives::{BlockNumHash, ChainInfo, Receipt, TxHash}; use reth_provider::{BlockReader, ProviderError}; use reth_rpc_types::{FilteredParams, Log}; +use crate::servers::filter::EthFilterError; + /// Returns all matching of a block's receipts when the transaction hashes are known. pub(crate) fn matching_block_logs_with_tx_hashes<'a, I>( filter: &FilteredParams, @@ -50,7 +54,7 @@ pub(crate) fn append_matching_block_logs( receipts: &[Receipt], removed: bool, block_timestamp: u64, -) -> Result<(), FilterError> { +) -> Result<(), EthFilterError> { // Tracks the index of a log in the entire block. let mut log_index: u64 = 0; diff --git a/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs b/crates/rpc/rpc-eth-api/src/pending_block.rs similarity index 72% rename from crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs rename to crates/rpc/rpc-eth-api/src/pending_block.rs index 118d3524cba..454c0b569ea 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/pending_block.rs @@ -1,66 +1,21 @@ -//! Support for building a pending block via local txpool. +//! Helper types for [`EthApiServer`](crate::api::EthApi) implementation. +//! +//! Types used in block building. -use std::time::Instant; +use std::{fmt, time::Instant}; use derive_more::Constructor; -use reth_errors::ProviderError; use reth_primitives::{ - revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg}, BlockId, BlockNumberOrTag, ChainSpec, SealedBlockWithSenders, SealedHeader, B256, }; +use reth_provider::ProviderError; use reth_revm::state_change::{apply_beacon_root_contract_call, apply_blockhashes_update}; -use revm::{Database, DatabaseCommit}; -use revm_primitives::EnvWithHandlerCfg; - -use crate::eth::{ - error::{EthApiError, EthResult}, - EthApi, +use revm_primitives::{ + db::{Database, DatabaseCommit}, + BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, }; -/// Implements [`LoadPendingBlock`](crate::eth::api::LoadPendingBlock) for a type, that has similar -/// data layout to [`EthApi`]. -#[macro_export] -macro_rules! load_pending_block_impl { - ($network_api:ty) => { - impl $crate::eth::api::LoadPendingBlock for $network_api - where - Self: $crate::eth::api::SpawnBlocking, - Provider: reth_provider::BlockReaderIdExt - + reth_provider::EvmEnvProvider - + reth_provider::ChainSpecProvider - + reth_provider::StateProviderFactory, - Pool: reth_transaction_pool::TransactionPool, - EvmConfig: reth_evm::ConfigureEvm, - { - #[inline] - fn provider( - &self, - ) -> impl reth_provider::BlockReaderIdExt - + reth_provider::EvmEnvProvider - + reth_provider::ChainSpecProvider - + reth_provider::StateProviderFactory { - self.inner.provider() - } - - #[inline] - fn pool(&self) -> impl reth_transaction_pool::TransactionPool { - self.inner.pool() - } - - #[inline] - fn pending_block(&self) -> &tokio::sync::Mutex> { - self.inner.pending_block() - } - - #[inline] - fn evm_config(&self) -> &impl reth_evm::ConfigureEvm { - self.inner.evm_config() - } - } - }; -} - -load_pending_block_impl!(EthApi); +use crate::{EthApiError, EthResult}; /// Configured [`BlockEnv`] and [`CfgEnvWithHandlerCfg`] for a pending block #[derive(Debug, Clone, Constructor)] @@ -89,7 +44,7 @@ pub fn pre_block_beacon_root_contract_call( parent_beacon_block_root: Option, ) -> EthResult<()> where - DB::Error: std::fmt::Display, + DB::Error: fmt::Display, { // apply pre-block EIP-4788 contract call let mut evm_pre_block = revm::Evm::builder() @@ -126,7 +81,7 @@ pub fn pre_block_blockhashes_update + Databa parent_block_hash: B256, ) -> EthResult<()> where - DB::Error: std::fmt::Display, + DB::Error: fmt::Display, { apply_blockhashes_update( db, diff --git a/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs b/crates/rpc/rpc-eth-api/src/receipt.rs similarity index 86% rename from crates/rpc/rpc-eth-api/src/eth/api/receipt.rs rename to crates/rpc/rpc-eth-api/src/receipt.rs index 6669925a143..25db9179871 100644 --- a/crates/rpc/rpc-eth-api/src/eth/api/receipt.rs +++ b/crates/rpc/rpc-eth-api/src/receipt.rs @@ -1,31 +1,13 @@ -//! Builds an RPC receipt response w.r.t. data layout of network. +//! RPC receipt response builder, extends a layer one receipt with layer two data. -use reth_primitives::{ - eip4844::calc_blob_gasprice, - Address, Receipt, TransactionMeta, TransactionSigned, - TxKind::{Call, Create}, -}; +use reth_primitives::{Address, Receipt, TransactionMeta, TransactionSigned, TxKind}; use reth_rpc_types::{ other::OtherFields, AnyReceiptEnvelope, AnyTransactionReceipt, Log, ReceiptWithBloom, TransactionReceipt, WithOtherFields, }; +use revm_primitives::calc_blob_gasprice; -use crate::eth::{ - api::LoadReceipt, - cache::EthStateCache, - error::{EthApiError, EthResult}, - EthApi, -}; - -impl LoadReceipt for EthApi -where - Self: Send + Sync, -{ - #[inline] - fn cache(&self) -> &EthStateCache { - &self.inner.eth_cache - } -} +use crate::{EthApiError, EthResult}; /// Receipt response builder. #[derive(Debug)] @@ -98,8 +80,8 @@ impl ReceiptBuilder { }; let (contract_address, to) = match transaction.transaction.kind() { - Create => (Some(from.create(transaction.transaction.nonce())), None), - Call(addr) => (None, Some(Address(*addr))), + TxKind::Create => (Some(from.create(transaction.transaction.nonce())), None), + TxKind::Call(addr) => (None, Some(Address(*addr))), }; #[allow(clippy::needless_update)] diff --git a/crates/rpc/rpc-eth-api/src/eth/revm_utils.rs b/crates/rpc/rpc-eth-api/src/revm_utils.rs similarity index 99% rename from crates/rpc/rpc-eth-api/src/eth/revm_utils.rs rename to crates/rpc/rpc-eth-api/src/revm_utils.rs index 20b42f5676d..2ed9e328ace 100644 --- a/crates/rpc/rpc-eth-api/src/eth/revm_utils.rs +++ b/crates/rpc/rpc-eth-api/src/revm_utils.rs @@ -1,6 +1,7 @@ //! utilities for working with revm -use crate::eth::error::{EthApiError, EthResult, RpcInvalidTransactionError}; +use std::cmp::min; + use reth_primitives::{Address, TxKind, B256, U256}; use reth_rpc_types::{ state::{AccountOverride, StateOverride}, @@ -17,9 +18,10 @@ use revm::{ }, Database, }; -use std::cmp::min; use tracing::trace; +use crate::{EthApiError, EthResult, RpcInvalidTransactionError}; + /// Helper type that bundles various overrides for EVM Execution. /// /// By `Default`, no overrides are included. diff --git a/crates/rpc/rpc-eth-api/src/transaction.rs b/crates/rpc/rpc-eth-api/src/transaction.rs new file mode 100644 index 00000000000..5a2ee9f6e6e --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/transaction.rs @@ -0,0 +1,96 @@ +//! Helper types for [`EthApiServer`](crate::api::EthApi) implementation. +//! +//! Transaction wrapper that lables transaction with its origin. + +use reth_primitives::{TransactionSignedEcRecovered, B256}; +use reth_rpc_types::{Transaction, TransactionInfo}; +use reth_rpc_types_compat::transaction::from_recovered_with_block_context; + +/// Represents from where a transaction was fetched. +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum TransactionSource { + /// Transaction exists in the pool (Pending) + Pool(TransactionSignedEcRecovered), + /// Transaction already included in a block + /// + /// This can be a historical block or a pending block (received from the CL) + Block { + /// Transaction fetched via provider + transaction: TransactionSignedEcRecovered, + /// Index of the transaction in the block + index: u64, + /// Hash of the block. + block_hash: B256, + /// Number of the block. + block_number: u64, + /// base fee of the block. + base_fee: Option, + }, +} + +// === impl TransactionSource === + +impl TransactionSource { + /// Consumes the type and returns the wrapped transaction. + pub fn into_recovered(self) -> TransactionSignedEcRecovered { + self.into() + } + + /// Returns the transaction and block related info, if not pending + pub fn split(self) -> (TransactionSignedEcRecovered, TransactionInfo) { + match self { + Self::Pool(tx) => { + let hash = tx.hash(); + ( + tx, + TransactionInfo { + hash: Some(hash), + index: None, + block_hash: None, + block_number: None, + base_fee: None, + }, + ) + } + Self::Block { transaction, index, block_hash, block_number, base_fee } => { + let hash = transaction.hash(); + ( + transaction, + TransactionInfo { + hash: Some(hash), + index: Some(index), + block_hash: Some(block_hash), + block_number: Some(block_number), + base_fee: base_fee.map(u128::from), + }, + ) + } + } + } +} + +impl From for TransactionSignedEcRecovered { + fn from(value: TransactionSource) -> Self { + match value { + TransactionSource::Pool(tx) => tx, + TransactionSource::Block { transaction, .. } => transaction, + } + } +} + +impl From for Transaction { + fn from(value: TransactionSource) -> Self { + match value { + TransactionSource::Pool(tx) => reth_rpc_types_compat::transaction::from_recovered(tx), + TransactionSource::Block { transaction, index, block_hash, block_number, base_fee } => { + from_recovered_with_block_context( + transaction, + block_hash, + block_number, + base_fee, + index as usize, + ) + } + } + } +} diff --git a/crates/rpc/rpc-eth-api/src/eth/utils.rs b/crates/rpc/rpc-eth-api/src/utils.rs similarity index 93% rename from crates/rpc/rpc-eth-api/src/eth/utils.rs rename to crates/rpc/rpc-eth-api/src/utils.rs index 5aa876c78c8..6573fb6b77c 100644 --- a/crates/rpc/rpc-eth-api/src/eth/utils.rs +++ b/crates/rpc/rpc-eth-api/src/utils.rs @@ -1,8 +1,9 @@ //! Commonly used code snippets -use crate::eth::error::{EthApiError, EthResult}; use reth_primitives::{Bytes, PooledTransactionsElement, PooledTransactionsElementEcRecovered}; +use crate::{EthApiError, EthResult}; + /// Recovers a [`PooledTransactionsElementEcRecovered`] from an enveloped encoded byte stream. /// /// See [`PooledTransactionsElement::decode_enveloped`] diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index fc49087a03a..a97bf20cd57 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -16,7 +16,6 @@ workspace = true reth-primitives.workspace = true reth-rpc-api.workspace = true reth-rpc-eth-api.workspace = true -reth-rpc-server-types.workspace = true reth-rpc-types.workspace = true reth-errors.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } @@ -28,15 +27,11 @@ reth-tasks = { workspace = true, features = ["rayon"] } reth-consensus-common.workspace = true reth-rpc-types-compat.workspace = true revm-inspectors = { workspace = true, features = ["js-tracer"] } -reth-evm.workspace = true -reth-trie.workspace = true reth-network-peers.workspace = true # eth alloy-rlp.workspace = true -alloy-dyn-abi = { workspace = true, features = ["eip712"] } alloy-primitives.workspace = true -alloy-sol-types.workspace = true revm = { workspace = true, features = [ "optional_block_gas_limit", "optional_eip3607", @@ -55,31 +50,12 @@ jsonwebtoken = "8" async-trait.workspace = true tokio = { workspace = true, features = ["sync"] } tower.workspace = true -tokio-stream = { workspace = true, features = ["sync"] } pin-project.workspace = true -parking_lot.workspace = true - -# metrics -reth-metrics.workspace = true -metrics.workspace = true # misc -secp256k1 = { workspace = true, features = [ - "global-context", - "rand-std", - "recovery", -] } -serde = { workspace = true, features = ["derive"] } -serde_json.workspace = true -thiserror.workspace = true -rand.workspace = true tracing.workspace = true tracing-futures = "0.2" -schnellru.workspace = true futures.workspace = true -derive_more.workspace = true -dyn-clone.workspace = true -auto_impl.workspace = true [dev-dependencies] reth-evm-ethereum.workspace = true diff --git a/crates/rpc/rpc/src/admin.rs b/crates/rpc/rpc/src/admin.rs index b1b0ca70580..fdf25e5b844 100644 --- a/crates/rpc/rpc/src/admin.rs +++ b/crates/rpc/rpc/src/admin.rs @@ -1,4 +1,5 @@ -use crate::result::ToRpcResult; +use std::sync::Arc; + use alloy_primitives::B256; use async_trait::async_trait; use jsonrpsee::core::RpcResult; @@ -10,7 +11,8 @@ use reth_rpc_types::{ admin::{EthProtocolInfo, NodeInfo, Ports, ProtocolInfo}, PeerEthProtocolInfo, PeerInfo, PeerNetworkInfo, PeerProtocolsInfo, }; -use std::sync::Arc; + +use crate::result::ToRpcResult; /// `admin` API implementation. /// diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 4ed2ffc01b0..ad54984cbfa 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -14,13 +14,10 @@ use reth_provider::{ use reth_revm::database::StateProviderDatabase; use reth_rpc_api::DebugApiServer; use reth_rpc_eth_api::{ - eth::{ - api::{EthTransactions, LoadBlock, LoadTransaction, StateCacheDB, TraceExt}, - error::{EthApiError, EthResult}, - revm_utils::{prepare_call_env, EvmOverrides}, - }, - result::{internal_rpc_err, ToRpcResult}, - EthApiSpec, + result::internal_rpc_err, + revm_utils::{prepare_call_env, EvmOverrides}, + servers::{EthApiSpec, EthTransactions, LoadBlock, LoadTransaction, TraceExt}, + EthApiError, EthResult, StateCacheDb, ToRpcResult, }; use reth_rpc_types::{ trace::geth::{ @@ -536,7 +533,7 @@ where &self, opts: GethDebugTracingOptions, env: EnvWithHandlerCfg, - db: &mut StateCacheDB<'_>, + db: &mut StateCacheDb<'_>, transaction_context: Option, ) -> EthResult<(GethTrace, revm_primitives::EvmState)> { let GethDebugTracingOptions { config, tracer, tracer_config, .. } = opts; diff --git a/crates/rpc/rpc/src/eth/mod.rs b/crates/rpc/rpc/src/eth/mod.rs deleted file mode 100644 index df13ea022e1..00000000000 --- a/crates/rpc/rpc/src/eth/mod.rs +++ /dev/null @@ -1,12 +0,0 @@ -pub mod bundle; -pub mod filter; -pub mod id_provider; -pub mod logs_utils; -pub mod pubsub; - -pub use bundle::EthBundle; -pub use filter::{EthFilter, EthFilterConfig}; -pub use id_provider::EthSubscriptionIdProvider; -pub use pubsub::EthPubSub; - -pub use reth_rpc_eth_api::eth::*; diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index ebb876d3757..31026f0f6f8 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -35,7 +35,6 @@ use tower as _; mod admin; mod debug; mod engine; -pub mod eth; mod net; mod otterscan; mod reth; @@ -46,7 +45,6 @@ mod web3; pub use admin::AdminApi; pub use debug::DebugApi; pub use engine::{EngineApi, EngineEthApi}; -pub use eth::{EthFilter, EthPubSub, EthSubscriptionIdProvider}; pub use net::NetApi; pub use otterscan::OtterscanApi; pub use reth::RethApi; @@ -55,4 +53,5 @@ pub use trace::TraceApi; pub use txpool::TxPoolApi; pub use web3::Web3Api; -pub use reth_rpc_eth_api::{eth::EthApi, result}; +pub use reth_rpc_eth_api as eth; +pub use reth_rpc_eth_api::result; diff --git a/crates/rpc/rpc/src/net.rs b/crates/rpc/rpc/src/net.rs index 2454e6ee56a..c3a1229a5c3 100644 --- a/crates/rpc/rpc/src/net.rs +++ b/crates/rpc/rpc/src/net.rs @@ -2,7 +2,7 @@ use jsonrpsee::core::RpcResult as Result; use reth_network_api::PeersInfo; use reth_primitives::U64; use reth_rpc_api::NetApiServer; -use reth_rpc_eth_api::eth::EthApiSpec; +use reth_rpc_eth_api::servers::EthApiSpec; use reth_rpc_types::PeerCount; /// `Net` API implementation. diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index c42c205c5d0..ba110017b37 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -4,8 +4,8 @@ use jsonrpsee::core::RpcResult; use reth_primitives::{Address, BlockId, BlockNumberOrTag, TxHash, B256}; use reth_rpc_api::{EthApiServer, OtterscanServer}; use reth_rpc_eth_api::{ - eth::api::{LoadBlock, LoadTransaction, TraceExt}, result::internal_rpc_err, + servers::{LoadBlock, LoadTransaction, TraceExt}, }; use reth_rpc_types::{ trace::otterscan::{ diff --git a/crates/rpc/rpc/src/reth.rs b/crates/rpc/rpc/src/reth.rs index 7d5f1e74ba7..11c437e696a 100644 --- a/crates/rpc/rpc/src/reth.rs +++ b/crates/rpc/rpc/src/reth.rs @@ -1,12 +1,13 @@ +use std::{collections::HashMap, future::Future, sync::Arc}; + use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_errors::RethResult; use reth_primitives::{Address, BlockId, U256}; use reth_provider::{BlockReaderIdExt, ChangeSetReader, StateProviderFactory}; use reth_rpc_api::RethApiServer; -use reth_rpc_eth_api::eth::error::{EthApiError, EthResult}; +use reth_rpc_eth_api::{EthApiError, EthResult}; use reth_tasks::TaskSpawner; -use std::{collections::HashMap, future::Future, sync::Arc}; use tokio::sync::oneshot; /// `reth` API implementation. diff --git a/crates/rpc/rpc/src/trace.rs b/crates/rpc/rpc/src/trace.rs index 4b5b38081c5..2740f561fac 100644 --- a/crates/rpc/rpc/src/trace.rs +++ b/crates/rpc/rpc/src/trace.rs @@ -7,10 +7,10 @@ use reth_primitives::{revm::env::tx_env_with_recovered, BlockId, Bytes, SealedHe use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory}; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::TraceApiServer; -use reth_rpc_eth_api::eth::{ - api::{LoadBlock, LoadTransaction, TraceExt}, +use reth_rpc_eth_api::{ error::{EthApiError, EthResult}, revm_utils::{prepare_call_env, EvmOverrides}, + servers::{LoadBlock, LoadTransaction, TraceExt}, utils::recover_raw_transaction, }; use reth_rpc_types::{ diff --git a/crates/rpc/rpc/src/web3.rs b/crates/rpc/rpc/src/web3.rs index 4ed94ac8552..78464327aa2 100644 --- a/crates/rpc/rpc/src/web3.rs +++ b/crates/rpc/rpc/src/web3.rs @@ -1,10 +1,11 @@ -use crate::result::ToRpcResult; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_network_api::NetworkInfo; use reth_primitives::{keccak256, Bytes, B256}; use reth_rpc_api::Web3ApiServer; +use crate::result::ToRpcResult; + /// `web3` API implementation. /// /// This type provides the functionality for handling `web3` related requests. diff --git a/crates/storage/nippy-jar/src/error.rs b/crates/storage/nippy-jar/src/error.rs index 58e27a76b4c..0c318f1bb1c 100644 --- a/crates/storage/nippy-jar/src/error.rs +++ b/crates/storage/nippy-jar/src/error.rs @@ -24,7 +24,7 @@ pub enum NippyJarError { #[error("unexpected missing value: row:col {0}:{1}")] UnexpectedMissingValue(u64, u64), #[error(transparent)] - FilterError(#[from] cuckoofilter::CuckooError), + EthFilterError(#[from] cuckoofilter::CuckooError), #[error("nippy jar initialized without filter")] FilterMissing, #[error("filter has reached max capacity")] From dd8920c4e798b0e8f94038c9eaff72bac44bc031 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 09:24:16 +0200 Subject: [PATCH 06/16] Add missing docs --- crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs | 4 ++-- crates/rpc/rpc-eth-api/src/cache/config.rs | 4 +++- crates/rpc/rpc-eth-api/src/cache/db.rs | 4 ++++ crates/rpc/rpc-eth-api/src/cache/metrics.rs | 2 ++ crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs | 7 +++++-- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs index 4627a27b00d..7179f0e47ad 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/spec.rs @@ -18,7 +18,7 @@ where { /// Returns the current ethereum protocol version. /// - /// Note: This returns an `U64`, since this should return as hex string. + /// Note: This returns an [`U64`], since this should return as hex string. async fn protocol_version(&self) -> RethResult { let status = self.network().network_status().await.map_err(RethError::other)?; Ok(U64::from(status.protocol_version)) @@ -42,7 +42,7 @@ where self.network().is_syncing() } - /// Returns the [SyncStatus] of the network + /// Returns the [`SyncStatus`] of the network fn sync_status(&self) -> RethResult { let status = if self.is_syncing() { let current_block = U256::from( diff --git a/crates/rpc/rpc-eth-api/src/cache/config.rs b/crates/rpc/rpc-eth-api/src/cache/config.rs index 5dc989e8e63..93207c930f5 100644 --- a/crates/rpc/rpc-eth-api/src/cache/config.rs +++ b/crates/rpc/rpc-eth-api/src/cache/config.rs @@ -1,7 +1,9 @@ +//! Configuration for RPC cache. + use reth_rpc_server_types::constants::cache::*; use serde::{Deserialize, Serialize}; -/// Settings for the [`EthStateCache`](crate::eth::cache::EthStateCache). +/// Settings for the [`EthStateCache`](crate::EthStateCache). #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct EthStateCacheConfig { diff --git a/crates/rpc/rpc-eth-api/src/cache/db.rs b/crates/rpc/rpc-eth-api/src/cache/db.rs index 55629c602ef..b6f7420e6b8 100644 --- a/crates/rpc/rpc-eth-api/src/cache/db.rs +++ b/crates/rpc/rpc-eth-api/src/cache/db.rs @@ -1,3 +1,7 @@ +//! Helper types to workaround 'higher-ranked lifetime error' +//! in default implementation of +//! [`Call`](crate::servers::Call). + use reth_primitives::{B256, U256}; use reth_provider::StateProvider; use reth_revm::{database::StateProviderDatabase, db::CacheDB, DatabaseRef}; diff --git a/crates/rpc/rpc-eth-api/src/cache/metrics.rs b/crates/rpc/rpc-eth-api/src/cache/metrics.rs index c9b18a299da..d87a35e0317 100644 --- a/crates/rpc/rpc-eth-api/src/cache/metrics.rs +++ b/crates/rpc/rpc-eth-api/src/cache/metrics.rs @@ -1,3 +1,5 @@ +//! Tracks state of RPC cache. + use metrics::Counter; use reth_metrics::{metrics::Gauge, Metrics}; diff --git a/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs b/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs index cd02ecc5672..b63795b59b3 100644 --- a/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs +++ b/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs @@ -1,3 +1,6 @@ +//! Metered cache, which also provides storage for senders in order to queue queries that result in +//! a cache miss. + use super::metrics::CacheMetrics; use schnellru::{ByLength, Limiter, LruMap}; use std::{ @@ -12,9 +15,9 @@ where K: Hash + Eq, L: Limiter, { - /// The LRU cache for the + /// The LRU cache. cache: LruMap, - /// All queued consumers + /// All queued consumers. queued: HashMap>, /// Cache metrics metrics: CacheMetrics, From 713923e058fcbfb016455f5e5f06ffbdcf505f25 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 09:50:38 +0200 Subject: [PATCH 07/16] Fix deps --- Cargo.lock | 1 + crates/e2e-test-utils/src/rpc.rs | 2 +- crates/ethereum/node/tests/e2e/dev.rs | 2 +- crates/optimism/node/src/rpc.rs | 2 +- crates/optimism/rpc/src/block.rs | 3 ++- crates/optimism/rpc/src/pending_block.rs | 2 +- crates/optimism/rpc/src/receipt.rs | 3 ++- crates/rpc/rpc-api/Cargo.toml | 3 +++ crates/rpc/rpc-testing-util/Cargo.toml | 2 +- examples/custom-dev-node/src/main.rs | 2 +- examples/custom-inspector/src/main.rs | 2 +- 11 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fdaec31803b..5e394e6cfbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7937,6 +7937,7 @@ dependencies = [ "reth-rpc-eth-api", "reth-rpc-types", "serde", + "serde_json", ] [[package]] diff --git a/crates/e2e-test-utils/src/rpc.rs b/crates/e2e-test-utils/src/rpc.rs index a7e63e1e7cf..0c55e9c23c0 100644 --- a/crates/e2e-test-utils/src/rpc.rs +++ b/crates/e2e-test-utils/src/rpc.rs @@ -2,7 +2,7 @@ use alloy_consensus::TxEnvelope; use alloy_network::eip2718::Decodable2718; use reth::{api::FullNodeComponents, builder::rpc::RpcRegistry, rpc::api::DebugApiServer}; use reth_primitives::{Bytes, B256}; -use reth_rpc::eth::{api::EthTransactions, error::EthResult}; +use reth_rpc::eth::{servers::EthTransactions, EthResult}; pub struct RpcTestContext { pub inner: RpcRegistry, diff --git a/crates/ethereum/node/tests/e2e/dev.rs b/crates/ethereum/node/tests/e2e/dev.rs index 4570a8c0e12..5d41f396f0b 100644 --- a/crates/ethereum/node/tests/e2e/dev.rs +++ b/crates/ethereum/node/tests/e2e/dev.rs @@ -1,6 +1,6 @@ use crate::utils::EthNode; use futures::StreamExt; -use reth::rpc::eth::EthTransactions; +use reth::rpc::eth::servers::EthTransactions; use reth_e2e_test_utils::setup; use reth_primitives::{b256, hex, ChainSpec, Genesis}; use reth_provider::CanonStateSubscriptions; diff --git a/crates/optimism/node/src/rpc.rs b/crates/optimism/node/src/rpc.rs index 582a83cef3e..01cb08c268d 100644 --- a/crates/optimism/node/src/rpc.rs +++ b/crates/optimism/node/src/rpc.rs @@ -3,8 +3,8 @@ use jsonrpsee::types::ErrorObject; use reqwest::Client; use reth_rpc::eth::{ - api::RawTransactionForwarder, error::{EthApiError, EthResult}, + servers::RawTransactionForwarder, }; use reth_rpc_types::ToRpcError; use std::sync::{atomic::AtomicUsize, Arc}; diff --git a/crates/optimism/rpc/src/block.rs b/crates/optimism/rpc/src/block.rs index 014d3f123d3..68979f31e90 100644 --- a/crates/optimism/rpc/src/block.rs +++ b/crates/optimism/rpc/src/block.rs @@ -3,8 +3,9 @@ use reth_primitives::TransactionMeta; use reth_provider::{BlockReaderIdExt, ChainSpecProvider, HeaderProvider}; use reth_rpc::eth::{ - api::{EthBlocks, LoadBlock, LoadReceipt, ReceiptBuilder}, error::EthResult, + servers::{EthBlocks, LoadBlock, LoadReceipt}, + ReceiptBuilder, }; use reth_rpc_types::{AnyTransactionReceipt, BlockId}; diff --git a/crates/optimism/rpc/src/pending_block.rs b/crates/optimism/rpc/src/pending_block.rs index 54b0d74c018..baf38ecfd41 100644 --- a/crates/optimism/rpc/src/pending_block.rs +++ b/crates/optimism/rpc/src/pending_block.rs @@ -9,7 +9,7 @@ use reth_provider::{ BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ExecutionOutcome, StateProviderFactory, }; use reth_rpc::eth::{ - api::{LoadPendingBlock, SpawnBlocking}, + servers::{LoadPendingBlock, SpawnBlocking}, PendingBlock, }; use reth_transaction_pool::TransactionPool; diff --git a/crates/optimism/rpc/src/receipt.rs b/crates/optimism/rpc/src/receipt.rs index e9735d86b03..dae5b7faa11 100644 --- a/crates/optimism/rpc/src/receipt.rs +++ b/crates/optimism/rpc/src/receipt.rs @@ -4,9 +4,10 @@ use crate::{transaction::OptimismTxMeta, OptimismApi}; use reth_primitives::{Receipt, TransactionMeta, TransactionSigned}; use reth_provider::{BlockIdReader, ChainSpecProvider}; use reth_rpc::eth::{ - api::{LoadReceipt, ReceiptBuilder}, cache::EthStateCache, error::{EthApiError, EthResult}, + servers::LoadReceipt, + ReceiptBuilder, }; use reth_rpc_types::{AnyTransactionReceipt, OptimismTransactionReceiptFields}; diff --git a/crates/rpc/rpc-api/Cargo.toml b/crates/rpc/rpc-api/Cargo.toml index a0d03a4039a..59ae5d4cfcd 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -23,6 +23,9 @@ reth-network-peers.workspace = true jsonrpsee = { workspace = true, features = ["server", "macros"] } serde = { workspace = true, features = ["derive"] } +[dev-dependencies] +serde_json.workspace = true + [features] client = [ "jsonrpsee/client", diff --git a/crates/rpc/rpc-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index 08745e0ca37..be72082692e 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -16,7 +16,6 @@ workspace = true reth-primitives.workspace = true reth-rpc-types.workspace = true reth-rpc-api = { workspace = true, features = ["client"] } -reth-rpc-eth-api = { workspace = true, features = ["client"] } # async futures.workspace = true @@ -32,3 +31,4 @@ similar-asserts.workspace = true [dev-dependencies] tokio = { workspace = true, features = ["rt-multi-thread", "macros", "rt"] } +reth-rpc-eth-api.workspace = true diff --git a/examples/custom-dev-node/src/main.rs b/examples/custom-dev-node/src/main.rs index b2950363878..a39c8a4b01f 100644 --- a/examples/custom-dev-node/src/main.rs +++ b/examples/custom-dev-node/src/main.rs @@ -7,7 +7,7 @@ use futures_util::StreamExt; use reth::{ builder::{NodeBuilder, NodeHandle}, providers::CanonStateSubscriptions, - rpc::eth::api::EthTransactions, + rpc::eth::servers::EthTransactions, tasks::TaskManager, }; use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; diff --git a/examples/custom-inspector/src/main.rs b/examples/custom-inspector/src/main.rs index df67f673491..dbc8e984920 100644 --- a/examples/custom-inspector/src/main.rs +++ b/examples/custom-inspector/src/main.rs @@ -23,7 +23,7 @@ use reth::{ }, rpc::{ compat::transaction::transaction_to_call_request, - eth::{api::Call, revm_utils::EvmOverrides}, + eth::{revm_utils::EvmOverrides, servers::Call}, }, transaction_pool::TransactionPool, }; From 592ab02443d6b6f191f6bf18975a31fc34ae0c45 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 10:00:02 +0200 Subject: [PATCH 08/16] Fix docs --- crates/node/builder/src/rpc.rs | 5 +++-- crates/optimism/rpc/src/lib.rs | 2 +- .../src/api/servers/helpers/traits/block.rs | 2 +- .../src/api/servers/helpers/traits/call.rs | 2 +- .../src/api/servers/helpers/traits/fee.rs | 2 +- .../src/api/servers/helpers/traits/mod.rs | 13 ++++++++----- .../src/api/servers/helpers/traits/transaction.rs | 2 +- crates/rpc/rpc-eth-api/src/api/servers/mod.rs | 2 +- crates/rpc/rpc-eth-api/src/id_provider.rs | 2 +- crates/rpc/rpc-eth-api/src/logs_utils.rs | 2 +- crates/rpc/rpc-eth-api/src/pending_block.rs | 2 +- crates/rpc/rpc-eth-api/src/transaction.rs | 2 +- crates/rpc/rpc/src/lib.rs | 11 ++++++----- 13 files changed, 27 insertions(+), 22 deletions(-) diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 9a6ada8f916..9a7a86b91b5 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -189,8 +189,9 @@ impl Clone for RpcRegistry { /// [`AuthRpcModule`]. /// /// This can be used to access installed modules, or create commonly used handlers like -/// [`reth_rpc::EthApi`], and ultimately merge additional rpc handler into the configured transport -/// modules [`TransportRpcModules`] as well as configured authenticated methods [`AuthRpcModule`]. +/// [`reth_rpc::eth::EthApi`], and ultimately merge additional rpc handler into the configured +/// transport modules [`TransportRpcModules`] as well as configured authenticated methods +/// [`AuthRpcModule`]. #[allow(missing_debug_implementations)] pub struct RpcContext<'a, Node: FullNodeComponents> { /// The node components. diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index fab542212a6..c843a381248 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -26,7 +26,7 @@ pub mod transaction; /// `Eth` API implementation for OP networks. /// /// This type provides OP specific extension of default functionality for handling `eth_` related -/// requests. See [`EthApi`](reth_rpc::EthApi) for the default L1 implementation. +/// requests. See [`EthApi`](reth_rpc_eth_api::EthApi) for the default L1 implementation. #[allow(missing_debug_implementations)] #[allow(dead_code)] #[derive(Clone)] diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs index 7e0027ef528..e009e3200c4 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs @@ -13,7 +13,7 @@ use crate::{ EthApiError, EthResult, EthStateCache, ReceiptBuilder, }; -/// Block related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the +/// Block related functions for the [`EthApiServer`](crate::EthApiServer) trait in the /// `eth_` namespace. pub trait EthBlocks: LoadBlock { /// Returns a handle for reading data from disk. diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs index 4882b983360..ccd0decf9c5 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs @@ -33,7 +33,7 @@ use crate::{ ESTIMATE_GAS_ERROR_RATIO, MIN_TRANSACTION_GAS, }; -/// Execution related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in +/// Execution related functions for the [`EthApiServer`](crate::EthApiServer) trait in /// the `eth_` namespace. pub trait EthCall: Call + LoadPendingBlock { /// Estimate gas needed for execution of the `request` at the [`BlockId`]. diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs index b0ae9a638c4..dda8c75edd2 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs @@ -12,7 +12,7 @@ use crate::{ RpcInvalidTransactionError, }; -/// Fee related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in the +/// Fee related functions for the [`EthApiServer`](crate::EthApiServer) trait in the /// `eth_` namespace. pub trait EthFees: LoadFee { /// Returns a suggestion for a gas price for legacy transactions. diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs index 66d6c6f1567..6fdeca0b70e 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs @@ -6,12 +6,15 @@ //! trait. //! //! Traits with `Eth` prefix, compose specific data needed to serve RPC requests in the `eth` -//! namespace. They use `Load` traits as building blocks. [`EthTransactions`] also writes data -//! (submits transactions). Based on the `eth_` request method semantics, request methods are -//! divided into: [`EthTransactions`], [`EthBlocks`], [`EthFees`], [`EthState`] and [`EthCall`]. -//! Default implementation of the `Eth` traits, is done w.r.t. L1. +//! namespace. They use `Load` traits as building blocks. +//! [`EthTransactions`](crate::servers::EthTransactions) also writes data (submits transactions). +//! Based on the `eth_` request method semantics, request methods are divided into: +//! [`EthTransactions`](crate::servers::EthTransactions), [`EthBlocks`](crate::servers::EthBlocks), +//! [`EthFees`](crate::servers::EthFees), [`EthState`](crate::servers::EthState) and +//! [`EthCall`](crate::servers::EthCall). Default implementation of the `Eth` traits, is done w.r.t. +//! L1. //! -//! [`EthApiServer`](reth_rpc_eth_api::EthApiServer), is implemented for any type that implements +//! [`EthApiServer`](crate::EthApiServer), is implemented for any type that implements //! all the `Eth` traits, e.g. [`EthApi`](crate::EthApi). pub mod block; diff --git a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs index 221aab91b32..19f51fb529b 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs @@ -29,7 +29,7 @@ use crate::{ EthApiError, EthResult, EthStateCache, SignError, TransactionSource, }; -/// Transaction related functions for the [`EthApiServer`](reth_rpc_eth_api::EthApiServer) trait in +/// Transaction related functions for the [`EthApiServer`](crate::EthApiServer) trait in /// the `eth_` namespace. /// /// This includes utilities for transaction tracing, transacting and inspection. diff --git a/crates/rpc/rpc-eth-api/src/api/servers/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs index ad8187cac8d..5be35304a2e 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/mod.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs @@ -40,7 +40,7 @@ use crate::{EthStateCache, FeeHistoryCache, GasCap, GasPriceOracle, PendingBlock /// This type provides the functionality for handling `eth_` related requests. /// These are implemented two-fold: Core functionality is implemented as [`EthApiSpec`] /// trait. Additionally, the required server implementations (e.g. -/// [`reth_rpc_eth_api::EthApiServer`]) are implemented separately in submodules. The rpc handler +/// [`EthApiServer`](crate::EthApiServer)) are implemented separately in submodules. The rpc handler /// implementation can then delegate to the main impls. This way [`EthApi`] is not limited to /// [`jsonrpsee`] and can be used standalone or in other network handlers (for example ipc). pub struct EthApi { diff --git a/crates/rpc/rpc-eth-api/src/id_provider.rs b/crates/rpc/rpc-eth-api/src/id_provider.rs index e3960d7c265..0b63da39f42 100644 --- a/crates/rpc/rpc-eth-api/src/id_provider.rs +++ b/crates/rpc/rpc-eth-api/src/id_provider.rs @@ -1,4 +1,4 @@ -//! Helper type for [`EthPubSubApiServer`](crate::api::pubsub::EthPubSubApi) implementation. +//! Helper type for [`EthPubSubApiServer`](crate::EthPubSubApiServer) implementation. //! //! Generates IDs for tracking subscriptions. diff --git a/crates/rpc/rpc-eth-api/src/logs_utils.rs b/crates/rpc/rpc-eth-api/src/logs_utils.rs index 12fae5fcf6f..1d3404432f8 100644 --- a/crates/rpc/rpc-eth-api/src/logs_utils.rs +++ b/crates/rpc/rpc-eth-api/src/logs_utils.rs @@ -1,4 +1,4 @@ -//! Helper functions for [`EthFilterApiServer`](crate::api::filter::EthFilterApi) implementation. +//! Helper functions for [`EthFilterApiServer`](crate::EthFilterApiServer) implementation. //! //! Log parsing for building filter. diff --git a/crates/rpc/rpc-eth-api/src/pending_block.rs b/crates/rpc/rpc-eth-api/src/pending_block.rs index 454c0b569ea..b55f6a044c2 100644 --- a/crates/rpc/rpc-eth-api/src/pending_block.rs +++ b/crates/rpc/rpc-eth-api/src/pending_block.rs @@ -1,4 +1,4 @@ -//! Helper types for [`EthApiServer`](crate::api::EthApi) implementation. +//! Helper types for [`EthApiServer`](crate::EthApiServer) implementation. //! //! Types used in block building. diff --git a/crates/rpc/rpc-eth-api/src/transaction.rs b/crates/rpc/rpc-eth-api/src/transaction.rs index 5a2ee9f6e6e..629e8d4be3a 100644 --- a/crates/rpc/rpc-eth-api/src/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/transaction.rs @@ -1,4 +1,4 @@ -//! Helper types for [`EthApiServer`](crate::api::EthApi) implementation. +//! Helper types for [`EthApiServer`](crate::EthApiServer) implementation. //! //! Transaction wrapper that lables transaction with its origin. diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index 31026f0f6f8..fbd9244734b 100644 --- a/crates/rpc/rpc/src/lib.rs +++ b/crates/rpc/rpc/src/lib.rs @@ -11,11 +11,12 @@ //! and can reduce overall performance of all concurrent requests handled via the jsonrpsee server. //! //! To avoid this, all blocking or CPU intensive handlers must be spawned to a separate task. See -//! the [`EthApi`] handler implementations for examples. The rpc-api traits make no use of the -//! available jsonrpsee `blocking` attribute to give implementers more freedom because the -//! `blocking` attribute and async handlers are mutually exclusive. However, as mentioned above, a -//! lot of handlers make use of async functions, caching for example, but are also using blocking -//! disk-io, hence these calls are spawned as futures to a blocking task manually. +//! the [`EthApi`](reth_rpc_eth_api::EthApi) handler implementations for examples. The rpc-api +//! traits make no use of the available jsonrpsee `blocking` attribute to give implementers more +//! freedom because the `blocking` attribute and async handlers are mutually exclusive. However, as +//! mentioned above, a lot of handlers make use of async functions, caching for example, but are +//! also using blocking disk-io, hence these calls are spawned as futures to a blocking task +//! manually. #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", From 9ec86dfa4bcff8b623d1c74034ec49fe48d2e0b8 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 10:59:08 +0200 Subject: [PATCH 09/16] Fix docs --- crates/rpc/rpc-eth-api/src/api/servers/server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/api/servers/server.rs b/crates/rpc/rpc-eth-api/src/api/servers/server.rs index e018699c4c5..df189df4f51 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/server.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/server.rs @@ -1,5 +1,5 @@ -//! Implementation of the [`jsonrpsee`] generated [`reth_rpc_api::EthApiServer`] trait -//! Handles RPC requests for the `eth_` namespace. +//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for +//! the `eth_` namespace. use alloy_dyn_abi::TypedData; use jsonrpsee::core::RpcResult as Result; From 90a9c4fc89f300655ea5033b5c63cd51ab6c7da5 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 11:01:43 +0200 Subject: [PATCH 10/16] Fix lint --- crates/rpc/rpc-eth-api/src/api/servers/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/src/api/servers/server.rs b/crates/rpc/rpc-eth-api/src/api/servers/server.rs index df189df4f51..14033b1f4b5 100644 --- a/crates/rpc/rpc-eth-api/src/api/servers/server.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/server.rs @@ -1,4 +1,4 @@ -//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for +//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`] trait. Handles RPC requests for //! the `eth_` namespace. use alloy_dyn_abi::TypedData; From fda6a66b49ec0540fef9dc54e92c4dee6b3fe7d1 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 11:12:49 +0200 Subject: [PATCH 11/16] Fix lint --- crates/rpc/rpc-eth-api/src/transaction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/src/transaction.rs b/crates/rpc/rpc-eth-api/src/transaction.rs index 629e8d4be3a..685f37b93d7 100644 --- a/crates/rpc/rpc-eth-api/src/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/transaction.rs @@ -1,6 +1,6 @@ //! Helper types for [`EthApiServer`](crate::EthApiServer) implementation. //! -//! Transaction wrapper that lables transaction with its origin. +//! Transaction wrapper that labels transaction with its origin. use reth_primitives::{TransactionSignedEcRecovered, B256}; use reth_rpc_types::{Transaction, TransactionInfo}; From 76db237b24769bb290d62082536ec4b0f475dae4 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 11:41:44 +0200 Subject: [PATCH 12/16] Fix deps --- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index 1948f56e473..4d3c6bc107b 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -26,7 +26,7 @@ reth-revm.workspace = true reth-rpc-server-types.workspace = true reth-rpc-types.workspace = true reth-rpc-types-compat.workspace = true -reth-tasks.workspace = true +reth-tasks = { workspace = true, features = ["rayon"] } reth-trie.workspace = true reth-transaction-pool.workspace = true From a7642a938061690398f7162da65b434b981e4a9e Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 11:49:47 +0200 Subject: [PATCH 13/16] Fix deps --- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index 4d3c6bc107b..907076715d0 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -14,7 +14,7 @@ workspace = true [dependencies] # reth revm.workspace = true -revm-inspectors.workspace = true +revm-inspectors = { workspace = true, features = ["js-tracer"] } revm-primitives.workspace = true reth-errors.workspace = true reth-evm.workspace = true From c5f6c5aef1031d947e3bca9667ac3bf82d277328 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 13:07:35 +0200 Subject: [PATCH 14/16] Enable dev feature for revm primitives --- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index 907076715d0..e27ebe6436f 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -15,7 +15,7 @@ workspace = true # reth revm.workspace = true revm-inspectors = { workspace = true, features = ["js-tracer"] } -revm-primitives.workspace = true +revm-primitives = { workspace = true, features = ["dev"] } reth-errors.workspace = true reth-evm.workspace = true reth-metrics.workspace = true From 9ecf0267e8732ccd4549d264459022f4ff1b5763 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 13:54:47 +0200 Subject: [PATCH 15/16] Feature gate api client export --- crates/rpc/rpc-eth-api/src/lib.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/rpc/rpc-eth-api/src/lib.rs b/crates/rpc/rpc-eth-api/src/lib.rs index e70bd8efd52..51cf5dafc07 100644 --- a/crates/rpc/rpc-eth-api/src/lib.rs +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -26,11 +26,15 @@ pub mod revm_utils; pub mod transaction; pub mod utils; +#[cfg(feature = "client")] pub use api::{ - bundle::{ - EthBundleApiClient, EthBundleApiServer, EthCallBundleApiClient, EthCallBundleApiServer, - }, - filter::{EthFilterApiClient, EthFilterApiServer}, + bundle::{EthBundleApiClient, EthCallBundleApiClient}, + filter::EthFilterApiClient, + EthApiClient, +}; +pub use api::{ + bundle::{EthBundleApiServer, EthCallBundleApiServer}, + filter::EthFilterApiServer, pubsub::EthPubSubApiServer, servers::{ self, @@ -39,7 +43,7 @@ pub use api::{ pubsub::EthPubSub, EthApi, }, - EthApiClient, EthApiServer, + EthApiServer, }; pub use cache::{ config::EthStateCacheConfig, db::StateCacheDb, multi_consumer::MultiConsumerLruCache, From fb78bdb5836740bfb4d5801f7e69158d4cadacc2 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 17 Jun 2024 14:03:28 +0200 Subject: [PATCH 16/16] Fix deps --- crates/rpc/rpc-eth-api/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc/rpc-eth-api/Cargo.toml b/crates/rpc/rpc-eth-api/Cargo.toml index e27ebe6436f..617215a1244 100644 --- a/crates/rpc/rpc-eth-api/Cargo.toml +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -36,7 +36,7 @@ alloy-sol-types.workspace = true secp256k1.workspace = true # rpc -jsonrpsee.workspace = true +jsonrpsee = { workspace = true, features = ["server", "macros"] } serde_json.workspace = true # async