@@ -3,60 +3,86 @@ use crate::{
33 utils:: { await_handler, response_tri} ,
44} ;
55use ajj:: { HandlerCtx , ResponsePayload } ;
6- use alloy:: { consensus:: BlockHeader , primitives:: B256 } ;
6+ use alloy:: { consensus:: BlockHeader , eips :: BlockId , primitives:: B256 } ;
77use itertools:: Itertools ;
88use reth:: rpc:: {
99 server_types:: eth:: EthApiError ,
1010 types:: {
1111 TransactionInfo ,
12- trace:: geth:: { GethDebugTracingOptions , GethTrace } ,
12+ trace:: geth:: { GethDebugTracingOptions , GethTrace , TraceResult } ,
1313 } ,
1414} ;
1515use reth_node_api:: FullNodeComponents ;
1616use signet_evm:: EvmErrored ;
1717use signet_node_types:: Pnt ;
1818use signet_types:: MagicSig ;
1919
20- // /// Params for the `debug_traceBlockByNumber` and `debug_traceBlockByHash`
21- // /// endpoints.
22- // #[derive(Debug, serde::Deserialize)]
23- // pub(super) struct TraceBlockParams<T>(T, #[serde(default)] Option<GethDebugTracingOptions>);
24-
25- // /// `debug_traceBlockByNumber` and `debug_traceBlockByHash` endpoint handler.
26- // pub(super) async fn trace_block<T, Host, Signet>(
27- // hctx: HandlerCtx,
28- // TraceBlockParams(id, opts): TraceBlockParams<T>,
29- // ctx: RpcCtx<Host, Signet>,
30- // ) -> ResponsePayload<Vec<TraceResult>, TraceError>
31- // where
32- // T: Into<BlockId>,
33- // Host: FullNodeComponents,
34- // Signet: Pnt,
35- // {
36- // let id = id.into();
37-
38- // let fut = async move {
39- // // Fetch the block by ID
40- // let Some((hash, block)) = response_tri!(ctx.signet().raw_block(id).await) else {
41- // return ResponsePayload::internal_error_message(
42- // EthApiError::HeaderNotFound(id).to_string().into(),
43- // );
44- // };
45- // // Instantiate the EVM with the block
46- // let evm = response_tri!(ctx.trevm(id, block.header()));
47-
48- // todo!()
49-
50- // // ResponsePayload::Success(vec![])
51- // };
52-
53- // await_jh_option_response!(hctx.spawn_blocking(fut))
54- // }
20+ /// Params for the `debug_traceBlockByNumber` and `debug_traceBlockByHash`
21+ /// endpoints.
22+ #[ derive( Debug , serde:: Deserialize ) ]
23+ pub ( super ) struct TraceBlockParams < T > ( T , #[ serde( default ) ] Option < GethDebugTracingOptions > ) ;
24+
25+ /// Params type for `debug_traceTransaction`.`
26+ #[ derive( Debug , serde:: Deserialize ) ]
27+ pub ( super ) struct TraceTransactionParams ( B256 , #[ serde( default ) ] Option < GethDebugTracingOptions > ) ;
28+
29+ /// `debug_traceBlockByNumber` and `debug_traceBlockByHash` endpoint handler.
30+ pub ( super ) async fn trace_block < T , Host , Signet > (
31+ hctx : HandlerCtx ,
32+ TraceBlockParams ( id, opts) : TraceBlockParams < T > ,
33+ ctx : RpcCtx < Host , Signet > ,
34+ ) -> ResponsePayload < Vec < TraceResult > , DebugError >
35+ where
36+ T : Into < BlockId > ,
37+ Host : FullNodeComponents ,
38+ Signet : Pnt ,
39+ {
40+ let id = id. into ( ) ;
41+ let fut = async move {
42+ // Fetch the block by ID
43+ let Some ( ( hash, block) ) = response_tri ! ( ctx. signet( ) . raw_block( id) . await ) else {
44+ return ResponsePayload :: internal_error_message (
45+ EthApiError :: HeaderNotFound ( id) . to_string ( ) . into ( ) ,
46+ ) ;
47+ } ;
48+
49+ // Allocate space for the frames
50+ let mut frames = Vec :: with_capacity ( block. transaction_count ( ) ) ;
51+ // Instantiate the EVM with the block
52+ let mut trevm = response_tri ! ( ctx. trevm( crate :: LoadState :: Before , block. header( ) ) ) ;
53+
54+ // Apply all transactions in the block up, tracing each one
55+ let opts = opts. unwrap_or_default ( ) ;
56+ let mut txns = block. body ( ) . transactions ( ) . enumerate ( ) . peekable ( ) ;
57+ for ( idx, tx) in txns
58+ . by_ref ( )
59+ . peeking_take_while ( |( _, t) | MagicSig :: try_from_signature ( t. signature ( ) ) . is_none ( ) )
60+ {
61+ let tx_info = TransactionInfo {
62+ hash : Some ( * tx. hash ( ) ) ,
63+ index : Some ( idx as u64 ) ,
64+ block_hash : Some ( hash) ,
65+ block_number : Some ( block. header ( ) . number ( ) ) ,
66+ base_fee : block. header ( ) . base_fee_per_gas ( ) ,
67+ } ;
68+
69+ let t = trevm. fill_tx ( tx) ;
70+
71+ let frame;
72+ ( frame, trevm) = response_tri ! ( crate :: debug:: tracer:: trace( t, & opts, tx_info) ) ;
73+ frames. push ( TraceResult :: Success { result : frame, tx_hash : Some ( * tx. hash ( ) ) } ) ;
74+ }
75+
76+ ResponsePayload :: Success ( frames)
77+ } ;
78+
79+ await_handler ! ( @response_option hctx. spawn_blocking( fut) )
80+ }
5581
5682/// Handle for `debug_traceTransaction`.
5783pub ( super ) async fn trace_transaction < Host , Signet > (
5884 hctx : HandlerCtx ,
59- ( tx_hash, opts) : ( B256 , Option < GethDebugTracingOptions > ) ,
85+ TraceTransactionParams ( tx_hash, opts) : TraceTransactionParams ,
6086 ctx : RpcCtx < Host , Signet > ,
6187) -> ResponsePayload < GethTrace , DebugError >
6288where
82108
83109 // Apply all transactions in the block up to (but not including) the
84110 // target one
85- // TODO: check if the tx signature is a magic sig, and abort if so.
86111 let mut txns = block. body ( ) . transactions ( ) . enumerate ( ) . peekable ( ) ;
87112 for ( _idx, tx) in txns. by_ref ( ) . peeking_take_while ( |( _, t) | t. hash ( ) != tx. hash ( ) ) {
88113 if MagicSig :: try_from_signature ( tx. signature ( ) ) . is_some ( ) {
0 commit comments