simperby_governance/
lib.rs1use serde::{Deserialize, Serialize};
2use simperby_core::utils::get_timestamp;
3use simperby_core::*;
4use simperby_network::*;
5use std::collections::{BTreeMap, BTreeSet};
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9pub type Error = eyre::Error;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct GovernanceStatus {
13 pub votes: BTreeMap<Hash256, BTreeMap<PublicKey, Signature>>,
15}
16
17#[derive(Clone, Debug, Serialize, Deserialize)]
18#[serde(transparent)]
19pub struct Vote {
20 pub agenda_hash: Hash256,
21}
22
23impl ToHash256 for Vote {
24 fn to_hash256(&self) -> Hash256 {
25 self.agenda_hash
26 }
27}
28
29impl DmsMessage for Vote {
30 const DMS_TAG: &'static str = "governance";
31
32 fn check(&self) -> Result<(), Error> {
33 Ok(())
34 }
35
36 fn commit(
38 &self,
39 _dms_key: &DmsKey,
40 private_key: &PrivateKey,
41 ) -> Result<MessageCommitmentProof, CryptoError>
42 where
43 Self: Sized,
44 {
45 Signature::sign(self.to_hash256(), private_key).map(|signature| MessageCommitmentProof {
46 committer: private_key.public_key(),
47 signature,
48 })
49 }
50
51 fn verify_commitment(
52 &self,
53 proof: &MessageCommitmentProof,
54 _dms_key: &DmsKey,
55 ) -> Result<(), CryptoError> {
56 proof.signature.verify(self.to_hash256(), &proof.committer)
57 }
58}
59
60pub struct Governance {
61 dms: Arc<RwLock<Dms<Vote>>>,
62 fi: FinalizationInfo,
63 verified_agendas: BTreeSet<Hash256>,
66}
67
68impl Governance {
69 pub async fn new(
70 dms: Arc<RwLock<Dms<Vote>>>,
71 fi: FinalizationInfo,
72 verified_agendas: BTreeSet<Hash256>,
73 ) -> Result<Self, Error> {
74 Ok(Self {
77 dms,
78 fi,
79 verified_agendas,
80 })
81 }
82
83 pub async fn read(&self) -> Result<GovernanceStatus, Error> {
84 let votes = self.dms.read().await.read_messages().await?;
85 let mut result = BTreeMap::<Hash256, BTreeMap<PublicKey, Signature>>::default();
86 for vote in votes {
87 for committers in vote.committers {
88 result
89 .entry(vote.message.to_hash256())
90 .or_default()
91 .insert(committers.committer, committers.signature);
92 }
93 }
94 let status = GovernanceStatus { votes: result };
95 Ok(status)
96 }
97
98 pub async fn register_verified_agenda_hash(
99 &mut self,
100 agenda_hash: Hash256,
101 ) -> Result<(), Error> {
102 self.verified_agendas.insert(agenda_hash);
103 Ok(())
104 }
105
106 pub async fn get_eligible_agendas(&self) -> Result<Vec<(Hash256, AgendaProof)>, Error> {
107 let governance_set = self
108 .fi
109 .reserved_state
110 .get_governance_set()
111 .unwrap()
113 .into_iter()
114 .collect::<BTreeMap<_, _>>();
115 let governance_state = self.read().await?;
116 let votes: Vec<(Hash256, VotingPower)> = governance_state
117 .votes
118 .iter()
119 .map(|(agenda, votes)| {
120 (
121 *agenda,
122 votes
123 .keys()
124 .map(|voter| governance_set.get(voter).unwrap())
125 .sum(),
126 )
127 })
128 .filter(|(agenda, _)| self.verified_agendas.contains(agenda))
129 .collect();
130 let mut result = Vec::new();
131 let total_voting_power = governance_set.values().sum::<VotingPower>();
132 for (agenda, voted_power) in votes {
133 if voted_power * 2 > total_voting_power {
134 let proof: Vec<_> = governance_state.votes[&agenda]
135 .iter()
136 .map(|(k, s)| TypedSignature::<Agenda>::new(s.clone(), k.clone()))
137 .collect();
138 result.push((
139 agenda,
140 AgendaProof {
141 height: self.fi.header.height + 1,
142 agenda_hash: agenda,
143 proof,
144 timestamp: get_timestamp(),
145 },
146 ));
147 }
148 }
149 Ok(result)
150 }
151
152 pub async fn vote(&mut self, agenda_hash: Hash256) -> Result<(), Error> {
153 self.dms
154 .write()
155 .await
156 .commit_message(&Vote { agenda_hash })
157 .await?;
158 Ok(())
159 }
160
161 pub async fn flush(&self) -> Result<(), Error> {
162 Ok(())
163 }
164
165 pub async fn update(&mut self) -> Result<(), Error> {
166 Ok(())
167 }
168
169 pub fn get_dms(&self) -> Arc<RwLock<Dms<Vote>>> {
170 Arc::clone(&self.dms)
171 }
172}