From 09fcf0751fbc0017712527bb4d21b5f2742fa551 Mon Sep 17 00:00:00 2001 From: Quertyy <98064975+Quertyy@users.noreply.github.com> Date: Thu, 28 Aug 2025 15:39:37 +0200 Subject: [PATCH] chore(rpc): add eth_getSystemTxsReceiptsByBlockNumber and eth_getSystemTxsReceiptsByBlockNumber rpc method --- src/addons/hl_node_compliance.rs | 93 +++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/src/addons/hl_node_compliance.rs b/src/addons/hl_node_compliance.rs index b76010450..4c1bcdd7f 100644 --- a/src/addons/hl_node_compliance.rs +++ b/src/addons/hl_node_compliance.rs @@ -74,7 +74,7 @@ impl EthWrapper for T where #[rpc(server, namespace = "eth")] #[async_trait] -pub trait EthSystemTransactionApi { +pub trait EthSystemTransactionApi { #[method(name = "getEvmSystemTxsByBlockHash")] async fn get_evm_system_txs_by_block_hash(&self, hash: B256) -> RpcResult>>; @@ -83,6 +83,18 @@ pub trait EthSystemTransactionApi { &self, block_id: Option, ) -> RpcResult>>; + + #[method(name = "getEvmSystemTxsReceiptsByBlockHash")] + async fn get_evm_system_txs_receipts_by_block_hash( + &self, + hash: B256, + ) -> RpcResult>>; + + #[method(name = "getEvmSystemTxsReceiptsByBlockNumber")] + async fn get_evm_system_txs_receipts_by_block_number( + &self, + block_id: Option, + ) -> RpcResult>>; } pub struct HlSystemTransactionExt { @@ -97,7 +109,8 @@ impl HlSystemTransactionExt { } #[async_trait] -impl EthSystemTransactionApiServer> +impl + EthSystemTransactionApiServer, RpcReceipt> for HlSystemTransactionExt where jsonrpsee_types::ErrorObject<'static>: From<::Error>, @@ -167,6 +180,82 @@ where )) } } + + /// Returns the receipts for the system transactions for a given block hash. + async fn get_evm_system_txs_receipts_by_block_hash( + &self, + hash: B256, + ) -> RpcResult>>> { + trace!(target: "rpc::eth", ?hash, "Serving eth_getEvmSystemTxsReceiptsByBlockHash"); + match self + .get_evm_system_txs_receipts_by_block_number(Some(BlockId::Hash(hash.into()))) + .await + { + Ok(Some(receipts)) => Ok(Some(receipts)), + _ => Ok(None), + } + } + + /// Returns the receipts for the system transactions for a given block number, or the latest + /// block if no block + async fn get_evm_system_txs_receipts_by_block_number( + &self, + block_id: Option, + ) -> RpcResult>>> { + trace!(target: "rpc::eth", ?block_id, "Serving eth_getEvmSystemTxsReceiptsByBlockNumber"); + if let Some((block, receipts)) = + EthBlocks::load_block_and_receipts(&self.eth_api, block_id.unwrap_or_default()).await? + { + let block_number = block.number; + let base_fee = block.base_fee_per_gas; + let block_hash = block.hash(); + let excess_blob_gas = block.excess_blob_gas; + let timestamp = block.timestamp; + let mut gas_used = 0; + let mut next_log_index = 0; + + let mut inputs = Vec::new(); + for (idx, (tx, receipt)) in + block.transactions_recovered().zip(receipts.iter()).enumerate() + { + if receipt.cumulative_gas_used() != 0 { + break; + } + + let meta = TransactionMeta { + tx_hash: *tx.tx_hash(), + index: idx as u64, + block_hash, + block_number, + base_fee, + excess_blob_gas, + timestamp, + }; + + let input = ConvertReceiptInput { + receipt: Cow::Borrowed(receipt), + tx, + gas_used: receipt.cumulative_gas_used() - gas_used, + next_log_index, + meta, + }; + + gas_used = receipt.cumulative_gas_used(); + next_log_index += receipt.logs().len(); + + inputs.push(input); + } + + let receipts = self.eth_api.tx_resp_builder().convert_receipts(inputs)?; + Ok(Some(receipts)) + } else { + Err(ErrorObject::owned( + INTERNAL_ERROR_CODE, + format!("invalid block height: {block_id:?}"), + Some(()), + )) + } + } } pub struct HlNodeFilterHttp {