avail_rust_core/
header.rs

1use 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, Default, 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
93impl Default for HeaderExtension {
94	fn default() -> Self {
95		Self::V3(Default::default())
96	}
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, Default)]
100#[serde(rename_all = "camelCase")]
101pub struct CompactDataLookup {
102	// Compact
103	pub size: u32,
104	pub index: Vec<DataLookupItem>,
105}
106impl Encode for CompactDataLookup {
107	fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
108		Compact(self.size).encode_to(dest);
109		self.index.encode_to(dest);
110	}
111}
112impl Decode for CompactDataLookup {
113	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
114		let size = Compact::<u32>::decode(input)?.0;
115		let index = Decode::decode(input)?;
116		Ok(Self { size, index })
117	}
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
121#[serde(rename_all = "camelCase")]
122pub struct DataLookupItem {
123	// Compact
124	pub app_id: u32,
125	// Compact
126	pub start: u32,
127}
128impl Encode for DataLookupItem {
129	fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
130		Compact(self.app_id).encode_to(dest);
131		Compact(self.start).encode_to(dest);
132	}
133}
134impl Decode for DataLookupItem {
135	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
136		let app_id = Compact::<u32>::decode(input)?.0;
137		let start = Compact::<u32>::decode(input)?.0;
138		Ok(Self { app_id, start })
139	}
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize, Default)]
143#[serde(rename_all = "camelCase")]
144pub struct KateCommitment {
145	// Compact
146	pub rows: u16,
147	// Compact
148	pub cols: u16,
149	pub commitment: Vec<u8>,
150	pub data_root: H256,
151}
152impl Encode for KateCommitment {
153	fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
154		Compact(self.rows).encode_to(dest);
155		Compact(self.cols).encode_to(dest);
156		self.commitment.encode_to(dest);
157		self.data_root.encode_to(dest);
158	}
159}
160impl Decode for KateCommitment {
161	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
162		let rows = Compact::<u16>::decode(input)?.0;
163		let cols = Compact::<u16>::decode(input)?.0;
164		let commitment = Decode::decode(input)?;
165		let data_root = Decode::decode(input)?;
166		Ok(Self { rows, cols, commitment, data_root })
167	}
168}