Skip to content

Commit a27aa5f

Browse files
Add Documentation for Debug endpoint (#1709)
* add draft design doc Signed-off-by: georgi-l95 <[email protected]> * add more info to design doc Signed-off-by: georgi-l95 <[email protected]> * Adds information about both tracers with example request, responses and params Signed-off-by: Konstantina Blazhukova <[email protected]> * Adds more detailed description for testing Signed-off-by: Konstantina Blazhukova <[email protected]> * corrects small mistake Signed-off-by: Konstantina Blazhukova <[email protected]> --------- Signed-off-by: georgi-l95 <[email protected]> Signed-off-by: Konstantina Blazhukova <[email protected]> Co-authored-by: Konstantina Blazhukova <[email protected]>
1 parent 949a2b1 commit a27aa5f

File tree

1 file changed

+351
-0
lines changed

1 file changed

+351
-0
lines changed

docs/design/debug-api.md

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
# Debug API design
2+
3+
## Purpose
4+
5+
The Debug API gives you access to several non-standard RPC methods, which will allow you to inspect, debug and set certain debugging flags during runtime. Also, it could help you replay all the transactions that have been executed prior and save considerable effort for your debugging process.
6+
7+
## Goals
8+
9+
1. **Debugging Capabilities**: Enable developers to retrieve detailed information about transactions, execution traces, and other debugging-related data.
10+
2. **Enhanced Insights**: Provide deeper insights into the behavior of smart contracts, transaction execution, and state changes on the Hedera network.
11+
3. **Ethereum Equivalent**: Makes the Hedera JSON-RPC Relay more equivalent to other providers used in the ethereum ecosystem, by providing the needed endpoints for easier debugging by developers.
12+
13+
## Architecture
14+
15+
New Debug API methods can be added and handled by adding debug service, which will be blueprinted by new `debug` interface added in the relay interface itself. Each method will be separate from the other and they won't overlap in terms of functionality.
16+
17+
### Interface
18+
```javascript
19+
export interface Debug {
20+
traceTransaction(transactionHash, { tracer, tracerConfig });
21+
22+
getModifiedAccountsByHash(startHash, endHash);
23+
24+
getModifiedAccountsByNumber(startNum, endNum);
25+
}
26+
```
27+
28+
### Service class
29+
```javascript
30+
class DebugService implements Debug{
31+
traceTransaction(transactionHash, { tracer, tracerConfig }) {
32+
// Implementation of traceTranscation depending on passed params.
33+
}
34+
35+
getModifiedAccountsByHash(startHash, endHash){
36+
// Implementation of getModifiedAccountsByHash depending on passed params.
37+
}
38+
39+
getModifiedAccountsByNumber(startNum, endNum){
40+
// Implementation of getModifiedAccountsByNumber depending on passed params.
41+
}
42+
}
43+
```
44+
45+
### Method description
46+
47+
`debug_traceTransaction` - Attempts to run the transaction in the exact same manner as it was executed on the network.
48+
This is achieved by utilizing the /api/v1/contracts/results/{transactionIdOrHash}/actions endpoint of the mirror node.
49+
The relevant fields retrieved from this endpoint are processed and formatted to generate the expected response as outlined below.
50+
51+
#### Parameters
52+
`transactionHash` - string - This is the hash of the transaction that we want to trace. <br>
53+
`tracer` - string - to specify the type of tracer. Possible values are `callTracer` or `opcodeLogger`. In the beginning only `callTracer` will be accepted. <br>
54+
`tracerConfig` - object
55+
* One property for log tracer called `onlyTopCall`, which is a boolean. <br>
56+
* For `opcodeLogger` it can have four properties - enableMemory, disableStack, disableStorage, enableReturnData - all booleans
57+
#### Returns for callTracer
58+
`object` - trace object:
59+
60+
1. `type` - string - CALL or CREATE
61+
2. `from` - string - address
62+
3. `to` - string - address
63+
4. `value` - string - hex-encoded amount of value transfer
64+
5. `gas` - string - hex-encoded gas provided for call
65+
6. `gasUsed` - string - hex-encoded gas used during call
66+
7. `input` - string - call data
67+
8. `output` - string - return data
68+
9. `error` - string - error, if any
69+
10. `revertReason` - string - Solidity revert reason, if any
70+
11. `calls` - []callframe - list of sub-calls
71+
72+
#### Example Request callTracer
73+
74+
```JSON
75+
{
76+
"jsonrpc": "2.0",
77+
"id": 1,
78+
"method": "debug_traceTransaction",
79+
"params":
80+
[
81+
"0x8fc90a6c3ee3001cdcbbb685b4fbe67b1fa2bec575b15b0395fea5540d0901ae",
82+
{
83+
"tracer": "callTracer"
84+
}
85+
]
86+
}
87+
```
88+
#### Example Response
89+
```JSON
90+
{
91+
"jsonrpc": "2.0",
92+
"id": 1,
93+
"result": {
94+
"type": "CALL",
95+
"from": "0x5067c042e35881843f2b31dfc2db1f4f272ef48c",
96+
"to": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
97+
"value": "0x0",
98+
"gas": "0x17459",
99+
"gasUsed": "0x166cb",
100+
"input": "0x0f5287b0000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000001debea42000000000000000000000000000000000000000000000000000000000000000167c46aa713cfe47608dd1c16f8a0325208df084c3cbebf9f366ad0eafc2653e400000000000000000000000000000000000000000000000000000000001e8542000000000000000000000000000000000000000000000000000000006eca0000",
101+
"output": "0x000000000000000000000000000000000000000000000000000000000001371e",
102+
"calls": [
103+
{
104+
"type": "DELEGATECALL",
105+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
106+
"to": "0x76364611e457b1f97cd58ffc332ddc7561a193f6",
107+
"gas": "0x15bc0",
108+
"gasUsed": "0x1538e",
109+
"input": "0x0f5287b0000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000001debea42000000000000000000000000000000000000000000000000000000000000000167c46aa713cfe47608dd1c16f8a0325208df084c3cbebf9f366ad0eafc2653e400000000000000000000000000000000000000000000000000000000001e8542000000000000000000000000000000000000000000000000000000006eca0000",
110+
"output": "0x000000000000000000000000000000000000000000000000000000000001371e",
111+
"calls": [
112+
{
113+
"type": "STATICCALL",
114+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
115+
"to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
116+
"gas": "0x123bb",
117+
"gasUsed": "0x25c0",
118+
"input": "0x313ce567",
119+
"output": "0x0000000000000000000000000000000000000000000000000000000000000006",
120+
"calls": [
121+
{
122+
"type": "DELEGATECALL",
123+
"from": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
124+
"to": "0xa2327a938febf5fec13bacfb16ae10ecbc4cbdcf",
125+
"gas": "0x10357",
126+
"gasUsed": "0x94d",
127+
"input": "0x313ce567",
128+
"output": "0x0000000000000000000000000000000000000000000000000000000000000006"
129+
}
130+
]
131+
},
132+
{
133+
"type": "STATICCALL",
134+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
135+
"to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
136+
"gas": "0xf9d6",
137+
"gasUsed": "0xcf3",
138+
"input": "0x70a082310000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
139+
"output": "0x00000000000000000000000000000000000000000000000000001691e551e115",
140+
"calls": [
141+
{
142+
"type": "DELEGATECALL",
143+
"from": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
144+
"to": "0xa2327a938febf5fec13bacfb16ae10ecbc4cbdcf",
145+
"gas": "0xf315",
146+
"gasUsed": "0x9e1",
147+
"input": "0x70a082310000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
148+
"output": "0x00000000000000000000000000000000000000000000000000001691e551e115"
149+
}
150+
]
151+
},
152+
{
153+
"type": "CALL",
154+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
155+
"to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
156+
"value": "0x0",
157+
"gas": "0xe796",
158+
"gasUsed": "0x5f48",
159+
"input": "0x23b872dd0000000000000000000000005067c042e35881843f2b31dfc2db1f4f272ef48c0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000000000000000000000000000000000000000000000000001debea42",
160+
"output": "0x0000000000000000000000000000000000000000000000000000000000000001",
161+
"calls": [
162+
{
163+
"type": "DELEGATECALL",
164+
"from": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
165+
"to": "0xa2327a938febf5fec13bacfb16ae10ecbc4cbdcf",
166+
"gas": "0xe115",
167+
"gasUsed": "0x5c2d",
168+
"input": "0x23b872dd0000000000000000000000005067c042e35881843f2b31dfc2db1f4f272ef48c0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000000000000000000000000000000000000000000000000001debea42",
169+
"output": "0x0000000000000000000000000000000000000000000000000000000000000001"
170+
}
171+
]
172+
},
173+
{
174+
"type": "STATICCALL",
175+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
176+
"to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
177+
"gas": "0x857c",
178+
"gasUsed": "0x523",
179+
"input": "0x70a082310000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
180+
"output": "0x00000000000000000000000000000000000000000000000000001692033dcb57",
181+
"calls": [
182+
{
183+
"type": "DELEGATECALL",
184+
"from": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
185+
"to": "0xa2327a938febf5fec13bacfb16ae10ecbc4cbdcf",
186+
"gas": "0x808c",
187+
"gasUsed": "0x211",
188+
"input": "0x70a082310000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
189+
"output": "0x00000000000000000000000000000000000000000000000000001692033dcb57"
190+
}
191+
]
192+
},
193+
{
194+
"type": "CALL",
195+
"from": "0x3ee18b2214aff97000d974cf647e7c347e8fa585",
196+
"to": "0x98f3c9e6e3face36baad05fe09d375ef1464288b",
197+
"value": "0x0",
198+
"gas": "0x4f9f",
199+
"gasUsed": "0x46c6",
200+
"input": "0xb19a437e000000000000000000000000000000000000000000000000000000006eca00000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000008501000000000000000000000000000000000000000000000000000000001debea42000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000267c46aa713cfe47608dd1c16f8a0325208df084c3cbebf9f366ad0eafc2653e4000100000000000000000000000000000000000000000000000000000000001e8542000000000000000000000000000000000000000000000000000000",
201+
"output": "0x000000000000000000000000000000000000000000000000000000000001371e",
202+
"calls": [
203+
{
204+
"type": "DELEGATECALL",
205+
"from": "0x98f3c9e6e3face36baad05fe09d375ef1464288b",
206+
"to": "0x8c0041566e0bc27efe285a9e98d0b4217a46809c",
207+
"gas": "0x3b88",
208+
"gasUsed": "0x3377",
209+
"input": "0xb19a437e000000000000000000000000000000000000000000000000000000006eca00000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000008501000000000000000000000000000000000000000000000000000000001debea42000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000267c46aa713cfe47608dd1c16f8a0325208df084c3cbebf9f366ad0eafc2653e4000100000000000000000000000000000000000000000000000000000000001e8542000000000000000000000000000000000000000000000000000000",
210+
"output": "0x000000000000000000000000000000000000000000000000000000000001371e"
211+
}
212+
]
213+
}
214+
]
215+
}
216+
]
217+
}
218+
}
219+
```
220+
#### Returns for opcodeLogger
221+
222+
`object` - trace object:
223+
1. `pc` - int - program counter
224+
2. `op` - string - opcode to be executed
225+
3. `gas`- int - remaining gas
226+
4. `gasCost`- int - cost for executing op
227+
5. `memory` - string[] - EVM memory. Enabled via enableMemory
228+
6. `memSize`- int - Size of memory
229+
7. `stack`- int[] - EVM stack. Disabled via disableStack
230+
8. `returnData` - string[] - Last call's return data. Enabled via enableReturnData
231+
9. `storage` - map[hash]hash - Storage slots of current contract read from and written to. Only emitted for SLOAD and SSTORE. Disabled via disableStorage
232+
10. `depth` - int - Current call depth
233+
11. `refund` - int - Refund counter
234+
12. `error` - string - Error message if any
235+
236+
#### Example Request opcodeLogger
237+
```JSON
238+
{
239+
"jsonrpc": "2.0",
240+
"id": 1,
241+
"method": "debug_traceTransaction",
242+
"params":
243+
[
244+
"0x8fc90a6c3ee3001cdcbbb685b4fbe67b1fa2bec575b15b0395fea5540d0901ae",
245+
{
246+
"tracer": "opcodeLogger"
247+
}
248+
]
249+
}
250+
```
251+
#### Example Response
252+
```JSON
253+
{
254+
"jsonrpc": "2.0",
255+
"id": 1,
256+
"result": {
257+
"gas": 85301,
258+
"returnValue": "",
259+
"structLogs": [{
260+
"depth": 1,
261+
"error": "",
262+
"gas": 162106,
263+
"gasCost": 3,
264+
"memory": null,
265+
"op": "PUSH1",
266+
"pc": 0,
267+
"stack": [],
268+
"storage": {}
269+
},
270+
/* skip */
271+
{
272+
"depth": 1,
273+
"error": "",
274+
"gas": 100000,
275+
"gasCost": 0,
276+
"memory": ["0000000000000000000000000000000000000000000000000000000000000006", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000060"],
277+
"op": "STOP",
278+
"pc": 120,
279+
"stack": ["00000000000000000000000000000000000000000000000000000000d67cbec9"],
280+
"storage": {
281+
"0000000000000000000000000000000000000000000000000000000000000004": "8241fa522772837f0d05511f20caa6da1d5a3209000000000000000400000001",
282+
"0000000000000000000000000000000000000000000000000000000000000006": "0000000000000000000000000000000000000000000000000000000000000001",
283+
"f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "00000000000000000000000002e816afc1b5c0f39852131959d946eb3b07b5ad"
284+
}
285+
}]
286+
}
287+
}
288+
```
289+
290+
## Error Codes
291+
292+
| Error Codes | Error message | Solution |
293+
| :---------: | :-------------------------: | :-----------------------------------------------------------------: |
294+
| 32000 | Transaction not found. | Occurs when user is trying to trace non-existing transaction. |
295+
| 32001 | Block hash not found. | Occurs when user is trying to get modified accounts for non-existing block hash. |
296+
| 32002 | Block number not found. | Occurs when user is trying to get modified accounts for non-existing block number. |
297+
298+
## Limits
299+
1. Trying to get modified accounts for more than ex. 100 blocks. Env. variable can be `DEBUG_MODIFIED_ACCOUNTS_LIMIT`
300+
301+
302+
## Metric Capturing
303+
304+
Capture metrics for the following:
305+
306+
1. Record each invocation of all debug API methods and maintain a cumulative count.
307+
2. Log every success or fail for each new API method and maintain a cumulative count.
308+
309+
## Tests
310+
The following test cases should be covered but additional tests would be welcome.
311+
312+
1. Test `debug_traceTransaction` with `callTracer` and `onlyTopCall` set to true.
313+
2. Test `debug_traceTransaction` with `callTracer` and `onlyTopCall` set to false.
314+
3. Test `debug_traceTransaction` with `opcodeLogger` and all the tracerConfig values set to false.
315+
4. Test `debug_traceTransaction` with `opcodeLogger` and all the tracerConfig values set to true.
316+
5. Test `debug_traceTransaction` with `opcodeLogger` and all different combinations of tracerConfig values.
317+
6. Test `debug_traceTransaction` with hashes for the different types of transactions e.g Legacy, 1559, 2930.
318+
7. Case where transaction is not found for `debug_traceTransaction`.
319+
320+
## Deployment
321+
322+
Debug API will run alongside the already available HTTP server.
323+
324+
## Answered Questions
325+
326+
1. What is the purpose of Debug API and what kind of goals adding it fulfil ?
327+
2. What new interfaces and classes would it need ?
328+
3. What new endpoints will be exposed ?
329+
4. What kind of parameters each method accepts ?
330+
5. What kind of response is expected to return ?
331+
6. What is the expected request and response ?
332+
7. What limits should be introduced ?
333+
8. What metrics should be captured ?
334+
335+
336+
## Tasks (in suggested order):
337+
338+
#### Milestone 1
339+
340+
1. Finalize design document
341+
342+
#### Milestone 2
343+
344+
1. Implement new interfaces and classes.
345+
2. Implement `debug_traceTransaction`.
346+
3. Add needed acceptance tests for `debug_traceTransaction`.
347+
348+
#### Milestone 3
349+
1. Implement `debug_getModifiedAccountsByHash`.
350+
2. Implement `debug_getModifiedAccountsByNumber`.
351+
3. Add needed acceptance tests for both new methods.

0 commit comments

Comments
 (0)