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    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
551        self,
552        worktop: &mut Worktop,
553        objects: &mut IntentProcessorObjects,
554        api: &mut Y,
555    ) -> Result<InstructionOutput, RuntimeError> {
556        let bucket = objects.take_bucket(&self.bucket_id)?;
557        let rtn = bucket.burn(api)?;
558
559        let result = IndexedScryptoValue::from_typed(&rtn);
560        objects.handle_call_return_data(&result, &worktop, api)?;
561        Ok(InstructionOutput::CallReturn(result.into()))
562    }
563}
564
565impl TxnNormalInstruction for CloneProof {
566    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
567        self,
568        _worktop: &mut Worktop,
569        objects: &mut IntentProcessorObjects,
570        api: &mut Y,
571    ) -> Result<InstructionOutput, RuntimeError> {
572        let proof = objects.get_proof(&self.proof_id)?;
573        let proof = proof.clone(api)?;
574        objects.create_manifest_proof(proof)?;
575        Ok(InstructionOutput::None)
576    }
577}
578
579impl TxnNormalInstruction for DropProof {
580    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
581        self,
582        _worktop: &mut Worktop,
583        objects: &mut IntentProcessorObjects,
584        api: &mut Y,
585    ) -> Result<InstructionOutput, RuntimeError> {
586        let proof = objects.take_proof(&self.proof_id)?;
587        proof.drop(api)?;
588        Ok(InstructionOutput::None)
589    }
590}
591
592fn handle_invocation<Y: SystemApi<RuntimeError> + KernelSubstateApi<L>, L: Default>(
593    api: &mut Y,
594    objects: &mut IntentProcessorObjects,
595    worktop: &mut Worktop,
596    args: ManifestValue,
597    invocation_handler: impl FnOnce(&mut Y, ScryptoValue) -> Result<Vec<u8>, RuntimeError>,
598) -> Result<InstructionOutput, RuntimeError> {
599    let scrypto_value = {
600        let mut processor_with_api = IntentProcessorObjectsWithApi {
601            worktop,
602            objects,
603            api,
604            current_total_size_of_blobs: 0,
605        };
606        transform(args, &mut processor_with_api)?
607    };
608
609    let rtn = invocation_handler(api, scrypto_value)?;
610
611    let result = IndexedScryptoValue::from_vec(rtn)
612        .map_err(|error| TransactionProcessorError::InvocationOutputDecodeError(error))?;
613    objects.handle_call_return_data(&result, &worktop, api)?;
614    Ok(InstructionOutput::CallReturn(result.into()))
615}
616
617impl TxnNormalInstruction for CallFunction {
618    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
619        self,
620        worktop: &mut Worktop,
621        objects: &mut IntentProcessorObjects,
622        api: &mut Y,
623    ) -> Result<InstructionOutput, RuntimeError> {
624        let package_address = objects.resolve_package_address(self.package_address)?;
625        handle_invocation(api, objects, worktop, self.args, |api, args| {
626            api.call_function(
627                package_address,
628                &self.blueprint_name,
629                &self.function_name,
630                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
631            )
632        })
633    }
634}
635
636impl TxnNormalInstruction for CallMethod {
637    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
638        self,
639        worktop: &mut Worktop,
640        objects: &mut IntentProcessorObjects,
641        api: &mut Y,
642    ) -> Result<InstructionOutput, RuntimeError> {
643        let address = objects.resolve_global_address(self.address)?;
644        handle_invocation(api, objects, worktop, self.args, |api, args| {
645            api.call_method(
646                address.as_node_id(),
647                &self.method_name,
648                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
649            )
650        })
651    }
652}
653
654impl TxnNormalInstruction for CallRoyaltyMethod {
655    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
656        self,
657        worktop: &mut Worktop,
658        objects: &mut IntentProcessorObjects,
659        api: &mut Y,
660    ) -> Result<InstructionOutput, RuntimeError> {
661        let address = objects.resolve_global_address(self.address)?;
662        handle_invocation(api, objects, worktop, self.args, |api, args| {
663            api.call_module_method(
664                address.as_node_id(),
665                AttachedModuleId::Royalty,
666                &self.method_name,
667                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
668            )
669        })
670    }
671}
672
673impl TxnNormalInstruction for CallMetadataMethod {
674    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
675        self,
676        worktop: &mut Worktop,
677        objects: &mut IntentProcessorObjects,
678        api: &mut Y,
679    ) -> Result<InstructionOutput, RuntimeError> {
680        let address = objects.resolve_global_address(self.address)?;
681        handle_invocation(api, objects, worktop, self.args, |api, args| {
682            api.call_module_method(
683                address.as_node_id(),
684                AttachedModuleId::Metadata,
685                &self.method_name,
686                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
687            )
688        })
689    }
690}
691
692impl TxnNormalInstruction for CallRoleAssignmentMethod {
693    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
694        self,
695        worktop: &mut Worktop,
696        objects: &mut IntentProcessorObjects,
697        api: &mut Y,
698    ) -> Result<InstructionOutput, RuntimeError> {
699        let address = objects.resolve_global_address(self.address)?;
700        handle_invocation(api, objects, worktop, self.args, |api, args| {
701            api.call_module_method(
702                address.as_node_id(),
703                AttachedModuleId::RoleAssignment,
704                &self.method_name,
705                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
706            )
707        })
708    }
709}
710
711impl TxnNormalInstruction for CallDirectVaultMethod {
712    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
713        self,
714        worktop: &mut Worktop,
715        objects: &mut IntentProcessorObjects,
716        api: &mut Y,
717    ) -> Result<InstructionOutput, RuntimeError> {
718        handle_invocation(api, objects, worktop, self.args, |api, args| {
719            api.call_direct_access_method(
720                self.address.as_node_id(),
721                &self.method_name,
722                scrypto_encode(&args).map_err(TransactionProcessorError::ArgsEncodeError)?,
723            )
724        })
725    }
726}
727
728impl TxnNormalInstruction for DropNamedProofs {
729    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
730        self,
731        _worktop: &mut Worktop,
732        objects: &mut IntentProcessorObjects,
733        api: &mut Y,
734    ) -> Result<InstructionOutput, RuntimeError> {
735        for (_, real_id) in objects.proof_mapping.drain(..) {
736            let proof = Proof(Own(real_id));
737            proof.drop(api).map(|_| IndexedScryptoValue::unit())?;
738        }
739        Ok(InstructionOutput::None)
740    }
741}
742
743impl TxnNormalInstruction for DropAllProofs {
744    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
745        self,
746        _worktop: &mut Worktop,
747        objects: &mut IntentProcessorObjects,
748        api: &mut Y,
749    ) -> Result<InstructionOutput, RuntimeError> {
750        for (_, real_id) in objects.proof_mapping.drain(..) {
751            let proof = Proof(Own(real_id));
752            proof.drop(api).map(|_| IndexedScryptoValue::unit())?;
753        }
754        LocalAuthZone::drop_proofs(api)?;
755        Ok(InstructionOutput::None)
756    }
757}
758
759impl TxnNormalInstruction for AllocateGlobalAddress {
760    fn execute<Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<L>, L: Default>(
761        self,
762        _worktop: &mut Worktop,
763        objects: &mut IntentProcessorObjects,
764        api: &mut Y,
765    ) -> Result<InstructionOutput, RuntimeError> {
766        let (address_reservation, address) = api.allocate_global_address(BlueprintId::new(
767            &self.package_address,
768            self.blueprint_name,
769        ))?;
770        objects.create_manifest_address_reservation(address_reservation)?;
771        objects.create_manifest_address(address)?;
772
773        Ok(InstructionOutput::None)
774    }
775}