Skip to main content

arb_sequencer_network/sequencer/
feed.rs

1use std::str::FromStr;
2
3use alloy_core::hex::FromHex;
4use alloy_primitives::{Address, FixedBytes, U256};
5use serde::*;
6use serde_json::Value;
7#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct Root {
10    pub version: u8,
11    pub messages: Option<Vec<BroadcastFeedMessage>>,
12}
13
14#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct BroadcastFeedMessage {
17    pub sequence_number: u64,
18    #[serde(rename = "message")]
19    pub message_with_meta_data: MessageWithMetadata,
20}
21
22#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct MessageWithMetadata {
25    #[serde(rename = "message")]
26    pub l1_incoming_message: L1IncomingMessage,
27    pub delayed_messages_read: u64,
28}
29#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct BatchDataStats {
31    #[serde(rename = "Length")]
32    pub length: u64,
33    #[serde(rename = "NonZeros")]
34    pub non_zeros: u64,
35}
36
37#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct L1IncomingMessage {
40    pub header: Header,
41    #[serde(rename = "l2Msg")]
42    pub l2msg: String,
43    #[serde(rename = "batchGasCost")]
44    pub legacy_batch_gas_cost: Option<u64>,
45    #[serde(rename = "batchDataTokens")]
46    pub batch_data_stats: Option<BatchDataStats>,
47}
48
49#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
50#[serde(rename_all = "camelCase")]
51pub struct Header {
52    pub kind: u8,
53    pub sender: String,
54    pub block_number: u64,
55    pub timestamp: u64,
56    pub request_id: Value,
57    pub base_fee_l1: Value,
58}
59#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct L1Header {
61    pub kind: u8,
62    pub block_number: u64,
63    pub timestamp: u64,
64    pub request_id: Option<FixedBytes<32>>,
65    pub base_fee_l1: Option<U256>,
66    pub poster: Address,
67    pub delayed_messages_read: u64,
68}
69impl L1Header {
70    pub fn from_header(header: &Header, delayed_messages_read: u64) -> Result<Self, String> {
71        let poster = Address::from_str(&header.sender)
72            .map_err(|e| format!("failed to parse poster address: {}", e))?;
73        let request_id_str = header.request_id.as_str();
74        let request_id = match request_id_str {
75            Some(s) => {
76                let bytes = <[u8; 32]>::from_hex(s.trim_start_matches("0x"))
77                    .map_err(|e| format!("failed to parse request_id hex string '{}': {}", s, e))?;
78                Some(FixedBytes::from(bytes))
79            }
80            None => None,
81        };
82        let base_fee_l1_u64 = header.base_fee_l1.as_u64();
83        let base_fee_l1 = base_fee_l1_u64.map(|x| U256::from(x));
84        Ok(L1Header {
85            kind: header.kind,
86            block_number: header.block_number,
87            timestamp: header.timestamp,
88            request_id,
89            base_fee_l1,
90            poster,
91            delayed_messages_read,
92        })
93    }
94}
95
96#[repr(u8)]
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub enum MessageType {
99    L2Message = 3,
100    EndOfBlock = 6,
101    L2FundedByL1 = 7,
102    RollupEvent = 8,
103    SubmitRetryable = 9,
104    BatchForGasEstimation = 10,
105    Initialize = 11,
106    EthDeposit = 12,
107    BatchPostingReport = 13,
108    Invalid = 0xFF,
109}
110impl MessageType {
111    pub fn from_u8(value: u8) -> Self {
112        match value {
113            3 => MessageType::L2Message,
114            6 => MessageType::EndOfBlock,
115            7 => MessageType::L2FundedByL1,
116            8 => MessageType::RollupEvent,
117            9 => MessageType::SubmitRetryable,
118            10 => MessageType::BatchForGasEstimation,
119            11 => MessageType::Initialize,
120            12 => MessageType::EthDeposit,
121            13 => MessageType::BatchPostingReport,
122            _ => MessageType::Invalid,
123        }
124    }
125    #[allow(dead_code)]
126    pub fn to_u8(&self) -> u8 {
127        match self {
128            MessageType::L2Message => 3,
129            MessageType::EndOfBlock => 6,
130            MessageType::L2FundedByL1 => 7,
131            MessageType::RollupEvent => 8,
132            MessageType::SubmitRetryable => 9,
133            MessageType::BatchForGasEstimation => 10,
134            MessageType::Initialize => 11,
135            MessageType::EthDeposit => 12,
136            MessageType::BatchPostingReport => 13,
137            MessageType::Invalid => 0xFF,
138        }
139    }
140}