Skip to main content

reth_rpc_api/
debug.rs

1use alloy_eips::{BlockId, BlockNumberOrTag};
2use alloy_genesis::ChainConfig;
3use alloy_json_rpc::RpcObject;
4use alloy_primitives::{Address, Bytes, B256, U64};
5use alloy_rpc_types_debug::ExecutionWitness;
6use alloy_rpc_types_eth::{Account, AccountInfo, Bundle, Index, StateContext};
7use alloy_rpc_types_trace::geth::{
8    BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult,
9};
10use jsonrpsee::{core::RpcResult, proc_macros::rpc};
11use reth_trie_common::{updates::TrieUpdates, ExecutionWitnessMode, HashedPostState};
12
13/// Debug rpc interface.
14#[cfg_attr(not(feature = "client"), rpc(server, namespace = "debug"))]
15#[cfg_attr(feature = "client", rpc(server, client, namespace = "debug"))]
16pub trait DebugApi<TxReq: RpcObject> {
17    /// Returns an RLP-encoded header.
18    #[method(name = "getRawHeader")]
19    async fn raw_header(&self, block_id: BlockId) -> RpcResult<Bytes>;
20
21    /// Returns an RLP-encoded block.
22    #[method(name = "getRawBlock")]
23    async fn raw_block(&self, block_id: BlockId) -> RpcResult<Bytes>;
24
25    /// Returns the RLP-encoded EIP-7928 block access list.
26    #[method(name = "getRawBlockAccessList")]
27    async fn raw_block_access_list(&self, block_id: BlockId) -> RpcResult<Bytes>;
28
29    /// Returns an EIP-2718 binary-encoded transaction.
30    ///
31    /// If this is a pooled EIP-4844 transaction, the blob sidecar is included.
32    #[method(name = "getRawTransaction")]
33    async fn raw_transaction(&self, hash: B256) -> RpcResult<Option<Bytes>>;
34
35    /// Returns an array of EIP-2718 binary-encoded transactions for the given [`BlockId`].
36    #[method(name = "getRawTransactions")]
37    async fn raw_transactions(&self, block_id: BlockId) -> RpcResult<Vec<Bytes>>;
38
39    /// Returns an array of EIP-2718 binary-encoded receipts.
40    #[method(name = "getRawReceipts")]
41    async fn raw_receipts(&self, block_id: BlockId) -> RpcResult<Vec<Bytes>>;
42
43    /// Returns an array of recent bad blocks that the client has seen on the network.
44    #[method(name = "getBadBlocks")]
45    async fn bad_blocks(&self) -> RpcResult<Vec<serde_json::Value>>;
46
47    /// Clears all transactions from the transaction pool.
48    #[method(name = "clearTxpool")]
49    async fn debug_clear_txpool(&self) -> RpcResult<()>;
50
51    /// Returns the structured logs created during the execution of EVM between two blocks
52    /// (excluding start) as a JSON object.
53    #[method(name = "traceChain")]
54    async fn debug_trace_chain(
55        &self,
56        start_exclusive: BlockNumberOrTag,
57        end_inclusive: BlockNumberOrTag,
58    ) -> RpcResult<Vec<BlockTraceResult>>;
59
60    /// The `debug_traceBlock` method will return a full stack trace of all invoked opcodes of all
61    /// transaction that were included in this block.
62    ///
63    /// This expects an rlp encoded block
64    ///
65    /// Note, the parent of this block must be present, or it will fail. For the second parameter
66    /// see [`GethDebugTracingOptions`] reference.
67    #[method(name = "traceBlock")]
68    async fn debug_trace_block(
69        &self,
70        rlp_block: Bytes,
71        opts: Option<GethDebugTracingOptions>,
72    ) -> RpcResult<Vec<TraceResult>>;
73
74    /// Similar to `debug_traceBlock`, `debug_traceBlockByHash` accepts a block hash and will replay
75    /// the block that is already present in the database. For the second parameter see
76    /// [`GethDebugTracingOptions`].
77    #[method(name = "traceBlockByHash")]
78    async fn debug_trace_block_by_hash(
79        &self,
80        block: B256,
81        opts: Option<GethDebugTracingOptions>,
82    ) -> RpcResult<Vec<TraceResult>>;
83
84    /// Similar to `debug_traceBlockByHash`, `debug_traceBlockByNumber` accepts a block number
85    /// [`BlockNumberOrTag`] and will replay the block that is already present in the database.
86    /// For the second parameter see [`GethDebugTracingOptions`].
87    #[method(name = "traceBlockByNumber")]
88    async fn debug_trace_block_by_number(
89        &self,
90        block: BlockNumberOrTag,
91        opts: Option<GethDebugTracingOptions>,
92    ) -> RpcResult<Vec<TraceResult>>;
93
94    /// The `debug_traceTransaction` debugging method will attempt to run the transaction in the
95    /// exact same manner as it was executed on the network. It will replay any transaction that
96    /// may have been executed prior to this one before it will finally attempt to execute the
97    /// transaction that corresponds to the given hash.
98    #[method(name = "traceTransaction")]
99    async fn debug_trace_transaction(
100        &self,
101        tx_hash: B256,
102        opts: Option<GethDebugTracingOptions>,
103    ) -> RpcResult<GethTrace>;
104
105    /// The `debug_traceCall` method lets you run an `eth_call` within the context of the given
106    /// block execution using the final state of parent block as the base.
107    ///
108    /// The first argument (just as in `eth_call`) is a transaction request.
109    /// The block can optionally be specified either by hash or by number as
110    /// the second argument.
111    /// The trace can be configured similar to `debug_traceTransaction`,
112    /// see [`GethDebugTracingOptions`]. The method returns the same output as
113    /// `debug_traceTransaction`.
114    #[method(name = "traceCall")]
115    async fn debug_trace_call(
116        &self,
117        request: TxReq,
118        block_id: Option<BlockId>,
119        opts: Option<GethDebugTracingCallOptions>,
120    ) -> RpcResult<GethTrace>;
121
122    /// The `debug_traceCallMany` method lets you run an `eth_callMany` within the context of the
123    /// given block execution using the final state of parent block as the base followed by n
124    /// transactions.
125    ///
126    /// The first argument is a list of bundles. Each bundle can overwrite the block headers. This
127    /// will affect all transaction in that bundle.
128    /// `BlockNumber` and `transaction_index` are optional. `Transaction_index`
129    /// specifies the number of tx in the block to replay and -1 means all transactions should be
130    /// replayed.
131    /// The trace can be configured similar to `debug_traceTransaction`.
132    /// State override apply to all bundles.
133    ///
134    /// This methods is similar to many `eth_callMany`, hence this returns nested lists of traces.
135    /// Where the length of the outer list is the number of bundles and the length of the inner list
136    /// (`Vec<GethTrace>`) is the number of transactions in the bundle.
137    #[method(name = "traceCallMany")]
138    async fn debug_trace_call_many(
139        &self,
140        bundles: Vec<Bundle<TxReq>>,
141        state_context: Option<StateContext>,
142        opts: Option<GethDebugTracingCallOptions>,
143    ) -> RpcResult<Vec<Vec<GethTrace>>>;
144
145    /// The `debug_executionWitness` method allows for re-execution of a block with the purpose of
146    /// generating an execution witness. The witness comprises of a map of all hashed trie nodes
147    /// to their preimages that were required during the execution of the block, including during
148    /// state root recomputation.
149    ///
150    /// The first argument is the block number or tag. The optional second argument selects the
151    /// witness generation mode and defaults to `legacy`.
152    #[method(name = "executionWitness")]
153    async fn debug_execution_witness(
154        &self,
155        block: BlockNumberOrTag,
156        mode: Option<ExecutionWitnessMode>,
157    ) -> RpcResult<ExecutionWitness>;
158
159    /// The `debug_executionWitnessByBlockHash` method allows for re-execution of a block with the
160    /// purpose of generating an execution witness. The witness comprises of a map of all hashed
161    /// trie nodes to their preimages that were required during the execution of the block,
162    /// including during state root recomputation.
163    ///
164    /// The first argument is the block hash. The optional second argument selects the witness
165    /// generation mode and defaults to `legacy`.
166    #[method(name = "executionWitnessByBlockHash")]
167    async fn debug_execution_witness_by_block_hash(
168        &self,
169        hash: B256,
170        mode: Option<ExecutionWitnessMode>,
171    ) -> RpcResult<ExecutionWitness>;
172
173    /// Returns account information, including the storage root, at the state after executing the
174    /// transaction with the given index in the block.
175    #[method(name = "accountAt")]
176    async fn debug_account_at(
177        &self,
178        block_id: BlockId,
179        tx_index: Index,
180        address: Address,
181    ) -> RpcResult<Option<Account>>;
182
183    /// Returns account information at the state after executing the transaction with the given
184    /// index in the block.
185    #[method(name = "accountInfoAt")]
186    async fn debug_account_info_at(
187        &self,
188        block_id: BlockId,
189        tx_index: Index,
190        address: Address,
191    ) -> RpcResult<Option<AccountInfo>>;
192
193    /// Enumerates all accounts at a given block with paging capability. `maxResults` are returned
194    /// in the page and the items have keys that come after the `start` key (hashed address).
195    ///
196    /// If incompletes is false, then accounts for which the key preimage (i.e: the address) doesn't
197    /// exist in db are skipped. NB: geth by default does not store preimages.
198    #[method(name = "accountRange")]
199    async fn debug_account_range(
200        &self,
201        block_number: BlockNumberOrTag,
202        start: Bytes,
203        max_results: u64,
204        nocode: bool,
205        nostorage: bool,
206        incompletes: bool,
207    ) -> RpcResult<()>;
208
209    /// Flattens the entire key-value database into a single level, removing all unused slots and
210    /// merging all keys.
211    #[method(name = "chaindbCompact")]
212    async fn debug_chaindb_compact(&self) -> RpcResult<()>;
213
214    /// Returns the current chain config.
215    #[method(name = "chainConfig")]
216    async fn debug_chain_config(&self) -> RpcResult<ChainConfig>;
217
218    /// Returns leveldb properties of the key-value database.
219    #[method(name = "chaindbProperty")]
220    async fn debug_chaindb_property(&self, property: String) -> RpcResult<()>;
221
222    /// Returns the code associated with a given hash at the specified block ID.
223    /// If no block ID is provided, it defaults to the latest block.
224    #[method(name = "codeByHash")]
225    async fn debug_code_by_hash(
226        &self,
227        hash: B256,
228        block_id: Option<BlockId>,
229    ) -> RpcResult<Option<Bytes>>;
230
231    /// Retrieves an ancient binary blob from the freezer. The freezer is a collection of
232    /// append-only immutable files. The first argument `kind` specifies which table to look up data
233    /// from. The list of all table kinds are as follows:
234    #[method(name = "dbAncient")]
235    async fn debug_db_ancient(&self, kind: String, number: u64) -> RpcResult<()>;
236
237    /// Returns the number of ancient items in the ancient store.
238    #[method(name = "dbAncients")]
239    async fn debug_db_ancients(&self) -> RpcResult<()>;
240
241    /// Returns the raw value of a key stored in the database.
242    #[method(name = "dbGet")]
243    async fn debug_db_get(&self, key: String) -> RpcResult<Option<Bytes>>;
244
245    /// Retrieves the state that corresponds to the block number and returns a list of accounts
246    /// (including storage and code).
247    #[method(name = "dumpBlock")]
248    async fn debug_dump_block(&self, number: BlockId) -> RpcResult<()>;
249
250    /// Forces garbage collection.
251    #[method(name = "freeOSMemory")]
252    async fn debug_free_os_memory(&self) -> RpcResult<()>;
253
254    /// Returns garbage collection statistics.
255    #[method(name = "gcStats")]
256    async fn debug_gc_stats(&self) -> RpcResult<()>;
257
258    /// Returns the first number where the node has accessible state on disk. This is the
259    /// post-state of that block and the pre-state of the next block. The (from, to) parameters
260    /// are the sequence of blocks to search, which can go either forwards or backwards.
261    ///
262    /// Note: to get the last state pass in the range of blocks in reverse, i.e. (last, first).
263    #[method(name = "getAccessibleState")]
264    async fn debug_get_accessible_state(
265        &self,
266        from: BlockNumberOrTag,
267        to: BlockNumberOrTag,
268    ) -> RpcResult<()>;
269
270    /// Returns all accounts that have changed between the two blocks specified. A change is defined
271    /// as a difference in nonce, balance, code hash, or storage hash. With one parameter, returns
272    /// the list of accounts modified in the specified block.
273    #[method(name = "getModifiedAccountsByHash")]
274    async fn debug_get_modified_accounts_by_hash(
275        &self,
276        start_hash: B256,
277        end_hash: B256,
278    ) -> RpcResult<()>;
279
280    /// Returns all accounts that have changed between the two blocks specified. A change is defined
281    /// as a difference in nonce, balance, code hash or storage hash.
282    #[method(name = "getModifiedAccountsByNumber")]
283    async fn debug_get_modified_accounts_by_number(
284        &self,
285        start_number: u64,
286        end_number: u64,
287    ) -> RpcResult<()>;
288
289    /// Executes a block (bad- or canon- or side-), and returns a list of intermediate roots: the
290    /// stateroot after each transaction.
291    #[method(name = "intermediateRoots")]
292    async fn debug_intermediate_roots(
293        &self,
294        block_hash: B256,
295        opts: Option<GethDebugTracingCallOptions>,
296    ) -> RpcResult<Vec<B256>>;
297
298    /// Returns detailed runtime memory statistics.
299    #[method(name = "memStats")]
300    async fn debug_mem_stats(&self) -> RpcResult<()>;
301
302    /// Returns the preimage for a sha3 hash, if known.
303    #[method(name = "preimage")]
304    async fn debug_preimage(&self, hash: B256) -> RpcResult<()>;
305
306    /// Retrieves a block and returns its pretty printed form.
307    #[method(name = "printBlock")]
308    async fn debug_print_block(&self, number: u64) -> RpcResult<()>;
309
310    /// Fetches and retrieves the seed hash of the block by number.
311    #[method(name = "seedHash")]
312    async fn debug_seed_hash(&self, number: u64) -> RpcResult<B256>;
313
314    /// Sets the garbage collection target percentage. A negative value disables garbage collection.
315    #[method(name = "setGCPercent")]
316    async fn debug_set_gc_percent(&self, v: i32) -> RpcResult<()>;
317
318    /// Sets the current head of the local chain by block number. Note, this is a destructive action
319    /// and may severely damage your chain. Use with extreme caution.
320    #[method(name = "setHead")]
321    async fn debug_set_head(&self, number: U64) -> RpcResult<()>;
322
323    /// Configures how often in-memory state tries are persisted to disk. The interval needs to be
324    /// in a format parsable by a time.Duration. Note that the interval is not wall-clock time.
325    /// Rather it is accumulated block processing time after which the state should be flushed.
326    #[method(name = "setTrieFlushInterval")]
327    async fn debug_set_trie_flush_interval(&self, interval: String) -> RpcResult<()>;
328
329    /// Used to obtain info about a block.
330    #[method(name = "standardTraceBadBlockToFile")]
331    async fn debug_standard_trace_bad_block_to_file(
332        &self,
333        block: BlockNumberOrTag,
334        opts: Option<GethDebugTracingCallOptions>,
335    ) -> RpcResult<()>;
336
337    /// This method is similar to `debug_standardTraceBlockToFile`, but can be used to obtain info
338    /// about a block which has been rejected as invalid (for some reason).
339    #[method(name = "standardTraceBlockToFile")]
340    async fn debug_standard_trace_block_to_file(
341        &self,
342        block: BlockNumberOrTag,
343        opts: Option<GethDebugTracingCallOptions>,
344    ) -> RpcResult<()>;
345
346    /// Returns the state root of the `HashedPostState` on top of the state for the given block with
347    /// trie updates.
348    #[method(name = "stateRootWithUpdates")]
349    async fn debug_state_root_with_updates(
350        &self,
351        hashed_state: HashedPostState,
352        block_id: Option<BlockId>,
353    ) -> RpcResult<(B256, TrieUpdates)>;
354
355    /// Returns the storage at the given block height and transaction index. The result can be
356    /// paged by providing a `maxResult` to cap the number of storage slots returned as well as
357    /// specifying the offset via `keyStart` (hash of storage key).
358    #[method(name = "storageRangeAt")]
359    async fn debug_storage_range_at(
360        &self,
361        block_hash: B256,
362        tx_idx: usize,
363        contract_address: Address,
364        key_start: B256,
365        max_result: u64,
366    ) -> RpcResult<()>;
367
368    /// Returns the structured logs created during the execution of EVM against a block pulled
369    /// from the pool of bad ones and returns them as a JSON object. For the second parameter see
370    /// `TraceConfig` reference.
371    #[method(name = "traceBadBlock")]
372    async fn debug_trace_bad_block(
373        &self,
374        block_hash: B256,
375        opts: Option<GethDebugTracingCallOptions>,
376    ) -> RpcResult<Vec<TraceResult>>;
377}