edb_engine/rpc/types.rs
1// EDB - Ethereum Debugger
2// Copyright (C) 2024 Zhuo Zhang and Wuqi Zhang
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Affero General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Affero General Public License for more details.
13//
14// You should have received a copy of the GNU Affero General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17//! JSON-RPC protocol types and data structures.
18//!
19//! This module defines all the data structures used for JSON-RPC communication
20//! between debugging clients (frontends, IDEs, etc.) and the EDB RPC server.
21//! All types implement the JSON-RPC 2.0 specification for consistent protocol handling.
22//!
23//! # Protocol Types
24//!
25//! - [`RpcRequest`] - Incoming JSON-RPC request with method and parameters
26//! - [`RpcResponse`] - Outgoing JSON-RPC response with result or error
27//! - [`RpcError`] - Structured error information following JSON-RPC error format
28//! - [`RpcId`] - Request/response identifier (string or number)
29//!
30//! # Debugging Types
31//!
32//! - [`Breakpoint`] - Breakpoint configuration and metadata
33//! - [`BreakpointLocation`] - Location specification for breakpoints
34//! - [`LocationType`] - Type of location (source line vs program counter)
35//!
36//! # Error Handling
37//!
38//! The module includes standard JSON-RPC error codes in the [`error_codes`] module
39//! for consistent error reporting across all RPC methods.
40
41use alloy_primitives::Address;
42use serde::{Deserialize, Serialize};
43
44/// JSON-RPC 2.0 request structure.
45///
46/// Represents an incoming RPC request from a debugging client.
47/// Contains the method to invoke and optional parameters.
48#[derive(Debug, Deserialize)]
49pub struct RpcRequest {
50 /// JSON-RPC version (always "2.0")
51 pub jsonrpc: String,
52 /// Method name to invoke (e.g., "snapshot_get", "expr_eval")
53 pub method: String,
54 /// Optional method parameters as JSON value
55 pub params: Option<serde_json::Value>,
56 /// Request identifier for matching with response
57 pub id: RpcId,
58}
59
60/// JSON-RPC 2.0 response structure.
61///
62/// Represents an outgoing RPC response to a debugging client.
63/// Contains either a successful result or an error, never both.
64#[derive(Debug, Serialize)]
65pub struct RpcResponse {
66 /// JSON-RPC version (always "2.0")
67 pub jsonrpc: String,
68 /// Successful method result (omitted if error occurred)
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub result: Option<serde_json::Value>,
71 /// Error information (omitted if method succeeded)
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub error: Option<RpcError>,
74 /// Request identifier matching the original request
75 pub id: RpcId,
76}
77
78/// JSON-RPC 2.0 error structure.
79///
80/// Provides structured error information when RPC methods fail.
81/// Follows the JSON-RPC error object specification.
82#[derive(Debug, Serialize)]
83pub struct RpcError {
84 /// Numeric error code indicating the error type
85 pub code: i32,
86 /// Human-readable error message
87 pub message: String,
88 /// Optional additional error data (context, stack traces, etc.)
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub data: Option<serde_json::Value>,
91}
92
93/// JSON-RPC request/response identifier.
94///
95/// Can be either a string or number as per JSON-RPC 2.0 specification.
96/// Used to match responses with their corresponding requests.
97#[derive(Debug, Clone, Serialize, Deserialize)]
98#[serde(untagged)]
99pub enum RpcId {
100 /// Numeric identifier
101 Number(u64),
102 /// String identifier
103 String(String),
104}
105
106/// Debugging breakpoint configuration.
107///
108/// Represents a breakpoint that can pause execution at specific locations.
109/// Supports both source-level and bytecode-level breakpoints with optional conditions.
110#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct Breakpoint {
112 /// Unique identifier for this breakpoint
113 pub id: BreakpointId,
114 /// Location where the breakpoint is set
115 pub location: BreakpointLocation,
116 /// Whether the breakpoint is currently active
117 pub enabled: bool,
118 /// Optional condition that must be true for breakpoint to trigger
119 pub condition: Option<String>,
120}
121
122/// Unique identifier for a breakpoint.
123///
124/// Used to reference breakpoints in enable/disable/remove operations.
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
126pub struct BreakpointId(pub String);
127
128/// Location specification for a breakpoint.
129///
130/// Defines where a breakpoint should be placed, supporting both source-level
131/// (line number) and bytecode-level (program counter) locations.
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct BreakpointLocation {
134 /// Contract address where the breakpoint is set
135 pub address: Address,
136 /// Type of location (source line or program counter)
137 pub location_type: LocationType,
138 /// Source code line number (for source-level breakpoints)
139 pub line: Option<usize>,
140 /// Program counter offset (for bytecode-level breakpoints)
141 pub pc: Option<usize>,
142 /// Source file path (for source-level breakpoints)
143 pub path: Option<String>,
144}
145
146/// Type of breakpoint location.
147///
148/// Determines whether the breakpoint is set at a source code line
149/// or at a specific bytecode instruction.
150#[derive(Debug, Clone, Serialize, Deserialize)]
151#[serde(rename_all = "snake_case")]
152pub enum LocationType {
153 /// Breakpoint set at a source code line
154 SourceLine,
155 /// Breakpoint set at a specific bytecode instruction (program counter)
156 ProgramCounter,
157}
158
159/// JSON-RPC error codes for consistent error reporting.
160///
161/// Includes both standard JSON-RPC 2.0 error codes and EDB-specific error codes
162/// for debugging-related failures.
163pub mod error_codes {
164 // Standard JSON-RPC 2.0 error codes
165
166 /// Parse error - Invalid JSON was received by the server
167 pub const PARSE_ERROR: i32 = -32700;
168 /// Invalid request - The JSON sent is not a valid request object
169 pub const INVALID_REQUEST: i32 = -32600;
170 /// Method not found - The method does not exist or is not available
171 pub const METHOD_NOT_FOUND: i32 = -32601;
172 /// Invalid params - Invalid method parameter(s)
173 pub const INVALID_PARAMS: i32 = -32602;
174 /// Internal error - Internal JSON-RPC error
175 pub const INTERNAL_ERROR: i32 = -32603;
176
177 // EDB-specific error codes (starting from -33000)
178
179 /// Snapshot index is out of bounds
180 pub const SNAPSHOT_OUT_OF_BOUNDS: i32 = -33001;
181 /// Invalid or malformed address
182 pub const INVALID_ADDRESS: i32 = -33002;
183 /// Trace entry not found for the given ID
184 pub const TRACE_ENTRY_NOT_FOUND: i32 = -33003;
185 /// Contract code not found at the given address
186 pub const CODE_NOT_FOUND: i32 = -33004;
187 /// User-defined snapshot ID not found
188 pub const USID_NOT_FOUND: i32 = -33005;
189 /// Expression evaluation failed
190 pub const EVAL_FAILED: i32 = -33006;
191}