Skip to content

Commit

Permalink
Add test for checking mutated transitions
Browse files Browse the repository at this point in the history
  • Loading branch information
raychu86 committed Jul 1, 2024
1 parent 87e611c commit f12c33d
Showing 1 changed file with 70 additions and 1 deletion.
71 changes: 70 additions & 1 deletion synthesizer/src/vm/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ mod tests {
account::{Address, ViewKey},
types::Field,
};
use ledger_block::{Block, Header, Metadata, Transaction};
use ledger_block::{Block, Header, Metadata, Transaction, Transition};

type CurrentNetwork = test_helpers::CurrentNetwork;

Expand Down Expand Up @@ -641,4 +641,73 @@ function compute:
// Ensure that the program can't be deployed.
assert!(vm.deploy_raw(&program, rng).is_err());
}

#[test]
fn test_check_mutated_execution() {
let rng = &mut TestRng::default();

// Initialize the VM.
let vm = crate::vm::test_helpers::sample_vm();
// Fetch the caller's private key.
let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng);
// Initialize the genesis block.
let genesis = crate::vm::test_helpers::sample_genesis_block(rng);
// Update the VM.
vm.add_next_block(&genesis).unwrap();

// Fetch a valid execution transaction with a public fee.
let valid_transaction = crate::vm::test_helpers::sample_execution_transaction_with_public_fee(rng);
vm.check_transaction(&valid_transaction, None, rng).unwrap();

// Mutate the execution transaction by inserting a Field::Zero as an output.
let execution = valid_transaction.execution().unwrap();

// Extract the first transition from the execution.
let transitions: Vec<_> = execution.transitions().collect();
assert_eq!(transitions.len(), 1);
let transition = transitions[0].clone();

// Mutate the transition by adding an additional `Field::zero` output. This is significant because the Varuna
// verifier pads the inputs with `Field::zero`s, which means that the same proof is valid for both the
// original and the mutated executions.
let added_output = Output::ExternalRecord(Field::zero());
let mutated_outputs = [transition.outputs(), &[added_output]].concat();
let mutated_transition = Transition::new(
*transition.program_id(),
*transition.function_name(),
transition.inputs().to_vec(),
mutated_outputs,
*transition.tpk(),
*transition.tcm(),
*transition.scm(),
)
.unwrap();

// Construct the mutated execution.
let mutated_execution = Execution::from(
[mutated_transition].into_iter(),
execution.global_state_root(),
execution.proof().cloned(),
)
.unwrap();

// Authorize the fee.
let authorization = vm
.authorize_fee_public(
&caller_private_key,
10_000_000,
100,
mutated_execution.to_execution_id().unwrap(),
rng,
)
.unwrap();
// Compute the fee.
let fee = vm.execute_fee_authorization(authorization, None, rng).unwrap();

// Construct the transaction.
let mutated_transaction = Transaction::from_execution(mutated_execution, Some(fee)).unwrap();

// Ensure that the mutated transaction fails verification due to an extra output.
assert!(vm.check_transaction(&mutated_transaction, None, rng).is_err());
}
}

0 comments on commit f12c33d

Please sign in to comment.