|
1 | 1 | use crate::{ |
2 | | - RpcCtx, TraceError, |
3 | | - utils::{await_jh_option_response, response_tri}, |
| 2 | + DebugError, RpcCtx, |
| 3 | + utils::{await_handler, response_tri}, |
4 | 4 | }; |
5 | 5 | use ajj::{HandlerCtx, ResponsePayload}; |
6 | | -use alloy::eips::BlockId; |
| 6 | +use alloy::primitives::B256; |
| 7 | +use itertools::Itertools; |
7 | 8 | use reth::rpc::{ |
8 | 9 | server_types::eth::EthApiError, |
9 | | - types::trace::geth::{GethDebugTracingOptions, TraceResult}, |
| 10 | + types::trace::geth::{GethDebugTracingOptions, GethTrace}, |
10 | 11 | }; |
11 | 12 | use reth_node_api::FullNodeComponents; |
| 13 | +use signet_evm::EvmErrored; |
12 | 14 | use signet_node_types::Pnt; |
13 | 15 |
|
14 | | -/// Params for the `debug_traceBlockByNumber` and `debug_traceBlockByHash` |
15 | | -/// endpoints. |
16 | | -#[derive(Debug, serde::Deserialize)] |
17 | | -pub(super) struct TraceBlockParams<T>(T, #[serde(default)] Option<GethDebugTracingOptions>); |
| 16 | +// /// Params for the `debug_traceBlockByNumber` and `debug_traceBlockByHash` |
| 17 | +// /// endpoints. |
| 18 | +// #[derive(Debug, serde::Deserialize)] |
| 19 | +// pub(super) struct TraceBlockParams<T>(T, #[serde(default)] Option<GethDebugTracingOptions>); |
18 | 20 |
|
19 | | -/// `debug_traceBlockByNumber` and `debug_traceBlockByHash` endpoint handler. |
20 | | -pub(super) async fn trace_block<T, Host, Signet>( |
| 21 | +// /// `debug_traceBlockByNumber` and `debug_traceBlockByHash` endpoint handler. |
| 22 | +// pub(super) async fn trace_block<T, Host, Signet>( |
| 23 | +// hctx: HandlerCtx, |
| 24 | +// TraceBlockParams(id, opts): TraceBlockParams<T>, |
| 25 | +// ctx: RpcCtx<Host, Signet>, |
| 26 | +// ) -> ResponsePayload<Vec<TraceResult>, TraceError> |
| 27 | +// where |
| 28 | +// T: Into<BlockId>, |
| 29 | +// Host: FullNodeComponents, |
| 30 | +// Signet: Pnt, |
| 31 | +// { |
| 32 | +// let id = id.into(); |
| 33 | + |
| 34 | +// let fut = async move { |
| 35 | +// // Fetch the block by ID |
| 36 | +// let Some((hash, block)) = response_tri!(ctx.signet().raw_block(id).await) else { |
| 37 | +// return ResponsePayload::internal_error_message( |
| 38 | +// EthApiError::HeaderNotFound(id).to_string().into(), |
| 39 | +// ); |
| 40 | +// }; |
| 41 | +// // Instantiate the EVM with the block |
| 42 | +// let evm = response_tri!(ctx.trevm(id, block.header())); |
| 43 | + |
| 44 | +// todo!() |
| 45 | + |
| 46 | +// // ResponsePayload::Success(vec![]) |
| 47 | +// }; |
| 48 | + |
| 49 | +// await_jh_option_response!(hctx.spawn_blocking(fut)) |
| 50 | +// } |
| 51 | + |
| 52 | +/// Handle for `debug_traceTransaction`. |
| 53 | +pub(super) async fn trace_transaction<Host, Signet>( |
21 | 54 | hctx: HandlerCtx, |
22 | | - TraceBlockParams(id, opts): TraceBlockParams<T>, |
| 55 | + (tx_hash, opts): (B256, Option<GethDebugTracingOptions>), |
23 | 56 | ctx: RpcCtx<Host, Signet>, |
24 | | -) -> ResponsePayload<Vec<TraceResult>, TraceError> |
| 57 | +) -> ResponsePayload<GethTrace, DebugError> |
25 | 58 | where |
26 | | - T: Into<BlockId>, |
27 | 59 | Host: FullNodeComponents, |
28 | 60 | Signet: Pnt, |
29 | 61 | { |
30 | | - let id = id.into(); |
31 | | - |
32 | 62 | let fut = async move { |
33 | | - // Fetch the block by ID |
34 | | - let Some((hash, block)) = response_tri!(ctx.signet().raw_block(id).await) else { |
35 | | - return ResponsePayload::internal_error_message( |
36 | | - EthApiError::HeaderNotFound(id).to_string().into(), |
37 | | - ); |
38 | | - }; |
39 | | - // Instantiate the EVM with the block |
40 | | - let evm = response_tri!(ctx.trevm(id, block.header())); |
41 | | - |
42 | | - todo!() |
43 | | - |
44 | | - // ResponsePayload::Success(vec![]) |
| 63 | + let (tx, meta) = response_tri!( |
| 64 | + response_tri!(ctx.signet().raw_transaction_by_hash(tx_hash)) |
| 65 | + .ok_or(EthApiError::TransactionNotFound) |
| 66 | + ); |
| 67 | + |
| 68 | + let res = response_tri!(ctx.signet().raw_block(meta.block_hash).await); |
| 69 | + let (_, block) = |
| 70 | + response_tri!(res.ok_or_else(|| EthApiError::HeaderNotFound(meta.block_hash.into()))); |
| 71 | + |
| 72 | + // Load trevm at the start of the block (i.e. before any transactions are applied) |
| 73 | + let mut trevm = response_tri!( |
| 74 | + ctx.trevm(crate::LoadState::Before, block.header()).map_err(EthApiError::from) |
| 75 | + ); |
| 76 | + |
| 77 | + let mut txns = block.body().transactions().peekable(); |
| 78 | + |
| 79 | + for tx in txns.by_ref().peeking_take_while(|t| t.hash() != tx.hash()) { |
| 80 | + // Apply all transactions before the target one |
| 81 | + trevm = response_tri!(trevm.run_tx(tx).map_err(EvmErrored::into_error)).accept_state(); |
| 82 | + } |
| 83 | + |
| 84 | + let tx = response_tri!(txns.next().ok_or(EthApiError::TransactionNotFound)); |
| 85 | + let trevm = trevm.fill_tx(tx); |
| 86 | + |
| 87 | + let res = response_tri!(crate::debug::tracer::trace(trevm, &opts.unwrap_or_default())); |
| 88 | + |
| 89 | + ResponsePayload::Success(res) |
45 | 90 | }; |
46 | 91 |
|
47 | | - await_jh_option_response!(hctx.spawn_blocking(fut)) |
| 92 | + await_handler!(@response_option hctx.spawn_blocking(fut)) |
48 | 93 | } |
0 commit comments