alloy_rpc_types_beacon/
header.rs1use alloy_primitives::{Bytes, B256};
6use serde::{Deserialize, Serialize};
7use serde_with::{serde_as, DisplayFromStr};
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
11pub struct HeadersResponse {
12 pub execution_optimistic: bool,
15 pub finalized: bool,
19 pub data: Vec<HeaderData>,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
25pub struct HeaderResponse {
26 pub execution_optimistic: bool,
29 pub finalized: bool,
33 pub data: HeaderData,
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
39pub struct HeaderData {
40 pub root: B256,
42 pub canonical: bool,
44 pub header: Header,
46}
47
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
50pub struct Header {
51 pub message: BeaconBlockHeader,
53 pub signature: Bytes,
55}
56
57#[serde_as]
61#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
62#[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))]
63pub struct BeaconBlockHeader {
64 #[serde_as(as = "DisplayFromStr")]
66 pub slot: u64,
67 #[serde_as(as = "DisplayFromStr")]
69 pub proposer_index: u64,
70 pub parent_root: B256,
72 pub state_root: B256,
74 pub body_root: B256,
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[test]
83 fn serde_headers_response() {
84 let s = r#"{
85 "execution_optimistic": false,
86 "finalized": false,
87 "data": [
88 {
89 "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
90 "canonical": true,
91 "header": {
92 "message": {
93 "slot": "1",
94 "proposer_index": "1",
95 "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
96 "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
97 "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
98 },
99 "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"
100 }
101 }
102 ]
103 }"#;
104 let _header_response: HeadersResponse = serde_json::from_str(s).unwrap();
105 }
106
107 #[test]
108 fn serde_header_response() {
109 let s = r#"{
110 "execution_optimistic": false,
111 "finalized": false,
112 "data": {
113 "root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
114 "canonical": true,
115 "header": {
116 "message": {
117 "slot": "1",
118 "proposer_index": "1",
119 "parent_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
120 "state_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2",
121 "body_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"
122 },
123 "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"
124 }
125 }
126 }"#;
127 let _header_response: HeaderResponse = serde_json::from_str(s).unwrap();
128 }
129
130 #[cfg(feature = "ssz")]
131 mod ssz_tests {
132 use super::*;
133 use ssz::{Decode, Encode};
134
135 #[test]
136 fn ssz_roundtrip_beacon_block_header() {
137 let header = BeaconBlockHeader {
138 slot: 12345,
139 proposer_index: 678,
140 parent_root: B256::repeat_byte(0x11),
141 state_root: B256::repeat_byte(0x22),
142 body_root: B256::repeat_byte(0x33),
143 };
144 let encoded = header.as_ssz_bytes();
145 let decoded = BeaconBlockHeader::from_ssz_bytes(&encoded).unwrap();
146 assert_eq!(header, decoded);
147 }
148 }
149}