// Talking to the DB use reth_db::open_db_read_only; use reth_primitives::ChainSpecBuilder; use reth_provider::{providers::BlockchainProvider, ProviderFactory}; // Bringing up the RPC use reth_rpc_builder::{ RethRpcModule, RpcModuleBuilder, RpcServerConfig, TransportRpcModuleConfig, }; // Code which we'd ideally like to not need to import if you're only spinning up // read-only parts of the API and do not require access to pending state or to // EVM sims use reth_beacon_consensus::BeaconConsensus; use reth_blockchain_tree::{ BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals, }; use reth_revm::Factory as ExecutionFactory; // Configuring the network parts, ideally also wouldn't ned to think about this. use reth_network_api::noop::NoopNetwork; use reth_provider::test_utils::TestCanonStateSubscriptions; use reth_tasks::TokioTaskExecutor; use reth_transaction_pool::noop::NoopTransactionPool; use std::{path::Path, sync::Arc}; // Example illustrating how to run the ETH JSON RPC API as standalone over a DB file. // TODO: Add example showing how to spin up your own custom RPC namespace alongside // the other default name spaces. #[tokio::main] async fn main() -> eyre::Result<()> { // 1. Setup the DB let db = Arc::new(open_db_read_only(Path::new(&std::env::var("RETH_DB_PATH")?), None)?); let spec = Arc::new(ChainSpecBuilder::mainnet().build()); let factory = ProviderFactory::new(db.clone(), spec.clone()); // 2. Setup blcokchain tree to be able to receive live notifs // TODO: Make this easier to configure let provider = { let consensus = Arc::new(BeaconConsensus::new(spec.clone())); let exec_factory = ExecutionFactory::new(spec.clone()); let externals = TreeExternals::new(db.clone(), consensus, exec_factory, spec.clone()); let tree_config = BlockchainTreeConfig::default(); let (canon_state_notification_sender, _receiver) = tokio::sync::broadcast::channel(tree_config.max_reorg_depth() as usize * 2); let tree = ShareableBlockchainTree::new(BlockchainTree::new( externals, canon_state_notification_sender, tree_config, )?); BlockchainProvider::new(factory, tree)? }; let rpc_builder = RpcModuleBuilder::default() .with_provider(provider) // Rest is just noops that do nothing .with_pool(NoopTransactionPool::default()) .with_network(NoopNetwork::default()) .with_executor(TokioTaskExecutor::default()) .with_events(TestCanonStateSubscriptions::default()); // Pick which namespaces to expose. let config = TransportRpcModuleConfig::default().with_http([RethRpcModule::Eth]); let server = rpc_builder.build(config); // Start the server & keep it alive let server_args = RpcServerConfig::http(Default::default()).with_http_address("0.0.0.0:8545".parse()?); let _handle = server_args.start(server).await?; futures::future::pending::<()>().await; Ok(()) }