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