Skip to main content

ethrex_p2p/rlpx/
message.rs

1use bytes::BufMut;
2use ethrex_rlp::error::{RLPDecodeError, RLPEncodeError};
3use std::fmt::Display;
4
5use crate::rlpx::snap::{
6    AccountRange, ByteCodes, GetAccountRange, GetByteCodes, GetStorageRanges, GetTrieNodes,
7    StorageRanges, TrieNodes,
8};
9
10use super::eth::block_access_lists::{BlockAccessLists, GetBlockAccessLists};
11use super::eth::blocks::{BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders};
12use super::eth::receipts::{
13    GetReceipts68, GetReceipts69, GetReceipts70, Receipts68, Receipts69, Receipts70,
14};
15use super::eth::status::{StatusMessage68, StatusMessage69, StatusMessage70, StatusMessage71};
16use super::eth::transactions::{
17    GetPooledTransactions, NewPooledTransactionHashes, PooledTransactions, Transactions,
18};
19use super::eth::update::BlockRangeUpdate;
20#[cfg(feature = "l2")]
21use super::l2::messages::{BatchSealed, L2Message, NewBlock};
22#[cfg(feature = "l2")]
23use super::l2::{self, messages};
24use super::p2p::{DisconnectMessage, HelloMessage, PingMessage, PongMessage};
25
26use ethrex_rlp::encode::RLPEncode;
27
28const ETH_CAPABILITY_OFFSET: u8 = 0x10;
29const SNAP_CAPABILITY_OFFSET_ETH_68: u8 = 0x21;
30const SNAP_CAPABILITY_OFFSET_ETH_69: u8 = 0x22;
31// eth/70 (EIP-7975) reuses the same message codes as eth/69 — it only changes the
32// format of GetReceipts (0x0F) and Receipts (0x10), so offsets are identical.
33// GetReceipts68 and GetReceipts69 are type aliases for the same struct (identical wire format).
34const SNAP_CAPABILITY_OFFSET_ETH_70: u8 = 0x22;
35const SNAP_CAPABILITY_OFFSET_ETH_71: u8 = 0x24;
36const BASED_CAPABILITY_OFFSET_ETH_68: u8 = 0x30;
37const BASED_CAPABILITY_OFFSET_ETH_69: u8 = 0x31;
38const BASED_CAPABILITY_OFFSET_ETH_70: u8 = 0x31;
39const BASED_CAPABILITY_OFFSET_ETH_71: u8 = 0x33;
40
41#[derive(Debug, Clone, Copy, Default)]
42pub enum EthCapVersion {
43    #[default]
44    V68,
45    V69,
46    V70,
47    V71,
48}
49
50impl EthCapVersion {
51    pub const fn eth_capability_offset(&self) -> u8 {
52        ETH_CAPABILITY_OFFSET
53    }
54
55    pub const fn snap_capability_offset(&self) -> u8 {
56        match self {
57            EthCapVersion::V68 => SNAP_CAPABILITY_OFFSET_ETH_68,
58            EthCapVersion::V69 => SNAP_CAPABILITY_OFFSET_ETH_69,
59            EthCapVersion::V70 => SNAP_CAPABILITY_OFFSET_ETH_70,
60            EthCapVersion::V71 => SNAP_CAPABILITY_OFFSET_ETH_71,
61        }
62    }
63
64    pub const fn based_capability_offset(&self) -> u8 {
65        match self {
66            EthCapVersion::V68 => BASED_CAPABILITY_OFFSET_ETH_68,
67            EthCapVersion::V69 => BASED_CAPABILITY_OFFSET_ETH_69,
68            EthCapVersion::V70 => BASED_CAPABILITY_OFFSET_ETH_70,
69            EthCapVersion::V71 => BASED_CAPABILITY_OFFSET_ETH_71,
70        }
71    }
72}
73
74pub trait RLPxMessage: Sized {
75    const CODE: u8;
76
77    fn encode(&self, buf: &mut dyn BufMut) -> Result<(), RLPEncodeError>;
78
79    fn decode(msg_data: &[u8]) -> Result<Self, RLPDecodeError>;
80}
81#[derive(Debug, Clone)]
82pub enum Message {
83    Hello(HelloMessage),
84    Disconnect(DisconnectMessage),
85    Ping(PingMessage),
86    Pong(PongMessage),
87    Status68(StatusMessage68),
88    Status69(StatusMessage69),
89    Status70(StatusMessage70),
90    Status71(StatusMessage71),
91    // eth capability
92    // https://github.com/ethereum/devp2p/blob/master/caps/eth.md
93    GetBlockHeaders(GetBlockHeaders),
94    BlockHeaders(BlockHeaders),
95    Transactions(Transactions),
96    GetBlockBodies(GetBlockBodies),
97    BlockBodies(BlockBodies),
98    NewPooledTransactionHashes(NewPooledTransactionHashes),
99    GetPooledTransactions(GetPooledTransactions),
100    PooledTransactions(PooledTransactions),
101    GetReceipts68(GetReceipts68),
102    GetReceipts69(GetReceipts69),
103    GetReceipts70(GetReceipts70),
104    Receipts68(Receipts68),
105    Receipts69(Receipts69),
106    Receipts70(Receipts70),
107    BlockRangeUpdate(BlockRangeUpdate),
108    GetBlockAccessLists(GetBlockAccessLists),
109    BlockAccessLists(BlockAccessLists),
110    // snap capability
111    // https://github.com/ethereum/devp2p/blob/master/caps/snap.md
112    GetAccountRange(GetAccountRange),
113    AccountRange(AccountRange),
114    GetStorageRanges(GetStorageRanges),
115    StorageRanges(StorageRanges),
116    GetByteCodes(GetByteCodes),
117    ByteCodes(ByteCodes),
118    GetTrieNodes(GetTrieNodes),
119    TrieNodes(TrieNodes),
120    // based capability
121    #[cfg(feature = "l2")]
122    L2(messages::L2Message),
123}
124
125impl Message {
126    pub const fn code(&self, eth_version: EthCapVersion) -> u8 {
127        match self {
128            Message::Hello(_) => HelloMessage::CODE,
129            Message::Disconnect(_) => DisconnectMessage::CODE,
130            Message::Ping(_) => PingMessage::CODE,
131            Message::Pong(_) => PongMessage::CODE,
132
133            // eth capability
134            Message::Status68(_) => eth_version.eth_capability_offset() + StatusMessage68::CODE,
135            Message::Status69(_) => eth_version.eth_capability_offset() + StatusMessage69::CODE,
136            Message::Status70(_) => eth_version.eth_capability_offset() + StatusMessage70::CODE,
137            Message::Status71(_) => eth_version.eth_capability_offset() + StatusMessage71::CODE,
138            Message::Transactions(_) => eth_version.eth_capability_offset() + Transactions::CODE,
139            Message::GetBlockHeaders(_) => {
140                eth_version.eth_capability_offset() + GetBlockHeaders::CODE
141            }
142            Message::BlockHeaders(_) => eth_version.eth_capability_offset() + BlockHeaders::CODE,
143            Message::GetBlockBodies(_) => {
144                eth_version.eth_capability_offset() + GetBlockBodies::CODE
145            }
146            Message::BlockBodies(_) => eth_version.eth_capability_offset() + BlockBodies::CODE,
147            Message::NewPooledTransactionHashes(_) => {
148                eth_version.eth_capability_offset() + NewPooledTransactionHashes::CODE
149            }
150            Message::GetPooledTransactions(_) => {
151                eth_version.eth_capability_offset() + GetPooledTransactions::CODE
152            }
153            Message::PooledTransactions(_) => {
154                eth_version.eth_capability_offset() + PooledTransactions::CODE
155            }
156            Message::GetReceipts68(_) => eth_version.eth_capability_offset() + GetReceipts68::CODE,
157            Message::GetReceipts69(_) => eth_version.eth_capability_offset() + GetReceipts69::CODE,
158            Message::GetReceipts70(_) => eth_version.eth_capability_offset() + GetReceipts70::CODE,
159            Message::Receipts68(_) => eth_version.eth_capability_offset() + Receipts68::CODE,
160            Message::Receipts69(_) => eth_version.eth_capability_offset() + Receipts69::CODE,
161            Message::Receipts70(_) => eth_version.eth_capability_offset() + Receipts70::CODE,
162            Message::BlockRangeUpdate(_) => {
163                eth_version.eth_capability_offset() + BlockRangeUpdate::CODE
164            }
165            Message::GetBlockAccessLists(_) => {
166                eth_version.eth_capability_offset() + GetBlockAccessLists::CODE
167            }
168            Message::BlockAccessLists(_) => {
169                eth_version.eth_capability_offset() + BlockAccessLists::CODE
170            }
171            // snap capability
172            Message::GetAccountRange(_) => {
173                eth_version.snap_capability_offset() + GetAccountRange::CODE
174            }
175            Message::AccountRange(_) => eth_version.snap_capability_offset() + AccountRange::CODE,
176            Message::GetStorageRanges(_) => {
177                eth_version.snap_capability_offset() + GetStorageRanges::CODE
178            }
179            Message::StorageRanges(_) => eth_version.snap_capability_offset() + StorageRanges::CODE,
180            Message::GetByteCodes(_) => eth_version.snap_capability_offset() + GetByteCodes::CODE,
181            Message::ByteCodes(_) => eth_version.snap_capability_offset() + ByteCodes::CODE,
182            Message::GetTrieNodes(_) => eth_version.snap_capability_offset() + GetTrieNodes::CODE,
183            Message::TrieNodes(_) => eth_version.snap_capability_offset() + TrieNodes::CODE,
184
185            #[cfg(feature = "l2")]
186            // based capability
187            Message::L2(l2_msg) => {
188                eth_version.based_capability_offset() + {
189                    match l2_msg {
190                        L2Message::NewBlock(_) => NewBlock::CODE,
191                        L2Message::BatchSealed(_) => BatchSealed::CODE,
192                    }
193                }
194            }
195        }
196    }
197    pub fn decode(
198        msg_id: u8,
199        data: &[u8],
200        eth_version: EthCapVersion,
201    ) -> Result<Message, RLPDecodeError> {
202        if msg_id < eth_version.eth_capability_offset() {
203            match msg_id {
204                HelloMessage::CODE => Ok(Message::Hello(HelloMessage::decode(data)?)),
205                DisconnectMessage::CODE => {
206                    Ok(Message::Disconnect(DisconnectMessage::decode(data)?))
207                }
208                PingMessage::CODE => Ok(Message::Ping(PingMessage::decode(data)?)),
209                PongMessage::CODE => Ok(Message::Pong(PongMessage::decode(data)?)),
210                _ => Err(RLPDecodeError::MalformedData),
211            }
212        } else if msg_id < eth_version.snap_capability_offset() {
213            // eth capability
214            match msg_id - eth_version.eth_capability_offset() {
215                StatusMessage68::CODE if matches!(eth_version, EthCapVersion::V68) => {
216                    Ok(Message::Status68(StatusMessage68::decode(data)?))
217                }
218                StatusMessage69::CODE if matches!(eth_version, EthCapVersion::V69) => {
219                    Ok(Message::Status69(StatusMessage69::decode(data)?))
220                }
221                StatusMessage70::CODE if matches!(eth_version, EthCapVersion::V70) => {
222                    Ok(Message::Status70(StatusMessage70::decode(data)?))
223                }
224                StatusMessage71::CODE if matches!(eth_version, EthCapVersion::V71) => {
225                    Ok(Message::Status71(StatusMessage71::decode(data)?))
226                }
227                Transactions::CODE => Ok(Message::Transactions(Transactions::decode(data)?)),
228                GetBlockHeaders::CODE => {
229                    Ok(Message::GetBlockHeaders(GetBlockHeaders::decode(data)?))
230                }
231                BlockHeaders::CODE => Ok(Message::BlockHeaders(BlockHeaders::decode(data)?)),
232                GetBlockBodies::CODE => Ok(Message::GetBlockBodies(GetBlockBodies::decode(data)?)),
233                BlockBodies::CODE => Ok(Message::BlockBodies(BlockBodies::decode(data)?)),
234                NewPooledTransactionHashes::CODE => Ok(Message::NewPooledTransactionHashes(
235                    NewPooledTransactionHashes::decode(data)?,
236                )),
237                GetPooledTransactions::CODE => Ok(Message::GetPooledTransactions(
238                    GetPooledTransactions::decode(data)?,
239                )),
240                PooledTransactions::CODE => Ok(Message::PooledTransactions(
241                    PooledTransactions::decode(data)?,
242                )),
243                GetReceipts68::CODE if matches!(eth_version, EthCapVersion::V68) => {
244                    Ok(Message::GetReceipts68(GetReceipts68::decode(data)?))
245                }
246                // eth/71 (EIP-8159) builds on eth/69, not eth/70 — it uses the
247                // same receipt format as eth/69.
248                GetReceipts69::CODE
249                    if matches!(eth_version, EthCapVersion::V69 | EthCapVersion::V71) =>
250                {
251                    Ok(Message::GetReceipts69(GetReceipts69::decode(data)?))
252                }
253                GetReceipts70::CODE if matches!(eth_version, EthCapVersion::V70) => {
254                    Ok(Message::GetReceipts70(GetReceipts70::decode(data)?))
255                }
256                Receipts68::CODE if matches!(eth_version, EthCapVersion::V68) => {
257                    Ok(Message::Receipts68(Receipts68::decode(data)?))
258                }
259                Receipts69::CODE
260                    if matches!(eth_version, EthCapVersion::V69 | EthCapVersion::V71) =>
261                {
262                    Ok(Message::Receipts69(Receipts69::decode(data)?))
263                }
264                Receipts70::CODE if matches!(eth_version, EthCapVersion::V70) => {
265                    Ok(Message::Receipts70(Receipts70::decode(data)?))
266                }
267                BlockRangeUpdate::CODE => {
268                    Ok(Message::BlockRangeUpdate(BlockRangeUpdate::decode(data)?))
269                }
270                GetBlockAccessLists::CODE if matches!(eth_version, EthCapVersion::V71) => Ok(
271                    Message::GetBlockAccessLists(GetBlockAccessLists::decode(data)?),
272                ),
273                BlockAccessLists::CODE if matches!(eth_version, EthCapVersion::V71) => {
274                    Ok(Message::BlockAccessLists(BlockAccessLists::decode(data)?))
275                }
276                _ => Err(RLPDecodeError::MalformedData),
277            }
278        } else if msg_id < eth_version.based_capability_offset() {
279            // snap capability
280            match msg_id - eth_version.snap_capability_offset() {
281                GetAccountRange::CODE => {
282                    Ok(Message::GetAccountRange(GetAccountRange::decode(data)?))
283                }
284                AccountRange::CODE => Ok(Message::AccountRange(AccountRange::decode(data)?)),
285                GetStorageRanges::CODE => {
286                    Ok(Message::GetStorageRanges(GetStorageRanges::decode(data)?))
287                }
288                StorageRanges::CODE => Ok(Message::StorageRanges(StorageRanges::decode(data)?)),
289                GetByteCodes::CODE => Ok(Message::GetByteCodes(GetByteCodes::decode(data)?)),
290                ByteCodes::CODE => Ok(Message::ByteCodes(ByteCodes::decode(data)?)),
291                GetTrieNodes::CODE => Ok(Message::GetTrieNodes(GetTrieNodes::decode(data)?)),
292                TrieNodes::CODE => Ok(Message::TrieNodes(TrieNodes::decode(data)?)),
293                _ => Err(RLPDecodeError::MalformedData),
294            }
295        } else {
296            // based capability
297            #[cfg(feature = "l2")]
298            return Ok(Message::L2(
299                match msg_id - eth_version.based_capability_offset() {
300                    messages::NewBlock::CODE => {
301                        let decoded = l2::messages::NewBlock::decode(data)?;
302                        L2Message::NewBlock(decoded)
303                    }
304                    BatchSealed::CODE => {
305                        let decoded = l2::messages::BatchSealed::decode(data)?;
306                        L2Message::BatchSealed(decoded)
307                    }
308                    _ => return Err(RLPDecodeError::MalformedData),
309                },
310            ));
311
312            #[cfg(not(feature = "l2"))]
313            Err(RLPDecodeError::MalformedData)
314        }
315    }
316
317    pub fn encode(
318        &self,
319        buf: &mut dyn BufMut,
320        eth_version: EthCapVersion,
321    ) -> Result<(), RLPEncodeError> {
322        self.code(eth_version).encode(buf);
323        match self {
324            Message::Hello(msg) => msg.encode(buf),
325            Message::Disconnect(msg) => msg.encode(buf),
326            Message::Ping(msg) => msg.encode(buf),
327            Message::Pong(msg) => msg.encode(buf),
328            Message::Status68(msg) => msg.encode(buf),
329            Message::Status69(msg) => msg.encode(buf),
330            Message::Status70(msg) => msg.encode(buf),
331            Message::Status71(msg) => msg.encode(buf),
332            Message::Transactions(msg) => msg.encode(buf),
333            Message::GetBlockHeaders(msg) => msg.encode(buf),
334            Message::BlockHeaders(msg) => msg.encode(buf),
335            Message::GetBlockBodies(msg) => msg.encode(buf),
336            Message::BlockBodies(msg) => msg.encode(buf),
337            Message::NewPooledTransactionHashes(msg) => msg.encode(buf),
338            Message::GetPooledTransactions(msg) => msg.encode(buf),
339            Message::PooledTransactions(msg) => msg.encode(buf),
340            Message::GetReceipts68(msg) => msg.encode(buf),
341            Message::GetReceipts69(msg) => msg.encode(buf),
342            Message::GetReceipts70(msg) => msg.encode(buf),
343            Message::Receipts68(msg) => msg.encode(buf),
344            Message::Receipts69(msg) => msg.encode(buf),
345            Message::Receipts70(msg) => msg.encode(buf),
346            Message::BlockRangeUpdate(msg) => msg.encode(buf),
347            Message::GetBlockAccessLists(msg) => msg.encode(buf),
348            Message::BlockAccessLists(msg) => msg.encode(buf),
349            Message::GetAccountRange(msg) => msg.encode(buf),
350            Message::AccountRange(msg) => msg.encode(buf),
351            Message::GetStorageRanges(msg) => msg.encode(buf),
352            Message::StorageRanges(msg) => msg.encode(buf),
353            Message::GetByteCodes(msg) => msg.encode(buf),
354            Message::ByteCodes(msg) => msg.encode(buf),
355            Message::GetTrieNodes(msg) => msg.encode(buf),
356            Message::TrieNodes(msg) => msg.encode(buf),
357            #[cfg(feature = "l2")]
358            Message::L2(l2_msg) => match l2_msg {
359                L2Message::BatchSealed(msg) => msg.encode(buf),
360                L2Message::NewBlock(msg) => msg.encode(buf),
361            },
362        }
363    }
364
365    pub fn request_id(&self) -> Option<u64> {
366        match self {
367            Message::GetBlockHeaders(message) => Some(message.id),
368            Message::GetBlockBodies(message) => Some(message.id),
369            Message::GetPooledTransactions(message) => Some(message.id),
370            Message::GetReceipts68(message) => Some(message.id),
371            Message::GetReceipts69(message) => Some(message.id),
372            Message::GetReceipts70(message) => Some(message.id),
373            Message::GetAccountRange(message) => Some(message.id),
374            Message::GetStorageRanges(message) => Some(message.id),
375            Message::GetByteCodes(message) => Some(message.id),
376            Message::GetTrieNodes(message) => Some(message.id),
377            Message::BlockHeaders(message) => Some(message.id),
378            Message::BlockBodies(message) => Some(message.id),
379            Message::PooledTransactions(message) => Some(message.id),
380            Message::Receipts68(message) => Some(message.id),
381            Message::Receipts69(message) => Some(message.id),
382            Message::Receipts70(message) => Some(message.id),
383            Message::AccountRange(message) => Some(message.id),
384            Message::StorageRanges(message) => Some(message.id),
385            Message::ByteCodes(message) => Some(message.id),
386            Message::TrieNodes(message) => Some(message.id),
387            Message::GetBlockAccessLists(message) => Some(message.id),
388            Message::BlockAccessLists(message) => Some(message.id),
389            // The rest of the message types does not have a request id.
390            Message::Hello(_)
391            | Message::Disconnect(_)
392            | Message::Ping(_)
393            | Message::Pong(_)
394            | Message::Status68(_)
395            | Message::Status69(_)
396            | Message::Status70(_)
397            | Message::Status71(_)
398            | Message::Transactions(_)
399            | Message::NewPooledTransactionHashes(_)
400            | Message::BlockRangeUpdate(_) => None,
401            #[cfg(feature = "l2")]
402            Message::L2(_) => None,
403        }
404    }
405}
406
407impl Message {
408    /// Returns a short, stable label suitable for use as a Prometheus metric label value.
409    pub fn metric_label(&self) -> &'static str {
410        match self {
411            Message::Hello(_) => "Hello",
412            Message::Disconnect(_) => "Disconnect",
413            Message::Ping(_) => "Ping",
414            Message::Pong(_) => "Pong",
415            Message::Status68(_) => "Status",
416            Message::Status69(_) => "Status",
417            Message::Status70(_) => "Status",
418            Message::Status71(_) => "Status",
419            Message::GetBlockHeaders(_) => "GetBlockHeaders",
420            Message::BlockHeaders(_) => "BlockHeaders",
421            Message::Transactions(_) => "Transactions",
422            Message::GetBlockBodies(_) => "GetBlockBodies",
423            Message::BlockBodies(_) => "BlockBodies",
424            Message::NewPooledTransactionHashes(_) => "NewPooledTransactionHashes",
425            Message::GetPooledTransactions(_) => "GetPooledTransactions",
426            Message::PooledTransactions(_) => "PooledTransactions",
427            Message::GetReceipts68(_) => "GetReceipts",
428            Message::GetReceipts69(_) => "GetReceipts",
429            Message::GetReceipts70(_) => "GetReceipts",
430            Message::Receipts68(_) => "Receipts",
431            Message::Receipts69(_) => "Receipts",
432            Message::Receipts70(_) => "Receipts",
433            Message::BlockRangeUpdate(_) => "BlockRangeUpdate",
434            Message::GetBlockAccessLists(_) => "GetBlockAccessLists",
435            Message::BlockAccessLists(_) => "BlockAccessLists",
436            Message::GetAccountRange(_) => "GetAccountRange",
437            Message::AccountRange(_) => "AccountRange",
438            Message::GetStorageRanges(_) => "GetStorageRanges",
439            Message::StorageRanges(_) => "StorageRanges",
440            Message::GetByteCodes(_) => "GetByteCodes",
441            Message::ByteCodes(_) => "ByteCodes",
442            Message::GetTrieNodes(_) => "GetTrieNodes",
443            Message::TrieNodes(_) => "TrieNodes",
444            #[cfg(feature = "l2")]
445            Message::L2(l2_msg) => match l2_msg {
446                L2Message::NewBlock(_) => "L2NewBlock",
447                L2Message::BatchSealed(_) => "L2BatchSealed",
448            },
449        }
450    }
451}
452
453impl Display for Message {
454    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
455        match self {
456            Message::Hello(_) => "p2p:Hello".fmt(f),
457            Message::Disconnect(_) => "p2p:Disconnect".fmt(f),
458            Message::Ping(_) => "p2p:Ping".fmt(f),
459            Message::Pong(_) => "p2p:Pong".fmt(f),
460            Message::Status68(_) => "eth:Status(68)".fmt(f),
461            Message::Status69(_) => "eth:Status(69)".fmt(f),
462            Message::Status70(_) => "eth:Status(70)".fmt(f),
463            Message::Status71(_) => "eth:Status(71)".fmt(f),
464            Message::GetBlockHeaders(_) => "eth:getBlockHeaders".fmt(f),
465            Message::BlockHeaders(_) => "eth:BlockHeaders".fmt(f),
466            Message::BlockBodies(_) => "eth:BlockBodies".fmt(f),
467            Message::NewPooledTransactionHashes(_) => "eth:NewPooledTransactionHashes".fmt(f),
468            Message::GetPooledTransactions(_) => "eth::GetPooledTransactions".fmt(f),
469            Message::PooledTransactions(_) => "eth::PooledTransactions".fmt(f),
470            Message::Transactions(_) => "eth:TransactionsMessage".fmt(f),
471            Message::GetBlockBodies(_) => "eth:GetBlockBodies".fmt(f),
472            Message::GetReceipts68(_) => "eth:GetReceipts(68)".fmt(f),
473            Message::GetReceipts69(_) => "eth:GetReceipts(69)".fmt(f),
474            Message::GetReceipts70(_) => "eth:GetReceipts(70)".fmt(f),
475            Message::Receipts68(_) => "eth:Receipts(68)".fmt(f),
476            Message::Receipts69(_) => "eth:Receipts(69)".fmt(f),
477            Message::Receipts70(_) => "eth:Receipts(70)".fmt(f),
478            Message::BlockRangeUpdate(_) => "eth:BlockRangeUpdate".fmt(f),
479            Message::GetBlockAccessLists(_) => "eth:GetBlockAccessLists".fmt(f),
480            Message::BlockAccessLists(_) => "eth:BlockAccessLists".fmt(f),
481            Message::GetAccountRange(_) => "snap:GetAccountRange".fmt(f),
482            Message::AccountRange(_) => "snap:AccountRange".fmt(f),
483            Message::GetStorageRanges(_) => "snap:GetStorageRanges".fmt(f),
484            Message::StorageRanges(_) => "snap:StorageRanges".fmt(f),
485            Message::GetByteCodes(_) => "snap:GetByteCodes".fmt(f),
486            Message::ByteCodes(_) => "snap:ByteCodes".fmt(f),
487            Message::GetTrieNodes(_) => "snap:GetTrieNodes".fmt(f),
488            Message::TrieNodes(_) => "snap:TrieNodes".fmt(f),
489            #[cfg(feature = "l2")]
490            Message::L2(l2_msg) => match l2_msg {
491                L2Message::BatchSealed(_) => "based:BatchSealed".fmt(f),
492                L2Message::NewBlock(_) => "based:NewBlock".fmt(f),
493            },
494        }
495    }
496}