1use alloy_consensus::Header;
5use alloy_primitives::{Address, B256, U256};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct NodeInfo {
13 pub name: String,
15
16 pub node: String,
18
19 pub port: u64,
21
22 #[serde(rename = "net")]
24 pub network: String,
25
26 pub protocol: String,
28
29 pub api: String,
31
32 pub os: String,
34
35 #[serde(rename = "os_v")]
37 pub os_ver: String,
38
39 pub client: String,
41
42 #[serde(rename = "canUpdateHistory")]
44 pub history: bool,
45}
46
47#[derive(Debug, Serialize, Deserialize)]
50pub struct AuthMsg {
51 pub id: String,
53
54 pub info: NodeInfo,
56
57 pub secret: String,
59}
60
61impl AuthMsg {
62 pub fn generate_login_message(&self) -> String {
64 serde_json::json!({
65 "emit": ["hello", self]
66 })
67 .to_string()
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct TxStats {
74 pub hash: B256,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
81#[serde(transparent)]
82pub struct UncleStats(pub Vec<Header>);
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct BlockStats {
87 pub number: U256,
89
90 pub hash: B256,
92
93 #[serde(rename = "parentHash")]
95 pub parent_hash: B256,
96
97 pub timestamp: U256,
99
100 pub miner: Address,
102
103 #[serde(rename = "gasUsed")]
105 pub gas_used: u64,
106
107 #[serde(rename = "gasLimit")]
109 pub gas_limit: u64,
110
111 #[serde(rename = "difficulty")]
113 pub diff: String,
114
115 #[serde(rename = "totalDifficulty")]
117 pub total_diff: String,
118
119 #[serde(rename = "transactions")]
121 pub txs: Vec<TxStats>,
122
123 #[serde(rename = "transactionsRoot")]
125 pub tx_root: B256,
126
127 #[serde(rename = "stateRoot")]
129 pub root: B256,
130
131 pub uncles: UncleStats,
133}
134
135#[derive(Debug, Serialize, Deserialize)]
137pub struct BlockMsg {
138 pub id: String,
140
141 pub block: BlockStats,
143}
144
145impl BlockMsg {
146 pub fn generate_block_message(&self) -> String {
148 serde_json::json!({
149 "emit": ["block", self]
150 })
151 .to_string()
152 }
153}
154
155#[derive(Debug, Serialize, Deserialize)]
157pub struct HistoryMsg {
158 pub id: String,
160
161 pub history: Vec<BlockStats>,
163}
164
165impl HistoryMsg {
166 pub fn generate_history_message(&self) -> String {
168 serde_json::json!({
169 "emit": ["history", self]
170 })
171 .to_string()
172 }
173}
174
175#[derive(Debug, Serialize, Deserialize)]
178pub struct PendingStats {
179 pub pending: u64,
181}
182
183#[derive(Debug, Serialize, Deserialize)]
186pub struct PendingMsg {
187 pub id: String,
189
190 pub stats: PendingStats,
192}
193
194impl PendingMsg {
195 pub fn generate_pending_message(&self) -> String {
197 serde_json::json!({
198 "emit": ["pending", self]
199 })
200 .to_string()
201 }
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct NodeStats {
207 pub active: bool,
209
210 pub syncing: bool,
212
213 pub peers: u64,
215
216 #[serde(rename = "gasPrice")]
218 pub gas_price: u64,
219
220 pub uptime: u64,
222}
223
224#[derive(Debug, Serialize, Deserialize)]
226pub struct StatsMsg {
227 pub id: String,
229
230 pub stats: NodeStats,
232}
233
234impl StatsMsg {
235 pub fn generate_stats_message(&self) -> String {
237 serde_json::json!({
238 "emit": ["stats", self]
239 })
240 .to_string()
241 }
242}
243
244#[derive(Serialize, Deserialize, Debug)]
246pub struct LatencyMsg {
247 pub id: String,
249
250 pub latency: u64,
252}
253
254impl LatencyMsg {
255 pub fn generate_latency_message(&self) -> String {
257 serde_json::json!({
258 "emit": ["latency", self]
259 })
260 .to_string()
261 }
262}
263
264#[derive(Serialize, Deserialize, Debug)]
266pub struct PingMsg {
267 pub id: String,
269
270 #[serde(rename = "clientTime")]
272 pub client_time: String,
273}
274
275impl PingMsg {
276 pub fn generate_ping_message(&self) -> String {
278 serde_json::json!({
279 "emit": ["node-ping", self]
280 })
281 .to_string()
282 }
283}
284
285#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct PayloadStats {
288 pub number: U256,
290
291 pub hash: B256,
293
294 #[serde(rename = "processingTime")]
296 pub processing_time: u64,
297}
298
299#[derive(Debug, Serialize, Deserialize)]
301pub struct PayloadMsg {
302 pub id: String,
304
305 pub payload: PayloadStats,
307}
308
309impl PayloadMsg {
310 pub fn generate_new_payload_message(&self) -> String {
312 serde_json::json!({
313 "emit": ["new-payload", self]
314 })
315 .to_string()
316 }
317}
318
319#[cfg(test)]
320mod tests {
321 use super::*;
322 use alloy_primitives::{B256, U256};
323
324 #[test]
325 fn test_payload_msg_generation() {
326 let payload_stats = PayloadStats {
327 number: U256::from(12345),
328 hash: B256::from_slice(&[1u8; 32]),
329 processing_time: 150,
330 };
331
332 let payload_msg = PayloadMsg { id: "test-node".to_string(), payload: payload_stats };
333
334 let message = payload_msg.generate_new_payload_message();
335 let parsed: serde_json::Value = serde_json::from_str(&message).expect("Valid JSON");
336
337 assert_eq!(parsed["emit"][0], "new-payload");
338 assert_eq!(parsed["emit"][1]["id"], "test-node");
339 assert_eq!(parsed["emit"][1]["payload"]["number"], "0x3039"); assert_eq!(parsed["emit"][1]["payload"]["processingTime"], 150);
341
342 assert!(parsed["emit"][1]["payload"]["hash"].is_string());
344 assert!(parsed["emit"][1]["payload"]["processingTime"].is_number());
345 }
346}