1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::rpc::{
    errors::invalid_params_msg,
    traits::eth_space::debug::Debug,
    types::eth::{BlockNumber, TransactionRequest},
};
use alloy_rpc_types_trace::geth::{
    GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace,
    TraceResult,
};
use cfx_rpc::DebugApi;
use cfx_types::{H256, U256};
use cfxcore::{ConsensusGraph, SharedConsensusGraph};
use jsonrpc_core::Result as JsonRpcResult;

pub struct GethDebugHandler {
    inner: DebugApi,
}

impl GethDebugHandler {
    pub fn new(
        consensus: SharedConsensusGraph, max_estimation_gas_limit: Option<U256>,
    ) -> Self {
        GethDebugHandler {
            inner: DebugApi::new(consensus.clone(), max_estimation_gas_limit),
        }
    }

    fn consensus_graph(&self) -> &ConsensusGraph {
        self.inner.consensus_graph()
    }
}

impl Debug for GethDebugHandler {
    fn db_get(&self, _key: String) -> JsonRpcResult<Option<String>> {
        Ok(Some("To be implemented!".into()))
    }

    fn debug_trace_transaction(
        &self, hash: H256, opts: Option<GethDebugTracingOptions>,
    ) -> JsonRpcResult<GethTrace> {
        self.inner
            .trace_transaction(hash, opts)
            .map_err(|err| err.into())
    }

    fn debug_trace_block_by_hash(
        &self, block_hash: H256, opts: Option<GethDebugTracingOptions>,
    ) -> JsonRpcResult<Vec<TraceResult>> {
        let epoch_num = self
            .consensus_graph()
            .get_block_epoch_number_with_pivot_check(&block_hash, false)?;

        self.inner
            .trace_block_by_num(epoch_num, opts)
            .map_err(|err| err.into())
    }

    fn debug_trace_block_by_number(
        &self, block: BlockNumber, opts: Option<GethDebugTracingOptions>,
    ) -> JsonRpcResult<Vec<TraceResult>> {
        let num = self
            .inner
            .get_block_epoch_num(block)
            .map_err(|e| invalid_params_msg(&e))?;

        self.inner
            .trace_block_by_num(num, opts)
            .map_err(|err| err.into())
    }

    // TODO: implement state and block override
    fn debug_trace_call(
        &self, request: TransactionRequest, block_number: Option<BlockNumber>,
        opts: Option<GethDebugTracingCallOptions>,
    ) -> JsonRpcResult<GethTrace> {
        self.inner
            .trace_call(request, block_number, opts)
            .map_err(|err| err.into())
    }
}