use crate::{
basicpre::BasicPrefix,
dummy_event::DummyInceptionEvent,
errors::KrError,
event_data::EventData,
event_message::EventMessage,
identifier_prefix::IdentifierPrefix,
identifier_state::{IdentifierState, LastEstablishmentData},
key_config::KeyConfig,
key_event_message::KeyEvent,
said::{SelfAddressing, SelfAddressingPrefix},
seal::Seal,
serialization_info::SerializationFormats,
witness_config::{InceptionWitnessConfig, WitnessConfig},
EventSemantics, EventTypeTag, SaidEvent, Typeable,
};
use serde::{Deserialize, Serialize};
use serde_hex::{Compact, SerHex};
#[derive(Clone, Debug)]
pub enum EventType {
Inception,
Rotation,
Delegation,
Termination,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Event {
#[serde(rename = "i")]
pub prefix: IdentifierPrefix,
#[serde(rename = "s", with = "SerHex::<Compact>")]
pub sn: u64,
#[serde(flatten)]
pub event_data: EventData,
}
impl Event {
pub fn new(prefix: IdentifierPrefix, sn: u64, event_data: EventData) -> Self {
Event {
prefix,
sn,
event_data,
}
}
pub fn to_message(
self,
format: SerializationFormats,
derivation: &SelfAddressing,
) -> Result<EventMessage<KeyEvent>, KrError> {
match (&self.prefix, self.event_data.clone()) {
(IdentifierPrefix::SelfAddressing(_), EventData::Icp(icp)) => {
icp.incept_self_addressing(derivation.clone(), format)
}
(IdentifierPrefix::SelfAddressing(_), EventData::Dip(dip)) => {
dip.incept_self_addressing(derivation.clone(), format)
}
_ => SaidEvent::<Event>::to_message(self, format, derivation),
}
}
}
impl Typeable for Event {
fn get_type(&self) -> EventTypeTag {
self.event_data.get_type()
}
}
impl EventSemantics for Event {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, KrError> {
match self.event_data {
EventData::Icp(_) | EventData::Dip(_) => {
if state.prefix != IdentifierPrefix::default() {
return Err(KrError::EventDuplicateError);
}
if self.sn != 0 {
return Err(KrError::SemanticError("SN is not correct".to_string()));
}
}
_ => {
if self.prefix != state.prefix {
return Err(KrError::SemanticError("Prefix does not match".to_string()));
} else if self.sn < state.sn + 1 {
return Err(KrError::EventDuplicateError);
} else if self.sn > state.sn + 1 {
return Err(KrError::EventOutOfOrderError);
}
}
};
self.event_data.apply_to(IdentifierState {
sn: self.sn,
prefix: self.prefix.clone(),
..state
})
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct KrInceptionEvent {
#[serde(flatten)]
pub key_config: KeyConfig,
#[serde(flatten)]
pub witness_config: InceptionWitnessConfig,
#[serde(rename = "c")]
pub inception_configuration: Vec<String>,
#[serde(rename = "a")]
pub data: Vec<Seal>,
}
impl KrInceptionEvent {
pub fn new(
key_config: KeyConfig,
witness_config: Option<InceptionWitnessConfig>,
inception_config: Option<Vec<String>>,
) -> Self {
Self {
key_config,
witness_config: witness_config.map_or_else(InceptionWitnessConfig::default, |w| w),
inception_configuration: inception_config.map_or_else(Vec::new, |c| c),
data: vec![],
}
}
pub fn incept_self_addressing(
self,
derivation: SelfAddressing,
format: SerializationFormats,
) -> Result<EventMessage<KeyEvent>, KrError> {
let dummy_event =
DummyInceptionEvent::dummy_inception_data(self.clone(), &derivation, format)?;
let digest = derivation.derive(&dummy_event.serialize()?);
let event = Event::new(
IdentifierPrefix::SelfAddressing(digest.clone()),
0,
EventData::Icp(self),
);
Ok(EventMessage {
serialization_info: dummy_event.serialization_info,
event: SaidEvent::new(digest, event),
})
}
}
impl EventSemantics for KrInceptionEvent {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, KrError> {
let last_est = LastEstablishmentData {
sn: state.sn,
digest: state.last_event_digest.clone(),
br: vec![],
ba: vec![],
};
Ok(IdentifierState {
current: self.key_config.clone(),
last_est,
..state
})
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct KrRotationEvent {
#[serde(rename = "p")]
pub previous_event_hash: SelfAddressingPrefix,
#[serde(flatten)]
pub key_config: KeyConfig,
#[serde(flatten)]
pub witness_config: WitnessConfig,
#[serde(rename = "a")]
pub data: Vec<Seal>,
}
impl EventSemantics for KrRotationEvent {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, KrError> {
if state.current.verify_next(&self.key_config) {
let witnesses =
if !self.witness_config.prune.is_empty() || !self.witness_config.graft.is_empty() {
let mut prunned = state
.witnesses
.into_iter()
.filter(|e| !self.witness_config.prune.contains(e))
.collect::<Vec<BasicPrefix>>();
prunned.append(&mut self.witness_config.graft.clone());
prunned
} else {
state.witnesses.clone()
};
let last_est = LastEstablishmentData {
sn: state.sn,
digest: state.last_event_digest.clone(),
br: self.witness_config.graft.clone(),
ba: self.witness_config.prune.clone(),
};
Ok(IdentifierState {
current: self.key_config.clone(),
tally: self.witness_config.tally,
witnesses,
last_est,
..state
})
} else {
Err(KrError::SemanticError(
"Incorrect Key Config binding".into(),
))
}
}
}