keri_core/state/
mod.rs

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                // save indexed signer's identifiers
51                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/// Identifier State
86///
87/// represents the accumulated state after applying events, based on section 13 of the paper
88#[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    /// Apply
169    ///
170    /// validates and applies the semantic rules of the event to the event state
171    pub fn apply<T: EventSemantics>(self, event: &T) -> Result<Self, Error> {
172        event.apply_to(self)
173    }
174}
175
176/// EventSemantics
177///
178/// Describes an interface for applying the semantic rule of an event to the state of an Identifier
179pub trait EventSemantics {
180    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
181        // default impl is the identity transition
182        Ok(state)
183    }
184}