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}