keri_core/event_message/
msg.rs

1use said::version::{format::SerializationFormats, SerializationInfo};
2use said::{
3    derivation::HashFunction, derivation::HashFunctionCode, sad::SAD, SelfAddressingIdentifier,
4};
5use serde::{Deserialize, Serialize};
6
7use super::{EventTypeTag, Typeable};
8use crate::database::redb::rkyv_adapter::said_wrapper::SaidValue;
9use crate::database::redb::rkyv_adapter::serialization_info_wrapper::SerializationInfoDef;
10use crate::error::Error;
11
12pub type KeriEvent<D> = TypedEvent<EventTypeTag, D>;
13
14#[derive(
15    Deserialize,
16    Serialize,
17    Debug,
18    Clone,
19    PartialEq,
20    rkyv::Archive,
21    rkyv::Serialize,
22    rkyv::Deserialize,
23)]
24pub struct TypedEvent<T: Serialize + Clone, D: Serialize + Clone + Typeable<TypeTag = T>> {
25    /// Serialization Information
26    ///
27    /// Encodes the version, size and serialization format of the event
28    #[serde(rename = "v")]
29    #[rkyv(with = SerializationInfoDef)]
30    pub serialization_info: SerializationInfo,
31
32    #[serde(rename = "t")]
33    pub event_type: T,
34
35    /// Digest of the event
36    ///
37    /// While computing the digest, this field is replaced with sequence of `#`,
38    /// its length depends on derivation type. Then it is replaced by computed
39    /// SAI.
40    #[serde(rename = "d")]
41    pub(crate) digest: Option<SaidValue>,
42    #[serde(flatten)]
43    pub data: D,
44}
45
46impl<T: Serialize + Clone, D: Serialize + Typeable<TypeTag = T> + Clone> TypedEvent<T, D> {
47    pub fn digest(&self) -> Result<SelfAddressingIdentifier, Error> {
48        self.digest
49            .to_owned()
50            .ok_or(Error::EventDigestError)
51            .map(|said| said.into())
52    }
53
54    pub fn check_digest(&self) -> Result<(), Error> {
55        let event_digest = self.digest()?;
56        let hash_function_code = event_digest.derivation.to_owned().into();
57        let dummy = self.derivation_data(&hash_function_code, &self.serialization_info.kind);
58        event_digest
59            .verify_binding(&dummy)
60            .then_some(())
61            .ok_or(Error::IncorrectDigest)
62    }
63
64    pub fn new(format: SerializationFormats, derivation: HashFunction, event: D) -> Self {
65        let tmp_serialization_info = SerializationInfo::new_empty("KERI".to_string(), 1, 0, format);
66
67        let mut tmp_self = Self {
68            serialization_info: tmp_serialization_info,
69            event_type: event.get_type(),
70            digest: None,
71            data: event,
72        };
73        let hash_function = derivation.into();
74        let encoded = tmp_self.derivation_data(&hash_function, &format);
75
76        let event_len = encoded.len();
77        tmp_self.serialization_info.size = event_len;
78        tmp_self.compute_digest(&hash_function, &format);
79        tmp_self
80    }
81
82    pub fn encode(&self) -> Result<Vec<u8>, Error> {
83        Ok(self.serialization_info.serialize(&self).unwrap())
84    }
85}
86
87impl<T: Serialize + Clone, D: Serialize + Clone + Typeable<TypeTag = T>> SAD for TypedEvent<T, D> {
88    fn compute_digest(&mut self, derivation: &HashFunctionCode, format: &SerializationFormats) {
89        let der_data = self.derivation_data(derivation, format);
90        let said = HashFunction::from(derivation.clone())
91            .derive(&der_data)
92            .into();
93        self.digest = Some(said);
94    }
95
96    fn derivation_data(
97        &self,
98        derivation: &HashFunctionCode,
99        format: &SerializationFormats,
100    ) -> Vec<u8> {
101        let tmp_event = DummyTypedEvent::convert(self.clone(), derivation.clone());
102        format.encode(&tmp_event).unwrap()
103    }
104}
105
106#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
107pub struct DummyTypedEvent<T: Serialize + Clone, D: Serialize + Clone + Typeable<TypeTag = T>> {
108    #[serde(rename = "v")]
109    pub serialization_info: SerializationInfo,
110
111    #[serde(rename = "t")]
112    pub event_type: T,
113
114    #[serde(rename = "d")]
115    digest: String,
116    #[serde(flatten)]
117    pub data: D,
118}
119
120impl<T: Serialize + Clone, D: Serialize + Clone + Typeable<TypeTag = T>> DummyTypedEvent<T, D> {
121    fn convert(value: TypedEvent<T, D>, hash_function: HashFunctionCode) -> Self {
122        Self {
123            serialization_info: value.serialization_info,
124            event_type: value.event_type,
125            digest: "#".repeat(HashFunction::from(hash_function).get_len()),
126            data: value.data,
127        }
128    }
129}
130
131#[test]
132fn test_rkyv_serialization() {
133    use crate::event::KeyEvent;
134    use rkyv::rancor::Failure;
135    let icp_raw: &[u8] = br#"{"v":"KERI10JSON0001e7_","t":"icp","d":"EBfxc4RiVY6saIFmUfEtETs1FcqmktZW88UkbnOg0Qen","i":"EBfxc4RiVY6saIFmUfEtETs1FcqmktZW88UkbnOg0Qen","s":"0","kt":"2","k":["DErocgXD2RGSyvn3MObcx59jeOsEQhv2TqHirVkzrp0Q","DFXLiTjiRdSBPLL6hLa0rskIxk3dh4XwJLfctkJFLRSS","DE9YgIQVgpLwocTVrG8tidKScsQSMWwLWywNC48fhq4f"],"nt":"2","n":["EDJk5EEpC4-tQ7YDwBiKbpaZahh1QCyQOnZRF7p2i8k8","EAXfDjKvUFRj-IEB_o4y-Y_qeJAjYfZtOMD9e7vHNFss","EN8l6yJC2PxribTN0xfri6bLz34Qvj-x3cNwcV3DvT2m"],"bt":"0","b":[],"c":[],"a":[]}"#;
136
137    let event: KeriEvent<KeyEvent> = serde_json::from_slice(icp_raw).unwrap();
138
139    let bytes = rkyv::to_bytes::<rkyv::rancor::Failure>(&event).unwrap();
140
141    let archived: &ArchivedTypedEvent<EventTypeTag, KeyEvent> =
142        rkyv::access::<_, Failure>(&bytes).unwrap();
143
144    let deserialized: KeriEvent<KeyEvent> =
145        rkyv::deserialize::<KeriEvent<KeyEvent>, Failure>(archived).unwrap();
146    assert_eq!(deserialized, event);
147}