hbkr-rs 0.3.2

Hashblock Key Rotation
Documentation
use crate::{
    derivation::DerivationCode,
    errors::KrError,
    event::{Event, KrInceptionEvent},
    event_data::EventData,
    event_message::EventMessage,
    identifier_prefix::IdentifierPrefix,
    identifier_state::IdentifierState,
    key_event_message::KeyEvent,
    said::SelfAddressing,
    serialization_info::{SerializationFormats, SerializationInfo},
    EventSemantics, EventTypeTag, SaidEvent, Typeable,
};
use serde::{Deserialize, Serialize};
use serde_hex::{Compact, SerHex};

pub fn dummy_prefix(derivation: &SelfAddressing) -> String {
    "#".repeat(derivation.code_len() + derivation.derivative_b64_len())
}

/// Dummy Inception Event
///
/// Used only to encapsulate the prefix derivation process for inception and delegated inception
#[derive(Serialize, Debug, Clone)]
pub(crate) struct DummyInceptionEvent {
    #[serde(rename = "v")]
    pub serialization_info: SerializationInfo,
    #[serde(rename = "t")]
    event_type: EventTypeTag,
    #[serde(rename = "d")]
    digest: String,
    #[serde(rename = "i")]
    prefix: String,
    #[serde(rename = "s", with = "SerHex::<Compact>")]
    sn: u8,
    #[serde(flatten)]
    data: EventData,
}

impl DummyInceptionEvent {
    pub fn dummy_inception_data(
        icp: KrInceptionEvent,
        derivation: &SelfAddressing,
        format: SerializationFormats,
    ) -> Result<Self, KrError> {
        DummyInceptionEvent::derive_data(EventData::Icp(icp), derivation, format)
    }

    pub fn dummy_delegated_inception_data(
        dip: DelegatedInceptionEvent,
        derivation: &SelfAddressing,
        format: SerializationFormats,
    ) -> Result<Self, KrError> {
        DummyInceptionEvent::derive_data(EventData::Dip(dip), derivation, format)
    }

    fn derive_data(
        data: EventData,
        derivation: &SelfAddressing,
        format: SerializationFormats,
    ) -> Result<Self, KrError> {
        Ok(Self {
            serialization_info: SerializationInfo::new(
                format,
                Self {
                    serialization_info: SerializationInfo::new(format, 0),
                    event_type: data.get_type(),
                    prefix: dummy_prefix(derivation),
                    digest: dummy_prefix(derivation),
                    sn: 0,
                    data: data.clone(),
                }
                .serialize()?
                .len(),
            ),
            event_type: data.get_type(),
            digest: dummy_prefix(derivation),
            prefix: dummy_prefix(derivation),
            sn: 0,
            data,
        })
    }

    pub fn serialize(&self) -> Result<Vec<u8>, KrError> {
        self.serialization_info.kind.encode(&self)
    }
}

#[derive(Serialize, Debug, Clone)]
pub(crate) struct DummyEventMessage<T: Serialize> {
    #[serde(rename = "v")]
    pub serialization_info: SerializationInfo,
    #[serde(rename = "t")]
    pub event_type: EventTypeTag,
    #[serde(rename = "d")]
    pub digest: String,
    #[serde(flatten)]
    pub data: T,
}

impl<T: Serialize + Typeable + Clone> DummyEventMessage<T> {
    pub fn dummy_event(
        event: T,
        format: SerializationFormats,
        derivation: &SelfAddressing,
    ) -> Result<Self, KrError> {
        Ok(Self {
            serialization_info: SerializationInfo::new(
                format,
                Self::get_size(&event, format, derivation)?,
            ),
            event_type: event.get_type(),
            data: event,
            digest: dummy_prefix(derivation),
        })
    }

    fn get_size(
        event: &T,
        format: SerializationFormats,
        derivation: &SelfAddressing,
    ) -> Result<usize, KrError> {
        Ok(Self {
            serialization_info: SerializationInfo::new(format, 0),
            event_type: event.get_type(),
            data: event.clone(),
            digest: dummy_prefix(derivation),
        }
        .serialize()?
        .len())
    }

    pub fn serialize(&self) -> Result<Vec<u8>, KrError> {
        self.serialization_info.kind.encode(&self)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct DelegatedInceptionEvent {
    #[serde(flatten)]
    pub inception_data: KrInceptionEvent,

    #[serde(rename = "di")]
    pub delegator: IdentifierPrefix,
}

impl DelegatedInceptionEvent {
    /// Incept Self Addressing
    ///
    /// Takes the inception data and creates an EventMessage based on it, with
    /// using the given format and deriving a Self Addressing Identifier with the
    /// given derivation method
    pub fn incept_self_addressing(
        self,
        derivation: SelfAddressing,
        format: SerializationFormats,
    ) -> Result<EventMessage<KeyEvent>, KrError> {
        let dummy_event =
            DummyInceptionEvent::dummy_delegated_inception_data(self.clone(), &derivation, format)?;
        let digest = derivation.derive(&dummy_event.serialize()?);
        let event = Event::new(
            IdentifierPrefix::SelfAddressing(digest.clone()),
            0,
            EventData::Dip(self),
        );
        Ok(EventMessage {
            serialization_info: dummy_event.serialization_info,
            event: SaidEvent::new(digest, event),
        })
    }
}

impl EventSemantics for DelegatedInceptionEvent {
    fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, KrError> {
        Ok(IdentifierState {
            delegator: Some(self.delegator.clone()),
            ..self.inception_data.apply_to(state)?
        })
    }
}