radix_transactions/
errors.rs

1use crate::internal_prelude::*;
2use sbor::*;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum HeaderValidationError {
6    InvalidEpochRange,
7    InvalidTimestampRange,
8    InvalidNetwork,
9    InvalidTip,
10    NoValidEpochRangeAcrossAllIntents,
11    NoValidTimestampRangeAcrossAllIntents,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum SignatureValidationError {
16    TooManySignatures { total: usize, limit: usize },
17    InvalidIntentSignature,
18    InvalidNotarySignature,
19    DuplicateSigner,
20    NotaryIsSignatorySoShouldNotAlsoBeASigner,
21    SerializationError(EncodeError),
22    IncorrectNumberOfSubintentSignatureBatches,
23}
24
25impl SignatureValidationError {
26    pub fn located(
27        self,
28        location: TransactionValidationErrorLocation,
29    ) -> TransactionValidationError {
30        TransactionValidationError::SignatureValidationError(location, self)
31    }
32}
33
34impl From<EncodeError> for SignatureValidationError {
35    fn from(err: EncodeError) -> Self {
36        Self::SerializationError(err)
37    }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
41pub enum ManifestIdValidationError {
42    BucketNotFound(ManifestBucket),
43    ProofNotFound(ManifestProof),
44    BucketLocked(ManifestBucket),
45    AddressReservationNotFound(ManifestAddressReservation),
46    AddressNotFound(ManifestNamedAddress),
47    IntentNotFound(ManifestNamedIntent),
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub enum ManifestBasicValidatorError {
52    ManifestIdValidationError(ManifestIdValidationError),
53}
54
55impl From<ManifestIdValidationError> for ManifestBasicValidatorError {
56    fn from(value: ManifestIdValidationError) -> Self {
57        Self::ManifestIdValidationError(value)
58    }
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub enum TransactionValidationError {
63    TransactionVersionNotPermitted(usize),
64    TransactionTooLarge,
65    EncodeError(EncodeError),
66    PrepareError(PrepareError),
67    SubintentStructureError(TransactionValidationErrorLocation, SubintentStructureError),
68    IntentValidationError(TransactionValidationErrorLocation, IntentValidationError),
69    SignatureValidationError(TransactionValidationErrorLocation, SignatureValidationError),
70}
71
72impl<'a> ContextualDisplay<TransactionHashDisplayContext<'a>> for TransactionValidationError {
73    type Error = fmt::Error;
74
75    fn contextual_format(
76        &self,
77        f: &mut fmt::Formatter,
78        context: &TransactionHashDisplayContext<'a>,
79    ) -> Result<(), Self::Error> {
80        match self {
81            Self::TransactionVersionNotPermitted(arg0) => f
82                .debug_tuple("TransactionVersionNotPermitted")
83                .field(arg0)
84                .finish(),
85            Self::TransactionTooLarge => write!(f, "TransactionTooLarge"),
86            Self::EncodeError(arg0) => f.debug_tuple("EncodeError").field(arg0).finish(),
87            Self::PrepareError(arg0) => f.debug_tuple("PrepareError").field(arg0).finish(),
88            Self::SubintentStructureError(arg0, arg1) => f
89                .debug_tuple("SubintentStructureError")
90                .field(&arg0.debug_as_display(*context))
91                .field(&arg1.debug_as_display(*context))
92                .finish(),
93            Self::IntentValidationError(arg0, arg1) => f
94                .debug_tuple("IntentValidationError")
95                .field(&arg0.debug_as_display(*context))
96                .field(arg1)
97                .finish(),
98            Self::SignatureValidationError(arg0, arg1) => f
99                .debug_tuple("SignatureValidationError")
100                .field(&arg0.debug_as_display(*context))
101                .field(arg1)
102                .finish(),
103        }
104    }
105}
106
107pub enum IntentSpecifier {
108    RootTransactionIntent(TransactionIntentHash),
109    RootSubintent(SubintentHash),
110    NonRootSubintent(SubintentIndex, SubintentHash),
111}
112
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub enum TransactionValidationErrorLocation {
115    RootTransactionIntent(TransactionIntentHash),
116    RootSubintent(SubintentHash),
117    NonRootSubintent(SubintentIndex, SubintentHash),
118    AcrossTransaction,
119    Unlocatable,
120}
121
122impl TransactionValidationErrorLocation {
123    pub fn for_root(intent_hash: IntentHash) -> Self {
124        match intent_hash {
125            IntentHash::Transaction(hash) => Self::RootTransactionIntent(hash),
126            IntentHash::Subintent(hash) => Self::RootSubintent(hash),
127        }
128    }
129}
130
131impl<'a> ContextualDisplay<TransactionHashDisplayContext<'a>>
132    for TransactionValidationErrorLocation
133{
134    type Error = fmt::Error;
135
136    fn contextual_format(
137        &self,
138        f: &mut fmt::Formatter,
139        context: &TransactionHashDisplayContext<'a>,
140    ) -> Result<(), Self::Error> {
141        // Copied from the auto-generated `Debug` implementation, and tweaked
142        match self {
143            Self::RootTransactionIntent(arg0) => f
144                .debug_tuple("RootTransactionIntent")
145                .field(&arg0.debug_as_display(*context))
146                .finish(),
147            Self::RootSubintent(arg0) => f
148                .debug_tuple("RootSubintent")
149                .field(&arg0.debug_as_display(*context))
150                .finish(),
151            Self::NonRootSubintent(arg0, arg1) => f
152                .debug_tuple("NonRootSubintent")
153                .field(arg0)
154                .field(&arg1.debug_as_display(*context))
155                .finish(),
156            Self::AcrossTransaction => write!(f, "AcrossTransaction"),
157            Self::Unlocatable => write!(f, "Unlocatable"),
158        }
159    }
160}
161
162impl From<PrepareError> for TransactionValidationError {
163    fn from(value: PrepareError) -> Self {
164        Self::PrepareError(value)
165    }
166}
167
168impl From<EncodeError> for TransactionValidationError {
169    fn from(value: EncodeError) -> Self {
170        Self::EncodeError(value)
171    }
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
175pub enum IntentValidationError {
176    ManifestBasicValidatorError(ManifestBasicValidatorError),
177    ManifestValidationError(ManifestValidationError),
178    InvalidMessage(InvalidMessageError),
179    HeaderValidationError(HeaderValidationError),
180    TooManyReferences { total: usize, limit: usize },
181}
182
183impl From<HeaderValidationError> for IntentValidationError {
184    fn from(value: HeaderValidationError) -> Self {
185        Self::HeaderValidationError(value)
186    }
187}
188
189impl From<InvalidMessageError> for IntentValidationError {
190    fn from(value: InvalidMessageError) -> Self {
191        Self::InvalidMessage(value)
192    }
193}
194
195impl From<ManifestBasicValidatorError> for IntentValidationError {
196    fn from(value: ManifestBasicValidatorError) -> Self {
197        Self::ManifestBasicValidatorError(value)
198    }
199}
200
201impl From<ManifestValidationError> for IntentValidationError {
202    fn from(value: ManifestValidationError) -> Self {
203        Self::ManifestValidationError(value)
204    }
205}
206
207#[derive(Debug, Clone, PartialEq, Eq)]
208pub enum InvalidMessageError {
209    PlaintextMessageTooLong {
210        actual: usize,
211        permitted: usize,
212    },
213    MimeTypeTooLong {
214        actual: usize,
215        permitted: usize,
216    },
217    EncryptedMessageTooLong {
218        actual: usize,
219        permitted: usize,
220    },
221    NoDecryptors,
222    MismatchingDecryptorCurves {
223        actual: CurveType,
224        expected: CurveType,
225    },
226    TooManyDecryptors {
227        actual: usize,
228        permitted: usize,
229    },
230    NoDecryptorsForCurveType {
231        curve_type: CurveType,
232    },
233}
234
235#[derive(Debug, Clone, PartialEq, Eq)]
236pub enum SubintentStructureError {
237    DuplicateSubintent,
238    SubintentHasMultipleParents,
239    ChildSubintentNotIncludedInTransaction(SubintentHash),
240    SubintentExceedsMaxDepth,
241    SubintentIsNotReachableFromTheTransactionIntent,
242    MismatchingYieldChildAndYieldParentCountsForSubintent,
243}
244
245impl<'a> ContextualDisplay<TransactionHashDisplayContext<'a>> for SubintentStructureError {
246    type Error = fmt::Error;
247
248    fn contextual_format(
249        &self,
250        f: &mut fmt::Formatter,
251        context: &TransactionHashDisplayContext<'a>,
252    ) -> Result<(), Self::Error> {
253        // Copied from the auto-generated `Debug` implementation, and tweaked
254        match self {
255            Self::DuplicateSubintent => write!(f, "DuplicateSubintent"),
256            Self::SubintentHasMultipleParents => write!(f, "SubintentHasMultipleParents"),
257            Self::ChildSubintentNotIncludedInTransaction(arg0) => f
258                .debug_tuple("ChildSubintentNotIncludedInTransaction")
259                .field(&arg0.debug_as_display(*context))
260                .finish(),
261            Self::SubintentExceedsMaxDepth => write!(f, "SubintentExceedsMaxDepth"),
262            Self::SubintentIsNotReachableFromTheTransactionIntent => {
263                write!(f, "SubintentIsNotReachableFromTheTransactionIntent")
264            }
265            Self::MismatchingYieldChildAndYieldParentCountsForSubintent => {
266                write!(f, "MismatchingYieldChildAndYieldParentCountsForSubintent")
267            }
268        }
269    }
270}
271
272impl SubintentStructureError {
273    pub fn for_unindexed(self) -> TransactionValidationError {
274        TransactionValidationError::SubintentStructureError(
275            TransactionValidationErrorLocation::Unlocatable,
276            self,
277        )
278    }
279
280    pub fn for_subintent(
281        self,
282        index: SubintentIndex,
283        hash: SubintentHash,
284    ) -> TransactionValidationError {
285        TransactionValidationError::SubintentStructureError(
286            TransactionValidationErrorLocation::NonRootSubintent(index, hash),
287            self,
288        )
289    }
290}