1use std::collections::HashSet;
2
3use crate::{
4 database::redb::rkyv_adapter::said_wrapper::SaidValue,
5 error::Error,
6 event::{
7 event_data::EventData,
8 sections::{threshold::SignatureThreshold, KeyConfig},
9 },
10 event_message::EventTypeTag,
11 prefix::{BasicPrefix, IdentifierPrefix, IndexedSignature, SelfSigningPrefix},
12};
13use serde::{Deserialize, Serialize};
14use serde_hex::{Compact, SerHex};
15
16#[derive(
17 Serialize,
18 Deserialize,
19 Debug,
20 Clone,
21 PartialEq,
22 Eq,
23 Default,
24 rkyv::Archive,
25 rkyv::Serialize,
26 rkyv::Deserialize,
27)]
28pub struct LastEstablishmentData {
29 #[serde(rename = "s", with = "SerHex::<Compact>")]
30 pub(crate) sn: u64,
31 #[serde(rename = "d")]
32 pub(crate) digest: SaidValue,
33 #[serde(rename = "br")]
34 pub(crate) br: Vec<BasicPrefix>,
35 #[serde(rename = "ba")]
36 pub(crate) ba: Vec<BasicPrefix>,
37}
38
39#[derive(
40 Default,
41 PartialEq,
42 Debug,
43 Clone,
44 Serialize,
45 Deserialize,
46 rkyv::Archive,
47 rkyv::Serialize,
48 rkyv::Deserialize,
49)]
50pub struct WitnessConfig {
51 #[serde(rename = "bt")]
52 pub tally: SignatureThreshold,
53
54 #[serde(rename = "b")]
55 pub witnesses: Vec<BasicPrefix>,
56}
57
58impl WitnessConfig {
59 pub fn enough_receipts<I, R>(
60 &self,
61 receipts_couplets: I,
62 indexed_receipts: R,
63 ) -> Result<bool, Error>
64 where
65 I: IntoIterator<Item = (BasicPrefix, SelfSigningPrefix)>,
66 R: IntoIterator<Item = IndexedSignature>,
67 {
68 match self.tally.clone() {
69 SignatureThreshold::Simple(t) => {
70 let mut unique = HashSet::new();
71 indexed_receipts.into_iter().for_each(|w| {
73 unique.insert(
74 self.witnesses
75 .get(w.index.current() as usize)
76 .unwrap()
77 .clone(),
78 );
79 });
80 receipts_couplets
81 .into_iter()
82 .filter(|(witness, _sig)| self.witnesses.contains(witness))
83 .for_each(|(witness_id, _witness_sig)| {
84 unique.insert(witness_id);
85 });
86 Ok(unique.len() >= t as usize)
87 }
88 SignatureThreshold::Weighted(t) => {
89 let indexes = receipts_couplets
90 .into_iter()
91 .filter_map(|(id, _signature)| self.witnesses.iter().position(|wit| wit == &id))
92 .chain(
93 indexed_receipts
94 .into_iter()
95 .map(|att| att.index.current() as usize),
96 )
97 .collect::<Vec<_>>();
98 match t.enough_signatures(&indexes) {
99 Ok(_) => Ok(true),
100 Err(e) => Err(Error::KeyConfigError(e)),
101 }
102 }
103 }
104 }
105}
106#[derive(
110 Default,
111 PartialEq,
112 Debug,
113 Clone,
114 Serialize,
115 Deserialize,
116 rkyv::Archive,
117 rkyv::Serialize,
118 rkyv::Deserialize,
119)]
120pub struct IdentifierState {
121 #[serde(rename = "i")]
122 pub prefix: IdentifierPrefix,
123
124 #[serde(rename = "s", with = "SerHex::<Compact>")]
125 pub sn: u64,
126
127 #[serde(rename = "d")]
128 pub last_event_digest: SaidValue,
129
130 #[serde(rename = "p")]
131 pub last_previous: Option<SaidValue>,
132
133 #[serde(rename = "et")]
134 pub last_event_type: Option<EventTypeTag>,
135
136 #[serde(flatten)]
137 pub current: KeyConfig,
138
139 #[serde(flatten)]
140 pub witness_config: WitnessConfig,
141
142 #[serde(rename = "di", with = "empty_string_as_none")]
143 pub delegator: Option<IdentifierPrefix>,
144
145 #[serde(rename = "ee")]
146 pub last_est: LastEstablishmentData,
147}
148
149mod empty_string_as_none {
150 use serde::{de::IntoDeserializer, Deserialize, Deserializer, Serializer};
151
152 pub fn deserialize<'d, D, T>(de: D) -> Result<Option<T>, D::Error>
153 where
154 D: Deserializer<'d>,
155 T: Deserialize<'d>,
156 {
157 let opt = Option::<String>::deserialize(de)?;
158 let opt = opt.as_deref();
159 match opt {
160 None | Some("") => Ok(None),
161 Some(s) => T::deserialize(s.into_deserializer()).map(Some),
162 }
163 }
164
165 pub fn serialize<S, T>(t: &Option<T>, s: S) -> Result<S::Ok, S::Error>
166 where
167 S: Serializer,
168 T: ToString,
169 {
170 s.serialize_str(&match &t {
171 Some(v) => v.to_string(),
172 None => "".into(),
173 })
174 }
175}
176
177impl EventTypeTag {
178 pub fn is_establishment_event(&self) -> bool {
179 matches!(
180 self,
181 EventTypeTag::Icp | EventTypeTag::Rot | EventTypeTag::Dip | EventTypeTag::Drt
182 )
183 }
184}
185
186impl From<&EventData> for EventTypeTag {
187 fn from(ed: &EventData) -> Self {
188 match ed {
189 EventData::Icp(_) => EventTypeTag::Icp,
190 EventData::Rot(_) => EventTypeTag::Rot,
191 EventData::Ixn(_) => EventTypeTag::Ixn,
192 EventData::Dip(_) => EventTypeTag::Dip,
193 EventData::Drt(_) => EventTypeTag::Drt,
194 }
195 }
196}
197
198impl IdentifierState {
199 pub fn apply<T: EventSemantics>(self, event: &T) -> Result<Self, Error> {
203 event.apply_to(self)
204 }
205}
206
207pub trait EventSemantics {
211 fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
212 Ok(state)
214 }
215}