openzeppelin_relayer/models/error/
stellar_validation.rs1use serde::Serialize;
7use thiserror::Error;
8
9#[derive(Error, Debug, Serialize, Clone, PartialEq)]
11#[serde(tag = "type", content = "details")]
12pub enum StellarValidationError {
13 #[error("Transaction must have at least one operation")]
15 EmptyOperations,
16
17 #[error("Transaction has {count} operations, but maximum allowed is {max}")]
19 TooManyOperations { count: usize, max: usize },
20
21 #[error("Transaction can contain at most one Soroban operation")]
23 MultipleSorobanOperations,
24
25 #[error("Soroban operations must be exclusive - no other operations allowed in the same transaction")]
27 SorobanNotExclusive,
28
29 #[error("Soroban operations cannot have a memo (except MemoNone)")]
31 SorobanWithMemo,
32
33 #[error("XDR source account {actual} does not match relayer account {expected}")]
35 SourceAccountMismatch { expected: String, actual: String },
36
37 #[error("Expected unsigned XDR but received signed XDR")]
39 UnexpectedSignedXdr,
40
41 #[error("Expected signed XDR but received unsigned XDR")]
43 UnexpectedUnsignedXdr,
44
45 #[error("max_fee must be greater than 0 for signed XDR")]
47 InvalidMaxFee,
48
49 #[error("Invalid XDR: {0}")]
51 InvalidXdr(String),
52}
53
54impl From<StellarValidationError> for crate::models::TransactionError {
56 fn from(err: StellarValidationError) -> Self {
57 crate::models::TransactionError::ValidationError(err.to_string())
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_error_messages() {
67 assert_eq!(
68 StellarValidationError::EmptyOperations.to_string(),
69 "Transaction must have at least one operation"
70 );
71
72 assert_eq!(
73 StellarValidationError::TooManyOperations {
74 count: 150,
75 max: 100
76 }
77 .to_string(),
78 "Transaction has 150 operations, but maximum allowed is 100"
79 );
80
81 assert_eq!(
82 StellarValidationError::SourceAccountMismatch {
83 expected: "GAAAA...".to_string(),
84 actual: "GBBBB...".to_string()
85 }
86 .to_string(),
87 "XDR source account GBBBB... does not match relayer account GAAAA..."
88 );
89 }
90
91 #[test]
92 fn test_serialization() {
93 let error = StellarValidationError::TooManyOperations {
94 count: 150,
95 max: 100,
96 };
97 let json = serde_json::to_string(&error).unwrap();
98 assert!(json.contains("\"type\":\"TooManyOperations\""));
99 assert!(json.contains("\"count\":150"));
100 assert!(json.contains("\"max\":100"));
101 }
102
103 #[test]
104 fn test_conversion_to_transaction_error() {
105 let stellar_err = StellarValidationError::SorobanWithMemo;
106 let tx_err: crate::models::TransactionError = stellar_err.into();
107
108 match tx_err {
109 crate::models::TransactionError::ValidationError(msg) => {
110 assert_eq!(
111 msg,
112 "Soroban operations cannot have a memo (except MemoNone)"
113 );
114 }
115 _ => panic!("Expected ValidationError variant"),
116 }
117 }
118}