@@ -2237,7 +2237,7 @@ impl RpcMethod<1> for EthGetTransactionByHash {
2237
2237
ctx : Ctx < impl Blockstore + Send + Sync + ' static > ,
2238
2238
( tx_hash, ) : Self :: Params ,
2239
2239
) -> Result < Self :: Ok , ServerError > {
2240
- get_eth_transaction_by_hash ( ctx, tx_hash, None ) . await
2240
+ get_eth_transaction_by_hash ( & ctx, & tx_hash, None ) . await
2241
2241
}
2242
2242
}
2243
2243
@@ -2256,16 +2256,16 @@ impl RpcMethod<2> for EthGetTransactionByHashLimited {
2256
2256
ctx : Ctx < impl Blockstore + Send + Sync + ' static > ,
2257
2257
( tx_hash, limit) : Self :: Params ,
2258
2258
) -> Result < Self :: Ok , ServerError > {
2259
- get_eth_transaction_by_hash ( ctx, tx_hash, Some ( limit) ) . await
2259
+ get_eth_transaction_by_hash ( & ctx, & tx_hash, Some ( limit) ) . await
2260
2260
}
2261
2261
}
2262
2262
2263
2263
async fn get_eth_transaction_by_hash (
2264
- ctx : Ctx < impl Blockstore + Send + Sync + ' static > ,
2265
- tx_hash : EthHash ,
2264
+ ctx : & Ctx < impl Blockstore + Send + Sync + ' static > ,
2265
+ tx_hash : & EthHash ,
2266
2266
limit : Option < ChainEpoch > ,
2267
2267
) -> Result < Option < ApiEthTx > , ServerError > {
2268
- let message_cid = ctx. chain_store ( ) . get_mapping ( & tx_hash) ?. unwrap_or_else ( || {
2268
+ let message_cid = ctx. chain_store ( ) . get_mapping ( tx_hash) ?. unwrap_or_else ( || {
2269
2269
tracing:: debug!(
2270
2270
"could not find transaction hash {} in Ethereum mapping" ,
2271
2271
tx_hash
@@ -2289,7 +2289,7 @@ async fn get_eth_transaction_by_hash(
2289
2289
return_dec : ipld,
2290
2290
} ;
2291
2291
2292
- if let Ok ( tx) = new_eth_tx_from_message_lookup ( & ctx, & message_lookup, None ) {
2292
+ if let Ok ( tx) = new_eth_tx_from_message_lookup ( ctx, & message_lookup, None ) {
2293
2293
return Ok ( Some ( tx) ) ;
2294
2294
}
2295
2295
}
@@ -3022,58 +3022,86 @@ impl RpcMethod<1> for EthTraceBlock {
3022
3022
ctx : Ctx < impl Blockstore + Send + Sync + ' static > ,
3023
3023
( block_param, ) : Self :: Params ,
3024
3024
) -> Result < Self :: Ok , ServerError > {
3025
- let ts = tipset_by_ext_block_number_or_hash ( ctx. chain_store ( ) , block_param) ?;
3026
-
3027
- let ( state_root, trace) = ctx. state_manager . execution_trace ( & ts) ?;
3028
-
3029
- let state = StateTree :: new_from_root ( ctx. store_owned ( ) , & state_root) ?;
3030
-
3031
- let cid = ts. key ( ) . cid ( ) ?;
3032
-
3033
- let block_hash: EthHash = cid. into ( ) ;
3025
+ trace_block ( ctx, block_param) . await
3026
+ }
3027
+ }
3034
3028
3035
- let mut all_traces = vec ! [ ] ;
3036
- let mut msg_idx = 0 ;
3037
- for ir in trace. into_iter ( ) {
3038
- // ignore messages from system actor
3039
- if ir. msg . from == system:: ADDRESS . into ( ) {
3040
- continue ;
3029
+ async fn trace_block < B : Blockstore + Send + Sync + ' static > (
3030
+ ctx : Ctx < B > ,
3031
+ block_param : ExtBlockNumberOrHash ,
3032
+ ) -> Result < Vec < EthBlockTrace > , ServerError > {
3033
+ let ts = tipset_by_ext_block_number_or_hash ( ctx. chain_store ( ) , block_param) ?;
3034
+ let ( state_root, trace) = ctx. state_manager . execution_trace ( & ts) ?;
3035
+ let state = StateTree :: new_from_root ( ctx. store_owned ( ) , & state_root) ?;
3036
+ let cid = ts. key ( ) . cid ( ) ?;
3037
+ let block_hash: EthHash = cid. into ( ) ;
3038
+ let mut all_traces = vec ! [ ] ;
3039
+ let mut msg_idx = 0 ;
3040
+ for ir in trace. into_iter ( ) {
3041
+ // ignore messages from system actor
3042
+ if ir. msg . from == system:: ADDRESS . into ( ) {
3043
+ continue ;
3044
+ }
3045
+ msg_idx += 1 ;
3046
+ let tx_hash = EthGetTransactionHashByCid :: handle ( ctx. clone ( ) , ( ir. msg_cid , ) ) . await ?;
3047
+ let tx_hash = tx_hash
3048
+ . with_context ( || format ! ( "cannot find transaction hash for cid {}" , ir. msg_cid) ) ?;
3049
+ let mut env = trace:: base_environment ( & state, & ir. msg . from )
3050
+ . map_err ( |e| format ! ( "when processing message {}: {}" , ir. msg_cid, e) ) ?;
3051
+ if let Some ( execution_trace) = ir. execution_trace {
3052
+ trace:: build_traces ( & mut env, & [ ] , execution_trace) ?;
3053
+ for trace in env. traces {
3054
+ all_traces. push ( EthBlockTrace {
3055
+ trace : EthTrace {
3056
+ r#type : trace. r#type ,
3057
+ subtraces : trace. subtraces ,
3058
+ trace_address : trace. trace_address ,
3059
+ action : trace. action ,
3060
+ result : trace. result ,
3061
+ error : trace. error ,
3062
+ } ,
3063
+ block_hash : block_hash. clone ( ) ,
3064
+ block_number : ts. epoch ( ) ,
3065
+ transaction_hash : tx_hash. clone ( ) ,
3066
+ transaction_position : msg_idx as i64 ,
3067
+ } ) ;
3041
3068
}
3069
+ }
3070
+ }
3071
+ Ok ( all_traces)
3072
+ }
3042
3073
3043
- msg_idx += 1 ;
3044
-
3045
- let tx_hash = EthGetTransactionHashByCid :: handle ( ctx. clone ( ) , ( ir. msg_cid , ) ) . await ?;
3046
-
3047
- let tx_hash = tx_hash
3048
- . with_context ( || format ! ( "cannot find transaction hash for cid {}" , ir. msg_cid) ) ?;
3049
-
3050
- let mut env = trace:: base_environment ( & state, & ir. msg . from )
3051
- . map_err ( |e| format ! ( "when processing message {}: {}" , ir. msg_cid, e) ) ?;
3052
-
3053
- if let Some ( execution_trace) = ir. execution_trace {
3054
- trace:: build_traces ( & mut env, & [ ] , execution_trace) ?;
3074
+ pub enum EthTraceTransaction { }
3075
+ impl RpcMethod < 1 > for EthTraceTransaction {
3076
+ const NAME : & ' static str = "Filecoin.EthTraceTransaction" ;
3077
+ const NAME_ALIAS : Option < & ' static str > = Some ( "trace_transaction" ) ;
3078
+ const N_REQUIRED_PARAMS : usize = 1 ;
3079
+ const PARAM_NAMES : [ & ' static str ; 1 ] = [ "txHash" ] ;
3080
+ const API_PATHS : ApiPaths = ApiPaths :: V1 ;
3081
+ const PERMISSION : Permission = Permission :: Read ;
3082
+ const DESCRIPTION : Option < & ' static str > =
3083
+ Some ( "Returns the traces for a specific transaction." ) ;
3055
3084
3056
- for trace in env. traces {
3057
- all_traces. push ( EthBlockTrace {
3058
- trace : EthTrace {
3059
- r#type : trace. r#type ,
3060
- subtraces : trace. subtraces ,
3061
- trace_address : trace. trace_address ,
3062
- action : trace. action ,
3063
- result : trace. result ,
3064
- error : trace. error ,
3065
- } ,
3066
-
3067
- block_hash : block_hash. clone ( ) ,
3068
- block_number : ts. epoch ( ) ,
3069
- transaction_hash : tx_hash. clone ( ) ,
3070
- transaction_position : msg_idx as i64 ,
3071
- } ) ;
3072
- }
3073
- }
3074
- }
3085
+ type Params = ( String , ) ;
3086
+ type Ok = Vec < EthBlockTrace > ;
3087
+ async fn handle (
3088
+ ctx : Ctx < impl Blockstore + Send + Sync + ' static > ,
3089
+ ( tx_hash, ) : Self :: Params ,
3090
+ ) -> Result < Self :: Ok , ServerError > {
3091
+ let eth_hash = EthHash :: from_str ( & tx_hash) ?;
3092
+ let eth_txn = get_eth_transaction_by_hash ( & ctx, & eth_hash, None )
3093
+ . await ?
3094
+ . ok_or ( ServerError :: internal_error ( "transaction not found" , None ) ) ?;
3075
3095
3076
- Ok ( all_traces)
3096
+ let traces = trace_block (
3097
+ ctx,
3098
+ ExtBlockNumberOrHash :: from_block_number ( eth_txn. block_number . 0 as i64 ) ,
3099
+ )
3100
+ . await ?
3101
+ . into_iter ( )
3102
+ . filter ( |trace| trace. transaction_hash == eth_hash)
3103
+ . collect ( ) ;
3104
+ Ok ( traces)
3077
3105
}
3078
3106
}
3079
3107
0 commit comments