hotshot_query_service/data_source/fetching/
transaction.rs1use std::sync::Arc;
16
17use async_trait::async_trait;
18use derive_more::From;
19use futures::future::{BoxFuture, FutureExt};
20use hotshot_types::traits::node_implementation::NodeType;
21
22use super::{AvailabilityProvider, FetchRequest, Fetchable, Fetcher, Notifiers};
23use crate::{
24 availability::{QueryableHeader, QueryablePayload, TransactionHash, TransactionQueryData},
25 data_source::{
26 storage::{
27 pruning::PrunedHeightStorage, AvailabilityStorage, NodeStorage,
28 UpdateAvailabilityStorage,
29 },
30 update::VersionedDataSource,
31 },
32 Header, Payload, QueryResult,
33};
34
35#[derive(Clone, Copy, Debug, From)]
36pub(super) struct TransactionRequest<Types: NodeType>(TransactionHash<Types>);
37
38impl<Types: NodeType> FetchRequest for TransactionRequest<Types> {}
39
40#[async_trait]
41impl<Types> Fetchable<Types> for TransactionQueryData<Types>
42where
43 Types: NodeType,
44 Header<Types>: QueryableHeader<Types>,
45 Payload<Types>: QueryablePayload<Types>,
46{
47 type Request = TransactionRequest<Types>;
48
49 fn satisfies(&self, req: Self::Request) -> bool {
50 req.0 == self.hash()
51 }
52
53 async fn passive_fetch(
54 notifications: &Notifiers<Types>,
55 req: Self::Request,
56 ) -> BoxFuture<'static, Option<Self>> {
57 let wait_block = notifications
60 .block
61 .wait_for(move |block| block.transaction_by_hash(req.0).is_some())
62 .await;
63
64 async move {
65 let block = wait_block.await?;
66 Self::with_hash(&block, req.0)
67 }
68 .boxed()
69 }
70
71 async fn active_fetch<S, P>(
72 _tx: &mut impl AvailabilityStorage<Types>,
73 _fetcher: Arc<Fetcher<Types, S, P>>,
74 req: Self::Request,
75 ) -> anyhow::Result<()>
76 where
77 S: VersionedDataSource + 'static,
78 for<'a> S::Transaction<'a>: UpdateAvailabilityStorage<Types>,
79 for<'a> S::ReadOnly<'a>:
80 AvailabilityStorage<Types> + NodeStorage<Types> + PrunedHeightStorage,
81 P: AvailabilityProvider<Types>,
82 {
83 tracing::debug!("not fetching unknown transaction {req:?}");
87 Ok(())
88 }
89
90 async fn load<S>(storage: &mut S, req: Self::Request) -> QueryResult<Self>
91 where
92 S: AvailabilityStorage<Types>,
93 {
94 storage.get_transaction(req.0).await
95 }
96}