Skip to main content

ave_core/model/
event.rs

1//! # Event data model.
2//!
3
4use std::collections::BTreeSet;
5
6use super::network::TimeOut;
7
8use crate::{
9    evaluation::response::{EvaluatorError, EvaluatorResponse},
10    subject::Metadata,
11    validation::request::ActualProtocols,
12};
13
14use ave_common::{
15    bridge::request::EventRequestType,
16    identity::{
17        DigestIdentifier, HashAlgorithm, PublicKey, Signature, Signed,
18        TimeStamp, hash_borsh,
19    },
20    request::{CreateRequest, EventRequest},
21    response::{EvalResDB, LedgerDB, RequestEventDB},
22};
23
24use borsh::{BorshDeserialize, BorshSerialize};
25use serde::{Deserialize, Serialize};
26
27use super::error::{LedgerError, ProtocolsError};
28
29#[derive(
30    Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize,
31)]
32pub enum EvaluationResponse {
33    Ok {
34        result: EvaluatorResponse,
35        result_hash: DigestIdentifier,
36    },
37    Error {
38        result: EvaluatorError,
39        result_hash: DigestIdentifier,
40    },
41}
42
43impl EvaluationResponse {
44    pub fn build_opaque(&self) -> EvaluationResponseOpaque {
45        match self.clone() {
46            Self::Ok { result_hash, .. } => {
47                EvaluationResponseOpaque::Ok { result_hash }
48            }
49            Self::Error { result_hash, .. } => {
50                EvaluationResponseOpaque::Error { result_hash }
51            }
52        }
53    }
54}
55
56#[derive(
57    Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize,
58)]
59pub enum EvaluationResponseOpaque {
60    Ok { result_hash: DigestIdentifier },
61    Error { result_hash: DigestIdentifier },
62}
63
64#[derive(
65    Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize,
66)]
67pub struct EvaluationDataOpaque {
68    pub eval_req_signature: Signature,
69    pub eval_req_hash: DigestIdentifier,
70    pub evaluators_signatures: Vec<Signature>,
71    pub viewpoints: BTreeSet<String>,
72    pub response: EvaluationResponseOpaque,
73}
74
75impl EvaluationDataOpaque {
76    pub const fn is_ok(&self) -> bool {
77        matches!(&self.response, EvaluationResponseOpaque::Ok { .. })
78    }
79}
80
81#[derive(
82    Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize,
83)]
84pub struct EvaluationData {
85    pub eval_req_signature: Signature,
86    pub eval_req_hash: DigestIdentifier,
87    pub evaluators_signatures: Vec<Signature>,
88    pub response: EvaluationResponse,
89}
90
91impl EvaluationData {
92    pub const fn is_ok(&self) -> bool {
93        matches!(&self.response, EvaluationResponse::Ok { .. })
94    }
95
96    pub fn evaluator_response_ok(&self) -> Option<EvaluatorResponse> {
97        match &self.response {
98            EvaluationResponse::Ok { result, .. } => Some(result.clone()),
99            _ => None,
100        }
101    }
102}
103
104#[derive(
105    Clone, Debug, Serialize, Deserialize, BorshDeserialize, BorshSerialize,
106)]
107pub struct ApprovalData {
108    pub approval_req_signature: Signature,
109    pub approval_req_hash: DigestIdentifier,
110    pub approvers_agrees_signatures: Vec<Signature>,
111    pub approvers_disagrees_signatures: Vec<Signature>,
112    pub approvers_timeout: Vec<TimeOut>,
113    pub approved: bool,
114}
115
116#[derive(
117    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
118)]
119pub struct ValidationData {
120    pub validation_req_signature: Signature,
121    pub validation_req_hash: DigestIdentifier,
122    pub validators_signatures: Vec<Signature>,
123    pub validation_metadata: ValidationMetadata,
124}
125
126#[derive(
127    Debug,
128    Clone,
129    Serialize,
130    Deserialize,
131    BorshSerialize,
132    BorshDeserialize,
133    Eq,
134    PartialEq,
135    Hash,
136)]
137pub enum ValidationMetadata {
138    ModifiedHash {
139        modified_metadata_without_propierties_hash: DigestIdentifier,
140        propierties_hash: DigestIdentifier,
141        event_request_hash: DigestIdentifier,
142        viewpoints_hash: DigestIdentifier,
143    },
144    Metadata(Box<Metadata>),
145}
146
147#[derive(
148    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
149)]
150pub struct OpaqueData {
151    pub subject_id: DigestIdentifier,
152    pub event_request_timestamp: TimeStamp,
153    pub signer: PublicKey,
154}
155
156#[derive(
157    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
158)]
159pub enum Protocols {
160    Create {
161        event_request: Signed<EventRequest>,
162        validation: ValidationData,
163    },
164    TrackerFactFull {
165        event_request: Signed<EventRequest>,
166        evaluation: EvaluationData,
167        validation: ValidationData,
168    },
169    TrackerFactOpaque {
170        event_request_hash: DigestIdentifier,
171        evaluation: EvaluationDataOpaque,
172        validation: ValidationData,
173        data: OpaqueData,
174    },
175    GovFact {
176        event_request: Signed<EventRequest>,
177        evaluation: EvaluationData,
178        approval: Option<ApprovalData>,
179        validation: ValidationData,
180    },
181    Transfer {
182        event_request: Signed<EventRequest>,
183        evaluation: EvaluationData,
184        validation: ValidationData,
185    },
186    TrackerConfirm {
187        event_request: Signed<EventRequest>,
188        validation: ValidationData,
189    },
190    GovConfirm {
191        event_request: Signed<EventRequest>,
192        evaluation: EvaluationData,
193        validation: ValidationData,
194    },
195    Reject {
196        event_request: Signed<EventRequest>,
197        validation: ValidationData,
198    },
199    EOL {
200        event_request: Signed<EventRequest>,
201        validation: ValidationData,
202    },
203}
204
205impl Protocols {
206    pub fn to_tracker_opaque(&self) -> Result<Self, ProtocolsError> {
207        match self {
208            Self::TrackerFactFull {
209                event_request,
210                evaluation,
211                validation,
212            } => {
213                let fact_request = match event_request.content() {
214                    EventRequest::Fact(fact_request) => fact_request,
215                    _ => {
216                        return Err(
217                            ProtocolsError::InvalidTrackerFactFullEventRequest,
218                        );
219                    }
220                };
221
222                Ok(Self::TrackerFactOpaque {
223                    data: OpaqueData {
224                        subject_id: event_request.content().get_subject_id(),
225                        event_request_timestamp: event_request
226                            .signature()
227                            .timestamp,
228                        signer: event_request.signature().signer.clone(),
229                    },
230                    event_request_hash: match &validation.validation_metadata {
231                        ValidationMetadata::ModifiedHash {
232                            event_request_hash,
233                            ..
234                        } => event_request_hash.clone(),
235                        ValidationMetadata::Metadata(..) => {
236                            return Err(
237                                ProtocolsError::InvalidTrackerFactFullEventRequest,
238                            );
239                        }
240                    },
241                    evaluation: EvaluationDataOpaque {
242                        eval_req_signature: evaluation
243                            .eval_req_signature
244                            .clone(),
245                        eval_req_hash: evaluation.eval_req_hash.clone(),
246                        evaluators_signatures: evaluation
247                            .evaluators_signatures
248                            .clone(),
249                        viewpoints: fact_request.viewpoints.clone(),
250                        response: evaluation.response.build_opaque(),
251                    },
252                    validation: validation.clone(),
253                })
254            }
255            Self::TrackerFactOpaque { .. } => Ok(self.clone()),
256            _ => Err(ProtocolsError::InvalidTrackerOpaqueProjection),
257        }
258    }
259
260    pub fn hash_for_ledger(
261        &self,
262        hash: &HashAlgorithm,
263    ) -> Result<DigestIdentifier, ProtocolsError> {
264        match self {
265            Self::TrackerFactFull { .. } => {
266                let opaque = self.to_tracker_opaque()?;
267                hash_borsh(&*hash.hasher(), &opaque)
268                    .map_err(|e| ProtocolsError::HashingFailed(e.to_string()))
269            }
270            _ => hash_borsh(&*hash.hasher(), self)
271                .map_err(|e| ProtocolsError::HashingFailed(e.to_string())),
272        }
273    }
274
275    pub fn buidl_event_db(&self) -> (RequestEventDB, DigestIdentifier, u64) {
276        match self {
277            Self::Create {
278                validation,
279                event_request,
280            } => {
281                let ValidationMetadata::Metadata(metadata) =
282                    &validation.validation_metadata
283                else {
284                    unreachable!(
285                        "Unreachable combination is a create event request"
286                    )
287                };
288
289                let EventRequest::Create(create) = event_request.content()
290                else {
291                    unreachable!(
292                        "Unreachable combination is a create event request"
293                    )
294                };
295
296                (
297                    RequestEventDB::Create {
298                        name: create.name.clone(),
299                        description: create.description.clone(),
300                        schema_id: create.schema_id.to_string(),
301                        namespace: create.namespace.to_string(),
302                    },
303                    metadata.subject_id.clone(),
304                    event_request.signature().timestamp.as_nanos(),
305                )
306            }
307            Self::TrackerFactFull {
308                evaluation,
309                event_request,
310                ..
311            } => {
312                let evaluation_response = match evaluation.response.clone() {
313                    EvaluationResponse::Ok { result, .. } => {
314                        EvalResDB::Patch(result.patch.0)
315                    }
316                    EvaluationResponse::Error { result, .. } => {
317                        EvalResDB::Error(result.to_string())
318                    }
319                };
320
321                let EventRequest::Fact(fact_request) = event_request.content()
322                else {
323                    unreachable!(
324                        "Unreachable combination is a fact event request"
325                    )
326                };
327
328                (
329                    RequestEventDB::TrackerFactFull {
330                        payload: fact_request.payload.0.clone(),
331                        viewpoints: fact_request
332                            .viewpoints
333                            .iter()
334                            .cloned()
335                            .collect(),
336                        evaluation_response,
337                    },
338                    event_request.content().get_subject_id(),
339                    event_request.signature().timestamp.as_nanos(),
340                )
341            }
342            Self::TrackerFactOpaque {
343                evaluation, data, ..
344            } => (
345                RequestEventDB::TrackerFactOpaque {
346                    viewpoints: evaluation.viewpoints.iter().cloned().collect(),
347                    evaluation_success: evaluation.is_ok(),
348                },
349                data.subject_id.clone(),
350                data.event_request_timestamp.as_nanos(),
351            ),
352            Self::GovFact {
353                evaluation,
354                approval,
355                event_request,
356                ..
357            } => {
358                let (evaluation_response, approval_success) = match evaluation
359                    .response
360                    .clone()
361                {
362                    EvaluationResponse::Ok { result, .. } => {
363                        if let Some(appr) = approval {
364                            (
365                                EvalResDB::Patch(result.patch.0),
366                                Some(appr.approved),
367                            )
368                        } else {
369                            unreachable!(
370                                "In a fact governance event, if the assessment is correct, there should be approval"
371                            )
372                        }
373                    }
374                    EvaluationResponse::Error { result, .. } => {
375                        (EvalResDB::Error(result.to_string()), None)
376                    }
377                };
378
379                let EventRequest::Fact(fact_request) = event_request.content()
380                else {
381                    unreachable!(
382                        "Unreachable combination is a fact event request"
383                    )
384                };
385
386                (
387                    RequestEventDB::GovernanceFact {
388                        payload: fact_request.payload.0.clone(),
389                        evaluation_response,
390                        approval_success,
391                    },
392                    event_request.content().get_subject_id(),
393                    event_request.signature().timestamp.as_nanos(),
394                )
395            }
396            Self::Transfer {
397                evaluation,
398                event_request,
399                ..
400            } => {
401                let EventRequest::Transfer(transfer_request) =
402                    event_request.content()
403                else {
404                    unreachable!(
405                        "Unreachable combination is a transfer event request"
406                    )
407                };
408
409                let evaluation_error = match evaluation.response.clone() {
410                    EvaluationResponse::Ok { .. } => None,
411                    EvaluationResponse::Error { result, .. } => {
412                        Some(result.to_string())
413                    }
414                };
415
416                (
417                    RequestEventDB::Transfer {
418                        new_owner: transfer_request.new_owner.to_string(),
419                        evaluation_error,
420                    },
421                    event_request.content().get_subject_id(),
422                    event_request.signature().timestamp.as_nanos(),
423                )
424            }
425            Self::TrackerConfirm { event_request, .. } => (
426                RequestEventDB::TrackerConfirm,
427                event_request.content().get_subject_id(),
428                event_request.signature().timestamp.as_nanos(),
429            ),
430            Self::GovConfirm {
431                evaluation,
432                event_request,
433                ..
434            } => {
435                let EventRequest::Confirm(confirm_request) =
436                    event_request.content()
437                else {
438                    unreachable!(
439                        "Unreachable combination is a confirm event request"
440                    )
441                };
442
443                let evaluation_response = match evaluation.response.clone() {
444                    EvaluationResponse::Ok { result, .. } => {
445                        EvalResDB::Patch(result.patch.0)
446                    }
447                    EvaluationResponse::Error { result, .. } => {
448                        EvalResDB::Error(result.to_string())
449                    }
450                };
451                (
452                    RequestEventDB::GovernanceConfirm {
453                        name_old_owner: confirm_request.name_old_owner.clone(),
454                        evaluation_response,
455                    },
456                    event_request.content().get_subject_id(),
457                    event_request.signature().timestamp.as_nanos(),
458                )
459            }
460            Self::Reject { event_request, .. } => (
461                RequestEventDB::Reject,
462                event_request.content().get_subject_id(),
463                event_request.signature().timestamp.as_nanos(),
464            ),
465            Self::EOL { event_request, .. } => (
466                RequestEventDB::EOL,
467                event_request.content().get_subject_id(),
468                event_request.signature().timestamp.as_nanos(),
469            ),
470        }
471    }
472
473    pub fn get_validation_data(&self) -> ValidationData {
474        match self {
475            Self::Create { validation, .. }
476            | Self::TrackerFactFull { validation, .. }
477            | Self::TrackerFactOpaque { validation, .. }
478            | Self::GovFact { validation, .. }
479            | Self::Transfer { validation, .. }
480            | Self::TrackerConfirm { validation, .. }
481            | Self::GovConfirm { validation, .. }
482            | Self::Reject { validation, .. }
483            | Self::EOL { validation, .. } => validation.clone(),
484        }
485    }
486
487    pub fn is_success(&self) -> bool {
488        match self {
489            Self::Create { .. } => true,
490            Self::TrackerFactFull { evaluation, .. } => evaluation.is_ok(),
491            Self::TrackerFactOpaque { evaluation, .. } => evaluation.is_ok(),
492            Self::GovFact { approval, .. } => {
493                approval.as_ref().is_some_and(|approval| approval.approved)
494            }
495            Self::Transfer { evaluation, .. } => evaluation.is_ok(),
496            Self::TrackerConfirm { .. } => true,
497            Self::GovConfirm { evaluation, .. } => evaluation.is_ok(),
498            Self::Reject { .. } => true,
499            Self::EOL { .. } => true,
500        }
501    }
502
503    pub fn build(
504        is_gov: bool,
505        event_request: Signed<EventRequest>,
506        actual_protocols: ActualProtocols,
507        validation: ValidationData,
508    ) -> Result<Self, ProtocolsError> {
509        let event_request_type =
510            EventRequestType::from(event_request.content());
511
512        match (event_request_type, is_gov) {
513            (EventRequestType::Create, _) => {
514                Err(ProtocolsError::InvalidEventRequestType {
515                    request_type: "Create",
516                    is_gov,
517                })
518            }
519            (EventRequestType::Fact, true) => {
520                let (evaluation, approval) = match actual_protocols {
521                    ActualProtocols::Eval { eval_data } => {
522                        if eval_data.is_ok() {
523                            return Err(ProtocolsError::InvalidEvaluation);
524                        } else {
525                            (eval_data, None)
526                        }
527                    }
528                    ActualProtocols::EvalApprove {
529                        eval_data,
530                        approval_data,
531                    } => {
532                        if let EvaluationResponse::Ok { result, .. } =
533                            &eval_data.response
534                        {
535                            if !result.appr_required {
536                                return Err(ProtocolsError::ApprovalRequired);
537                            }
538                        } else {
539                            return Err(ProtocolsError::InvalidEvaluation);
540                        }
541
542                        (eval_data, Some(approval_data))
543                    }
544                    ActualProtocols::None => {
545                        return Err(ProtocolsError::InvalidActualProtocols {
546                            expected: "Eval or EvalApprove",
547                            got: "None",
548                        });
549                    }
550                };
551
552                Ok(Self::GovFact {
553                    event_request,
554                    evaluation,
555                    approval,
556                    validation,
557                })
558            }
559            (EventRequestType::Fact, false) => {
560                let evaluation = match actual_protocols {
561                    ActualProtocols::Eval { eval_data } => eval_data,
562                    ActualProtocols::None => {
563                        return Err(ProtocolsError::InvalidActualProtocols {
564                            expected: "Eval",
565                            got: "None",
566                        });
567                    }
568                    ActualProtocols::EvalApprove { .. } => {
569                        return Err(ProtocolsError::InvalidActualProtocols {
570                            expected: "Eval",
571                            got: "EvalApprove",
572                        });
573                    }
574                };
575
576                Ok(Self::TrackerFactFull {
577                    event_request,
578                    evaluation,
579                    validation,
580                })
581            }
582            (EventRequestType::Transfer, true)
583            | (EventRequestType::Transfer, false) => {
584                let evaluation = match actual_protocols {
585                    ActualProtocols::Eval { eval_data } => eval_data,
586                    ActualProtocols::None => {
587                        return Err(ProtocolsError::InvalidActualProtocols {
588                            expected: "Eval",
589                            got: "None",
590                        });
591                    }
592                    ActualProtocols::EvalApprove { .. } => {
593                        return Err(ProtocolsError::InvalidActualProtocols {
594                            expected: "Eval",
595                            got: "EvalApprove",
596                        });
597                    }
598                };
599
600                Ok(Self::Transfer {
601                    event_request,
602                    evaluation,
603                    validation,
604                })
605            }
606            (EventRequestType::Confirm, true) => {
607                let evaluation = match actual_protocols {
608                    ActualProtocols::Eval { eval_data } => eval_data,
609                    ActualProtocols::None => {
610                        return Err(ProtocolsError::InvalidActualProtocols {
611                            expected: "Eval",
612                            got: "None",
613                        });
614                    }
615                    ActualProtocols::EvalApprove { .. } => {
616                        return Err(ProtocolsError::InvalidActualProtocols {
617                            expected: "Eval",
618                            got: "EvalApprove",
619                        });
620                    }
621                };
622                Ok(Self::GovConfirm {
623                    event_request,
624                    evaluation,
625                    validation,
626                })
627            }
628            (EventRequestType::Confirm, false) => {
629                match actual_protocols {
630                    ActualProtocols::Eval { .. } => {
631                        return Err(ProtocolsError::InvalidActualProtocols {
632                            expected: "None",
633                            got: "Eval",
634                        });
635                    }
636                    ActualProtocols::EvalApprove { .. } => {
637                        return Err(ProtocolsError::InvalidActualProtocols {
638                            expected: "None",
639                            got: "EvalApprove",
640                        });
641                    }
642                    ActualProtocols::None => {}
643                }
644                Ok(Self::TrackerConfirm {
645                    event_request,
646                    validation,
647                })
648            }
649            (EventRequestType::Reject, true)
650            | (EventRequestType::Reject, false) => {
651                match actual_protocols {
652                    ActualProtocols::Eval { .. } => {
653                        return Err(ProtocolsError::InvalidActualProtocols {
654                            expected: "None",
655                            got: "Eval",
656                        });
657                    }
658                    ActualProtocols::EvalApprove { .. } => {
659                        return Err(ProtocolsError::InvalidActualProtocols {
660                            expected: "None",
661                            got: "EvalApprove",
662                        });
663                    }
664                    ActualProtocols::None => {}
665                }
666                Ok(Self::Reject {
667                    event_request,
668                    validation,
669                })
670            }
671            (EventRequestType::Eol, true) | (EventRequestType::Eol, false) => {
672                match actual_protocols {
673                    ActualProtocols::Eval { .. } => {
674                        return Err(ProtocolsError::InvalidActualProtocols {
675                            expected: "None",
676                            got: "Eval",
677                        });
678                    }
679                    ActualProtocols::EvalApprove { .. } => {
680                        return Err(ProtocolsError::InvalidActualProtocols {
681                            expected: "None",
682                            got: "EvalApprove",
683                        });
684                    }
685                    ActualProtocols::None => {}
686                }
687                Ok(Self::EOL {
688                    event_request,
689                    validation,
690                })
691            }
692        }
693    }
694}
695
696#[derive(
697    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
698)]
699pub struct LedgerSeal {
700    pub gov_version: u64,
701    pub sn: u64,
702    pub prev_ledger_event_hash: DigestIdentifier,
703    pub protocols_hash: DigestIdentifier,
704}
705
706#[derive(
707    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
708)]
709pub struct LedgerHash {
710    pub gov_version: u64,
711    pub sn: u64,
712    pub prev_ledger_event_hash: DigestIdentifier,
713    pub protocols_hash: DigestIdentifier,
714}
715
716#[derive(
717    Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
718)]
719pub struct Ledger {
720    pub gov_version: u64,
721    pub sn: u64,
722    pub prev_ledger_event_hash: DigestIdentifier,
723    pub ledger_seal_signature: Signature,
724    pub protocols: Protocols,
725}
726
727impl Ledger {
728    pub fn to_tracker_opaque(&self) -> Result<Self, LedgerError> {
729        Ok(Self {
730            gov_version: self.gov_version,
731            sn: self.sn,
732            prev_ledger_event_hash: self.prev_ledger_event_hash.clone(),
733            ledger_seal_signature: self.ledger_seal_signature.clone(),
734            protocols: self.protocols.to_tracker_opaque()?,
735        })
736    }
737
738    pub fn get_create_event(&self) -> Option<CreateRequest> {
739        match &self.protocols {
740            Protocols::Create { event_request, .. } => {
741                if let EventRequest::Create(create_request) =
742                    &event_request.content()
743                {
744                    Some(create_request.clone())
745                } else {
746                    None
747                }
748            }
749            _ => None,
750        }
751    }
752
753    pub const fn is_create_event(&self) -> bool {
754        matches!(&self.protocols, Protocols::Create { .. })
755    }
756
757    pub fn get_issuer_event_request_timestamp(&self) -> (String, u64) {
758        match &self.protocols {
759            Protocols::TrackerFactOpaque { data, .. } => (
760                data.signer.to_string(),
761                data.event_request_timestamp.as_nanos(),
762            ),
763            Protocols::Create { event_request, .. }
764            | Protocols::TrackerFactFull { event_request, .. }
765            | Protocols::GovFact { event_request, .. }
766            | Protocols::Transfer { event_request, .. }
767            | Protocols::TrackerConfirm { event_request, .. }
768            | Protocols::GovConfirm { event_request, .. }
769            | Protocols::Reject { event_request, .. }
770            | Protocols::EOL { event_request, .. } => (
771                event_request.signature().signer.clone().to_string(),
772                event_request.signature().timestamp.clone().as_nanos(),
773            ),
774        }
775    }
776
777    pub fn ledger_hash(
778        &self,
779        hash: HashAlgorithm,
780    ) -> Result<DigestIdentifier, LedgerError> {
781        let protocols_hash = self.protocols.hash_for_ledger(&hash)?;
782
783        let ledger_hash = LedgerHash {
784            gov_version: self.gov_version,
785            sn: self.sn,
786            prev_ledger_event_hash: self.prev_ledger_event_hash.clone(),
787            protocols_hash,
788        };
789
790        hash_borsh(&*hash.hasher(), &ledger_hash)
791            .map_err(|e| LedgerError::HashingFailed(e.to_string()))
792    }
793
794    pub const fn get_event_request_type(&self) -> EventRequestType {
795        match &self.protocols {
796            Protocols::Create { .. } => EventRequestType::Create,
797            Protocols::TrackerFactFull { .. }
798            | Protocols::TrackerFactOpaque { .. }
799            | Protocols::GovFact { .. } => EventRequestType::Fact,
800            Protocols::Transfer { .. } => EventRequestType::Transfer,
801            Protocols::TrackerConfirm { .. } | Protocols::GovConfirm { .. } => {
802                EventRequestType::Confirm
803            }
804            Protocols::Reject { .. } => EventRequestType::Reject,
805            Protocols::EOL { .. } => EventRequestType::Eol,
806        }
807    }
808
809    pub fn get_event_request(&self) -> Option<EventRequest> {
810        match &self.protocols {
811            Protocols::TrackerFactOpaque { .. } => None,
812            Protocols::Create { event_request, .. }
813            | Protocols::TrackerFactFull { event_request, .. }
814            | Protocols::GovFact { event_request, .. }
815            | Protocols::Transfer { event_request, .. }
816            | Protocols::TrackerConfirm { event_request, .. }
817            | Protocols::GovConfirm { event_request, .. }
818            | Protocols::Reject { event_request, .. }
819            | Protocols::EOL { event_request, .. } => {
820                Some(event_request.content().clone())
821            }
822        }
823    }
824
825    pub fn get_subject_id(&self) -> DigestIdentifier {
826        match &self.protocols {
827            Protocols::Create {
828                event_request,
829                validation,
830            } => {
831                if let ValidationMetadata::Metadata(metadata) =
832                    &validation.validation_metadata
833                {
834                    metadata.subject_id.clone()
835                } else {
836                    event_request.content().get_subject_id()
837                }
838            }
839            Protocols::TrackerFactOpaque { data, .. } => {
840                data.subject_id.clone()
841            }
842            Protocols::TrackerFactFull { event_request, .. }
843            | Protocols::GovFact { event_request, .. }
844            | Protocols::Transfer { event_request, .. }
845            | Protocols::TrackerConfirm { event_request, .. }
846            | Protocols::GovConfirm { event_request, .. }
847            | Protocols::Reject { event_request, .. }
848            | Protocols::EOL { event_request, .. } => {
849                event_request.content().get_subject_id()
850            }
851        }
852    }
853
854    pub fn build_ledger_db(&self, signature_timestamp: u64) -> LedgerDB {
855        let (event, subject_id, event_request_timestamp) =
856            self.protocols.buidl_event_db();
857
858        LedgerDB {
859            subject_id: subject_id.to_string(),
860            sn: self.sn,
861            event_request_timestamp,
862            event_ledger_timestamp: signature_timestamp,
863            sink_timestamp: TimeStamp::now().as_nanos(),
864            event_type: event.get_event_type(),
865            event,
866        }
867    }
868    pub fn get_create_metadata(&self) -> Result<Metadata, ProtocolsError> {
869        if let Protocols::Create { validation, .. } = &self.protocols
870            && let ValidationMetadata::Metadata(metadata) =
871                &validation.validation_metadata
872        {
873            Ok(*metadata.clone())
874        } else {
875            Err(ProtocolsError::NotCreateWithMetadata)
876        }
877    }
878}