hotshot_query_service/availability/
data_source.rs1use std::ops::{Bound, RangeBounds};
14
15use async_trait::async_trait;
16use futures::{
17 future::Future,
18 stream::{BoxStream, StreamExt},
19};
20pub use hotshot_new_protocol::message::Certificate2;
21pub use hotshot_query_service_types::availability::{BlockId, LeafId};
22use hotshot_types::{
23 data::VidShare, simple_certificate::CertificatePair, traits::node_implementation::NodeType,
24};
25
26use super::{
27 BlockWithTransaction,
28 fetch::Fetch,
29 query_data::{
30 BlockQueryData, LeafQueryData, PayloadMetadata, PayloadQueryData, QueryableHeader,
31 QueryablePayload, TransactionHash, VidCommonMetadata, VidCommonQueryData,
32 },
33};
34use crate::{Header, Payload, QueryResult, types::HeightIndexed};
35
36pub type FetchStream<T> = BoxStream<'static, Fetch<T>>;
37
38#[async_trait]
66pub trait AvailabilityDataSource<Types: NodeType>
67where
68 Header<Types>: QueryableHeader<Types>,
69 Payload<Types>: QueryablePayload<Types>,
70{
71 async fn get_leaf<ID>(&self, id: ID) -> Fetch<LeafQueryData<Types>>
72 where
73 ID: Into<LeafId<Types>> + Send + Sync;
74
75 async fn get_header<ID>(&self, id: ID) -> Fetch<Header<Types>>
76 where
77 ID: Into<BlockId<Types>> + Send + Sync;
78
79 async fn get_block<ID>(&self, id: ID) -> Fetch<BlockQueryData<Types>>
80 where
81 ID: Into<BlockId<Types>> + Send + Sync;
82
83 async fn get_payload<ID>(&self, id: ID) -> Fetch<PayloadQueryData<Types>>
84 where
85 ID: Into<BlockId<Types>> + Send + Sync;
86
87 async fn get_payload_metadata<ID>(&self, id: ID) -> Fetch<PayloadMetadata<Types>>
88 where
89 ID: Into<BlockId<Types>> + Send + Sync;
90
91 async fn get_vid_common<ID>(&self, id: ID) -> Fetch<VidCommonQueryData<Types>>
92 where
93 ID: Into<BlockId<Types>> + Send + Sync;
94
95 async fn get_vid_common_metadata<ID>(&self, id: ID) -> Fetch<VidCommonMetadata<Types>>
96 where
97 ID: Into<BlockId<Types>> + Send + Sync;
98
99 async fn get_leaf_range<R>(&self, range: R) -> FetchStream<LeafQueryData<Types>>
100 where
101 R: RangeBounds<usize> + Send + 'static;
102
103 async fn get_header_range<R>(&self, range: R) -> FetchStream<Header<Types>>
104 where
105 R: RangeBounds<usize> + Send + 'static;
106
107 async fn get_block_range<R>(&self, range: R) -> FetchStream<BlockQueryData<Types>>
108 where
109 R: RangeBounds<usize> + Send + 'static;
110
111 async fn get_payload_range<R>(&self, range: R) -> FetchStream<PayloadQueryData<Types>>
112 where
113 R: RangeBounds<usize> + Send + 'static;
114
115 async fn get_payload_metadata_range<R>(&self, range: R) -> FetchStream<PayloadMetadata<Types>>
116 where
117 R: RangeBounds<usize> + Send + 'static;
118
119 async fn get_vid_common_range<R>(&self, range: R) -> FetchStream<VidCommonQueryData<Types>>
120 where
121 R: RangeBounds<usize> + Send + 'static;
122
123 async fn get_vid_common_metadata_range<R>(
124 &self,
125 range: R,
126 ) -> FetchStream<VidCommonMetadata<Types>>
127 where
128 R: RangeBounds<usize> + Send + 'static;
129
130 async fn get_leaf_range_rev(
131 &self,
132 start: Bound<usize>,
133 end: usize,
134 ) -> FetchStream<LeafQueryData<Types>>;
135
136 async fn get_block_range_rev(
137 &self,
138 start: Bound<usize>,
139 end: usize,
140 ) -> FetchStream<BlockQueryData<Types>>;
141
142 async fn get_payload_range_rev(
143 &self,
144 start: Bound<usize>,
145 end: usize,
146 ) -> FetchStream<PayloadQueryData<Types>>;
147
148 async fn get_payload_metadata_range_rev(
149 &self,
150 start: Bound<usize>,
151 end: usize,
152 ) -> FetchStream<PayloadMetadata<Types>>;
153
154 async fn get_vid_common_range_rev(
155 &self,
156 start: Bound<usize>,
157 end: usize,
158 ) -> FetchStream<VidCommonQueryData<Types>>;
159
160 async fn get_vid_common_metadata_range_rev(
161 &self,
162 start: Bound<usize>,
163 end: usize,
164 ) -> FetchStream<VidCommonMetadata<Types>>;
165
166 async fn get_block_containing_transaction(
167 &self,
168 h: TransactionHash<Types>,
169 ) -> Fetch<BlockWithTransaction<Types>>;
170
171 async fn subscribe_blocks(&self, from: usize) -> BoxStream<'static, BlockQueryData<Types>> {
172 self.get_block_range(from..)
173 .await
174 .then(Fetch::resolve)
175 .boxed()
176 }
177
178 async fn subscribe_payloads(&self, from: usize) -> BoxStream<'static, PayloadQueryData<Types>> {
179 self.get_payload_range(from..)
180 .await
181 .then(Fetch::resolve)
182 .boxed()
183 }
184
185 async fn subscribe_payload_metadata(
186 &self,
187 from: usize,
188 ) -> BoxStream<'static, PayloadMetadata<Types>> {
189 self.get_payload_metadata_range(from..)
190 .await
191 .then(Fetch::resolve)
192 .boxed()
193 }
194
195 async fn subscribe_leaves(&self, from: usize) -> BoxStream<'static, LeafQueryData<Types>> {
196 self.get_leaf_range(from..)
197 .await
198 .then(Fetch::resolve)
199 .boxed()
200 }
201
202 async fn subscribe_headers(&self, from: usize) -> BoxStream<'static, Header<Types>> {
203 self.get_header_range(from..)
204 .await
205 .then(Fetch::resolve)
206 .boxed()
207 }
208
209 async fn subscribe_vid_common(
210 &self,
211 from: usize,
212 ) -> BoxStream<'static, VidCommonQueryData<Types>> {
213 self.get_vid_common_range(from..)
214 .await
215 .then(Fetch::resolve)
216 .boxed()
217 }
218
219 async fn subscribe_vid_common_metadata(
220 &self,
221 from: usize,
222 ) -> BoxStream<'static, VidCommonMetadata<Types>> {
223 self.get_vid_common_metadata_range(from..)
224 .await
225 .then(Fetch::resolve)
226 .boxed()
227 }
228
229 async fn get_cert2(&self, _height: u64) -> QueryResult<Option<Certificate2<Types>>> {
230 Ok(None)
231 }
232}
233
234#[derive(Clone, Debug)]
243pub struct BlockInfo<Types: NodeType> {
244 pub leaf: LeafQueryData<Types>,
245 pub block: Option<BlockQueryData<Types>>,
246 pub vid_common: Option<VidCommonQueryData<Types>>,
247 pub vid_share: Option<VidShare>,
248 pub qc_chain: Option<[CertificatePair<Types>; 2]>,
249 pub cert2: Option<Certificate2<Types>>,
251}
252
253impl<Types: NodeType> From<LeafQueryData<Types>> for BlockInfo<Types> {
254 fn from(leaf: LeafQueryData<Types>) -> Self {
255 Self::new(leaf, None, None, None)
256 }
257}
258
259impl<Types: NodeType> HeightIndexed for BlockInfo<Types> {
260 fn height(&self) -> u64 {
261 self.leaf.height()
262 }
263}
264
265impl<Types: NodeType> BlockInfo<Types> {
266 pub fn new(
267 leaf: LeafQueryData<Types>,
268 block: Option<BlockQueryData<Types>>,
269 vid_common: Option<VidCommonQueryData<Types>>,
270 vid_share: Option<VidShare>,
271 ) -> Self {
272 Self {
273 leaf,
274 block,
275 vid_common,
276 vid_share,
277 qc_chain: None,
278 cert2: None,
279 }
280 }
281
282 pub fn with_qc_chain(mut self, qc_chain: [CertificatePair<Types>; 2]) -> Self {
283 self.qc_chain = Some(qc_chain);
284 self
285 }
286
287 pub fn with_cert2(mut self, cert2: Certificate2<Types>) -> Self {
288 self.cert2 = Some(cert2);
289 self
290 }
291}
292
293pub trait UpdateAvailabilityData<Types: NodeType> {
294 fn append(&self, info: BlockInfo<Types>) -> impl Send + Future<Output = anyhow::Result<()>>;
296
297 fn append_payload(
304 &self,
305 _block: BlockQueryData<Types>,
306 ) -> impl Send + Future<Output = anyhow::Result<()>> {
307 async { Ok(()) }
308 }
309}