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