From b37a30fb37086e5452ff0bc463efcef3983908c5 Mon Sep 17 00:00:00 2001 From: sprites0 <199826320+sprites0@users.noreply.github.com> Date: Thu, 4 Sep 2025 18:35:20 -0400 Subject: [PATCH] fix: Fill precompiles in tracing APIs --- src/node/rpc/block.rs | 12 +++--- src/node/rpc/call.rs | 50 ++++++++++++++++++++--- src/node/rpc/mod.rs | 81 ++++++++++++++++++++++++++++--------- src/node/rpc/transaction.rs | 8 ++-- 4 files changed, 117 insertions(+), 34 deletions(-) diff --git a/src/node/rpc/block.rs b/src/node/rpc/block.rs index c9a70c83c..ea4867fbb 100644 --- a/src/node/rpc/block.rs +++ b/src/node/rpc/block.rs @@ -1,4 +1,4 @@ -use crate::node::rpc::HlEthApi; +use crate::node::rpc::{HlEthApi, HlRpcNodeCore}; use reth::rpc::server_types::eth::{ builder::config::PendingBlockKind, error::FromEvmError, EthApiError, PendingBlock, }; @@ -6,12 +6,12 @@ use reth_rpc_eth_api::{ helpers::{ pending_block::PendingEnvBuilder, EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, }, - RpcConvert, RpcNodeCore, + RpcConvert, }; impl EthBlocks for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { @@ -19,7 +19,7 @@ where impl LoadBlock for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { @@ -27,7 +27,7 @@ where impl LoadPendingBlock for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { @@ -49,7 +49,7 @@ where impl LoadReceipt for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { diff --git a/src/node/rpc/call.rs b/src/node/rpc/call.rs index 943f6825d..3519fb2fd 100644 --- a/src/node/rpc/call.rs +++ b/src/node/rpc/call.rs @@ -1,14 +1,23 @@ -use super::HlEthApi; +use super::{HlEthApi, HlRpcNodeCore}; +use crate::{node::evm::apply_precompiles, HlBlock}; +use alloy_evm::Evm; +use alloy_primitives::B256; use reth::rpc::server_types::eth::EthApiError; -use reth_evm::TxEnvFor; +use reth_evm::{ConfigureEvm, Database, EvmEnvFor, TxEnvFor}; +use reth_primitives::{NodePrimitives, Recovered}; +use reth_primitives_traits::SignedTransaction; +use reth_provider::{ProviderError, ProviderTx}; use reth_rpc_eth_api::{ helpers::{estimate::EstimateCall, Call, EthCall}, FromEvmError, RpcConvert, RpcNodeCore, }; +use revm::DatabaseCommit; + +impl HlRpcNodeCore for N where N: RpcNodeCore> {} impl EthCall for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert>, { @@ -16,7 +25,7 @@ where impl EstimateCall for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert>, { @@ -24,7 +33,7 @@ where impl Call for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert>, { @@ -37,4 +46,35 @@ where fn max_simulate_blocks(&self) -> u64 { self.inner.eth_api.max_simulate_blocks() } + + fn replay_transactions_until<'a, DB, I>( + &self, + db: &mut DB, + evm_env: EvmEnvFor, + transactions: I, + target_tx_hash: B256, + ) -> Result + where + DB: Database + DatabaseCommit + core::fmt::Debug, + I: IntoIterator>>, + { + let block_number = evm_env.block_env().number; + let hl_extras = self.get_hl_extras(block_number.try_into().unwrap())?; + + let mut evm = self.evm_config().evm_with_env(db, evm_env); + apply_precompiles(&mut evm, &hl_extras); + + let mut index = 0; + for tx in transactions { + if *tx.tx_hash() == target_tx_hash { + // reached the target transaction + break; + } + + let tx_env = self.evm_config().tx_env(tx); + evm.transact_commit(tx_env).map_err(Self::Error::from_evm_err)?; + index += 1; + } + Ok(index) + } } diff --git a/src/node/rpc/mod.rs b/src/node/rpc/mod.rs index ce55a65c7..b647e9352 100644 --- a/src/node/rpc/mod.rs +++ b/src/node/rpc/mod.rs @@ -1,3 +1,9 @@ +use crate::{ + chainspec::HlChainSpec, + node::{evm::apply_precompiles, types::HlExtras}, + HlBlock, HlPrimitives, +}; +use alloy_evm::Evm; use alloy_network::Ethereum; use alloy_primitives::U256; use reth::{ @@ -18,8 +24,9 @@ use reth::{ TaskSpawner, }, }; -use reth_evm::ConfigureEvm; -use reth_provider::{ChainSpecProvider, ProviderHeader, ProviderTx}; +use reth_evm::{ConfigureEvm, Database, EvmEnvFor, HaltReasonFor, InspectorFor, TxEnvFor}; +use reth_primitives::NodePrimitives; +use reth_provider::{BlockReader, ChainSpecProvider, ProviderError, ProviderHeader, ProviderTx}; use reth_rpc::RpcTypes; use reth_rpc_eth_api::{ helpers::{ @@ -29,17 +36,18 @@ use reth_rpc_eth_api::{ EthApiTypes, FromEvmError, RpcConvert, RpcConverter, RpcNodeCore, RpcNodeCoreExt, SignableTxRequest, }; +use revm::context::result::ResultAndState; use std::{fmt, marker::PhantomData, sync::Arc}; -use crate::chainspec::HlChainSpec; - mod block; mod call; pub mod engine_api; mod transaction; +pub trait HlRpcNodeCore: RpcNodeCore> {} + /// Container type `HlEthApi` -pub(crate) struct HlEthApiInner { +pub(crate) struct HlEthApiInner { /// Gateway to node's core components. pub(crate) eth_api: EthApiInner, } @@ -48,14 +56,14 @@ type HlRpcConvert = RpcConverter::Evm, EthReceiptConverter>; #[derive(Clone)] -pub struct HlEthApi { +pub struct HlEthApi { /// Gateway to node's core components. pub(crate) inner: Arc>, } impl fmt::Debug for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -65,7 +73,7 @@ where impl EthApiTypes for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { type Error = EthApiError; @@ -79,7 +87,7 @@ where impl RpcNodeCore for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { type Primitives = N::Primitives; @@ -111,7 +119,7 @@ where impl RpcNodeCoreExt for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { #[inline] @@ -122,7 +130,7 @@ where impl EthApiSpec for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { type Transaction = ProviderTx; @@ -141,7 +149,7 @@ where impl SpawnBlocking for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { #[inline] @@ -162,7 +170,7 @@ where impl LoadFee for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { @@ -179,14 +187,14 @@ where impl LoadState for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { } impl EthState for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { #[inline] @@ -197,7 +205,7 @@ where impl EthFees for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { @@ -205,15 +213,50 @@ where impl Trace for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, EthApiError: FromEvmError, Rpc: RpcConvert, { + fn inspect( + &self, + db: DB, + evm_env: EvmEnvFor, + tx_env: TxEnvFor, + inspector: I, + ) -> Result>, Self::Error> + where + DB: Database, + I: InspectorFor, + { + let block_number = evm_env.block_env().number; + let hl_extras = self.get_hl_extras(block_number.try_into().unwrap())?; + + let mut evm = self.evm_config().evm_with_env_and_inspector(db, evm_env, inspector); + apply_precompiles(&mut evm, &hl_extras); + evm.transact(tx_env).map_err(Self::Error::from_evm_err) + } +} + +impl HlEthApi +where + N: HlRpcNodeCore, + Rpc: RpcConvert, +{ + fn get_hl_extras(&self, block_number: u64) -> Result { + Ok(self + .provider() + .block_by_number(block_number)? + .map(|block| HlExtras { + read_precompile_calls: block.body.read_precompile_calls.clone(), + highest_precompile_address: block.body.highest_precompile_address, + }) + .unwrap_or_default()) + } } impl AddDevSigners for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert< Network: RpcTypes>>, >, @@ -239,7 +282,7 @@ impl Default for HlEthApiBuilder { impl EthApiBuilder for HlEthApiBuilder where - N: FullNodeComponents> + N: FullNodeComponents> + RpcNodeCore< Primitives = PrimitivesTy, Evm: ConfigureEvm>>, diff --git a/src/node/rpc/transaction.rs b/src/node/rpc/transaction.rs index 160f8bbdd..d24bea2ba 100644 --- a/src/node/rpc/transaction.rs +++ b/src/node/rpc/transaction.rs @@ -1,21 +1,21 @@ -use crate::node::rpc::HlEthApi; +use crate::node::rpc::{HlEthApi, HlRpcNodeCore}; use alloy_primitives::{Bytes, B256}; use reth::rpc::server_types::eth::EthApiError; use reth_rpc_eth_api::{ helpers::{spec::SignersForRpc, EthTransactions, LoadTransaction}, - RpcConvert, RpcNodeCore, + RpcConvert, }; impl LoadTransaction for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { } impl EthTransactions for HlEthApi where - N: RpcNodeCore, + N: HlRpcNodeCore, Rpc: RpcConvert, { fn signers(&self) -> &SignersForRpc {