1use crate::role::Roles;
23
24use bitflags::bitflags;
25use codec::{Decode, Encode, Error, Input, Output};
26pub use generic::{BlockAnnounce, FromBlock};
27use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};
28
29pub type BlockRequest<B> =
31	generic::BlockRequest<<B as BlockT>::Hash, <<B as BlockT>::Header as HeaderT>::Number>;
32
33pub type BlockData<B> =
35	generic::BlockData<<B as BlockT>::Header, <B as BlockT>::Hash, <B as BlockT>::Extrinsic>;
36
37pub type BlockResponse<B> =
39	generic::BlockResponse<<B as BlockT>::Header, <B as BlockT>::Hash, <B as BlockT>::Extrinsic>;
40
41bitflags! {
43	pub struct BlockAttributes: u8 {
45		const HEADER = 0b00000001;
47		const BODY = 0b00000010;
49		const RECEIPT = 0b00000100;
51		const MESSAGE_QUEUE = 0b00001000;
53		const JUSTIFICATION = 0b00010000;
55		const INDEXED_BODY = 0b00100000;
57	}
58}
59
60impl BlockAttributes {
61	pub fn to_be_u32(&self) -> u32 {
64		u32::from_be_bytes([self.bits(), 0, 0, 0])
65	}
66
67	pub fn from_be_u32(encoded: u32) -> Result<Self, Error> {
69		Self::from_bits(encoded.to_be_bytes()[0])
70			.ok_or_else(|| Error::from("Invalid BlockAttributes"))
71	}
72}
73
74impl Encode for BlockAttributes {
75	fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
76		dest.push_byte(self.bits())
77	}
78}
79
80impl codec::EncodeLike for BlockAttributes {}
81
82impl Decode for BlockAttributes {
83	fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
84		Self::from_bits(input.read_byte()?).ok_or_else(|| Error::from("Invalid bytes"))
85	}
86}
87
88#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)]
89pub enum Direction {
91	Ascending = 0,
93	Descending = 1,
95}
96
97#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)]
99pub enum BlockState {
100	Normal,
102	Best,
104}
105
106#[derive(Debug)]
108pub struct AnnouncementSummary<H: HeaderT> {
109	pub block_hash: H::Hash,
110	pub number: H::Number,
111	pub parent_hash: H::Hash,
112	pub state: Option<BlockState>,
113}
114
115impl<H: HeaderT> BlockAnnounce<H> {
116	pub fn summary(&self) -> AnnouncementSummary<H> {
117		AnnouncementSummary {
118			block_hash: self.header.hash(),
119			number: *self.header.number(),
120			parent_hash: *self.header.parent_hash(),
121			state: self.state,
122		}
123	}
124}
125
126pub mod generic {
128	use super::{BlockAttributes, BlockState, Direction};
129	use crate::message::RequestId;
130	use codec::{Decode, Encode, Input, Output};
131	use sp_runtime::{EncodedJustification, Justifications};
132
133	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
135	pub struct BlockData<Header, Hash, Extrinsic> {
136		pub hash: Hash,
138		pub header: Option<Header>,
140		pub body: Option<Vec<Extrinsic>>,
142		pub indexed_body: Option<Vec<Vec<u8>>>,
144		pub receipt: Option<Vec<u8>>,
146		pub message_queue: Option<Vec<u8>>,
148		pub justification: Option<EncodedJustification>,
150		pub justifications: Option<Justifications>,
152	}
153
154	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
156	pub struct BlockRequest<Hash, Number> {
157		pub id: RequestId,
159		pub fields: BlockAttributes,
161		pub from: FromBlock<Hash, Number>,
163		pub direction: Direction,
165		pub max: Option<u32>,
168	}
169
170	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
172	pub enum FromBlock<Hash, Number> {
173		Hash(Hash),
175		Number(Number),
177	}
178
179	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
181	pub struct BlockResponse<Header, Hash, Extrinsic> {
182		pub id: RequestId,
184		pub blocks: Vec<BlockData<Header, Hash, Extrinsic>>,
186	}
187
188	#[derive(Debug, PartialEq, Eq, Clone)]
190	pub struct BlockAnnounce<H> {
191		pub header: H,
193		pub state: Option<BlockState>,
195		pub data: Option<Vec<u8>>,
197	}
198
199	impl<H: Encode> Encode for BlockAnnounce<H> {
203		fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
204			self.header.encode_to(dest);
205			if let Some(state) = &self.state {
206				state.encode_to(dest);
207			}
208			if let Some(data) = &self.data {
209				data.encode_to(dest)
210			}
211		}
212	}
213
214	impl<H: Decode> Decode for BlockAnnounce<H> {
215		fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
216			let header = H::decode(input)?;
217			let state = BlockState::decode(input).ok();
218			let data = Vec::decode(input).ok();
219			Ok(Self { header, state, data })
220		}
221	}
222}
223
224#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
226pub struct BlockAnnouncesHandshake<B: BlockT> {
227	pub roles: Roles,
229	pub best_number: NumberFor<B>,
231	pub best_hash: B::Hash,
233	pub genesis_hash: B::Hash,
235}
236
237impl<B: BlockT> BlockAnnouncesHandshake<B> {
238	pub fn build(
239		roles: Roles,
240		best_number: NumberFor<B>,
241		best_hash: B::Hash,
242		genesis_hash: B::Hash,
243	) -> Self {
244		Self { genesis_hash, roles, best_number, best_hash }
245	}
246}