From fd117d7a7064d98084380d06277d1d7d1dd6855b Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 17 Jul 2024 05:35:27 +0800 Subject: [PATCH] feat(rpc/otterscan): set total_fees in ots_getBlockDetails (#9477) Signed-off-by: jsvisa Co-authored-by: Matthias Seitz --- crates/rpc/rpc-api/src/otterscan.rs | 4 +-- crates/rpc/rpc-builder/tests/it/http.rs | 4 +-- crates/rpc/rpc-builder/tests/it/utils.rs | 3 +- crates/rpc/rpc/src/otterscan.rs | 40 ++++++++++++++++++------ 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/crates/rpc/rpc-api/src/otterscan.rs b/crates/rpc/rpc-api/src/otterscan.rs index c29d335a8f..165e88d3df 100644 --- a/crates/rpc/rpc-api/src/otterscan.rs +++ b/crates/rpc/rpc-api/src/otterscan.rs @@ -48,11 +48,11 @@ pub trait Otterscan { /// Tailor-made and expanded version of eth_getBlockByNumber for block details page in /// Otterscan. #[method(name = "getBlockDetails")] - async fn get_block_details(&self, block_number: u64) -> RpcResult>; + async fn get_block_details(&self, block_number: u64) -> RpcResult; /// Tailor-made and expanded version of eth_getBlockByHash for block details page in Otterscan. #[method(name = "getBlockDetailsByHash")] - async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult>; + async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult; /// Get paginated transactions for a certain block. Also remove some verbose fields like logs. #[method(name = "getBlockTransactions")] diff --git a/crates/rpc/rpc-builder/tests/it/http.rs b/crates/rpc/rpc-builder/tests/it/http.rs index 3db8bd88a9..fa4ade38ef 100644 --- a/crates/rpc/rpc-builder/tests/it/http.rs +++ b/crates/rpc/rpc-builder/tests/it/http.rs @@ -314,9 +314,9 @@ where OtterscanClient::trace_transaction(client, tx_hash).await.unwrap(); - OtterscanClient::get_block_details(client, block_number).await.unwrap(); + OtterscanClient::get_block_details(client, block_number).await.unwrap_err(); - OtterscanClient::get_block_details_by_hash(client, block_hash).await.unwrap(); + OtterscanClient::get_block_details_by_hash(client, block_hash).await.unwrap_err(); OtterscanClient::get_block_transactions(client, block_number, page_number, page_size) .await diff --git a/crates/rpc/rpc-builder/tests/it/utils.rs b/crates/rpc/rpc-builder/tests/it/utils.rs index a9727c0d57..85d81ea39f 100644 --- a/crates/rpc/rpc-builder/tests/it/utils.rs +++ b/crates/rpc/rpc-builder/tests/it/utils.rs @@ -69,7 +69,7 @@ pub async fn launch_ws(modules: impl Into) -> RpcServerHandl let server = builder.build(TransportRpcModuleConfig::set_ws(modules), Box::new(EthApi::with_spawner)); RpcServerConfig::ws(Default::default()) - .with_http_address(test_address()) + .with_ws_address(test_address()) .start(&server) .await .unwrap() @@ -84,6 +84,7 @@ pub async fn launch_http_ws(modules: impl Into) -> RpcServer Box::new(EthApi::with_spawner), ); RpcServerConfig::ws(Default::default()) + .with_ws_address(test_address()) .with_ws_address(test_address()) .with_http(Default::default()) .with_http_address(test_address()) diff --git a/crates/rpc/rpc/src/otterscan.rs b/crates/rpc/rpc/src/otterscan.rs index 34a92992a5..320c6856de 100644 --- a/crates/rpc/rpc/src/otterscan.rs +++ b/crates/rpc/rpc/src/otterscan.rs @@ -1,7 +1,7 @@ use alloy_primitives::Bytes; use async_trait::async_trait; use jsonrpsee::core::RpcResult; -use reth_primitives::{Address, BlockNumberOrTag, TxHash, B256}; +use reth_primitives::{Address, BlockNumberOrTag, TxHash, B256, U256}; use reth_rpc_api::{EthApiServer, OtterscanServer}; use reth_rpc_eth_api::helpers::TraceExt; use reth_rpc_eth_types::EthApiError; @@ -14,7 +14,7 @@ use reth_rpc_types::{ }, parity::{Action, CreateAction, CreateOutput, TraceOutput}, }, - BlockTransactions, Header, + AnyTransactionReceipt, BlockTransactions, Header, RichBlock, }; use revm_inspectors::{ tracing::{types::CallTraceNode, TracingInspectorConfig}, @@ -36,6 +36,24 @@ impl OtterscanApi { pub const fn new(eth: Eth) -> Self { Self { eth } } + + /// Constructs a `BlockDetails` from a block and its receipts. + fn block_details( + &self, + block: Option, + receipts: Option>, + ) -> RpcResult { + let block = block.ok_or_else(|| EthApiError::UnknownBlockNumber)?; + let receipts = receipts.ok_or_else(|| EthApiError::UnknownBlockNumber)?; + + // blob fee is burnt, so we don't need to calculate it + let total_fees = receipts + .iter() + .map(|receipt| receipt.gas_used.saturating_mul(receipt.effective_gas_price)) + .sum::(); + + Ok(BlockDetails::new(block, Default::default(), U256::from(total_fees))) + } } #[async_trait] @@ -133,15 +151,19 @@ where } /// Handler for `ots_getBlockDetails` - async fn get_block_details(&self, block_number: u64) -> RpcResult> { - let block = self.eth.block_by_number(BlockNumberOrTag::Number(block_number), true).await?; - Ok(block.map(Into::into)) + async fn get_block_details(&self, block_number: u64) -> RpcResult { + let block = self.eth.block_by_number(block_number.into(), true); + let receipts = self.eth.block_receipts(block_number.into()); + let (block, receipts) = futures::try_join!(block, receipts)?; + self.block_details(block, receipts) } /// Handler for `getBlockDetailsByHash` - async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult> { - let block = self.eth.block_by_hash(block_hash, true).await?; - Ok(block.map(Into::into)) + async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult { + let block = self.eth.block_by_hash(block_hash, true); + let receipts = self.eth.block_receipts(block_hash.into()); + let (block, receipts) = futures::try_join!(block, receipts)?; + self.block_details(block, receipts) } /// Handler for `getBlockTransactions` @@ -156,7 +178,7 @@ where let receipts = self.eth.block_receipts(block_number.into()); let (block, receipts) = futures::try_join!(block, receipts)?; - let mut block = block.ok_or_else(|| internal_rpc_err("block not found"))?; + let mut block = block.ok_or_else(|| EthApiError::UnknownBlockNumber)?; let mut receipts = receipts.ok_or_else(|| internal_rpc_err("receipts not found"))?; // check if the number of transactions matches the number of receipts