hotshot_query_service/availability/
data_source.rs1use std::{
14 cmp::Ordering,
15 ops::{Bound, RangeBounds},
16};
17
18use async_trait::async_trait;
19use derivative::Derivative;
20use derive_more::{Display, From};
21use futures::{
22 future::Future,
23 stream::{BoxStream, StreamExt},
24};
25use hotshot_types::{
26 data::{VidCommitment, VidShare},
27 simple_certificate::CertificatePair,
28 traits::node_implementation::NodeType,
29};
30
31use super::{
32 fetch::Fetch,
33 query_data::{
34 BlockHash, BlockQueryData, LeafHash, LeafQueryData, PayloadMetadata, PayloadQueryData,
35 QueryableHeader, QueryablePayload, TransactionHash, VidCommonMetadata, VidCommonQueryData,
36 },
37 BlockWithTransaction,
38};
39use crate::{types::HeightIndexed, Header, Payload};
40
41#[derive(Derivative, From, Display)]
42#[derivative(Ord = "feature_allow_slow_enum")]
43#[derivative(
44 Copy(bound = ""),
45 Debug(bound = ""),
46 PartialEq(bound = ""),
47 Eq(bound = ""),
48 Ord(bound = ""),
49 Hash(bound = "")
50)]
51pub enum LeafId<Types: NodeType> {
52 #[display("{_0}")]
53 Number(usize),
54 #[display("{_0}")]
55 Hash(LeafHash<Types>),
56}
57
58impl<Types: NodeType> Clone for LeafId<Types> {
59 fn clone(&self) -> Self {
60 *self
61 }
62}
63
64impl<Types: NodeType> PartialOrd for LeafId<Types> {
65 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
66 Some(self.cmp(other))
67 }
68}
69
70#[derive(Derivative, From, Display)]
71#[derivative(Ord = "feature_allow_slow_enum")]
72#[derivative(
73 Copy(bound = ""),
74 Debug(bound = ""),
75 PartialEq(bound = ""),
76 Eq(bound = ""),
77 Ord(bound = ""),
78 Hash(bound = "")
79)]
80pub enum BlockId<Types: NodeType> {
81 #[display("{_0}")]
82 Number(usize),
83 #[display("{_0}")]
84 Hash(BlockHash<Types>),
85 #[display("{_0}")]
86 #[from(ignore)]
87 PayloadHash(VidCommitment),
88}
89
90impl<Types: NodeType> Clone for BlockId<Types> {
91 fn clone(&self) -> Self {
92 *self
93 }
94}
95
96impl<Types: NodeType> PartialOrd for BlockId<Types> {
97 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
98 Some(self.cmp(other))
99 }
100}
101
102pub type FetchStream<T> = BoxStream<'static, Fetch<T>>;
103
104#[async_trait]
132pub trait AvailabilityDataSource<Types: NodeType>
133where
134 Header<Types>: QueryableHeader<Types>,
135 Payload<Types>: QueryablePayload<Types>,
136{
137 async fn get_leaf<ID>(&self, id: ID) -> Fetch<LeafQueryData<Types>>
138 where
139 ID: Into<LeafId<Types>> + Send + Sync;
140
141 async fn get_header<ID>(&self, id: ID) -> Fetch<Header<Types>>
142 where
143 ID: Into<BlockId<Types>> + Send + Sync;
144
145 async fn get_block<ID>(&self, id: ID) -> Fetch<BlockQueryData<Types>>
146 where
147 ID: Into<BlockId<Types>> + Send + Sync;
148
149 async fn get_payload<ID>(&self, id: ID) -> Fetch<PayloadQueryData<Types>>
150 where
151 ID: Into<BlockId<Types>> + Send + Sync;
152
153 async fn get_payload_metadata<ID>(&self, id: ID) -> Fetch<PayloadMetadata<Types>>
154 where
155 ID: Into<BlockId<Types>> + Send + Sync;
156
157 async fn get_vid_common<ID>(&self, id: ID) -> Fetch<VidCommonQueryData<Types>>
158 where
159 ID: Into<BlockId<Types>> + Send + Sync;
160
161 async fn get_vid_common_metadata<ID>(&self, id: ID) -> Fetch<VidCommonMetadata<Types>>
162 where
163 ID: Into<BlockId<Types>> + Send + Sync;
164
165 async fn get_leaf_range<R>(&self, range: R) -> FetchStream<LeafQueryData<Types>>
166 where
167 R: RangeBounds<usize> + Send + 'static;
168
169 async fn get_header_range<R>(&self, range: R) -> FetchStream<Header<Types>>
170 where
171 R: RangeBounds<usize> + Send + 'static;
172
173 async fn get_block_range<R>(&self, range: R) -> FetchStream<BlockQueryData<Types>>
174 where
175 R: RangeBounds<usize> + Send + 'static;
176
177 async fn get_payload_range<R>(&self, range: R) -> FetchStream<PayloadQueryData<Types>>
178 where
179 R: RangeBounds<usize> + Send + 'static;
180
181 async fn get_payload_metadata_range<R>(&self, range: R) -> FetchStream<PayloadMetadata<Types>>
182 where
183 R: RangeBounds<usize> + Send + 'static;
184
185 async fn get_vid_common_range<R>(&self, range: R) -> FetchStream<VidCommonQueryData<Types>>
186 where
187 R: RangeBounds<usize> + Send + 'static;
188
189 async fn get_vid_common_metadata_range<R>(
190 &self,
191 range: R,
192 ) -> FetchStream<VidCommonMetadata<Types>>
193 where
194 R: RangeBounds<usize> + Send + 'static;
195
196 async fn get_leaf_range_rev(
197 &self,
198 start: Bound<usize>,
199 end: usize,
200 ) -> FetchStream<LeafQueryData<Types>>;
201
202 async fn get_block_range_rev(
203 &self,
204 start: Bound<usize>,
205 end: usize,
206 ) -> FetchStream<BlockQueryData<Types>>;
207
208 async fn get_payload_range_rev(
209 &self,
210 start: Bound<usize>,
211 end: usize,
212 ) -> FetchStream<PayloadQueryData<Types>>;
213
214 async fn get_payload_metadata_range_rev(
215 &self,
216 start: Bound<usize>,
217 end: usize,
218 ) -> FetchStream<PayloadMetadata<Types>>;
219
220 async fn get_vid_common_range_rev(
221 &self,
222 start: Bound<usize>,
223 end: usize,
224 ) -> FetchStream<VidCommonQueryData<Types>>;
225
226 async fn get_vid_common_metadata_range_rev(
227 &self,
228 start: Bound<usize>,
229 end: usize,
230 ) -> FetchStream<VidCommonMetadata<Types>>;
231
232 async fn get_block_containing_transaction(
233 &self,
234 h: TransactionHash<Types>,
235 ) -> Fetch<BlockWithTransaction<Types>>;
236
237 async fn subscribe_blocks(&self, from: usize) -> BoxStream<'static, BlockQueryData<Types>> {
238 self.get_block_range(from..)
239 .await
240 .then(Fetch::resolve)
241 .boxed()
242 }
243
244 async fn subscribe_payloads(&self, from: usize) -> BoxStream<'static, PayloadQueryData<Types>> {
245 self.get_payload_range(from..)
246 .await
247 .then(Fetch::resolve)
248 .boxed()
249 }
250
251 async fn subscribe_payload_metadata(
252 &self,
253 from: usize,
254 ) -> BoxStream<'static, PayloadMetadata<Types>> {
255 self.get_payload_metadata_range(from..)
256 .await
257 .then(Fetch::resolve)
258 .boxed()
259 }
260
261 async fn subscribe_leaves(&self, from: usize) -> BoxStream<'static, LeafQueryData<Types>> {
262 self.get_leaf_range(from..)
263 .await
264 .then(Fetch::resolve)
265 .boxed()
266 }
267
268 async fn subscribe_headers(&self, from: usize) -> BoxStream<'static, Header<Types>> {
269 self.get_header_range(from..)
270 .await
271 .then(Fetch::resolve)
272 .boxed()
273 }
274
275 async fn subscribe_vid_common(
276 &self,
277 from: usize,
278 ) -> BoxStream<'static, VidCommonQueryData<Types>> {
279 self.get_vid_common_range(from..)
280 .await
281 .then(Fetch::resolve)
282 .boxed()
283 }
284
285 async fn subscribe_vid_common_metadata(
286 &self,
287 from: usize,
288 ) -> BoxStream<'static, VidCommonMetadata<Types>> {
289 self.get_vid_common_metadata_range(from..)
290 .await
291 .then(Fetch::resolve)
292 .boxed()
293 }
294}
295
296#[derive(Clone, Debug)]
305pub struct BlockInfo<Types: NodeType> {
306 pub leaf: LeafQueryData<Types>,
307 pub block: Option<BlockQueryData<Types>>,
308 pub vid_common: Option<VidCommonQueryData<Types>>,
309 pub vid_share: Option<VidShare>,
310 pub qc_chain: Option<[CertificatePair<Types>; 2]>,
311}
312
313impl<Types: NodeType> From<LeafQueryData<Types>> for BlockInfo<Types> {
314 fn from(leaf: LeafQueryData<Types>) -> Self {
315 Self::new(leaf, None, None, None)
316 }
317}
318
319impl<Types: NodeType> HeightIndexed for BlockInfo<Types> {
320 fn height(&self) -> u64 {
321 self.leaf.height()
322 }
323}
324
325impl<Types: NodeType> BlockInfo<Types> {
326 pub fn new(
327 leaf: LeafQueryData<Types>,
328 block: Option<BlockQueryData<Types>>,
329 vid_common: Option<VidCommonQueryData<Types>>,
330 vid_share: Option<VidShare>,
331 ) -> Self {
332 Self {
333 leaf,
334 block,
335 vid_common,
336 vid_share,
337 qc_chain: None,
338 }
339 }
340
341 pub fn with_qc_chain(mut self, qc_chain: [CertificatePair<Types>; 2]) -> Self {
342 self.qc_chain = Some(qc_chain);
343 self
344 }
345}
346
347pub trait UpdateAvailabilityData<Types: NodeType> {
348 fn append(&self, info: BlockInfo<Types>) -> impl Send + Future<Output = anyhow::Result<()>>;
350}