reth_node_ethstats/
events.rs

1//! Types for ethstats event reporting.
2//! These structures define the data format used to report blockchain events to ethstats servers.
3
4use alloy_consensus::Header;
5use alloy_primitives::{Address, B256, U256};
6use serde::{Deserialize, Serialize};
7
8/// Collection of meta information about a node that is displayed on the monitoring page.
9/// This information is used to identify and display node details in the ethstats monitoring
10/// interface.
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct NodeInfo {
13    /// The display name of the node in the monitoring interface
14    pub name: String,
15
16    /// The node's unique identifier
17    pub node: String,
18
19    /// The port number the node is listening on for P2P connections
20    pub port: u64,
21
22    /// The network ID the node is connected to (e.g. "1" for mainnet)
23    #[serde(rename = "net")]
24    pub network: String,
25
26    /// Comma-separated list of supported protocols and their versions
27    pub protocol: String,
28
29    /// API availability indicator ("Yes" or "No")
30    pub api: String,
31
32    /// Operating system the node is running on
33    pub os: String,
34
35    /// Operating system version/architecture
36    #[serde(rename = "os_v")]
37    pub os_ver: String,
38
39    /// Client software version
40    pub client: String,
41
42    /// Whether the node can provide historical block data
43    #[serde(rename = "canUpdateHistory")]
44    pub history: bool,
45}
46
47/// Authentication message used to login to the ethstats monitoring server.
48/// Contains node identification and authentication information.
49#[derive(Debug, Serialize, Deserialize)]
50pub struct AuthMsg {
51    /// The node's unique identifier
52    pub id: String,
53
54    /// Detailed information about the node
55    pub info: NodeInfo,
56
57    /// Secret password for authentication with the monitoring server
58    pub secret: String,
59}
60
61impl AuthMsg {
62    /// Generate a login message for the ethstats monitoring server.
63    pub fn generate_login_message(&self) -> String {
64        serde_json::json!({
65            "emit": ["hello", self]
66        })
67        .to_string()
68    }
69}
70
71/// Simplified transaction info, containing only the hash.
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct TxStats {
74    /// Transaction hash
75    pub hash: B256,
76}
77
78/// Wrapper for uncle block headers.
79/// This ensures empty lists serialize as `[]` instead of `null`.
80#[derive(Debug, Clone, Serialize, Deserialize)]
81#[serde(transparent)]
82pub struct UncleStats(pub Vec<Header>);
83
84/// Information to report about individual blocks.
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct BlockStats {
87    /// Block number (height in the chain).
88    pub number: U256,
89
90    /// Hash of this block.
91    pub hash: B256,
92
93    /// Hash of the parent block.
94    #[serde(rename = "parentHash")]
95    pub parent_hash: B256,
96
97    /// Timestamp of the block (Unix time).
98    pub timestamp: U256,
99
100    /// Address of the miner who produced this block.
101    pub miner: Address,
102
103    /// Total gas used by all transactions in the block.
104    #[serde(rename = "gasUsed")]
105    pub gas_used: u64,
106
107    /// Maximum gas allowed for this block.
108    #[serde(rename = "gasLimit")]
109    pub gas_limit: u64,
110
111    /// Difficulty for mining this block (as a decimal string).
112    #[serde(rename = "difficulty")]
113    pub diff: String,
114
115    /// Cumulative difficulty up to this block (as a decimal string).
116    #[serde(rename = "totalDifficulty")]
117    pub total_diff: String,
118
119    /// Simplified list of transactions in the block.
120    #[serde(rename = "transactions")]
121    pub txs: Vec<TxStats>,
122
123    /// Root hash of all transactions (Merkle root).
124    #[serde(rename = "transactionsRoot")]
125    pub tx_root: B256,
126
127    /// State root after applying this block.
128    #[serde(rename = "stateRoot")]
129    pub root: B256,
130
131    /// List of uncle block headers.
132    pub uncles: UncleStats,
133}
134
135/// Message containing a block to be reported to the ethstats monitoring server.
136#[derive(Debug, Serialize, Deserialize)]
137pub struct BlockMsg {
138    /// The node's unique identifier
139    pub id: String,
140
141    /// The block to report
142    pub block: BlockStats,
143}
144
145impl BlockMsg {
146    /// Generate a block message for the ethstats monitoring server.
147    pub fn generate_block_message(&self) -> String {
148        serde_json::json!({
149            "emit": ["block", self]
150        })
151        .to_string()
152    }
153}
154
155/// Message containing historical block data to be reported to the ethstats monitoring server.
156#[derive(Debug, Serialize, Deserialize)]
157pub struct HistoryMsg {
158    /// The node's unique identifier
159    pub id: String,
160
161    /// The historical block data to report
162    pub history: Vec<BlockStats>,
163}
164
165impl HistoryMsg {
166    /// Generate a history message for the ethstats monitoring server.
167    pub fn generate_history_message(&self) -> String {
168        serde_json::json!({
169            "emit": ["history", self]
170        })
171        .to_string()
172    }
173}
174
175/// Message containing pending transaction statistics to be reported to the ethstats monitoring
176/// server.
177#[derive(Debug, Serialize, Deserialize)]
178pub struct PendingStats {
179    /// Number of pending transactions
180    pub pending: u64,
181}
182
183/// Message containing pending transaction statistics to be reported to the ethstats monitoring
184/// server.
185#[derive(Debug, Serialize, Deserialize)]
186pub struct PendingMsg {
187    /// The node's unique identifier
188    pub id: String,
189
190    /// The pending transaction statistics to report
191    pub stats: PendingStats,
192}
193
194impl PendingMsg {
195    /// Generate a pending message for the ethstats monitoring server.
196    pub fn generate_pending_message(&self) -> String {
197        serde_json::json!({
198            "emit": ["pending", self]
199        })
200        .to_string()
201    }
202}
203
204/// Information reported about the local node.
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct NodeStats {
207    /// Whether the node is active
208    pub active: bool,
209
210    /// Whether the node is currently syncing
211    pub syncing: bool,
212
213    /// Number of connected peers
214    pub peers: u64,
215
216    /// Current gas price in wei
217    #[serde(rename = "gasPrice")]
218    pub gas_price: u64,
219
220    /// Node uptime percentage
221    pub uptime: u64,
222}
223
224/// Message containing node statistics to be reported to the ethstats monitoring server.
225#[derive(Debug, Serialize, Deserialize)]
226pub struct StatsMsg {
227    /// The node's unique identifier
228    pub id: String,
229
230    /// The stats to report
231    pub stats: NodeStats,
232}
233
234impl StatsMsg {
235    /// Generate a stats message for the ethstats monitoring server.
236    pub fn generate_stats_message(&self) -> String {
237        serde_json::json!({
238            "emit": ["stats", self]
239        })
240        .to_string()
241    }
242}
243
244/// Latency report message used to report network latency to the ethstats monitoring server.
245#[derive(Serialize, Deserialize, Debug)]
246pub struct LatencyMsg {
247    /// The node's unique identifier
248    pub id: String,
249
250    /// The latency to report in milliseconds
251    pub latency: u64,
252}
253
254impl LatencyMsg {
255    /// Generate a latency message for the ethstats monitoring server.
256    pub fn generate_latency_message(&self) -> String {
257        serde_json::json!({
258            "emit": ["latency", self]
259        })
260        .to_string()
261    }
262}
263
264/// Ping message sent to the ethstats monitoring server to initiate latency measurement.
265#[derive(Serialize, Deserialize, Debug)]
266pub struct PingMsg {
267    /// The node's unique identifier
268    pub id: String,
269
270    /// Client timestamp when the ping was sent
271    #[serde(rename = "clientTime")]
272    pub client_time: String,
273}
274
275impl PingMsg {
276    /// Generate a ping message for the ethstats monitoring server.
277    pub fn generate_ping_message(&self) -> String {
278        serde_json::json!({
279            "emit": ["node-ping", self]
280        })
281        .to_string()
282    }
283}