diff --git a/crates/rpc/rpc-builder/src/lib.rs b/crates/rpc/rpc-builder/src/lib.rs index 8b883f4218..c87dcf3bfe 100644 --- a/crates/rpc/rpc-builder/src/lib.rs +++ b/crates/rpc/rpc-builder/src/lib.rs @@ -491,7 +491,10 @@ where /// Register Debug Namespace pub fn register_debug(&mut self) -> &mut Self { let eth_api = self.eth_api(); - self.modules.insert(RethRpcModule::Debug, DebugApi::new(eth_api).into_rpc().into()); + self.modules.insert( + RethRpcModule::Debug, + DebugApi::new(self.client.clone(), eth_api).into_rpc().into(), + ); self } @@ -541,7 +544,9 @@ where RethRpcModule::Admin => { AdminApi::new(self.network.clone()).into_rpc().into() } - RethRpcModule::Debug => DebugApi::new(eth_api.clone()).into_rpc().into(), + RethRpcModule::Debug => { + DebugApi::new(self.client.clone(), eth_api.clone()).into_rpc().into() + } RethRpcModule::Eth => eth_api.clone().into_rpc().into(), RethRpcModule::Net => { NetApi::new(self.network.clone(), eth_api.clone()).into_rpc().into() diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index 1516a97679..e45107a275 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -130,11 +130,9 @@ where { let block_id = BlockId::Number(BlockNumberOrTag::default()); - assert!(is_unimplemented(DebugApiClient::raw_header(client, block_id).await.err().unwrap())); - assert!(is_unimplemented(DebugApiClient::raw_block(client, block_id).await.err().unwrap())); - assert!(is_unimplemented( - DebugApiClient::raw_transaction(client, H256::default()).await.err().unwrap() - )); + DebugApiClient::raw_header(client, block_id).await.unwrap(); + DebugApiClient::raw_block(client, block_id).await.unwrap(); + DebugApiClient::raw_transaction(client, H256::default()).await.unwrap(); assert!(is_unimplemented(DebugApiClient::raw_receipts(client, block_id).await.err().unwrap())); assert!(is_unimplemented(DebugApiClient::bad_blocks(client).await.err().unwrap())); } diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index b413051352..93e786a94e 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -2,14 +2,15 @@ use crate::{ eth::{ error::{EthApiError, EthResult}, revm_utils::inspect, - EthTransactions, + EthTransactions, TransactionSource, }, - result::internal_rpc_err, + result::{internal_rpc_err, ToRpcResult}, EthApiSpec, }; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_primitives::{BlockId, BlockNumberOrTag, Bytes, H256, U256}; +use reth_provider::{BlockProvider, HeaderProvider}; use reth_revm::{ database::{State, SubState}, env::tx_env_with_recovered, @@ -29,24 +30,27 @@ use revm::primitives::Env; /// /// This type provides the functionality for handling `debug` related requests. #[non_exhaustive] -pub struct DebugApi { +pub struct DebugApi { + /// The client that can interact with the chain. + client: Client, /// The implementation of `eth` API eth_api: Eth, } // === impl DebugApi === -impl DebugApi { +impl DebugApi { /// Create a new instance of the [DebugApi] - pub fn new(eth: Eth) -> Self { - Self { eth_api: eth } + pub fn new(client: Client, eth: Eth) -> Self { + Self { client, eth_api: eth } } } // === impl DebugApi === -impl DebugApi +impl DebugApi where + Client: BlockProvider + HeaderProvider + 'static, Eth: EthTransactions + 'static, { /// Trace the transaction according to the provided options. @@ -117,25 +121,58 @@ where } } +use reth_rlp::Encodable; + #[async_trait] -impl DebugApiServer for DebugApi +impl DebugApiServer for DebugApi where + Client: BlockProvider + HeaderProvider + 'static, Eth: EthApiSpec + 'static, { /// Handler for `debug_getRawHeader` - async fn raw_header(&self, _block_id: BlockId) -> RpcResult { - Err(internal_rpc_err("unimplemented")) + async fn raw_header(&self, block_id: BlockId) -> RpcResult { + let header = match block_id { + BlockId::Hash(hash) => self.client.header(&hash.into()).to_rpc_result()?, + BlockId::Number(number_or_tag) => { + let number = + self.client.convert_block_number(number_or_tag).to_rpc_result()?.ok_or( + jsonrpsee::core::Error::Custom("Pending block not supported".to_string()), + )?; + self.client.header_by_number(number).to_rpc_result()? + } + }; + + let mut res = Vec::new(); + if let Some(header) = header { + header.encode(&mut res); + } + + Ok(res.into()) } /// Handler for `debug_getRawBlock` - async fn raw_block(&self, _block_id: BlockId) -> RpcResult { - Err(internal_rpc_err("unimplemented")) + async fn raw_block(&self, block_id: BlockId) -> RpcResult { + let block = self.client.block(block_id).to_rpc_result()?; + + let mut res = Vec::new(); + if let Some(block) = block { + block.encode(&mut res); + } + + Ok(res.into()) } /// Handler for `debug_getRawTransaction` /// Returns the bytes of the transaction for the given hash. - async fn raw_transaction(&self, _hash: H256) -> RpcResult { - Err(internal_rpc_err("unimplemented")) + async fn raw_transaction(&self, hash: H256) -> RpcResult { + let tx = self.eth_api.transaction_by_hash(hash).await?; + + let mut res = Vec::new(); + if let Some(tx) = tx.map(TransactionSource::into_recovered) { + tx.encode(&mut res); + } + + Ok(res.into()) } /// Handler for `debug_getRawReceipts` @@ -204,7 +241,7 @@ where } } -impl std::fmt::Debug for DebugApi { +impl std::fmt::Debug for DebugApi { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DebugApi").finish_non_exhaustive() }