radix_engine/system/transaction/
instructions.rs

1use crate::blueprints::transaction_processor::*;
2use crate::internal_prelude::*;
3use radix_engine_interface::blueprints::transaction_processor::*;
4use radix_transactions::data::transform;
5use radix_transactions::manifest::*;
6use radix_transactions::prelude::*;
7
8pub enum MultiThreadResult {
9    SwitchToChild(usize, ScryptoValue),
10    SwitchToParent(ScryptoValue),
11    VerifyParent(AccessRule),
12}
13
14pub trait TxnInstruction {
15    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
16        self,
17        worktop: &mut Worktop,
18        objects: &mut IntentProcessorObjects,
19        api: &mut Y,
20    ) -> Result<(InstructionOutput, Option<MultiThreadResult>), RuntimeError>;
21}
22
23impl TxnInstruction for InstructionV1 {
24    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
25        self,
26        worktop: &mut Worktop,
27        objects: &mut IntentProcessorObjects,
28        api: &mut Y,
29    ) -> Result<(InstructionOutput, Option<MultiThreadResult>), RuntimeError> {
30        let output = match self {
31            InstructionV1::TakeAllFromWorktop(i) => i.execute(worktop, objects, api),
32            InstructionV1::TakeFromWorktop(i) => i.execute(worktop, objects, api),
33            InstructionV1::TakeNonFungiblesFromWorktop(i) => i.execute(worktop, objects, api),
34            InstructionV1::ReturnToWorktop(i) => i.execute(worktop, objects, api),
35            InstructionV1::AssertWorktopContainsAny(i) => i.execute(worktop, objects, api),
36            InstructionV1::AssertWorktopContains(i) => i.execute(worktop, objects, api),
37            InstructionV1::AssertWorktopContainsNonFungibles(i) => i.execute(worktop, objects, api),
38            InstructionV1::PopFromAuthZone(i) => i.execute(worktop, objects, api),
39            InstructionV1::PushToAuthZone(i) => i.execute(worktop, objects, api),
40            InstructionV1::CreateProofFromAuthZoneOfAmount(i) => i.execute(worktop, objects, api),
41            InstructionV1::CreateProofFromAuthZoneOfNonFungibles(i) => {
42                i.execute(worktop, objects, api)
43            }
44            InstructionV1::CreateProofFromAuthZoneOfAll(i) => i.execute(worktop, objects, api),
45            InstructionV1::CreateProofFromBucketOfAmount(i) => i.execute(worktop, objects, api),
46            InstructionV1::CreateProofFromBucketOfNonFungibles(i) => {
47                i.execute(worktop, objects, api)
48            }
49            InstructionV1::CreateProofFromBucketOfAll(i) => i.execute(worktop, objects, api),
50            InstructionV1::DropAuthZoneProofs(i) => i.execute(worktop, objects, api),
51            InstructionV1::DropAuthZoneRegularProofs(i) => i.execute(worktop, objects, api),
52            InstructionV1::DropAuthZoneSignatureProofs(i) => i.execute(worktop, objects, api),
53            InstructionV1::BurnResource(i) => i.execute(worktop, objects, api),
54            InstructionV1::CloneProof(i) => i.execute(worktop, objects, api),
55            InstructionV1::DropProof(i) => i.execute(worktop, objects, api),
56            InstructionV1::CallFunction(i) => i.execute(worktop, objects, api),
57            InstructionV1::CallMethod(i) => i.execute(worktop, objects, api),
58            InstructionV1::CallRoyaltyMethod(i) => i.execute(worktop, objects, api),
59            InstructionV1::CallMetadataMethod(i) => i.execute(worktop, objects, api),
60            InstructionV1::CallRoleAssignmentMethod(i) => i.execute(worktop, objects, api),
61            InstructionV1::CallDirectVaultMethod(i) => i.execute(worktop, objects, api),
62            InstructionV1::DropNamedProofs(i) => i.execute(worktop, objects, api),
63            InstructionV1::DropAllProofs(i) => i.execute(worktop, objects, api),
64            InstructionV1::AllocateGlobalAddress(i) => i.execute(worktop, objects, api),
65        }?;
66        Ok((output, None))
67    }
68}
69
70impl TxnInstruction for InstructionV2 {
71    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
72        self,
73        worktop: &mut Worktop,
74        objects: &mut IntentProcessorObjects,
75        api: &mut Y,
76    ) -> Result<(InstructionOutput, Option<MultiThreadResult>), RuntimeError> {
77        let output = match self {
78            InstructionV2::TakeAllFromWorktop(i) => i.execute(worktop, objects, api),
79            InstructionV2::TakeFromWorktop(i) => i.execute(worktop, objects, api),
80            InstructionV2::TakeNonFungiblesFromWorktop(i) => i.execute(worktop, objects, api),
81            InstructionV2::ReturnToWorktop(i) => i.execute(worktop, objects, api),
82            InstructionV2::AssertWorktopContainsAny(i) => i.execute(worktop, objects, api),
83            InstructionV2::AssertWorktopContains(i) => i.execute(worktop, objects, api),
84            InstructionV2::AssertWorktopContainsNonFungibles(i) => i.execute(worktop, objects, api),
85            InstructionV2::AssertWorktopResourcesOnly(i) => i.execute(worktop, objects, api),
86            InstructionV2::AssertWorktopResourcesInclude(i) => i.execute(worktop, objects, api),
87            InstructionV2::AssertNextCallReturnsOnly(i) => i.execute(worktop, objects, api),
88            InstructionV2::AssertNextCallReturnsInclude(i) => i.execute(worktop, objects, api),
89            InstructionV2::AssertBucketContents(i) => i.execute(worktop, objects, api),
90            InstructionV2::PopFromAuthZone(i) => i.execute(worktop, objects, api),
91            InstructionV2::PushToAuthZone(i) => i.execute(worktop, objects, api),
92            InstructionV2::CreateProofFromAuthZoneOfAmount(i) => i.execute(worktop, objects, api),
93            InstructionV2::CreateProofFromAuthZoneOfNonFungibles(i) => {
94                i.execute(worktop, objects, api)
95            }
96            InstructionV2::CreateProofFromAuthZoneOfAll(i) => i.execute(worktop, objects, api),
97            InstructionV2::CreateProofFromBucketOfAmount(i) => i.execute(worktop, objects, api),
98            InstructionV2::CreateProofFromBucketOfNonFungibles(i) => {
99                i.execute(worktop, objects, api)
100            }
101            InstructionV2::CreateProofFromBucketOfAll(i) => i.execute(worktop, objects, api),
102            InstructionV2::DropAuthZoneProofs(i) => i.execute(worktop, objects, api),
103            InstructionV2::DropAuthZoneRegularProofs(i) => i.execute(worktop, objects, api),
104            InstructionV2::DropAuthZoneSignatureProofs(i) => i.execute(worktop, objects, api),
105            InstructionV2::BurnResource(i) => i.execute(worktop, objects, api),
106            InstructionV2::CloneProof(i) => i.execute(worktop, objects, api),
107            InstructionV2::DropProof(i) => i.execute(worktop, objects, api),
108            InstructionV2::CallFunction(i) => i.execute(worktop, objects, api),
109            InstructionV2::CallMethod(i) => i.execute(worktop, objects, api),
110            InstructionV2::CallRoyaltyMethod(i) => i.execute(worktop, objects, api),
111            InstructionV2::CallMetadataMethod(i) => i.execute(worktop, objects, api),
112            InstructionV2::CallRoleAssignmentMethod(i) => i.execute(worktop, objects, api),
113            InstructionV2::CallDirectVaultMethod(i) => i.execute(worktop, objects, api),
114            InstructionV2::DropNamedProofs(i) => i.execute(worktop, objects, api),
115            InstructionV2::DropAllProofs(i) => i.execute(worktop, objects, api),
116            InstructionV2::AllocateGlobalAddress(i) => i.execute(worktop, objects, api),
117            InstructionV2::VerifyParent(i) => {
118                return i
119                    .execute(worktop, objects, api)
120                    .map(|rtn| (InstructionOutput::None, Some(rtn)));
121            }
122            InstructionV2::YieldToChild(i) => {
123                return i
124                    .execute(worktop, objects, api)
125                    .map(|rtn| (InstructionOutput::None, Some(rtn)));
126            }
127            InstructionV2::YieldToParent(i) => {
128                return i
129                    .execute(worktop, objects, api)
130                    .map(|rtn| (InstructionOutput::None, Some(rtn)));
131            }
132        }?;
133
134        Ok((output, None))
135    }
136}
137
138pub trait MultiThreadInstruction {
139    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
140        self,
141        worktop: &mut Worktop,
142        objects: &mut IntentProcessorObjects,
143        api: &mut Y,
144    ) -> Result<MultiThreadResult, RuntimeError>;
145}
146
147impl MultiThreadInstruction for YieldToChild {
148    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
149        self,
150        worktop: &mut Worktop,
151        objects: &mut IntentProcessorObjects,
152        api: &mut Y,
153    ) -> Result<MultiThreadResult, RuntimeError> {
154        // TODO: should we disallow blobs in yield instructions?
155        let scrypto_value = {
156            let mut processor_with_api = IntentProcessorObjectsWithApi {
157                worktop,
158                objects,
159                api,
160                current_total_size_of_blobs: 0,
161            };
162            transform(self.args, &mut processor_with_api)?
163        };
164
165        Ok(MultiThreadResult::SwitchToChild(
166            self.child_index.0 as usize,
167            scrypto_value,
168        ))
169    }
170}
171
172impl MultiThreadInstruction for YieldToParent {
173    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
174        self,
175        worktop: &mut Worktop,
176        objects: &mut IntentProcessorObjects,
177        api: &mut Y,
178    ) -> Result<MultiThreadResult, RuntimeError> {
179        // TODO: should we disallow blobs in yield instructions?
180        let scrypto_value = {
181            let mut processor_with_api = IntentProcessorObjectsWithApi {
182                worktop,
183                objects,
184                api,
185                current_total_size_of_blobs: 0,
186            };
187            transform(self.args, &mut processor_with_api)?
188        };
189
190        Ok(MultiThreadResult::SwitchToParent(scrypto_value))
191    }
192}
193
194impl MultiThreadInstruction for VerifyParent {
195    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
196        self,
197        _worktop: &mut Worktop,
198        _objects: &mut IntentProcessorObjects,
199        _api: &mut Y,
200    ) -> Result<MultiThreadResult, RuntimeError> {
201        Ok(MultiThreadResult::VerifyParent(self.access_rule))
202    }
203}
204
205pub trait TxnNormalInstruction {
206    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
207        self,
208        worktop: &mut Worktop,
209        objects: &mut IntentProcessorObjects,
210        api: &mut Y,
211    ) -> Result<InstructionOutput, RuntimeError>;
212}
213
214impl TxnNormalInstruction for TakeAllFromWorktop {
215    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
216        self,
217        worktop: &mut Worktop,
218        objects: &mut IntentProcessorObjects,
219        api: &mut Y,
220    ) -> Result<InstructionOutput, RuntimeError> {
221        let bucket = worktop.take_all(self.resource_address, api)?;
222        objects.create_manifest_bucket(bucket)?;
223        Ok(InstructionOutput::None)
224    }
225}
226
227impl TxnNormalInstruction for TakeFromWorktop {
228    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
229        self,
230        worktop: &mut Worktop,
231        objects: &mut IntentProcessorObjects,
232        api: &mut Y,
233    ) -> Result<InstructionOutput, RuntimeError> {
234        let bucket = worktop.take(self.resource_address, self.amount, api)?;
235        objects.create_manifest_bucket(bucket)?;
236        Ok(InstructionOutput::None)
237    }
238}
239
240impl TxnNormalInstruction for TakeNonFungiblesFromWorktop {
241    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
242        self,
243        worktop: &mut Worktop,
244        objects: &mut IntentProcessorObjects,
245        api: &mut Y,
246    ) -> Result<InstructionOutput, RuntimeError> {
247        let bucket = worktop.take_non_fungibles(
248            self.resource_address,
249            self.ids.into_iter().collect(),
250            api,
251        )?;
252        objects.create_manifest_bucket(bucket)?;
253        Ok(InstructionOutput::None)
254    }
255}
256
257impl TxnNormalInstruction for ReturnToWorktop {
258    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
259        self,
260        worktop: &mut Worktop,
261        objects: &mut IntentProcessorObjects,
262        api: &mut Y,
263    ) -> Result<InstructionOutput, RuntimeError> {
264        let bucket = objects.take_bucket(&self.bucket_id)?;
265        worktop.put(bucket, api)?;
266        Ok(InstructionOutput::None)
267    }
268}
269
270impl TxnNormalInstruction for AssertWorktopContainsAny {
271    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
272        self,
273        worktop: &mut Worktop,
274        _objects: &mut IntentProcessorObjects,
275        api: &mut Y,
276    ) -> Result<InstructionOutput, RuntimeError> {
277        worktop.assert_contains(self.resource_address, api)?;
278        Ok(InstructionOutput::None)
279    }
280}
281
282impl TxnNormalInstruction for AssertWorktopContains {
283    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
284        self,
285        worktop: &mut Worktop,
286        _objects: &mut IntentProcessorObjects,
287        api: &mut Y,
288    ) -> Result<InstructionOutput, RuntimeError> {
289        worktop.assert_contains_amount(self.resource_address, self.amount, api)?;
290        Ok(InstructionOutput::None)
291    }
292}
293
294impl TxnNormalInstruction for AssertWorktopContainsNonFungibles {
295    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
296        self,
297        worktop: &mut Worktop,
298        _objects: &mut IntentProcessorObjects,
299        api: &mut Y,
300    ) -> Result<InstructionOutput, RuntimeError> {
301        worktop.assert_contains_non_fungibles(
302            self.resource_address,
303            self.ids.into_iter().collect(),
304            api,
305        )?;
306        Ok(InstructionOutput::None)
307    }
308}
309
310impl TxnNormalInstruction for AssertWorktopResourcesInclude {
311    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
312        self,
313        worktop: &mut Worktop,
314        _objects: &mut IntentProcessorObjects,
315        api: &mut Y,
316    ) -> Result<InstructionOutput, RuntimeError> {
317        worktop.assert_resources_include(self.constraints, api)?;
318
319        Ok(InstructionOutput::None)
320    }
321}
322
323impl TxnNormalInstruction for AssertWorktopResourcesOnly {
324    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
325        self,
326        worktop: &mut Worktop,
327        _objects: &mut IntentProcessorObjects,
328        api: &mut Y,
329    ) -> Result<InstructionOutput, RuntimeError> {
330        worktop.assert_resources_only(self.constraints, api)?;
331
332        Ok(InstructionOutput::None)
333    }
334}
335
336impl TxnNormalInstruction for AssertNextCallReturnsOnly {
337    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
338        self,
339        _worktop: &mut Worktop,
340        objects: &mut IntentProcessorObjects,
341        _api: &mut Y,
342    ) -> Result<InstructionOutput, RuntimeError> {
343        objects.next_call_return_constraints = Some(NextCallReturnsChecker {
344            constraints: self.constraints,
345            prevent_unspecified_resource_balances: true,
346            aggregate_balances: AggregateResourceBalances::new(),
347        });
348
349        Ok(InstructionOutput::None)
350    }
351}
352
353impl TxnNormalInstruction for AssertNextCallReturnsInclude {
354    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
355        self,
356        _worktop: &mut Worktop,
357        objects: &mut IntentProcessorObjects,
358        _api: &mut Y,
359    ) -> Result<InstructionOutput, RuntimeError> {
360        objects.next_call_return_constraints = Some(NextCallReturnsChecker {
361            constraints: self.constraints,
362            prevent_unspecified_resource_balances: false,
363            aggregate_balances: AggregateResourceBalances::new(),
364        });
365
366        Ok(InstructionOutput::None)
367    }
368}
369
370impl TxnNormalInstruction for AssertBucketContents {
371    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
372        self,
373        _worktop: &mut Worktop,
374        objects: &mut IntentProcessorObjects,
375        api: &mut Y,
376    ) -> Result<InstructionOutput, RuntimeError> {
377        let bucket = objects.get_bucket(&self.bucket_id)?;
378
379        let resource_address = bucket.resource_address(api)?;
380        if resource_address.is_fungible() {
381            let amount = bucket.amount(api)?;
382            self.constraint.validate_fungible(amount).map_err(|e| {
383                RuntimeError::SystemError(SystemError::IntentError(
384                    IntentError::AssertBucketContentsFailed(e),
385                ))
386            })?;
387        } else {
388            let ids = bucket.non_fungible_local_ids(api)?;
389            self.constraint.validate_non_fungible(&ids).map_err(|e| {
390                RuntimeError::SystemError(SystemError::IntentError(
391                    IntentError::AssertBucketContentsFailed(e),
392                ))
393            })?;
394        }
395
396        Ok(InstructionOutput::None)
397    }
398}
399
400impl TxnNormalInstruction for PopFromAuthZone {
401    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
402        self,
403        _worktop: &mut Worktop,
404        objects: &mut IntentProcessorObjects,
405        api: &mut Y,
406    ) -> Result<InstructionOutput, RuntimeError> {
407        let proof = LocalAuthZone::pop(api)?.ok_or(RuntimeError::ApplicationError(
408            ApplicationError::TransactionProcessorError(TransactionProcessorError::AuthZoneIsEmpty),
409        ))?;
410        objects.create_manifest_proof(proof)?;
411        Ok(InstructionOutput::None)
412    }
413}
414
415impl TxnNormalInstruction for PushToAuthZone {
416    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
417        self,
418        _worktop: &mut Worktop,
419        objects: &mut IntentProcessorObjects,
420        api: &mut Y,
421    ) -> Result<InstructionOutput, RuntimeError> {
422        let proof = objects.take_proof(&self.proof_id)?;
423        LocalAuthZone::push(proof, api)?;
424        Ok(InstructionOutput::None)
425    }
426}
427
428impl TxnNormalInstruction for CreateProofFromAuthZoneOfAmount {
429    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
430        self,
431        _worktop: &mut Worktop,
432        objects: &mut IntentProcessorObjects,
433        api: &mut Y,
434    ) -> Result<InstructionOutput, RuntimeError> {
435        let proof = LocalAuthZone::create_proof_of_amount(self.amount, self.resource_address, api)?;
436        objects.create_manifest_proof(proof)?;
437        Ok(InstructionOutput::None)
438    }
439}
440
441impl TxnNormalInstruction for CreateProofFromAuthZoneOfNonFungibles {
442    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
443        self,
444        _worktop: &mut Worktop,
445        objects: &mut IntentProcessorObjects,
446        api: &mut Y,
447    ) -> Result<InstructionOutput, RuntimeError> {
448        let proof = LocalAuthZone::create_proof_of_non_fungibles(
449            &self.ids.into_iter().collect(),
450            self.resource_address,
451            api,
452        )?;
453        objects.create_manifest_proof(proof)?;
454        Ok(InstructionOutput::None)
455    }
456}
457
458impl TxnNormalInstruction for CreateProofFromAuthZoneOfAll {
459    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
460        self,
461        _worktop: &mut Worktop,
462        objects: &mut IntentProcessorObjects,
463        api: &mut Y,
464    ) -> Result<InstructionOutput, RuntimeError> {
465        let proof = LocalAuthZone::create_proof_of_all(self.resource_address, api)?;
466        objects.create_manifest_proof(proof)?;
467        Ok(InstructionOutput::None)
468    }
469}
470
471impl TxnNormalInstruction for CreateProofFromBucketOfAmount {
472    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
473        self,
474        _worktop: &mut Worktop,
475        objects: &mut IntentProcessorObjects,
476        api: &mut Y,
477    ) -> Result<InstructionOutput, RuntimeError> {
478        let bucket = objects.get_bucket(&self.bucket_id)?;
479        let proof = bucket.create_proof_of_amount(self.amount, api)?;
480        objects.create_manifest_proof(proof.into())?;
481        Ok(InstructionOutput::None)
482    }
483}
484
485impl TxnNormalInstruction for CreateProofFromBucketOfNonFungibles {
486    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
487        self,
488        _worktop: &mut Worktop,
489        objects: &mut IntentProcessorObjects,
490        api: &mut Y,
491    ) -> Result<InstructionOutput, RuntimeError> {
492        let bucket = objects.get_bucket(&self.bucket_id)?;
493        let proof = bucket.create_proof_of_non_fungibles(self.ids.into_iter().collect(), api)?;
494        objects.create_manifest_proof(proof.into())?;
495        Ok(InstructionOutput::None)
496    }
497}
498
499impl TxnNormalInstruction for CreateProofFromBucketOfAll {
500    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
501        self,
502        _worktop: &mut Worktop,
503        objects: &mut IntentProcessorObjects,
504        api: &mut Y,
505    ) -> Result<InstructionOutput, RuntimeError> {
506        let bucket = objects.get_bucket(&self.bucket_id)?;
507        let proof = bucket.create_proof_of_all(api)?;
508        objects.create_manifest_proof(proof)?;
509        Ok(InstructionOutput::None)
510    }
511}
512
513impl TxnNormalInstruction for DropAuthZoneProofs {
514    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
515        self,
516        _worktop: &mut Worktop,
517        _objects: &mut IntentProcessorObjects,
518        api: &mut Y,
519    ) -> Result<InstructionOutput, RuntimeError> {
520        LocalAuthZone::drop_proofs(api)?;
521        Ok(InstructionOutput::None)
522    }
523}
524
525impl TxnNormalInstruction for DropAuthZoneRegularProofs {
526    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
527        self,
528        _worktop: &mut Worktop,
529        _objects: &mut IntentProcessorObjects,
530        api: &mut Y,
531    ) -> Result<InstructionOutput, RuntimeError> {
532        LocalAuthZone::drop_regular_proofs(api)?;
533        Ok(InstructionOutput::None)
534    }
535}
536
537impl TxnNormalInstruction for DropAuthZoneSignatureProofs {
538    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
539        self,
540        _worktop: &mut Worktop,
541        _objects: &mut IntentProcessorObjects,
542        api: &mut Y,
543    ) -> Result<InstructionOutput, RuntimeError> {
544        LocalAuthZone::drop_signature_proofs(api)?;
545        Ok(InstructionOutput::None)
546    }
547}
548
549impl TxnNormalInstruction for BurnResource {
550    #[allow(clippy::let_unit_value)]
551    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
552        self,
553        worktop: &mut Worktop,
554        objects: &mut IntentProcessorObjects,
555        api: &mut Y,
556    ) -> Result<InstructionOutput, RuntimeError> {
557        let bucket = objects.take_bucket(&self.bucket_id)?;
558        let rtn = bucket.burn(api)?;
559
560        let result = IndexedScryptoValue::from_typed(&rtn);
561        objects.handle_call_return_data(&result, worktop, api)?;
562        Ok(InstructionOutput::CallReturn(result.into()))
563    }
564}
565
566impl TxnNormalInstruction for CloneProof {
567    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
568        self,
569        _worktop: &mut Worktop,
570        objects: &mut IntentProcessorObjects,
571        api: &mut Y,
572    ) -> Result<InstructionOutput, RuntimeError> {
573        let proof = objects.get_proof(&self.proof_id)?;
574        let proof = proof.clone(api)?;
575        objects.create_manifest_proof(proof)?;
576        Ok(InstructionOutput::None)
577    }
578}
579
580impl TxnNormalInstruction for DropProof {
581    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
582        self,
583        _worktop: &mut Worktop,
584        objects: &mut IntentProcessorObjects,
585        api: &mut Y,
586    ) -> Result<InstructionOutput, RuntimeError> {
587        let proof = objects.take_proof(&self.proof_id)?;
588        proof.drop(api)?;
589        Ok(InstructionOutput::None)
590    }
591}
592
593fn handle_invocation<Y: SystemApi<RuntimeError> + KernelSubstateApi<L>, L: Default>(
594    api: &mut Y,
595    objects: &mut IntentProcessorObjects,
596    worktop: &mut Worktop,
597    args: ManifestValue,
598    invocation_handler: impl FnOnce(&mut Y, ScryptoValue) -> Result<Vec<u8>, RuntimeError>,
599) -> Result<InstructionOutput, RuntimeError> {
600    let scrypto_value = {
601        let mut processor_with_api = IntentProcessorObjectsWithApi {
602            worktop,
603            objects,
604            api,
605            current_total_size_of_blobs: 0,
606        };
607        transform(args, &mut processor_with_api)?
608    };
609
610    let rtn = invocation_handler(api, scrypto_value)?;
611
612    let result = IndexedScryptoValue::from_vec(rtn)
613        .map_err(TransactionProcessorError::InvocationOutputDecodeError)?;
614    objects.handle_call_return_data(&result, worktop, api)?;
615    Ok(InstructionOutput::CallReturn(result.into()))
616}
617
618impl TxnNormalInstruction for CallFunction {
619    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
620        self,
621        worktop: &mut Worktop,
622        objects: &mut IntentProcessorObjects,
623        api: &mut Y,
624    ) -> Result<InstructionOutput, RuntimeError> {
625        let package_address = objects.resolve_package_address(self.package_address)?;
626        handle_invocation(api, objects, worktop, self.args, |api, args| {
627            api.call_function(
628                package_address,
629                &self.blueprint_name,
630                &self.function_name,
631                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
632            )
633        })
634    }
635}
636
637impl TxnNormalInstruction for CallMethod {
638    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
639        self,
640        worktop: &mut Worktop,
641        objects: &mut IntentProcessorObjects,
642        api: &mut Y,
643    ) -> Result<InstructionOutput, RuntimeError> {
644        let address = objects.resolve_global_address(self.address)?;
645        handle_invocation(api, objects, worktop, self.args, |api, args| {
646            api.call_method(
647                address.as_node_id(),
648                &self.method_name,
649                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
650            )
651        })
652    }
653}
654
655impl TxnNormalInstruction for CallRoyaltyMethod {
656    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
657        self,
658        worktop: &mut Worktop,
659        objects: &mut IntentProcessorObjects,
660        api: &mut Y,
661    ) -> Result<InstructionOutput, RuntimeError> {
662        let address = objects.resolve_global_address(self.address)?;
663        handle_invocation(api, objects, worktop, self.args, |api, args| {
664            api.call_module_method(
665                address.as_node_id(),
666                AttachedModuleId::Royalty,
667                &self.method_name,
668                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
669            )
670        })
671    }
672}
673
674impl TxnNormalInstruction for CallMetadataMethod {
675    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
676        self,
677        worktop: &mut Worktop,
678        objects: &mut IntentProcessorObjects,
679        api: &mut Y,
680    ) -> Result<InstructionOutput, RuntimeError> {
681        let address = objects.resolve_global_address(self.address)?;
682        handle_invocation(api, objects, worktop, self.args, |api, args| {
683            api.call_module_method(
684                address.as_node_id(),
685                AttachedModuleId::Metadata,
686                &self.method_name,
687                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
688            )
689        })
690    }
691}
692
693impl TxnNormalInstruction for CallRoleAssignmentMethod {
694    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
695        self,
696        worktop: &mut Worktop,
697        objects: &mut IntentProcessorObjects,
698        api: &mut Y,
699    ) -> Result<InstructionOutput, RuntimeError> {
700        let address = objects.resolve_global_address(self.address)?;
701        handle_invocation(api, objects, worktop, self.args, |api, args| {
702            api.call_module_method(
703                address.as_node_id(),
704                AttachedModuleId::RoleAssignment,
705                &self.method_name,
706                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
707            )
708        })
709    }
710}
711
712impl TxnNormalInstruction for CallDirectVaultMethod {
713    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
714        self,
715        worktop: &mut Worktop,
716        objects: &mut IntentProcessorObjects,
717        api: &mut Y,
718    ) -> Result<InstructionOutput, RuntimeError> {
719        handle_invocation(api, objects, worktop, self.args, |api, args| {
720            api.call_direct_access_method(
721                self.address.as_node_id(),
722                &self.method_name,
723                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
724            )
725        })
726    }
727}
728
729impl TxnNormalInstruction for DropNamedProofs {
730    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
731        self,
732        _worktop: &mut Worktop,
733        objects: &mut IntentProcessorObjects,
734        api: &mut Y,
735    ) -> Result<InstructionOutput, RuntimeError> {
736        for (_, real_id) in objects.proof_mapping.drain(..) {
737            let proof = Proof(Own(real_id));
738            proof.drop(api).map(|_| IndexedScryptoValue::unit())?;
739        }
740        Ok(InstructionOutput::None)
741    }
742}
743
744impl TxnNormalInstruction for DropAllProofs {
745    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
746        self,
747        _worktop: &mut Worktop,
748        objects: &mut IntentProcessorObjects,
749        api: &mut Y,
750    ) -> Result<InstructionOutput, RuntimeError> {
751        for (_, real_id) in objects.proof_mapping.drain(..) {
752            let proof = Proof(Own(real_id));
753            proof.drop(api).map(|_| IndexedScryptoValue::unit())?;
754        }
755        LocalAuthZone::drop_proofs(api)?;
756        Ok(InstructionOutput::None)
757    }
758}
759
760impl TxnNormalInstruction for AllocateGlobalAddress {
761    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
762        self,
763        _worktop: &mut Worktop,
764        objects: &mut IntentProcessorObjects,
765        api: &mut Y,
766    ) -> Result<InstructionOutput, RuntimeError> {
767        let (address_reservation, address) = api.allocate_global_address(BlueprintId::new(
768            &self.package_address,
769            self.blueprint_name,
770        ))?;
771        objects.create_manifest_address_reservation(address_reservation)?;
772        objects.create_manifest_address(address)?;
773
774        Ok(InstructionOutput::None)
775    }
776}