hotshot_query_service/fetching/
request.rs1use std::{fmt::Debug, hash::Hash};
16
17use alloy::primitives::{FixedBytes, Keccak256};
18use derive_more::{From, Into};
19use hotshot_types::{
20 data::{VidCommitment, VidCommon},
21 traits::node_implementation::NodeType,
22};
23
24use crate::{
25 Payload,
26 availability::{
27 BlockQueryData, LeafHash, LeafQueryData, QcHash, QueryableHeader, VidCommonQueryData,
28 },
29 fetching::NonEmptyRange,
30};
31
32pub trait Request<Types>: Copy + Debug + Eq + Hash + Send {
34 type Response: Clone + Send;
36}
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
40pub struct PayloadRequest(pub VidCommitment);
41
42impl<Types: NodeType> Request<Types> for PayloadRequest {
43 type Response = Payload<Types>;
44}
45
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
48pub struct RangeRequest {
49 pub start: u64,
51
52 pub end: u64,
54
55 pub expected_hash: FixedBytes<32>,
61}
62
63impl RangeRequest {
64 pub fn from_headers<Types: NodeType>(
66 headers: &NonEmptyRange<impl QueryableHeader<Types>>,
67 ) -> Self {
68 let expected_hash =
69 Self::hash_payloads(headers.iter().map(|header| header.payload_commitment()));
70 Self {
71 start: headers.start(),
72 end: headers.end(),
73 expected_hash,
74 }
75 }
76
77 pub fn hash_payloads(
79 payload_commitments: impl IntoIterator<Item = VidCommitment>,
80 ) -> FixedBytes<32> {
81 let mut hasher = Keccak256::new();
82 for comm in payload_commitments {
83 hasher.update(comm);
84 }
85 hasher.finalize()
86 }
87}
88
89#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, From, Into)]
91pub struct BlockRangeRequest(RangeRequest);
92
93impl<Types: NodeType> Request<Types> for BlockRangeRequest {
94 type Response = NonEmptyRange<BlockQueryData<Types>>;
95}
96
97impl BlockRangeRequest {
98 pub fn from_headers<Types: NodeType>(
99 headers: &NonEmptyRange<impl QueryableHeader<Types>>,
100 ) -> Self {
101 RangeRequest::from_headers(headers).into()
102 }
103}
104
105#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
107pub struct VidCommonRequest(pub VidCommitment);
108
109impl<Types: NodeType> Request<Types> for VidCommonRequest {
110 type Response = VidCommon;
111}
112
113#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, From, Into)]
115pub struct VidCommonRangeRequest(RangeRequest);
116
117impl<Types: NodeType> Request<Types> for VidCommonRangeRequest {
118 type Response = NonEmptyRange<VidCommonQueryData<Types>>;
119}
120
121impl VidCommonRangeRequest {
122 pub fn from_headers<Types: NodeType>(
123 headers: &NonEmptyRange<impl QueryableHeader<Types>>,
124 ) -> Self {
125 RangeRequest::from_headers(headers).into()
126 }
127}
128
129#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, From, Into)]
134pub struct LeafRequest<Types: NodeType> {
135 pub height: u64,
136 pub expected_leaf: LeafHash<Types>,
137 pub expected_qc: QcHash<Types>,
138}
139
140impl<Types: NodeType> LeafRequest<Types> {
141 pub fn new(height: u64, expected_leaf: LeafHash<Types>, expected_qc: QcHash<Types>) -> Self {
142 Self {
143 height,
144 expected_leaf,
145 expected_qc,
146 }
147 }
148}
149
150impl<Types: NodeType> Request<Types> for LeafRequest<Types> {
151 type Response = LeafQueryData<Types>;
152}
153
154#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
156pub struct LeafRangeRequest<Types: NodeType> {
157 pub start: u64,
159
160 pub end: u64,
162
163 pub last_leaf: LeafHash<Types>,
167
168 pub last_qc: QcHash<Types>,
172}
173
174impl<Types: NodeType> Request<Types> for LeafRangeRequest<Types> {
175 type Response = NonEmptyRange<LeafQueryData<Types>>;
176}