1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
use std::collections::HashSet;

use crate::{
    error::Error,
    event::{
        event_data::EventData,
        sections::{threshold::SignatureThreshold, KeyConfig},
    },
    event_message::EventTypeTag,
    prefix::{BasicPrefix, IdentifierPrefix, IndexedSignature, SelfSigningPrefix},
};
use said::SelfAddressingIdentifier;
use serde::{Deserialize, Serialize};
use serde_hex::{Compact, SerHex};

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
pub struct LastEstablishmentData {
    #[serde(rename = "s", with = "SerHex::<Compact>")]
    pub(crate) sn: u64,
    #[serde(rename = "d")]
    pub(crate) digest: SelfAddressingIdentifier,
    #[serde(rename = "br")]
    pub(crate) br: Vec<BasicPrefix>,
    #[serde(rename = "ba")]
    pub(crate) ba: Vec<BasicPrefix>,
}

#[derive(Default, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct WitnessConfig {
    #[serde(rename = "bt")]
    pub tally: SignatureThreshold,

    #[serde(rename = "b")]
    pub witnesses: Vec<BasicPrefix>,
}

impl WitnessConfig {
    pub fn enough_receipts<I, R>(
        &self,
        receipts_couplets: I,
        indexed_receipts: R,
    ) -> Result<bool, Error>
    where
        I: IntoIterator<Item = (BasicPrefix, SelfSigningPrefix)>,
        R: IntoIterator<Item = IndexedSignature>,
    {
        match self.tally.clone() {
            SignatureThreshold::Simple(t) => {
                let mut unique = HashSet::new();
                // save indexed signer's identifiers
                indexed_receipts.into_iter().for_each(|w| {
                    unique.insert(
                        self.witnesses
                            .get(w.index.current() as usize)
                            .unwrap()
                            .clone(),
                    );
                });
                receipts_couplets
                    .into_iter()
                    .filter(|(witness, _sig)| self.witnesses.contains(witness))
                    .for_each(|(witness_id, _witness_sig)| {
                        unique.insert(witness_id);
                    });
                Ok(unique.len() >= t as usize)
            }
            SignatureThreshold::Weighted(t) => {
                let indexes = receipts_couplets
                    .into_iter()
                    .filter_map(|(id, _signature)| self.witnesses.iter().position(|wit| wit == &id))
                    .chain(
                        indexed_receipts
                            .into_iter()
                            .map(|att| att.index.current() as usize),
                    )
                    .collect::<Vec<_>>();
                match t.enough_signatures(&indexes) {
                    Ok(_) => Ok(true),
                    Err(e) => Err(Error::KeyConfigError(e)),
                }
            }
        }
    }
}
/// Identifier State
///
/// represents the accumulated state after applying events, based on section 13 of the paper
#[derive(Default, PartialEq, Debug, Clone, Serialize, Deserialize)]
pub struct IdentifierState {
    #[serde(rename = "i")]
    pub prefix: IdentifierPrefix,

    #[serde(rename = "s", with = "SerHex::<Compact>")]
    pub sn: u64,

    #[serde(rename = "d")]
    pub last_event_digest: SelfAddressingIdentifier,

    #[serde(rename = "p")]
    pub last_previous: Option<SelfAddressingIdentifier>,

    #[serde(rename = "et")]
    pub last_event_type: Option<EventTypeTag>,

    #[serde(flatten)]
    pub current: KeyConfig,

    #[serde(flatten)]
    pub witness_config: WitnessConfig,

    #[serde(rename = "di", with = "empty_string_as_none")]
    pub delegator: Option<IdentifierPrefix>,

    #[serde(rename = "ee")]
    pub last_est: LastEstablishmentData,
}

mod empty_string_as_none {
    use serde::{de::IntoDeserializer, Deserialize, Deserializer, Serializer};

    pub fn deserialize<'d, D, T>(de: D) -> Result<Option<T>, D::Error>
    where
        D: Deserializer<'d>,
        T: Deserialize<'d>,
    {
        let opt = Option::<String>::deserialize(de)?;
        let opt = opt.as_deref();
        match opt {
            None | Some("") => Ok(None),
            Some(s) => T::deserialize(s.into_deserializer()).map(Some),
        }
    }

    pub fn serialize<S, T>(t: &Option<T>, s: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
        T: ToString,
    {
        s.serialize_str(&match &t {
            Some(v) => v.to_string(),
            None => "".into(),
        })
    }
}

impl EventTypeTag {
    pub fn is_establishment_event(&self) -> bool {
        matches!(
            self,
            EventTypeTag::Icp | EventTypeTag::Rot | EventTypeTag::Dip | EventTypeTag::Drt
        )
    }
}

impl From<&EventData> for EventTypeTag {
    fn from(ed: &EventData) -> Self {
        match ed {
            EventData::Icp(_) => EventTypeTag::Icp,
            EventData::Rot(_) => EventTypeTag::Rot,
            EventData::Ixn(_) => EventTypeTag::Ixn,
            EventData::Dip(_) => EventTypeTag::Dip,
            EventData::Drt(_) => EventTypeTag::Drt,
        }
    }
}

impl IdentifierState {
    /// Apply
    ///
    /// validates and applies the semantic rules of the event to the event state
    pub fn apply<T: EventSemantics>(self, event: &T) -> Result<Self, Error> {
        event.apply_to(self)
    }
}

/// EventSemantics
///
/// Describes an interface for applying the semantic rule of an event to the state of an Identifier
pub trait EventSemantics {
    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
        // default impl is the identity transition
        Ok(state)
    }
}