diff --git a/Cargo.lock b/Cargo.lock index 52ebcf889e4..5e34ff3b8c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7437,8 +7437,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", @@ -7602,7 +7602,7 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-rpc", - "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-types", "reth-tasks", "reth-transaction-pool", @@ -7836,30 +7836,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", - "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", @@ -7867,24 +7857,17 @@ dependencies = [ "reth-revm", "reth-rpc-api", "reth-rpc-engine-api", - "reth-rpc-server-types", + "reth-rpc-eth-api", "reth-rpc-types", "reth-rpc-types-compat", "reth-tasks", "reth-testing-utils", "reth-transaction-pool", - "reth-trie", "revm", "revm-inspectors", "revm-primitives", - "schnellru", - "secp256k1", - "serde", - "serde_json", "tempfile", - "thiserror", "tokio", - "tokio-stream", "tower", "tracing", "tracing-futures", @@ -7894,11 +7877,11 @@ dependencies = [ name = "reth-rpc-api" version = "1.0.0-rc.1" dependencies = [ - "alloy-dyn-abi", "jsonrpsee", "reth-engine-primitives", "reth-network-peers", "reth-primitives", + "reth-rpc-eth-api", "reth-rpc-types", "serde", "serde_json", @@ -7912,6 +7895,7 @@ dependencies = [ "jsonrpsee", "reth-primitives", "reth-rpc-api", + "reth-rpc-eth-api", "reth-rpc-types", "serde_json", "similar-asserts", @@ -7991,6 +7975,49 @@ dependencies = [ "tracing", ] +[[package]] +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", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + [[package]] name = "reth-rpc-layer" version = "1.0.0-rc.1" diff --git a/Cargo.toml b/Cargo.toml index 30c56cd1f29..e42cb6545e6 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/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 dcda6929fde..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::api::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/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/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/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/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/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/lib.rs b/crates/optimism/rpc/src/lib.rs index 985b0131637..c843a381248 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, }; @@ -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/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 5374c46e489..59ae5d4cfcd 100644 --- a/crates/rpc/rpc-api/Cargo.toml +++ b/crates/rpc/rpc-api/Cargo.toml @@ -15,11 +15,11 @@ 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 -alloy-dyn-abi = { workspace = true, features = ["eip712"] } jsonrpsee = { workspace = true, features = ["server", "macros"] } serde = { workspace = true, features = ["derive"] } @@ -27,4 +27,9 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true [features] -client = ["jsonrpsee/client", "jsonrpsee/async-client"] +client = [ + "jsonrpsee/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-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index 82af34a86d7..661b7780e18 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -16,12 +16,8 @@ mod admin; mod anvil; -mod bundle; mod debug; mod engine; -mod eth; -mod eth_filter; -mod eth_pubsub; mod ganache; mod hardhat; mod mev; @@ -42,12 +38,8 @@ pub use servers::*; pub mod servers { pub use crate::{ admin::AdminApiServer, - bundle::{EthBundleApiServer, EthCallBundleApiServer}, debug::DebugApiServer, engine::{EngineApiServer, EngineEthApiServer}, - eth::EthApiServer, - eth_filter::EthFilterApiServer, - eth_pubsub::EthPubSubApiServer, mev::MevApiServer, net::NetApiServer, otterscan::OtterscanServer, @@ -58,6 +50,10 @@ pub mod servers { validation::BlockSubmissionValidationApiServer, web3::Web3ApiServer, }; + pub use reth_rpc_eth_api::{ + EthApiServer, EthBundleApiServer, EthCallBundleApiServer, EthFilterApiServer, + EthPubSubApiServer, + }; } /// re-export of all client traits @@ -70,11 +66,8 @@ pub mod clients { pub use crate::{ admin::AdminApiClient, anvil::AnvilApiClient, - bundle::{EthBundleApiClient, EthCallBundleApiClient}, debug::DebugApiClient, engine::{EngineApiClient, EngineEthApiClient}, - eth::EthApiClient, - eth_filter::EthFilterApiClient, ganache::GanacheApiClient, hardhat::HardhatApiClient, mev::MevApiClient, @@ -86,4 +79,7 @@ pub mod clients { validation::BlockSubmissionValidationApiClient, web3::Web3ApiClient, }; + 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 5d0d064247a..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, - EthFilterConfig, FeeHistoryCacheConfig, RPC_DEFAULT_GAS_CAP, - }, - EthApi, 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 new file mode 100644 index 00000000000..617215a1244 --- /dev/null +++ b/crates/rpc/rpc-eth-api/Cargo.toml @@ -0,0 +1,66 @@ +[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 +revm.workspace = true +revm-inspectors = { workspace = true, features = ["js-tracer"] } +revm-primitives = { workspace = true, features = ["dev"] } +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, features = ["rayon"] } +reth-trie.workspace = true +reth-transaction-pool.workspace = true + +# ethereum +alloy-dyn-abi = { workspace = true, features = ["eip712"] } +alloy-sol-types.workspace = true +secp256k1.workspace = true + +# rpc +jsonrpsee = { workspace = true, features = ["server", "macros"] } +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"] +optimism = ["reth-primitives/optimism"] \ No newline at end of file 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-api/src/eth.rs b/crates/rpc/rpc-eth-api/src/api/mod.rs similarity index 99% rename from crates/rpc/rpc-api/src/eth.rs rename to crates/rpc/rpc-eth-api/src/api/mod.rs index eb11fde824c..63e61254afc 100644 --- a/crates/rpc/rpc-api/src/eth.rs +++ b/crates/rpc/rpc-eth-api/src/api/mod.rs @@ -1,3 +1,5 @@ +//! `eth_` RPC API. + use alloy_dyn_abi::TypedData; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_primitives::{Address, BlockId, BlockNumberOrTag, Bytes, B256, B64, U256, U64}; @@ -8,6 +10,11 @@ use reth_rpc_types::{ 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"))] 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 a452f60b6c7..fa768de566b 100644 --- a/crates/rpc/rpc/src/eth/bundle.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/bundle.rs @@ -11,7 +11,6 @@ use reth_primitives::{ PooledTransactionsElement, U256, }; use reth_revm::database::StateProviderDatabase; -use reth_rpc_api::EthCallBundleApiServer; use reth_rpc_types::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use reth_tasks::pool::BlockingTaskGuard; use revm::{ @@ -20,10 +19,10 @@ use revm::{ }; use revm_primitives::{EnvWithHandlerCfg, MAX_BLOB_GAS_PER_BLOCK}; -use crate::eth::{ - api::{Call, EthTransactions, LoadPendingBlock}, - error::{EthApiError, EthResult, RpcInvalidTransactionError}, +use crate::{ + servers::{Call, EthTransactions, LoadPendingBlock}, utils::recover_raw_transaction, + EthApiError, EthCallBundleApiServer, EthResult, RpcInvalidTransactionError, }; /// `Eth` bundle implementation. 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 08b22aa7407..5ca7f7e45c0 100644 --- a/crates/rpc/rpc/src/eth/filter.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/filter.rs @@ -1,39 +1,36 @@ -use super::cache::EthStateCache; -use crate::{ - eth::{ - error::EthApiError, - logs_utils::{self, append_matching_block_logs}, - }, - result::{rpc_error_with_code, ToRpcResult}, - EthSubscriptionIdProvider, +//! `eth_` `Filter` RPC handler implementation + +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_types::{ BlockNumHash, Filter, FilterBlockOption, FilterChanges, FilterId, FilteredParams, Log, PendingTransactionFilterKind, }; - 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::{ + 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. const MAX_HEADERS_RANGE: u64 = 1_000; // with ~530bytes per header this is ~500kb @@ -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/src/eth/api/block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs similarity index 63% rename from crates/rpc/rpc/src/eth/api/block.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs index 4c16a7c8c2e..fb714de6ba3 100644 --- a/crates/rpc/rpc/src/eth/api/block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/block.rs @@ -2,14 +2,14 @@ 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/src/eth/api/call.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs similarity index 61% rename from crates/rpc/rpc/src/eth/api/call.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs index db68343b531..981e4a44891 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/call.rs @@ -2,26 +2,26 @@ 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/src/eth/api/fees.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs similarity index 60% rename from crates/rpc/rpc/src/eth/api/fees.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs index 0392bbc60e1..65fd086403d 100644 --- a/crates/rpc/rpc/src/eth/api/fees.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/fees.rs @@ -2,26 +2,26 @@ 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/src/eth/signer.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/signer.rs similarity index 85% rename from crates/rpc/rpc/src/eth/signer.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/signer.rs index 016b70fe80c..bd2cdc244ac 100644 --- a/crates/rpc/rpc/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, } @@ -121,9 +95,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..7179f0e47ad --- /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/src/eth/api/state.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs similarity index 84% rename from crates/rpc/rpc/src/eth/api/state.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs index 49df9989490..bc0e15f36fd 100644 --- a/crates/rpc/rpc/src/eth/api/state.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/state.rs @@ -2,24 +2,24 @@ 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/src/eth/api/trace.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs similarity index 68% rename from crates/rpc/rpc/src/eth/api/trace.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs index 9d19d85d5e3..43fa1c1f4ac 100644 --- a/crates/rpc/rpc/src/eth/api/trace.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/trace.rs @@ -2,14 +2,14 @@ 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/src/eth/api/traits/block.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs similarity index 97% rename from crates/rpc/rpc/src/eth/api/traits/block.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs index 2526353e555..e009e3200c4 100644 --- a/crates/rpc/rpc/src/eth/api/traits/block.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/block.rs @@ -8,13 +8,12 @@ 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_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/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/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/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/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/src/eth/api/traits/call.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs index 29446a91976..ccd0decf9c5 100644 --- a/crates/rpc/rpc/src/eth/api/traits/call.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/call.rs @@ -21,27 +21,20 @@ 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_api::EthApiServer) trait in the -/// `eth_` namespace. +/// 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`]. fn estimate_gas_at( @@ -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/src/eth/api/traits/fee.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs similarity index 97% rename from crates/rpc/rpc/src/eth/api/traits/fee.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs index fa7f45c2982..dda8c75edd2 100644 --- a/crates/rpc/rpc/src/eth/api/traits/fee.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/fee.rs @@ -6,18 +6,13 @@ 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_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 new file mode 100644 index 00000000000..6fdeca0b70e --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/mod.rs @@ -0,0 +1,40 @@ +//! Behaviour needed to serve `eth_` RPC requests, divided into general database reads and +//! specific database access. +//! +//! Traits with `Load` prefix, read atomic data from database, e.g. a block or transaction. Any +//! database read done in more than one default `Eth` trait implementation, is defined in a `Load` +//! 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`](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`](crate::EthApiServer), is implemented for any type that implements +//! all the `Eth` traits, e.g. [`EthApi`](crate::EthApi). + +pub mod block; +pub mod blocking_task; +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; + +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 {} + +impl TraceExt for T where T: LoadPendingBlock + Trace + Call {} diff --git a/crates/rpc/rpc/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/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/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/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/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/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/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/src/eth/api/traits/state.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/state.rs index c0637396707..220a33e9168 100644 --- a/crates/rpc/rpc/src/eth/api/traits/state.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/state.rs @@ -13,12 +13,8 @@ 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, + servers::{EthApiSpec, LoadPendingBlock, SpawnBlocking}, + EthApiError, EthResult, EthStateCache, PendingBlockEnv, RpcInvalidTransactionError, }; /// 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/api/servers/helpers/traits/trace.rs similarity index 94% rename from crates/rpc/rpc/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/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/src/eth/api/traits/transaction.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs similarity index 98% rename from crates/rpc/rpc/src/eth/api/traits/transaction.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs index 4edd15c36b6..c6a7112d49e 100644 --- a/crates/rpc/rpc/src/eth/api/traits/transaction.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/helpers/traits/transaction.rs @@ -20,16 +20,16 @@ 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_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/src/eth/api/transactions.rs b/crates/rpc/rpc-eth-api/src/api/servers/helpers/transaction.rs similarity index 61% rename from crates/rpc/rpc/src/eth/api/transactions.rs rename to crates/rpc/rpc-eth-api/src/api/servers/helpers/transaction.rs index 180c50ca470..3f5551d682e 100644 --- a/crates/rpc/rpc/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; -/// 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/src/eth/api/mod.rs b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs similarity index 64% rename from crates/rpc/rpc/src/eth/api/mod.rs rename to crates/rpc/rpc-eth-api/src/api/servers/mod.rs index 172ed4f62cf..5be35304a2e 100644 --- a/crates/rpc/rpc/src/eth/api/mod.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/mod.rs @@ -1,79 +1,48 @@ -//! 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. /// /// 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`]) -/// 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. +/// [`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 { /// All nested fields bundled together. inner: Arc>, @@ -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/src/eth/api/server.rs b/crates/rpc/rpc-eth-api/src/api/servers/server.rs similarity index 95% rename from crates/rpc/rpc/src/eth/api/server.rs rename to crates/rpc/rpc-eth-api/src/api/servers/server.rs index bda9a7b7a7d..14033b1f4b5 100644 --- a/crates/rpc/rpc/src/eth/api/server.rs +++ b/crates/rpc/rpc-eth-api/src/api/servers/server.rs @@ -1,46 +1,37 @@ -//! 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; -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, + FeeHistory, Header, Index, RichBlock, StateContext, SyncStatus, Transaction, + TransactionRequest, Work, }; -use reth_transaction_pool::TransactionPool; use tracing::trace; use crate::{ - eth::{ - api::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions}, - error::EthApiError, - revm_utils::EvmOverrides, - EthApi, + result::internal_rpc_err, + revm_utils::EvmOverrides, + servers::{ + EthApiSpec, EthBlocks, EthCall, EthFees, EthState, EthTransactions, LoadReceipt, Trace, }, - result::{internal_rpc_err, ToRpcResult}, + EthApiError, EthApiServer, ToRpcResult, }; #[async_trait::async_trait] -impl EthApiServer for EthApi +impl EthApiServer for T 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, + Self: EthApiSpec + + EthTransactions + + EthBlocks + + EthState + + EthCall + + EthFees + + Trace + + LoadReceipt, { /// Handler for: `eth_protocolVersion` async fn protocol_version(&self) -> Result { @@ -158,7 +149,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)) } @@ -428,13 +419,6 @@ where #[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; @@ -446,12 +430,15 @@ 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}; 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/src/eth/cache/config.rs b/crates/rpc/rpc-eth-api/src/cache/config.rs similarity index 91% rename from crates/rpc/rpc/src/eth/cache/config.rs rename to crates/rpc/rpc-eth-api/src/cache/config.rs index 5dc989e8e63..93207c930f5 100644 --- a/crates/rpc/rpc/src/eth/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 new file mode 100644 index 00000000000..74b20defbc6 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/cache/db.rs @@ -0,0 +1,169 @@ +//! 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}; +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/src/eth/cache/metrics.rs b/crates/rpc/rpc-eth-api/src/cache/metrics.rs similarity index 93% rename from crates/rpc/rpc/src/eth/cache/metrics.rs rename to crates/rpc/rpc-eth-api/src/cache/metrics.rs index c9b18a299da..d87a35e0317 100644 --- a/crates/rpc/rpc/src/eth/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/src/eth/cache/mod.rs b/crates/rpc/rpc-eth-api/src/cache/mod.rs similarity index 99% rename from crates/rpc/rpc/src/eth/cache/mod.rs rename to crates/rpc/rpc-eth-api/src/cache/mod.rs index 95c1669a280..32c97f51e85 100644 --- a/crates/rpc/rpc/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/src/eth/cache/multi_consumer.rs b/crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs similarity index 94% rename from crates/rpc/rpc/src/eth/cache/multi_consumer.rs rename to crates/rpc/rpc-eth-api/src/cache/multi_consumer.rs index cd02ecc5672..b63795b59b3 100644 --- a/crates/rpc/rpc/src/eth/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, diff --git a/crates/rpc/rpc/src/eth/error.rs b/crates/rpc/rpc-eth-api/src/error.rs similarity index 100% rename from crates/rpc/rpc/src/eth/error.rs rename to crates/rpc/rpc-eth-api/src/error.rs diff --git a/crates/rpc/rpc/src/eth/api/fee_history.rs b/crates/rpc/rpc-eth-api/src/fee_history.rs similarity index 99% rename from crates/rpc/rpc/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/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/src/eth/gas_oracle.rs b/crates/rpc/rpc-eth-api/src/gas_oracle.rs similarity index 90% rename from crates/rpc/rpc/src/eth/gas_oracle.rs rename to crates/rpc/rpc-eth-api/src/gas_oracle.rs index 346f7852f54..3cc55eb2b34 100644 --- a/crates/rpc/rpc/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..0b63da39f42 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::EthPubSubApiServer) 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 new file mode 100644 index 00000000000..51cf5dafc07 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/lib.rs @@ -0,0 +1,62 @@ +//! 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))] + +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 revm_utils; +pub mod transaction; +pub mod utils; + +#[cfg(feature = "client")] +pub use api::{ + bundle::{EthBundleApiClient, EthCallBundleApiClient}, + filter::EthFilterApiClient, + EthApiClient, +}; +pub use api::{ + bundle::{EthBundleApiServer, EthCallBundleApiServer}, + filter::EthFilterApiServer, + pubsub::EthPubSubApiServer, + servers::{ + self, + bundle::EthBundle, + filter::{EthFilter, EthFilterConfig}, + pubsub::EthPubSub, + EthApi, + }, + 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..1d3404432f8 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::EthFilterApiServer) 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/src/eth/api/pending_block.rs b/crates/rpc/rpc-eth-api/src/pending_block.rs similarity index 72% rename from crates/rpc/rpc/src/eth/api/pending_block.rs rename to crates/rpc/rpc-eth-api/src/pending_block.rs index fab17ef7718..b55f6a044c2 100644 --- a/crates/rpc/rpc/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::EthApiServer) 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/src/eth/api/receipt.rs b/crates/rpc/rpc-eth-api/src/receipt.rs similarity index 85% rename from crates/rpc/rpc/src/eth/api/receipt.rs rename to crates/rpc/rpc-eth-api/src/receipt.rs index 27cea387080..25db9179871 100644 --- a/crates/rpc/rpc/src/eth/api/receipt.rs +++ b/crates/rpc/rpc-eth-api/src/receipt.rs @@ -1,33 +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)] @@ -100,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/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/src/eth/revm_utils.rs b/crates/rpc/rpc-eth-api/src/revm_utils.rs similarity index 99% rename from crates/rpc/rpc/src/eth/revm_utils.rs rename to crates/rpc/rpc-eth-api/src/revm_utils.rs index ced65c72de8..61eaaff565c 100644 --- a/crates/rpc/rpc/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..685f37b93d7 --- /dev/null +++ b/crates/rpc/rpc-eth-api/src/transaction.rs @@ -0,0 +1,96 @@ +//! Helper types for [`EthApiServer`](crate::EthApiServer) implementation. +//! +//! Transaction wrapper that labels 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/src/eth/utils.rs b/crates/rpc/rpc-eth-api/src/utils.rs similarity index 79% rename from crates/rpc/rpc/src/eth/utils.rs rename to crates/rpc/rpc-eth-api/src/utils.rs index a4291c4b933..6573fb6b77c 100644 --- a/crates/rpc/rpc/src/eth/utils.rs +++ b/crates/rpc/rpc-eth-api/src/utils.rs @@ -1,14 +1,13 @@ //! 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`] -pub(crate) 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-testing-util/Cargo.toml b/crates/rpc/rpc-testing-util/Cargo.toml index 898fec038f7..8ab37d1b18d 100644 --- a/crates/rpc/rpc-testing-util/Cargo.toml +++ b/crates/rpc/rpc-testing-util/Cargo.toml @@ -29,3 +29,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/crates/rpc/rpc-testing-util/tests/it/trace.rs b/crates/rpc/rpc-testing-util/tests/it/trace.rs index a6439f0744c..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_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/Cargo.toml b/crates/rpc/rpc/Cargo.toml index 549ed1e2e38..7ee7cfda3da 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -15,7 +15,7 @@ workspace = true # reth reth-primitives.workspace = true reth-rpc-api.workspace = true -reth-rpc-server-types.workspace = true +reth-rpc-eth-api.workspace = true reth-rpc-types.workspace = true reth-errors.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } @@ -27,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", @@ -54,31 +50,12 @@ jsonwebtoken.workspace = true 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 @@ -93,4 +70,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/admin.rs b/crates/rpc/rpc/src/admin.rs index 2ea412bb207..a42bea31f7c 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 186adecbd17..ad54984cbfa 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -13,6 +13,12 @@ use reth_provider::{ }; use reth_revm::database::StateProviderDatabase; use reth_rpc_api::DebugApiServer; +use reth_rpc_eth_api::{ + 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::{ BlockTraceResult, FourByteFrame, GethDebugBuiltInTracerType, GethDebugTracerType, @@ -31,16 +37,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. @@ -537,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/api/optimism.rs b/crates/rpc/rpc/src/eth/api/optimism.rs deleted file mode 100644 index af58450145b..00000000000 --- a/crates/rpc/rpc/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/src/eth/api/sign.rs b/crates/rpc/rpc/src/eth/api/sign.rs deleted file mode 100644 index b6c096084ef..00000000000 --- a/crates/rpc/rpc/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/src/eth/api/traits/mod.rs b/crates/rpc/rpc/src/eth/api/traits/mod.rs deleted file mode 100644 index 38b518f6e38..00000000000 --- a/crates/rpc/rpc/src/eth/api/traits/mod.rs +++ /dev/null @@ -1,40 +0,0 @@ -//! Behaviour needed to serve `eth_` RPC requests, divided into general database reads and -//! specific database access. -//! -//! Traits with `Load` prefix, read atomic data from database, e.g. a block or transaction. Any -//! database read done in more than one default `Eth` trait implementation, is defined in a `Load` -//! 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. -//! -//! [`EthApiServer`](reth_rpc_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; -pub mod call; -pub mod fee; -pub mod pending_block; -pub mod receipt; -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}; - -/// Extension trait that bundles traits needed for tracing transactions. -pub trait TraceExt: LoadPendingBlock + SpawnBlocking + Trace + Call {} - -impl TraceExt for T where T: LoadPendingBlock + Trace + Call {} diff --git a/crates/rpc/rpc/src/eth/mod.rs b/crates/rpc/rpc/src/eth/mod.rs deleted file mode 100644 index 79a8028a258..00000000000 --- a/crates/rpc/rpc/src/eth/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! `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 use bundle::EthBundle; -pub use filter::{EthFilter, EthFilterConfig}; -pub use id_provider::EthSubscriptionIdProvider; -pub use pubsub::EthPubSub; -pub use signer::EthSigner; diff --git a/crates/rpc/rpc/src/lib.rs b/crates/rpc/rpc/src/lib.rs index 17dc8fcb809..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", @@ -35,7 +36,6 @@ use tower as _; mod admin; mod debug; mod engine; -pub mod eth; mod net; mod otterscan; mod reth; @@ -46,7 +46,6 @@ 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 net::NetApi; pub use otterscan::OtterscanApi; pub use reth::RethApi; @@ -54,4 +53,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 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 8e6615a281b..c3a1229a5c3 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::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 6314acd9f7e..ba110017b37 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::{ + result::internal_rpc_err, + servers::{LoadBlock, LoadTransaction, TraceExt}, +}; 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..11c437e696a 100644 --- a/crates/rpc/rpc/src/reth.rs +++ b/crates/rpc/rpc/src/reth.rs @@ -1,12 +1,13 @@ -use crate::eth::error::{EthApiError, EthResult}; +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::{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 50b6c2bcf22..2740f561fac 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::{ + error::{EthApiError, EthResult}, + revm_utils::{prepare_call_env, EvmOverrides}, + servers::{LoadBlock, LoadTransaction, TraceExt}, + 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. 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 a440a9cb3e3..225d4fba30f 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")] 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, };