Skip to content

Commit

Permalink
Add test demonstrating transfer_public_to_private using a program
Browse files Browse the repository at this point in the history
  • Loading branch information
d0cd committed Mar 22, 2024
1 parent 502c682 commit 761d493
Showing 1 changed file with 187 additions and 1 deletion.
188 changes: 187 additions & 1 deletion synthesizer/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ pub(crate) mod test_helpers {
use console::{
account::{Address, ViewKey},
network::MainnetV0,
program::Value,
program::{Entry, Value},
types::Field,
};
use ledger_block::{Block, Header, Metadata, Transition};
Expand Down Expand Up @@ -1960,6 +1960,192 @@ finalize transfer_public_as_signer:
assert_eq!(balance, 1, "Update me if the test amount changes.");
}

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

// Initialize a new caller.
let caller_private_key = crate::vm::test_helpers::sample_genesis_private_key(rng);
let caller_address = Address::try_from(&caller_private_key).unwrap();

// Initialize a recipient.
let recipient_private_key = PrivateKey::new(rng).unwrap();
let recipient_address = Address::try_from(&recipient_private_key).unwrap();

// Initialize the genesis block.
let genesis = crate::vm::test_helpers::sample_genesis_block(rng);

// Initialize the VM.
let vm = crate::vm::test_helpers::sample_vm();

// Update the VM.
vm.add_next_block(&genesis).unwrap();

// Check the balance of the caller.
let credits_program_id = ProgramID::from_str("credits.aleo").unwrap();
let account_mapping_name = Identifier::from_str("account").unwrap();
let balance = match vm
.finalize_store()
.get_value_confirmed(
credits_program_id,
account_mapping_name,
&Plaintext::from(Literal::Address(caller_address)),
)
.unwrap()
{
Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance,
_ => panic!("Expected a valid balance"),
};
assert_eq!(balance, 182_499_999_894_244, "Update me if the initial balance changes.");

// Check that the recipient does not have a public balance.
let balance = vm
.finalize_store()
.get_value_confirmed(
credits_program_id,
account_mapping_name,
&Plaintext::from(Literal::Address(recipient_address)),
)
.unwrap();
assert!(balance.is_none());

// Initialize a wrapper program, importing `credits.aleo` and calling `transfer_public_as_signer` then `transfer_public_to_private`.
let program = Program::from_str(
r"
import credits.aleo;
program credits_wrapper.aleo;
function transfer_public_to_private:
input r0 as address.private;
input r1 as u64.public;
call credits.aleo/transfer_public_as_signer credits_wrapper.aleo r1 into r2;
call credits.aleo/transfer_public_to_private r0 r1 into r3 r4;
async transfer_public_to_private r2 r4 into r5;
output r3 as credits.aleo/credits.record;
output r5 as credits_wrapper.aleo/transfer_public_to_private.future;
finalize transfer_public_to_private:
input r0 as credits.aleo/transfer_public_as_signer.future;
input r1 as credits.aleo/transfer_public_to_private.future;
contains credits.aleo/account[credits_wrapper.aleo] into r2;
assert.eq r2 false;
await r0;
get credits.aleo/account[credits_wrapper.aleo] into r3;
assert.eq r3 r0[2u32];
await r1;
",
)
.unwrap();

// Get the address of the wrapper program.
let wrapper_program_id = ProgramID::from_str("credits_wrapper.aleo").unwrap();

// Deploy the wrapper program.
let deployment = vm.deploy(&caller_private_key, &program, None, 0, None, rng).unwrap();

// Add the deployment to a block and update the VM.
let block = sample_next_block(&vm, &caller_private_key, &[deployment], rng).unwrap();

// Update the VM.
vm.add_next_block(&block).unwrap();

// Call the wrapper program to transfer credits from the caller to the recipient.
let transaction = vm
.execute(
&caller_private_key,
("credits_wrapper.aleo", "transfer_public_to_private"),
[Value::from_str(&format!("{recipient_address}")).unwrap(), Value::from_str("1u64").unwrap()].iter(),
None,
0,
None,
rng,
)
.unwrap();

// Verify the transaction.
vm.check_transaction(&transaction, None, rng).unwrap();

// Add the transaction to a block and update the VM.
let block = sample_next_block(&vm, &caller_private_key, &[transaction.clone()], rng).unwrap();

// Update the VM.
vm.add_next_block(&block).unwrap();

// Check the balance of the caller.
let balance = match vm
.finalize_store()
.get_value_confirmed(
credits_program_id,
account_mapping_name,
&Plaintext::from(Literal::Address(caller_address)),
)
.unwrap()
{
Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance,
_ => panic!("Expected a valid balance"),
};

assert_eq!(balance, 182_499_996_924_681, "Update me if the initial balance changes.");

// Check that the `credits_wrapper` program has a balance of 0.
let balance = match vm
.finalize_store()
.get_value_confirmed(
credits_program_id,
account_mapping_name,
&Plaintext::from(Literal::Address(wrapper_program_id.to_address().unwrap())),
)
.unwrap()
{
Some(Value::Plaintext(Plaintext::Literal(Literal::U64(balance), _))) => *balance,
_ => panic!("Expected a valid balance"),
};
assert_eq!(balance, 0);

// Check that the recipient does not have a public balance.
let balance = vm
.finalize_store()
.get_value_confirmed(
credits_program_id,
account_mapping_name,
&Plaintext::from(Literal::Address(recipient_address)),
)
.unwrap();
assert!(balance.is_none());

// Get the output record from the transaction and check that it is well-formed.
let records = transaction.records().collect_vec();
assert_eq!(records.len(), 1);
let (commitment, record) = records[0];
let record = record.decrypt(&ViewKey::try_from(&recipient_private_key).unwrap()).unwrap();
assert_eq!(**record.owner(), recipient_address);
let data = record.data();
assert_eq!(data.len(), 1);
match data.get(&Identifier::from_str("microcredits").unwrap()) {
Some(Entry::<CurrentNetwork, _>::Private(Plaintext::Literal(Literal::U64(value), _))) => {
assert_eq!(**value, 1)
}
_ => panic!("Incorrect record."),
}

// Check that the record exists in the VM.
assert!(vm.transition_store().get_record(commitment).unwrap().is_some());

// Check that the serial number of the record does not exist in the VM.
assert!(
!vm.transition_store()
.contains_serial_number(
&Record::<CurrentNetwork, Plaintext<CurrentNetwork>>::serial_number(
recipient_private_key,
*commitment
)
.unwrap()
)
.unwrap()
);
}

#[test]
fn test_vm_puzzle() {
// Attention: This test is used to ensure that the VM has performed downcasting correctly for
Expand Down

0 comments on commit 761d493

Please sign in to comment.