radix_transactions/manifest/
any_manifest.rs1use crate::internal_prelude::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, ManifestSbor, ScryptoDescribe)]
18pub enum AnyManifest {
19 V1(TransactionManifestV1),
20 SystemV1(SystemTransactionManifestV1),
21 V2(TransactionManifestV2),
22 SubintentV2(SubintentManifestV2),
23}
24
25impl From<TransactionManifestV1> for AnyManifest {
26 fn from(value: TransactionManifestV1) -> Self {
27 Self::V1(value)
28 }
29}
30
31impl TryFrom<AnyManifest> for TransactionManifestV1 {
32 type Error = ();
33
34 fn try_from(value: AnyManifest) -> Result<Self, Self::Error> {
35 match value {
36 AnyManifest::V1(manifest) => Ok(manifest),
37 _ => Err(()),
38 }
39 }
40}
41
42impl From<SystemTransactionManifestV1> for AnyManifest {
43 fn from(value: SystemTransactionManifestV1) -> Self {
44 Self::SystemV1(value)
45 }
46}
47
48impl TryFrom<AnyManifest> for SystemTransactionManifestV1 {
49 type Error = ();
50
51 fn try_from(value: AnyManifest) -> Result<Self, Self::Error> {
52 match value {
53 AnyManifest::SystemV1(manifest) => Ok(manifest),
54 _ => Err(()),
55 }
56 }
57}
58
59impl From<TransactionManifestV2> for AnyManifest {
60 fn from(value: TransactionManifestV2) -> Self {
61 Self::V2(value)
62 }
63}
64
65impl TryFrom<AnyManifest> for TransactionManifestV2 {
66 type Error = ();
67
68 fn try_from(value: AnyManifest) -> Result<Self, Self::Error> {
69 match value {
70 AnyManifest::V2(manifest) => Ok(manifest),
71 _ => Err(()),
72 }
73 }
74}
75
76impl From<SubintentManifestV2> for AnyManifest {
77 fn from(value: SubintentManifestV2) -> Self {
78 Self::SubintentV2(value)
79 }
80}
81
82impl TryFrom<AnyManifest> for SubintentManifestV2 {
83 type Error = ();
84
85 fn try_from(value: AnyManifest) -> Result<Self, Self::Error> {
86 match value {
87 AnyManifest::SubintentV2(manifest) => Ok(manifest),
88 _ => Err(()),
89 }
90 }
91}
92
93define_raw_transaction_payload!(RawManifest, TransactionPayloadKind::Other);
95
96impl AnyManifest {
97 pub fn to_raw(&self) -> Result<RawManifest, EncodeError> {
98 Ok(RawManifest::from_vec(manifest_encode(self)?))
99 }
100
101 pub fn from_raw(raw: &RawManifest) -> Result<Self, DecodeError> {
102 Ok(manifest_decode(raw.as_slice())?)
103 }
104
105 pub fn attempt_decode_from_arbitrary_payload(bytes: &[u8]) -> Result<Self, String> {
106 if let Ok(any_manifest) = manifest_decode::<Self>(bytes) {
108 return Ok(any_manifest);
109 }
110
111 if let Ok(legacy_v1_manifest) = manifest_decode::<LegacyTransactionManifestV1>(bytes) {
113 return Ok(Self::V1(legacy_v1_manifest.into()));
114 }
115
116 if let Ok(any_transaction) = manifest_decode::<AnyTransaction>(bytes) {
118 return Ok(match any_transaction {
119 AnyTransaction::TransactionIntentV1(intent) => {
120 TransactionManifestV1::from_intent(&intent).into()
121 }
122 AnyTransaction::SignedTransactionIntentV1(signed_intent) => {
123 TransactionManifestV1::from_intent(&signed_intent.intent).into()
124 }
125 AnyTransaction::NotarizedTransactionV1(notarized) => {
126 TransactionManifestV1::from_intent(¬arized.signed_intent.intent).into()
127 }
128 AnyTransaction::SystemTransactionV1(system_transaction) => {
129 SystemTransactionManifestV1::from_transaction(&system_transaction).into()
130 }
131 AnyTransaction::TransactionIntentV2(intent) => {
132 TransactionManifestV2::from_intent_core(&intent.root_intent_core).into()
133 }
134 AnyTransaction::SignedTransactionIntentV2(signed_intent) => {
135 TransactionManifestV2::from_intent_core(
136 &signed_intent.transaction_intent.root_intent_core,
137 )
138 .into()
139 }
140 AnyTransaction::NotarizedTransactionV2(notarized) => {
141 TransactionManifestV2::from_intent_core(
142 ¬arized
143 .signed_transaction_intent
144 .transaction_intent
145 .root_intent_core,
146 )
147 .into()
148 }
149 AnyTransaction::SubintentV2(subintent) => {
150 SubintentManifestV2::from_intent_core(&subintent.intent_core).into()
151 }
152 other_type => {
153 return Err(format!(
154 "Transaction type with discriminator {} not currently supported",
155 other_type.get_discriminator()
156 ))
157 }
158 });
159 }
160
161 Err(format!(
162 "Cannot decode transaction manifest or transaction payload"
163 ))
164 }
165}
166
167impl ReadableManifestBase for AnyManifest {
168 fn is_subintent(&self) -> bool {
169 match self {
170 AnyManifest::V1(m) => m.is_subintent(),
171 AnyManifest::SystemV1(m) => m.is_subintent(),
172 AnyManifest::V2(m) => m.is_subintent(),
173 AnyManifest::SubintentV2(m) => m.is_subintent(),
174 }
175 }
176
177 fn get_blobs<'a>(&'a self) -> impl Iterator<Item = (&'a Hash, &'a Vec<u8>)> {
178 let iterator: Box<dyn Iterator<Item = (&'a Hash, &'a Vec<u8>)> + 'a> = match self {
179 AnyManifest::V1(m) => Box::new(m.get_blobs()),
180 AnyManifest::SystemV1(m) => Box::new(m.get_blobs()),
181 AnyManifest::V2(m) => Box::new(m.get_blobs()),
182 AnyManifest::SubintentV2(m) => Box::new(m.get_blobs()),
183 };
184 iterator
185 }
186
187 fn get_known_object_names_ref(&self) -> ManifestObjectNamesRef {
188 match self {
189 AnyManifest::V1(m) => m.get_known_object_names_ref(),
190 AnyManifest::SystemV1(m) => m.get_known_object_names_ref(),
191 AnyManifest::V2(m) => m.get_known_object_names_ref(),
192 AnyManifest::SubintentV2(m) => m.get_known_object_names_ref(),
193 }
194 }
195
196 fn get_preallocated_addresses(&self) -> &[PreAllocatedAddress] {
197 match self {
198 AnyManifest::V1(m) => m.get_preallocated_addresses(),
199 AnyManifest::SystemV1(m) => m.get_preallocated_addresses(),
200 AnyManifest::V2(m) => m.get_preallocated_addresses(),
201 AnyManifest::SubintentV2(m) => m.get_preallocated_addresses(),
202 }
203 }
204
205 fn get_child_subintent_hashes<'a>(
206 &'a self,
207 ) -> impl ExactSizeIterator<Item = &'a ChildSubintentSpecifier> {
208 let iterator: Box<dyn ExactSizeIterator<Item = &'a ChildSubintentSpecifier>> = match self {
209 AnyManifest::V1(m) => Box::new(m.get_child_subintent_hashes()),
210 AnyManifest::SystemV1(m) => Box::new(m.get_child_subintent_hashes()),
211 AnyManifest::V2(m) => Box::new(m.get_child_subintent_hashes()),
212 AnyManifest::SubintentV2(m) => Box::new(m.get_child_subintent_hashes()),
213 };
214 iterator
215 }
216}
217
218impl ReadableManifest for AnyManifest {
219 fn iter_instruction_effects(&self) -> impl Iterator<Item = ManifestInstructionEffect> {
220 let iterator: Box<dyn Iterator<Item = ManifestInstructionEffect>> = match self {
221 AnyManifest::V1(m) => Box::new(m.iter_instruction_effects()),
222 AnyManifest::SystemV1(m) => Box::new(m.iter_instruction_effects()),
223 AnyManifest::V2(m) => Box::new(m.iter_instruction_effects()),
224 AnyManifest::SubintentV2(m) => Box::new(m.iter_instruction_effects()),
225 };
226 iterator
227 }
228
229 fn iter_cloned_instructions(&self) -> impl Iterator<Item = AnyInstruction> {
230 let iterator: Box<dyn Iterator<Item = AnyInstruction>> = match self {
231 AnyManifest::V1(m) => Box::new(m.iter_cloned_instructions()),
232 AnyManifest::SystemV1(m) => Box::new(m.iter_cloned_instructions()),
233 AnyManifest::V2(m) => Box::new(m.iter_cloned_instructions()),
234 AnyManifest::SubintentV2(m) => Box::new(m.iter_cloned_instructions()),
235 };
236 iterator
237 }
238
239 fn instruction_count(&self) -> usize {
240 match self {
241 AnyManifest::V1(m) => m.instruction_count(),
242 AnyManifest::SystemV1(m) => m.instruction_count(),
243 AnyManifest::V2(m) => m.instruction_count(),
244 AnyManifest::SubintentV2(m) => m.instruction_count(),
245 }
246 }
247
248 fn instruction_effect(&self, index: usize) -> ManifestInstructionEffect {
249 match self {
250 AnyManifest::V1(m) => m.instruction_effect(index),
251 AnyManifest::SystemV1(m) => m.instruction_effect(index),
252 AnyManifest::V2(m) => m.instruction_effect(index),
253 AnyManifest::SubintentV2(m) => m.instruction_effect(index),
254 }
255 }
256}
257
258pub enum ManifestKind {
259 V1,
260 SystemV1,
261 V2,
262 SubintentV2,
263}
264
265impl ManifestKind {
266 const LATEST_SYSTEM: Self = Self::SystemV1;
267 const LATEST_TRANSACTION: Self = Self::V2;
268 const LATEST_SUBINTENT: Self = Self::SubintentV2;
269
270 pub fn parse_or_latest(arg: Option<&str>) -> Result<Self, String> {
271 match arg {
272 Some(kind) => kind.try_into(),
273 None => Ok(Self::LATEST_TRANSACTION),
274 }
275 }
276}
277
278impl TryFrom<&str> for ManifestKind {
279 type Error = String;
280
281 fn try_from(value: &str) -> Result<Self, Self::Error> {
282 let kind = match value.to_ascii_lowercase().as_str() {
283 "v1" => Self::V1,
284 "systemv1" => Self::SystemV1,
285 "v2" => Self::V2,
286 "subintentv2" => Self::SubintentV2,
287 "system" => Self::LATEST_SYSTEM,
288 "transaction" => Self::LATEST_TRANSACTION,
289 "subintent" => Self::LATEST_SUBINTENT,
290 _ => {
291 return Err(format!(
292 "Manifest kind not recognized. Try one of: V1 | SystemV1 | V2 | SubintentV2"
293 ))
294 }
295 };
296 Ok(kind)
297 }
298}