1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) 2021-2024 Espresso Systems (espressosys.com)
// This file is part of the HotShot repository.

// You should have received a copy of the MIT License
// along with the HotShot repository. If not, see <https://mit-license.org/>.

//! Abstract storage type for storing DA proposals and VID shares
//!
//! This modules provides the [`Storage`] trait.
//!

use std::collections::BTreeMap;

use anyhow::Result;
use async_trait::async_trait;
use committable::Commitment;
use jf_vid::VidScheme;

use super::node_implementation::NodeType;
use crate::{
    consensus::{CommitmentMap, View},
    data::{
        DaProposal, DaProposal2, Leaf, Leaf2, QuorumProposal, QuorumProposal2,
        QuorumProposalWrapper, VidDisperseShare, VidDisperseShare2,
    },
    event::HotShotAction,
    message::{convert_proposal, Proposal},
    simple_certificate::{
        NextEpochQuorumCertificate2, QuorumCertificate, QuorumCertificate2, UpgradeCertificate,
    },
    vid::VidSchemeType,
};

/// Abstraction for storing a variety of consensus payload datum.
#[async_trait]
pub trait Storage<TYPES: NodeType>: Send + Sync + Clone {
    /// Add a proposal to the stored VID proposals.
    async fn append_vid(&self, proposal: &Proposal<TYPES, VidDisperseShare<TYPES>>) -> Result<()>;
    /// Add a proposal to the stored VID proposals.
    async fn append_vid2(
        &self,
        proposal: &Proposal<TYPES, VidDisperseShare2<TYPES>>,
    ) -> Result<()> {
        self.append_vid(&convert_proposal(proposal.clone())).await
    }
    /// Add a proposal to the stored DA proposals.
    async fn append_da(
        &self,
        proposal: &Proposal<TYPES, DaProposal<TYPES>>,
        vid_commit: <VidSchemeType as VidScheme>::Commit,
    ) -> Result<()>;
    /// Add a proposal to the stored DA proposals.
    async fn append_da2(
        &self,
        proposal: &Proposal<TYPES, DaProposal2<TYPES>>,
        vid_commit: <VidSchemeType as VidScheme>::Commit,
    ) -> Result<()> {
        self.append_da(&convert_proposal(proposal.clone()), vid_commit)
            .await
    }
    /// Add a proposal we sent to the store
    async fn append_proposal(
        &self,
        proposal: &Proposal<TYPES, QuorumProposal<TYPES>>,
    ) -> Result<()>;
    /// Add a proposal we sent to the store
    async fn append_proposal2(
        &self,
        proposal: &Proposal<TYPES, QuorumProposal2<TYPES>>,
    ) -> Result<()> {
        self.append_proposal(&convert_proposal(proposal.clone()))
            .await
    }
    /// Add a proposal we sent to the store
    async fn append_proposal_wrapper(
        &self,
        proposal: &Proposal<TYPES, QuorumProposalWrapper<TYPES>>,
    ) -> Result<()> {
        self.append_proposal(&convert_proposal(proposal.clone()))
            .await
    }
    /// Record a HotShotAction taken.
    async fn record_action(&self, view: TYPES::View, action: HotShotAction) -> Result<()>;
    /// Update the current high QC in storage.
    async fn update_high_qc(&self, high_qc: QuorumCertificate<TYPES>) -> Result<()>;
    /// Update the current high QC in storage.
    async fn update_high_qc2(&self, high_qc: QuorumCertificate2<TYPES>) -> Result<()> {
        self.update_high_qc(high_qc.to_qc()).await
    }
    /// Update the current high QC in storage.
    async fn update_next_epoch_high_qc2(
        &self,
        _next_epoch_high_qc: NextEpochQuorumCertificate2<TYPES>,
    ) -> Result<()> {
        Ok(())
    }
    /// Update the currently undecided state of consensus.  This includes the undecided leaf chain,
    /// and the undecided state.
    async fn update_undecided_state(
        &self,
        leaves: CommitmentMap<Leaf<TYPES>>,
        state: BTreeMap<TYPES::View, View<TYPES>>,
    ) -> Result<()>;
    /// Update the currently undecided state of consensus.  This includes the undecided leaf chain,
    /// and the undecided state.
    async fn update_undecided_state2(
        &self,
        leaves: CommitmentMap<Leaf2<TYPES>>,
        state: BTreeMap<TYPES::View, View<TYPES>>,
    ) -> Result<()> {
        self.update_undecided_state(
            leaves
                .iter()
                .map(|(&commitment, leaf)| {
                    (
                        Commitment::from_raw(commitment.into()),
                        leaf.clone().to_leaf_unsafe(),
                    )
                })
                .collect(),
            state,
        )
        .await
    }
    /// Upgrade the current decided upgrade certificate in storage.
    async fn update_decided_upgrade_certificate(
        &self,
        decided_upgrade_certificate: Option<UpgradeCertificate<TYPES>>,
    ) -> Result<()>;
    /// Migrate leaves from `Leaf` to `Leaf2`, and proposals from `QuorumProposal` to `QuorumProposal2`
    async fn migrate_consensus(
        &self,
        _convert_leaf: fn(Leaf<TYPES>) -> Leaf2<TYPES>,
        _convert_proposal: fn(
            Proposal<TYPES, QuorumProposal<TYPES>>,
        ) -> Proposal<TYPES, QuorumProposal2<TYPES>>,
    ) -> Result<()> {
        Ok(())
    }
}