keri_core/state/
mod.rs

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                // save indexed signer's identifiers
72                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/// Identifier State
107///
108/// represents the accumulated state after applying events, based on section 13 of the paper
109#[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    /// Apply
200    ///
201    /// validates and applies the semantic rules of the event to the event state
202    pub fn apply<T: EventSemantics>(self, event: &T) -> Result<Self, Error> {
203        event.apply_to(self)
204    }
205}
206
207/// EventSemantics
208///
209/// Describes an interface for applying the semantic rule of an event to the state of an Identifier
210pub trait EventSemantics {
211    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
212        // default impl is the identity transition
213        Ok(state)
214    }
215}