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