sequencer/persistence/
no_storage.rs

1//! Mock implementation of persistence, for testing.
2use std::{collections::BTreeMap, sync::Arc};
3
4use anyhow::bail;
5use async_trait::async_trait;
6use espresso_types::{
7    traits::{EventsPersistenceRead, MembershipPersistence},
8    v0::traits::{EventConsumer, PersistenceOptions, SequencerPersistence},
9    v0_3::{EventKey, IndexedStake, RewardAmount, StakeTableEvent},
10    Leaf2, NetworkConfig, StakeTableHash, ValidatorMap,
11};
12use hotshot::InitializerEpochInfo;
13use hotshot_libp2p_networking::network::behaviours::dht::store::persistent::{
14    DhtPersistentStorage, SerializableRecord,
15};
16use hotshot_types::{
17    data::{
18        vid_disperse::{ADVZDisperseShare, VidDisperseShare2},
19        DaProposal, DaProposal2, EpochNumber, QuorumProposalWrapper, VidCommitment,
20        VidDisperseShare,
21    },
22    drb::{DrbInput, DrbResult},
23    event::{Event, EventType, HotShotAction, LeafInfo},
24    message::Proposal,
25    simple_certificate::{
26        LightClientStateUpdateCertificateV2, NextEpochQuorumCertificate2, QuorumCertificate2,
27        UpgradeCertificate,
28    },
29    traits::metrics::Metrics,
30};
31
32use crate::{NodeType, SeqTypes, ViewNumber};
33
34#[derive(Clone, Copy, Debug)]
35pub struct Options;
36
37#[async_trait]
38impl PersistenceOptions for Options {
39    type Persistence = NoStorage;
40
41    fn set_view_retention(&mut self, _: u64) {}
42
43    async fn create(&mut self) -> anyhow::Result<Self::Persistence> {
44        Ok(NoStorage)
45    }
46
47    async fn reset(self) -> anyhow::Result<()> {
48        Ok(())
49    }
50}
51
52#[derive(Clone, Copy, Debug)]
53pub struct NoStorage;
54
55#[async_trait]
56impl SequencerPersistence for NoStorage {
57    async fn load_config(&self) -> anyhow::Result<Option<NetworkConfig>> {
58        Ok(None)
59    }
60
61    async fn save_config(&self, _: &NetworkConfig) -> anyhow::Result<()> {
62        Ok(())
63    }
64
65    async fn append_decided_leaves(
66        &self,
67        view_number: ViewNumber,
68        leaves: impl IntoIterator<Item = (&LeafInfo<SeqTypes>, QuorumCertificate2<SeqTypes>)> + Send,
69        consumer: &impl EventConsumer,
70    ) -> anyhow::Result<()> {
71        let leaves = leaves
72            .into_iter()
73            .map(|(info_ref, qc)| (info_ref.clone(), qc))
74            .collect::<Vec<_>>();
75        for (leaf_info, qc) in leaves {
76            consumer
77                .handle_event(&Event {
78                    view_number,
79                    event: EventType::Decide {
80                        leaf_chain: Arc::new(vec![leaf_info.clone()]),
81                        qc: Arc::new(qc),
82                        block_size: None,
83                    },
84                })
85                .await?;
86        }
87        Ok(())
88    }
89
90    async fn load_latest_acted_view(&self) -> anyhow::Result<Option<ViewNumber>> {
91        Ok(None)
92    }
93
94    async fn load_restart_view(&self) -> anyhow::Result<Option<ViewNumber>> {
95        Ok(None)
96    }
97
98    async fn load_anchor_leaf(
99        &self,
100    ) -> anyhow::Result<Option<(Leaf2, QuorumCertificate2<SeqTypes>)>> {
101        Ok(None)
102    }
103
104    async fn load_da_proposal(
105        &self,
106        _view: ViewNumber,
107    ) -> anyhow::Result<Option<Proposal<SeqTypes, DaProposal2<SeqTypes>>>> {
108        Ok(None)
109    }
110
111    async fn load_vid_share(
112        &self,
113        _view: ViewNumber,
114    ) -> anyhow::Result<Option<Proposal<SeqTypes, VidDisperseShare<SeqTypes>>>> {
115        Ok(None)
116    }
117
118    async fn load_quorum_proposals(
119        &self,
120    ) -> anyhow::Result<BTreeMap<ViewNumber, Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>>>
121    {
122        Ok(Default::default())
123    }
124    async fn load_quorum_proposal(
125        &self,
126        view: ViewNumber,
127    ) -> anyhow::Result<Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>> {
128        bail!("proposal {view:?} not available");
129    }
130    async fn load_upgrade_certificate(
131        &self,
132    ) -> anyhow::Result<Option<UpgradeCertificate<SeqTypes>>> {
133        Ok(None)
134    }
135
136    async fn append_vid(
137        &self,
138        _proposal: &Proposal<SeqTypes, ADVZDisperseShare<SeqTypes>>,
139    ) -> anyhow::Result<()> {
140        Ok(())
141    }
142    async fn append_vid2(
143        &self,
144        _proposal: &Proposal<SeqTypes, VidDisperseShare2<SeqTypes>>,
145    ) -> anyhow::Result<()> {
146        Ok(())
147    }
148    async fn append_da(
149        &self,
150        _proposal: &Proposal<SeqTypes, DaProposal<SeqTypes>>,
151        _vid_commit: VidCommitment,
152    ) -> anyhow::Result<()> {
153        Ok(())
154    }
155    async fn record_action(
156        &self,
157        _view: ViewNumber,
158        _epoch: Option<EpochNumber>,
159        _action: HotShotAction,
160    ) -> anyhow::Result<()> {
161        Ok(())
162    }
163    async fn append_quorum_proposal2(
164        &self,
165        _proposal: &Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>,
166    ) -> anyhow::Result<()> {
167        Ok(())
168    }
169    async fn store_upgrade_certificate(
170        &self,
171        _decided_upgrade_certificate: Option<UpgradeCertificate<SeqTypes>>,
172    ) -> anyhow::Result<()> {
173        Ok(())
174    }
175
176    async fn store_next_epoch_quorum_certificate(
177        &self,
178        _high_qc: NextEpochQuorumCertificate2<SeqTypes>,
179    ) -> anyhow::Result<()> {
180        Ok(())
181    }
182
183    async fn load_next_epoch_quorum_certificate(
184        &self,
185    ) -> anyhow::Result<Option<NextEpochQuorumCertificate2<SeqTypes>>> {
186        Ok(None)
187    }
188
189    async fn append_da2(
190        &self,
191        _proposal: &Proposal<SeqTypes, DaProposal2<SeqTypes>>,
192        _vid_commit: VidCommitment,
193    ) -> anyhow::Result<()> {
194        Ok(())
195    }
196
197    async fn append_proposal2(
198        &self,
199        _proposal: &Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>,
200    ) -> anyhow::Result<()> {
201        Ok(())
202    }
203
204    async fn migrate_anchor_leaf(&self) -> anyhow::Result<()> {
205        Ok(())
206    }
207    async fn migrate_da_proposals(&self) -> anyhow::Result<()> {
208        Ok(())
209    }
210    async fn migrate_vid_shares(&self) -> anyhow::Result<()> {
211        Ok(())
212    }
213    async fn migrate_quorum_proposals(&self) -> anyhow::Result<()> {
214        Ok(())
215    }
216    async fn migrate_quorum_certificates(&self) -> anyhow::Result<()> {
217        Ok(())
218    }
219
220    async fn store_drb_result(
221        &self,
222        _epoch: EpochNumber,
223        _drb_result: DrbResult,
224    ) -> anyhow::Result<()> {
225        Ok(())
226    }
227
228    async fn store_drb_input(&self, _drb_input: DrbInput) -> anyhow::Result<()> {
229        Ok(())
230    }
231    async fn load_drb_input(&self, _epoch: u64) -> anyhow::Result<DrbInput> {
232        bail!("Cannot load from NoStorage")
233    }
234
235    async fn store_epoch_root(
236        &self,
237        _epoch: EpochNumber,
238        _block_header: <SeqTypes as NodeType>::BlockHeader,
239    ) -> anyhow::Result<()> {
240        Ok(())
241    }
242
243    async fn load_start_epoch_info(&self) -> anyhow::Result<Vec<InitializerEpochInfo<SeqTypes>>> {
244        Ok(Vec::new())
245    }
246
247    async fn add_state_cert(
248        &self,
249        _state_cert: LightClientStateUpdateCertificateV2<SeqTypes>,
250    ) -> anyhow::Result<()> {
251        Ok(())
252    }
253
254    async fn load_state_cert(
255        &self,
256    ) -> anyhow::Result<Option<LightClientStateUpdateCertificateV2<SeqTypes>>> {
257        Ok(None)
258    }
259
260    fn enable_metrics(&mut self, _metrics: &dyn Metrics) {}
261}
262
263#[async_trait]
264impl MembershipPersistence for NoStorage {
265    async fn load_stake(
266        &self,
267        _epoch: EpochNumber,
268    ) -> anyhow::Result<Option<(ValidatorMap, Option<RewardAmount>, Option<StakeTableHash>)>> {
269        Ok(None)
270    }
271
272    async fn load_latest_stake(&self, _limit: u64) -> anyhow::Result<Option<Vec<IndexedStake>>> {
273        Ok(None)
274    }
275
276    async fn store_stake(
277        &self,
278        _epoch: EpochNumber,
279        _stake: ValidatorMap,
280        _block_reward: Option<RewardAmount>,
281        _stake_table_hash: Option<StakeTableHash>,
282    ) -> anyhow::Result<()> {
283        Ok(())
284    }
285
286    async fn store_events(
287        &self,
288        _l1: u64,
289        _events: Vec<(EventKey, StakeTableEvent)>,
290    ) -> anyhow::Result<()> {
291        Ok(())
292    }
293    async fn load_events(
294        &self,
295        _l1_block: u64,
296    ) -> anyhow::Result<(
297        Option<EventsPersistenceRead>,
298        Vec<(EventKey, StakeTableEvent)>,
299    )> {
300        Ok((None, Vec::new()))
301    }
302}
303
304#[async_trait]
305impl DhtPersistentStorage for NoStorage {
306    /// Don't do anything
307    async fn save(&self, _records: Vec<SerializableRecord>) -> anyhow::Result<()> {
308        Ok(())
309    }
310
311    /// Don't do anything
312    async fn load(&self) -> anyhow::Result<Vec<SerializableRecord>> {
313        Ok(vec![])
314    }
315}