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
//! Contains the data structures related to event  to send to approvers, or to validators if approval is not required.
use crate::{
    commons::{errors::SubjectError, models::event::Metadata},
    identifier::{DigestIdentifier, KeyIdentifier},
    request::StartRequest,
    signature::Signature,
};
use borsh::{BorshDeserialize, BorshSerialize};
use serde::{Deserialize, Serialize};

use super::{state::Subject, HashId};

/// A struct representing a validation proof.
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
pub struct ValidationProof {
    /// The identifier of the subject being validated.
    pub subject_id: DigestIdentifier,
    /// The identifier of the schema used to validate the subject.
    pub schema_id: String,
    /// The namespace of the subject being validated.
    pub namespace: String,
    /// The name of the subject being validated.
    pub name: String,
    /// The identifier of the public key of the subject being validated.
    pub subject_public_key: KeyIdentifier,
    /// The identifier of the governance contract associated with the subject being validated.
    pub governance_id: DigestIdentifier,
    /// The version of the governance contract that created the subject being validated.
    pub genesis_governance_version: u64,
    /// The sequence number of the subject being validated.
    pub sn: u64,
    /// The identifier of the previous event in the validation chain.
    pub prev_event_hash: DigestIdentifier,
    /// The identifier of the current event in the validation chain.
    pub event_hash: DigestIdentifier,
    /// The version of the governance contract used to validate the subject.
    pub governance_version: u64,
}

impl HashId for ValidationProof {
    fn hash_id(&self) -> Result<DigestIdentifier, SubjectError> {
        DigestIdentifier::from_serializable_borsh(&self)
            .map_err(|_| SubjectError::CryptoError("Hashing error in ValidationProof".to_string()))
    }
}

impl ValidationProof {
    pub fn new_from_genesis_event(
        start_request: StartRequest,
        event_hash: DigestIdentifier,
        governance_version: u64,
        subject_id: DigestIdentifier,
    ) -> Self {
        Self {
            governance_id: start_request.governance_id,
            governance_version,
            subject_id,
            sn: 0,
            schema_id: start_request.schema_id,
            namespace: start_request.namespace,
            prev_event_hash: DigestIdentifier::default(),
            event_hash,
            subject_public_key: start_request.public_key,
            genesis_governance_version: governance_version,
            name: start_request.name,
        }
    }
    pub fn new_from_transfer_event(
        subject: &Subject,
        sn: u64,
        prev_event_hash: DigestIdentifier,
        event_hash: DigestIdentifier,
        governance_version: u64,
        subject_public_key: KeyIdentifier,
    ) -> Self {
        Self {
            governance_id: subject.governance_id.clone(),
            governance_version,
            subject_id: subject.subject_id.clone(),
            sn,
            schema_id: subject.schema_id.clone(),
            namespace: subject.namespace.clone(),
            prev_event_hash,
            event_hash,
            subject_public_key,
            genesis_governance_version: subject.genesis_gov_version,
            name: subject.name.clone(),
        }
    }

    pub fn new(
        subject: &Subject,
        sn: u64,
        prev_event_hash: DigestIdentifier,
        event_hash: DigestIdentifier,
        governance_version: u64,
    ) -> Self {
        Self {
            governance_id: subject.governance_id.clone(),
            governance_version,
            subject_id: subject.subject_id.clone(),
            sn,
            schema_id: subject.schema_id.clone(),
            namespace: subject.namespace.clone(),
            prev_event_hash,
            event_hash,
            subject_public_key: subject.public_key.clone(),
            genesis_governance_version: subject.genesis_gov_version,
            name: subject.name.clone(),
        }
    }

    pub fn get_metadata(&self) -> Metadata {
        Metadata {
            namespace: self.namespace.clone(),
            governance_id: self.governance_id.clone(),
            governance_version: self.governance_version,
            schema_id: self.schema_id.clone(),
            subject_id: self.subject_id.clone(),
        }
    }

    pub fn is_similar(&self, other: &ValidationProof) -> bool {
        self.governance_id == other.governance_id
            && self.subject_id == other.subject_id
            && self.sn == other.sn
            && self.schema_id == other.schema_id
            && self.namespace == other.namespace
            && self.prev_event_hash == other.prev_event_hash
            && self.event_hash == other.event_hash
            && self.subject_public_key == other.subject_public_key
            && self.genesis_governance_version == other.genesis_governance_version
            && self.name == other.name
    }
}

#[derive(
    Debug,
    Clone,
    Serialize,
    Deserialize,
    PartialEq,
    Eq,
    Hash,
    BorshSerialize,
    BorshDeserialize,
    PartialOrd,
)]
pub struct ValidationEventResponse {
    pub validation_signature: Signature,
    pub gov_version_validation: u64,
}