diff --git a/radix-engine-tests/assets/blueprints/execution_trace/src/execution_trace.rs b/radix-engine-tests/assets/blueprints/execution_trace/src/execution_trace.rs index 2f11e7fa850..510f3e40bdf 100644 --- a/radix-engine-tests/assets/blueprints/execution_trace/src/execution_trace.rs +++ b/radix-engine-tests/assets/blueprints/execution_trace/src/execution_trace.rs @@ -9,6 +9,7 @@ mod execution_trace_test { impl ExecutionTraceBp { pub fn transfer_resource_between_two_components( amount: u8, + use_take_advanced: bool, ) -> ( ResourceAddress, Global, @@ -34,7 +35,11 @@ mod execution_trace_test { .prepare_to_globalize(OwnerRole::None) .globalize(); - let transfer_bucket: Bucket = source_component.take(amount); + let transfer_bucket: Bucket = if use_take_advanced { + source_component.take_advanced(amount) + } else { + source_component.take(amount) + }; target_component.put(transfer_bucket); (resource_address, source_component, target_component) @@ -44,6 +49,10 @@ mod execution_trace_test { self.vault.take(amount) } + pub fn take_advanced(&mut self, amount: u8) -> Bucket { + self.vault.take_advanced(amount, WithdrawStrategy::Exact) + } + pub fn put(&mut self, b: Bucket) { self.vault.put(b) } diff --git a/radix-engine-tests/tests/application/execution_trace.rs b/radix-engine-tests/tests/application/execution_trace.rs index 0718004e4d5..edc7aed514d 100644 --- a/radix-engine-tests/tests/application/execution_trace.rs +++ b/radix-engine-tests/tests/application/execution_trace.rs @@ -7,7 +7,16 @@ use radix_transactions::model::PreviewFlags; use scrypto_test::prelude::*; #[test] -fn test_trace_resource_transfers() { +fn test_trace_resource_transfers_using_take() { + run_resource_transfers_trace_test(false); +} + +#[test] +fn test_trace_resource_transfers_using_take_advanced() { + run_resource_transfers_trace_test(true); +} + +fn run_resource_transfers_trace_test(use_take_advanced: bool) { // Arrange let mut ledger = LedgerSimulatorBuilder::new().build(); let (public_key, _, account) = ledger.new_allocated_account(); @@ -21,7 +30,7 @@ fn test_trace_resource_transfers() { package_address, "ExecutionTraceBp", "transfer_resource_between_two_components", - manifest_args!(transfer_amount), + manifest_args!(transfer_amount, use_take_advanced), ) .build(); let receipt = ledger.preview_manifest( diff --git a/radix-engine/src/system/system_modules/execution_trace/module.rs b/radix-engine/src/system/system_modules/execution_trace/module.rs index 972ea86c115..2be7839dd55 100644 --- a/radix-engine/src/system/system_modules/execution_trace/module.rs +++ b/radix-engine/src/system/system_modules/execution_trace/module.rs @@ -90,9 +90,10 @@ impl From<&BucketSnapshot> for ResourceSpecifier { #[derive(Debug, Clone)] pub enum VaultOp { - Create(Decimal), // TODO: add trace of vault creation Put(ResourceAddress, Decimal), // TODO: add non-fungible support Take(ResourceAddress, Decimal), + TakeAdvanced(ResourceAddress, Decimal), + Recall(ResourceAddress, Decimal), LockFee(Decimal, bool), } @@ -508,18 +509,37 @@ impl ExecutionTraceModule { match &callee { Actor::Method(actor @ MethodActor { node_id, ident, .. }) - if VaultUtil::is_vault_blueprint(&actor.get_blueprint_id()) - && ident.eq(VAULT_PUT_IDENT) => + if VaultUtil::is_vault_blueprint(&actor.get_blueprint_id()) => { - self.handle_vault_put_input(&resource_summary, current_actor, node_id) - } - Actor::Method(actor @ MethodActor { node_id, ident, .. }) - if VaultUtil::is_vault_blueprint(&actor.get_blueprint_id()) - && ident.eq(FUNGIBLE_VAULT_LOCK_FEE_IDENT) => - { - self.handle_vault_lock_fee_input(current_actor, node_id, args) + match ident.as_str() { + VAULT_PUT_IDENT => { + self.handle_vault_put_input(&resource_summary, current_actor, node_id) + } + FUNGIBLE_VAULT_LOCK_FEE_IDENT => { + self.handle_vault_lock_fee_input(current_actor, node_id, args) + } + VAULT_BURN_IDENT + | VAULT_TAKE_IDENT + | VAULT_TAKE_ADVANCED_IDENT + | VAULT_RECALL_IDENT + | VAULT_GET_AMOUNT_IDENT + | VAULT_FREEZE_IDENT + | VAULT_UNFREEZE_IDENT => { /* no-op */ } + FUNGIBLE_VAULT_LOCK_FUNGIBLE_AMOUNT_IDENT + | FUNGIBLE_VAULT_UNLOCK_FUNGIBLE_AMOUNT_IDENT + | FUNGIBLE_VAULT_CREATE_PROOF_OF_AMOUNT_IDENT => { /* no-op */ } + NON_FUNGIBLE_VAULT_TAKE_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_GET_NON_FUNGIBLE_LOCAL_IDS_IDENT + | NON_FUNGIBLE_VAULT_CONTAINS_NON_FUNGIBLE_IDENT + | NON_FUNGIBLE_VAULT_RECALL_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_CREATE_PROOF_OF_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_LOCK_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_UNLOCK_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_BURN_NON_FUNGIBLES_IDENT => { /* no-op */ } + _ => panic!("Unhandled vault method"), + } } - _ => {} + _ => { /* no-op */ } } } @@ -538,10 +558,49 @@ impl ExecutionTraceModule { match current_actor { Actor::Method(actor @ MethodActor { node_id, ident, .. }) => { - if VaultUtil::is_vault_blueprint(&actor.get_blueprint_id()) - && ident.eq(VAULT_TAKE_IDENT) - { - self.handle_vault_take_output(&resource_summary, &caller, node_id) + if VaultUtil::is_vault_blueprint(&actor.get_blueprint_id()) { + match ident.as_str() { + VAULT_TAKE_IDENT | VAULT_TAKE_ADVANCED_IDENT | VAULT_RECALL_IDENT => { + for (_, resource) in &resource_summary.buckets { + let op = if ident == VAULT_TAKE_IDENT { + VaultOp::Take(resource.resource_address(), resource.amount()) + } else if ident == VAULT_TAKE_ADVANCED_IDENT { + VaultOp::TakeAdvanced( + resource.resource_address(), + resource.amount(), + ) + } else if ident == VAULT_RECALL_IDENT { + VaultOp::Recall(resource.resource_address(), resource.amount()) + } else { + panic!("Unhandled vault method") + }; + self.vault_ops.push(( + caller.clone(), + node_id.clone(), + op, + self.instruction_index(), + )); + } + } + VAULT_PUT_IDENT + | VAULT_GET_AMOUNT_IDENT + | VAULT_FREEZE_IDENT + | VAULT_UNFREEZE_IDENT + | VAULT_BURN_IDENT => { /* no-op */ } + FUNGIBLE_VAULT_LOCK_FEE_IDENT + | FUNGIBLE_VAULT_LOCK_FUNGIBLE_AMOUNT_IDENT + | FUNGIBLE_VAULT_UNLOCK_FUNGIBLE_AMOUNT_IDENT + | FUNGIBLE_VAULT_CREATE_PROOF_OF_AMOUNT_IDENT => { /* no-op */ } + NON_FUNGIBLE_VAULT_TAKE_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_GET_NON_FUNGIBLE_LOCAL_IDS_IDENT + | NON_FUNGIBLE_VAULT_CONTAINS_NON_FUNGIBLE_IDENT + | NON_FUNGIBLE_VAULT_RECALL_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_CREATE_PROOF_OF_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_LOCK_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_UNLOCK_NON_FUNGIBLES_IDENT + | NON_FUNGIBLE_VAULT_BURN_NON_FUNGIBLES_IDENT => { /* no-op */ } + _ => panic!("Unhandled vault method"), + } } } Actor::Function(_) => {} @@ -649,22 +708,6 @@ impl ExecutionTraceModule { self.instruction_index(), )); } - - fn handle_vault_take_output<'s>( - &mut self, - resource_summary: &ResourceSummary, - actor: &TraceActor, - vault_id: &NodeId, - ) { - for (_, resource) in &resource_summary.buckets { - self.vault_ops.push(( - actor.clone(), - vault_id.clone(), - VaultOp::Take(resource.resource_address(), resource.amount()), - self.instruction_index(), - )); - } - } } pub fn calculate_resource_changes( @@ -683,7 +726,6 @@ pub fn calculate_resource_changes( for (actor, vault_id, vault_op, instruction_index) in vault_ops { if let TraceActor::Method(node_id) = actor { match vault_op { - VaultOp::Create(_) => todo!("Not supported yet!"), VaultOp::Put(resource_address, amount) => { let entry = &mut vault_changes .entry(instruction_index) @@ -695,7 +737,9 @@ pub fn calculate_resource_changes( .1; *entry = entry.checked_add(amount).unwrap(); } - VaultOp::Take(resource_address, amount) => { + VaultOp::Take(resource_address, amount) + | VaultOp::TakeAdvanced(resource_address, amount) + | VaultOp::Recall(resource_address, amount) => { let entry = &mut vault_changes .entry(instruction_index) .or_default()