Skip to main content

espresso_node/persistence/
no_storage.rs

1//! Mock implementation of persistence, for testing.
2use std::collections::BTreeMap;
3
4use anyhow::bail;
5use async_trait::async_trait;
6use espresso_types::{
7    AuthenticatedValidatorMap, Header, Leaf2, NetworkConfig, PubKey, RegisteredValidatorMap,
8    StakeTableHash,
9    traits::{EventsPersistenceRead, MembershipPersistence, StakeTuple},
10    v0::traits::{EventConsumer, PersistenceOptions, SequencerPersistence, StateCertPersistence},
11    v0_3::{EventKey, IndexedStake, RegisteredValidator, RewardAmount, StakeTableEvent},
12};
13use hotshot_types::{
14    data::{
15        DaProposal, DaProposal2, EpochNumber, QuorumProposalWrapper, VidCommitment,
16        VidDisperseShare,
17    },
18    drb::{DrbInput, DrbResult},
19    event::{HotShotAction, LeafInfo},
20    initializer::InitializerEpochInfo,
21    message::Proposal,
22    new_protocol::CoordinatorEvent,
23    simple_certificate::{
24        Certificate2, CertificatePair, LightClientStateUpdateCertificateV2,
25        NextEpochQuorumCertificate2, QuorumCertificate2, UpgradeCertificate,
26    },
27    traits::metrics::Metrics,
28};
29
30use crate::{SeqTypes, ViewNumber};
31
32#[derive(Clone, Copy, Debug)]
33pub struct Options;
34
35#[async_trait]
36impl PersistenceOptions for Options {
37    type Persistence = NoStorage;
38
39    fn set_view_retention(&mut self, _: u64) {}
40
41    fn set_consensus_only(&mut self) {}
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 persist_decided_leaves(
66        &self,
67        leaves: impl IntoIterator<Item = (&LeafInfo<SeqTypes>, CertificatePair<SeqTypes>)> + Send,
68        _cert2: Option<&Certificate2<SeqTypes>>,
69        consumer: &(impl EventConsumer + 'static),
70    ) -> anyhow::Result<()> {
71        // The iterator is not `Send`, so build the event before awaiting.
72        let event = {
73            let mut leaves = leaves.into_iter();
74            let Some((newest, cert)) = leaves.next() else {
75                return Ok(());
76            };
77            CoordinatorEvent::NewDecide {
78                leaf_infos: std::iter::once(newest.clone())
79                    .chain(leaves.map(|(info, _)| info.clone()))
80                    .collect(),
81                cert1: cert.qc().clone(),
82                cert2: None,
83            }
84        };
85        consumer.handle_event(&event).await
86    }
87
88    async fn load_latest_acted_view(&self) -> anyhow::Result<Option<ViewNumber>> {
89        Ok(None)
90    }
91
92    async fn load_restart_view(&self) -> anyhow::Result<Option<ViewNumber>> {
93        Ok(None)
94    }
95
96    async fn load_anchor_leaf(&self) -> anyhow::Result<Option<(Leaf2, CertificatePair<SeqTypes>)>> {
97        Ok(None)
98    }
99
100    async fn load_da_proposal(
101        &self,
102        _view: ViewNumber,
103    ) -> anyhow::Result<Option<Proposal<SeqTypes, DaProposal2<SeqTypes>>>> {
104        Ok(None)
105    }
106
107    async fn load_vid_share(
108        &self,
109        _view: ViewNumber,
110    ) -> anyhow::Result<Option<Proposal<SeqTypes, VidDisperseShare<SeqTypes>>>> {
111        Ok(None)
112    }
113
114    async fn load_quorum_proposals(
115        &self,
116    ) -> anyhow::Result<BTreeMap<ViewNumber, Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>>>
117    {
118        Ok(Default::default())
119    }
120    async fn load_quorum_proposal(
121        &self,
122        view: ViewNumber,
123    ) -> anyhow::Result<Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>> {
124        bail!("proposal {view:?} not available");
125    }
126    async fn load_upgrade_certificate(
127        &self,
128    ) -> anyhow::Result<Option<UpgradeCertificate<SeqTypes>>> {
129        Ok(None)
130    }
131
132    async fn append_vid(
133        &self,
134        _proposal: &Proposal<SeqTypes, VidDisperseShare<SeqTypes>>,
135    ) -> anyhow::Result<()> {
136        Ok(())
137    }
138    async fn append_da(
139        &self,
140        _proposal: &Proposal<SeqTypes, DaProposal<SeqTypes>>,
141        _vid_commit: VidCommitment,
142    ) -> anyhow::Result<()> {
143        Ok(())
144    }
145    async fn record_action(&self, _view: ViewNumber, _action: HotShotAction) -> anyhow::Result<()> {
146        Ok(())
147    }
148    async fn append_quorum_proposal2(
149        &self,
150        _proposal: &Proposal<SeqTypes, QuorumProposalWrapper<SeqTypes>>,
151    ) -> anyhow::Result<()> {
152        Ok(())
153    }
154    async fn store_upgrade_certificate(
155        &self,
156        _decided_upgrade_certificate: Option<UpgradeCertificate<SeqTypes>>,
157    ) -> anyhow::Result<()> {
158        Ok(())
159    }
160
161    async fn store_eqc(
162        &self,
163        _high_qc: QuorumCertificate2<SeqTypes>,
164        _next_epoch_high_qc: NextEpochQuorumCertificate2<SeqTypes>,
165    ) -> anyhow::Result<()> {
166        Ok(())
167    }
168
169    async fn load_eqc(
170        &self,
171    ) -> Option<(
172        QuorumCertificate2<SeqTypes>,
173        NextEpochQuorumCertificate2<SeqTypes>,
174    )> {
175        None
176    }
177
178    async fn append_da2(
179        &self,
180        _proposal: &Proposal<SeqTypes, DaProposal2<SeqTypes>>,
181        _vid_commit: VidCommitment,
182    ) -> anyhow::Result<()> {
183        Ok(())
184    }
185
186    async fn store_drb_result(
187        &self,
188        _epoch: EpochNumber,
189        _drb_result: DrbResult,
190    ) -> anyhow::Result<()> {
191        Ok(())
192    }
193
194    async fn store_drb_input(&self, _drb_input: DrbInput) -> anyhow::Result<()> {
195        Ok(())
196    }
197    async fn load_drb_input(&self, _epoch: u64) -> anyhow::Result<DrbInput> {
198        bail!("Cannot load from NoStorage")
199    }
200
201    async fn load_start_epoch_info(&self) -> anyhow::Result<Vec<InitializerEpochInfo<SeqTypes>>> {
202        Ok(Vec::new())
203    }
204
205    async fn add_state_cert(
206        &self,
207        _state_cert: LightClientStateUpdateCertificateV2<SeqTypes>,
208    ) -> anyhow::Result<()> {
209        Ok(())
210    }
211
212    async fn load_state_cert(
213        &self,
214    ) -> anyhow::Result<Option<LightClientStateUpdateCertificateV2<SeqTypes>>> {
215        Ok(None)
216    }
217
218    fn enable_metrics(&mut self, _metrics: &dyn Metrics) {}
219}
220
221#[async_trait]
222impl StateCertPersistence for NoStorage {
223    async fn get_state_cert_by_epoch(
224        &self,
225        _epoch: u64,
226    ) -> anyhow::Result<Option<LightClientStateUpdateCertificateV2<SeqTypes>>> {
227        Ok(None)
228    }
229
230    async fn insert_state_cert(
231        &self,
232        _epoch: u64,
233        _cert: LightClientStateUpdateCertificateV2<SeqTypes>,
234    ) -> anyhow::Result<()> {
235        Ok(())
236    }
237}
238
239#[async_trait]
240impl MembershipPersistence for NoStorage {
241    async fn load_stake(&self, _epoch: EpochNumber) -> anyhow::Result<Option<StakeTuple>> {
242        Ok(None)
243    }
244
245    async fn load_latest_stake(&self, _limit: u64) -> anyhow::Result<Option<Vec<IndexedStake>>> {
246        Ok(None)
247    }
248
249    async fn load_drb_result(&self, _epoch: EpochNumber) -> anyhow::Result<Option<DrbResult>> {
250        Ok(None)
251    }
252
253    async fn load_epoch_root(&self, _epoch: EpochNumber) -> anyhow::Result<Option<Header>> {
254        Ok(None)
255    }
256
257    async fn store_epoch_root(
258        &self,
259        _epoch: EpochNumber,
260        _block_header: Header,
261    ) -> anyhow::Result<()> {
262        Ok(())
263    }
264
265    async fn store_stake(
266        &self,
267        _epoch: EpochNumber,
268        _stake: AuthenticatedValidatorMap,
269        _block_reward: Option<RewardAmount>,
270        _stake_table_hash: Option<StakeTableHash>,
271    ) -> anyhow::Result<()> {
272        Ok(())
273    }
274
275    async fn store_events(
276        &self,
277        _l1: u64,
278        _events: Vec<(EventKey, StakeTableEvent)>,
279    ) -> anyhow::Result<()> {
280        Ok(())
281    }
282    async fn load_events(
283        &self,
284        _from_l1_block: u64,
285        _l1_block: u64,
286    ) -> anyhow::Result<(
287        Option<EventsPersistenceRead>,
288        Vec<(EventKey, StakeTableEvent)>,
289    )> {
290        Ok((None, Vec::new()))
291    }
292
293    async fn delete_stake_tables(&self) -> anyhow::Result<()> {
294        Ok(())
295    }
296
297    async fn store_all_validators(
298        &self,
299        _epoch: EpochNumber,
300        _all_validators: RegisteredValidatorMap,
301    ) -> anyhow::Result<()> {
302        Ok(())
303    }
304
305    async fn load_all_validators(
306        &self,
307        _epoch: EpochNumber,
308        _offset: u64,
309        _limit: u64,
310    ) -> anyhow::Result<Vec<RegisteredValidator<PubKey>>> {
311        Ok(Default::default())
312    }
313}