taple_core/commons/models/
request.rs

1//! Contains all valid event requests
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    commons::errors::SubjectError,
8    signature::{Signature, Signed},
9    DigestIdentifier, KeyIdentifier, ValueWrapper, DigestDerivator,
10};
11
12use super::HashId;
13
14/// An enum representing a TAPLE event request.
15#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
16pub enum EventRequest {
17    /// A request to create a new subject.
18    Create(StartRequest),
19    /// A request to add a fact to a subject.
20    Fact(FactRequest),
21    /// A request to transfer ownership of a subject.
22    Transfer(TransferRequest),
23    /// A request to mark a subject as end-of-life.
24    EOL(EOLRequest),
25}
26
27/// A struct representing a request to create a new subject.
28#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
29pub struct StartRequest {
30    /// The identifier of the governance contract.
31    pub governance_id: DigestIdentifier,
32    /// The identifier of the schema used to validate the event.
33    pub schema_id: String,
34    /// The namespace of the subject.
35    pub namespace: String,
36    /// The name of the subject.
37    pub name: String,
38    /// The identifier of the public key of the subject owner.
39    pub public_key: KeyIdentifier,
40}
41
42/// A struct representing a request to add a fact to a subject.
43#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
44pub struct FactRequest {
45    /// The identifier of the subject to which the fact will be added.
46    pub subject_id: DigestIdentifier,
47    /// The payload of the fact to be added.
48    pub payload: ValueWrapper,
49}
50
51/// A struct representing a request to transfer ownership of a subject.
52#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
53pub struct TransferRequest {
54    /// The identifier of the subject to transfer ownership of.
55    pub subject_id: DigestIdentifier,
56    /// The identifier of the public key of the new owner.
57    pub public_key: KeyIdentifier,
58}
59
60/// A struct representing a request to mark a subject as end-of-life.
61#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
62pub struct EOLRequest {
63    /// The identifier of the subject to mark as end-of-life.
64    pub subject_id: DigestIdentifier,
65}
66
67impl EventRequest {
68    pub fn requires_eval_appr(&self) -> bool {
69        match self {
70            EventRequest::Fact(_) => true,
71            EventRequest::Create(_) | EventRequest::Transfer(_) | EventRequest::EOL(_) => false,
72        }
73    }
74}
75
76impl HashId for EventRequest {
77    fn hash_id(&self, derivator: DigestDerivator) -> Result<DigestIdentifier, SubjectError> {
78        DigestIdentifier::from_serializable_borsh(&self, derivator).map_err(|_| {
79            SubjectError::SignatureCreationFails("HashId for EventRequest Fails".to_string())
80        })
81    }
82}
83
84impl Signed<EventRequest> {
85    pub fn new(request: EventRequest, signature: Signature) -> Self {
86        Self {
87            content: request,
88            signature,
89        }
90    }
91
92    pub fn verify(&self) -> Result<(), SubjectError> {
93        self.signature.verify(&self.content)
94    }
95}
96
97/// Indicates the current status of an event request.
98#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
99pub enum RequestState {
100    Finished,
101    Error,
102    Processing,
103}
104
105/// A struct representing a TAPLE request.
106#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
107pub struct TapleRequest {
108    /// The identifier of the request.
109    pub id: DigestIdentifier,
110    /// The identifier of the subject associated with the request, if any.
111    pub subject_id: Option<DigestIdentifier>,
112    /// The sequence number of the request, if any.
113    pub sn: Option<u64>,
114    /// The event request associated with the request.
115    pub event_request: Signed<EventRequest>,
116    /// The state of the request.
117    pub state: RequestState,
118    /// The success status of the request, if any.
119    pub success: Option<bool>,
120}
121
122impl TryFrom<Signed<EventRequest>> for TapleRequest {
123    type Error = SubjectError;
124
125    fn try_from(event_request: Signed<EventRequest>) -> Result<Self, Self::Error> {
126        let id = DigestIdentifier::generate_with_blake3(&event_request)
127            .map_err(|_| SubjectError::CryptoError("Error generation request hash".to_owned()))?;
128        let subject_id = match &event_request.content {
129            crate::EventRequest::Create(_) => None,
130            crate::EventRequest::Fact(fact_request) => Some(fact_request.subject_id.clone()),
131            crate::EventRequest::Transfer(transfer_res) => Some(transfer_res.subject_id.clone()),
132            crate::EventRequest::EOL(eol_request) => Some(eol_request.subject_id.clone()),
133        };
134        Ok(Self {
135            id,
136            subject_id,
137            sn: None,
138            event_request,
139            state: RequestState::Processing,
140            success: None,
141        })
142    }
143}