1use std::sync::Arc;
13
14use anyhow::{anyhow, ensure, Result};
15use async_trait::async_trait;
16use futures::future::BoxFuture;
17
18use super::node_implementation::NodeType;
19use crate::{
20 data::{
21 DaProposal, DaProposal2, QuorumProposal, QuorumProposal2, QuorumProposalWrapper,
22 VidCommitment, VidDisperseShare,
23 },
24 drb::{DrbInput, DrbResult},
25 event::HotShotAction,
26 message::{convert_proposal, Proposal},
27 simple_certificate::{
28 LightClientStateUpdateCertificateV2, NextEpochQuorumCertificate2, QuorumCertificate,
29 QuorumCertificate2, UpgradeCertificate,
30 },
31};
32
33#[async_trait]
35pub trait Storage<TYPES: NodeType>: Send + Sync + Clone + 'static {
36 async fn append_vid(&self, proposal: &Proposal<TYPES, VidDisperseShare<TYPES>>) -> Result<()>;
38
39 async fn append_da(
41 &self,
42 proposal: &Proposal<TYPES, DaProposal<TYPES>>,
43 vid_commit: VidCommitment,
44 ) -> Result<()>;
45 async fn append_da2(
47 &self,
48 proposal: &Proposal<TYPES, DaProposal2<TYPES>>,
49 vid_commit: VidCommitment,
50 ) -> Result<()> {
51 self.append_da(&convert_proposal(proposal.clone()), vid_commit)
52 .await
53 }
54 async fn append_proposal(
56 &self,
57 proposal: &Proposal<TYPES, QuorumProposal<TYPES>>,
58 ) -> Result<()>;
59 async fn append_proposal2(
61 &self,
62 proposal: &Proposal<TYPES, QuorumProposal2<TYPES>>,
63 ) -> Result<()>;
64 async fn append_proposal_wrapper(
66 &self,
67 proposal: &Proposal<TYPES, QuorumProposalWrapper<TYPES>>,
68 ) -> Result<()> {
69 self.append_proposal2(&convert_proposal(proposal.clone()))
70 .await
71 }
72 async fn record_action(
74 &self,
75 view: TYPES::View,
76 epoch: Option<TYPES::Epoch>,
77 action: HotShotAction,
78 ) -> Result<()>;
79 async fn update_high_qc(&self, high_qc: QuorumCertificate<TYPES>) -> Result<()>;
81 async fn update_high_qc2(&self, high_qc: QuorumCertificate2<TYPES>) -> Result<()> {
83 self.update_high_qc(high_qc.to_qc()).await
84 }
85 async fn update_state_cert(
87 &self,
88 state_cert: LightClientStateUpdateCertificateV2<TYPES>,
89 ) -> Result<()>;
90
91 async fn update_high_qc2_and_state_cert(
92 &self,
93 high_qc: QuorumCertificate2<TYPES>,
94 state_cert: LightClientStateUpdateCertificateV2<TYPES>,
95 ) -> Result<()> {
96 self.update_high_qc2(high_qc).await?;
97 self.update_state_cert(state_cert).await
98 }
99 async fn update_next_epoch_high_qc2(
101 &self,
102 _next_epoch_high_qc: NextEpochQuorumCertificate2<TYPES>,
103 ) -> Result<()>;
104
105 async fn update_eqc(
107 &self,
108 _high_qc: QuorumCertificate2<TYPES>,
109 _next_epoch_high_qc: NextEpochQuorumCertificate2<TYPES>,
110 ) -> Result<()>;
111
112 async fn update_decided_upgrade_certificate(
114 &self,
115 decided_upgrade_certificate: Option<UpgradeCertificate<TYPES>>,
116 ) -> Result<()>;
117 async fn migrate_storage(&self) -> Result<()> {
119 Ok(())
120 }
121 async fn store_drb_result(&self, epoch: TYPES::Epoch, drb_result: DrbResult) -> Result<()>;
123 async fn store_epoch_root(
125 &self,
126 epoch: TYPES::Epoch,
127 block_header: TYPES::BlockHeader,
128 ) -> Result<()>;
129 async fn load_drb_result(&self, epoch: TYPES::Epoch) -> Result<DrbResult> {
130 match self.load_drb_input(*epoch).await {
131 Ok(drb_input) => {
132 ensure!(drb_input.iteration == drb_input.difficulty_level);
133
134 Ok(drb_input.value)
135 },
136 Err(e) => Err(e),
137 }
138 }
139 async fn store_drb_input(&self, drb_input: DrbInput) -> Result<()>;
140 async fn load_drb_input(&self, _epoch: u64) -> Result<DrbInput>;
141}
142
143pub async fn load_drb_input_impl<TYPES: NodeType>(
144 storage: impl Storage<TYPES>,
145 epoch: u64,
146) -> Result<DrbInput> {
147 storage.load_drb_input(epoch).await
148}
149
150pub type LoadDrbProgressFn =
151 std::sync::Arc<dyn Fn(u64) -> BoxFuture<'static, Result<DrbInput>> + Send + Sync>;
152
153pub fn load_drb_progress_fn<TYPES: NodeType>(
154 storage: impl Storage<TYPES> + 'static,
155) -> LoadDrbProgressFn {
156 Arc::new(move |epoch| {
157 let storage = storage.clone();
158 Box::pin(load_drb_input_impl(storage, epoch))
159 })
160}
161
162pub fn null_load_drb_progress_fn() -> LoadDrbProgressFn {
163 Arc::new(move |_drb_input| {
164 Box::pin(async { Err(anyhow!("Using null implementation of load_drb_input")) })
165 })
166}
167
168pub async fn store_drb_input_impl<TYPES: NodeType>(
169 storage: impl Storage<TYPES>,
170 drb_input: DrbInput,
171) -> Result<()> {
172 storage.store_drb_input(drb_input).await
173}
174
175pub type StoreDrbProgressFn =
176 std::sync::Arc<dyn Fn(DrbInput) -> BoxFuture<'static, Result<()>> + Send + Sync>;
177
178pub fn store_drb_progress_fn<TYPES: NodeType>(
179 storage: impl Storage<TYPES> + 'static,
180) -> StoreDrbProgressFn {
181 Arc::new(move |drb_input| {
182 let storage = storage.clone();
183 Box::pin(store_drb_input_impl(storage, drb_input))
184 })
185}
186
187pub fn null_store_drb_progress_fn() -> StoreDrbProgressFn {
188 Arc::new(move |_drb_input| Box::pin(async { Ok(()) }))
189}
190
191pub type StoreDrbResultFn<TYPES> = Arc<
192 Box<
193 dyn Fn(<TYPES as NodeType>::Epoch, DrbResult) -> BoxFuture<'static, Result<()>>
194 + Send
195 + Sync
196 + 'static,
197 >,
198>;
199
200async fn store_drb_result_impl<TYPES: NodeType>(
201 storage: impl Storage<TYPES>,
202 epoch: TYPES::Epoch,
203 drb_result: DrbResult,
204) -> Result<()> {
205 storage.store_drb_result(epoch, drb_result).await
206}
207
208pub fn store_drb_result_fn<TYPES: NodeType>(
210 storage: impl Storage<TYPES> + 'static,
211) -> StoreDrbResultFn<TYPES> {
212 Arc::new(Box::new(move |epoch, drb_result| {
213 let st = storage.clone();
214 Box::pin(store_drb_result_impl(st, epoch, drb_result))
215 }))
216}