avail_rust_core/
header.rs1use codec::{Compact, Decode, Encode};
2use primitive_types::H256;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use subxt_core::config::{Hasher, Header, substrate::BlakeTwo256};
5
6pub use subxt_core::config::substrate::{Digest, DigestItem};
7
8#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
9#[serde(rename_all = "camelCase")]
10pub struct AvailHeader {
11 pub parent_hash: H256,
12 #[serde(serialize_with = "number_to_hex", deserialize_with = "number_from_hex")]
13 #[codec(compact)]
14 pub number: u32,
15 pub state_root: H256,
16 pub extrinsics_root: H256,
17 pub digest: Digest,
18 pub extension: HeaderExtension,
19}
20
21impl AvailHeader {
22 pub fn data_root(&self) -> H256 {
23 match &self.extension {
24 HeaderExtension::V3(ext) => ext.commitment.data_root,
25 }
26 }
27
28 pub fn hash(&self) -> H256 {
29 BlakeTwo256::hash_of(self)
30 }
31}
32
33impl Header for AvailHeader {
34 type Hasher = BlakeTwo256;
35 type Number = u32;
36
37 fn number(&self) -> Self::Number {
38 self.number
39 }
40
41 fn hash(&self) -> <Self::Hasher as Hasher>::Output {
42 self.hash()
43 }
44}
45
46fn number_to_hex<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
47where
48 S: Serializer,
49{
50 let hex_string = format!("{:X}", value);
51 serializer.serialize_str(&hex_string)
52}
53
54fn number_from_hex<'de, D>(deserializer: D) -> Result<u32, D::Error>
55where
56 D: Deserializer<'de>,
57{
58 let buf = String::deserialize(deserializer)?;
59 let without_prefix = buf.trim_start_matches("0x");
60 let result = u32::from_str_radix(without_prefix, 16);
61 match result {
62 Ok(res) => Ok(res),
63 Err(err) => Err(serde::de::Error::custom(err)),
64 }
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
68#[repr(u8)]
69pub enum HeaderExtension {
70 V3(V3HeaderExtension) = 2,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize, Default)]
74#[serde(rename_all = "camelCase")]
75pub struct V3HeaderExtension {
76 pub app_lookup: CompactDataLookup,
77 pub commitment: KateCommitment,
78}
79impl Encode for V3HeaderExtension {
80 fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
81 self.app_lookup.encode_to(dest);
82 self.commitment.encode_to(dest);
83 }
84}
85impl Decode for V3HeaderExtension {
86 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
87 let app_lookup = Decode::decode(input)?;
88 let commitment = Decode::decode(input)?;
89 Ok(Self { app_lookup, commitment })
90 }
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, Default)]
94#[serde(rename_all = "camelCase")]
95pub struct CompactDataLookup {
96 pub size: u32,
98 pub index: Vec<DataLookupItem>,
99}
100impl Encode for CompactDataLookup {
101 fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
102 Compact(self.size).encode_to(dest);
103 self.index.encode_to(dest);
104 }
105}
106impl Decode for CompactDataLookup {
107 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
108 let size = Compact::<u32>::decode(input)?.0;
109 let index = Decode::decode(input)?;
110 Ok(Self { size, index })
111 }
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
115#[serde(rename_all = "camelCase")]
116pub struct DataLookupItem {
117 pub app_id: u32,
119 pub start: u32,
121}
122impl Encode for DataLookupItem {
123 fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
124 Compact(self.app_id).encode_to(dest);
125 Compact(self.start).encode_to(dest);
126 }
127}
128impl Decode for DataLookupItem {
129 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
130 let app_id = Compact::<u32>::decode(input)?.0;
131 let start = Compact::<u32>::decode(input)?.0;
132 Ok(Self { app_id, start })
133 }
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, Default)]
137#[serde(rename_all = "camelCase")]
138pub struct KateCommitment {
139 pub rows: u16,
141 pub cols: u16,
143 pub commitment: Vec<u8>,
144 pub data_root: H256,
145}
146impl Encode for KateCommitment {
147 fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
148 Compact(self.rows).encode_to(dest);
149 Compact(self.cols).encode_to(dest);
150 self.commitment.encode_to(dest);
151 self.data_root.encode_to(dest);
152 }
153}
154impl Decode for KateCommitment {
155 fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
156 let rows = Compact::<u16>::decode(input)?.0;
157 let cols = Compact::<u16>::decode(input)?.0;
158 let commitment = Decode::decode(input)?;
159 let data_root = Decode::decode(input)?;
160 Ok(Self { rows, cols, commitment, data_root })
161 }
162}