use crate::{CallStack, InclusionVersion, Process, Trace, execution_cost, execution_cost_for_authorization};
use circuit::{Aleo, network::AleoV0};
use console::{
account::{Address, PrivateKey, ViewKey},
network::{MainnetV0, prelude::*},
program::{Identifier, Literal, Plaintext, ProgramID, Record, Value},
types::{Field, U64},
};
use snarkvm_algorithms::snark::varuna::VarunaVersion;
use snarkvm_ledger_block::{Fee, Output, Transaction, Transition};
use snarkvm_ledger_query::Query;
use snarkvm_ledger_store::{
BlockStorage,
BlockStore,
FinalizeStorage,
FinalizeStore,
helpers::memory::{BlockMemory, FinalizeMemory},
};
use snarkvm_synthesizer_program::{FinalizeGlobalState, FinalizeStoreTrait, Program, StackTrait};
use snarkvm_synthesizer_snark::UniversalSRS;
use aleo_std::StorageMode;
#[cfg(feature = "locktick")]
use locktick::parking_lot::RwLock;
#[cfg(not(feature = "locktick"))]
use parking_lot::RwLock;
use std::sync::Arc;
type CurrentNetwork = MainnetV0;
type CurrentAleo = AleoV0;
pub fn sample_finalize_state(block_height: u32) -> FinalizeGlobalState {
FinalizeGlobalState::from(block_height as u64, block_height, None, [0u8; 32])
}
pub fn sample_fee<N: Network, A: Aleo<Network = N>, B: BlockStorage<N>, P: FinalizeStorage<N>>(
process: &Process<N>,
block_store: &BlockStore<N, B>,
finalize_store: &FinalizeStore<N, P>,
rng: &mut TestRng,
) -> Fee<N> {
let program_id = ProgramID::from_str("credits.aleo").unwrap();
let account_mapping = Identifier::from_str("account").unwrap();
let _ = finalize_store.initialize_mapping(program_id, account_mapping);
let private_key = PrivateKey::<N>::new(rng).unwrap();
let address = Address::try_from(private_key).unwrap();
let key = Plaintext::from(Literal::Address(address));
let value = Value::from(Literal::U64(U64::new(100)));
finalize_store.update_key_value(program_id, account_mapping, key, value).unwrap();
let base_fee_in_microcredits = 100;
let priority_fee_in_microcredits = 0;
let id = Field::rand(rng);
let authorization = process
.authorize_fee_public::<A, _>(&private_key, base_fee_in_microcredits, priority_fee_in_microcredits, id, rng)
.unwrap();
let (_, mut trace) = process.execute::<A, _>(authorization, rng).unwrap();
trace.prepare(&Query::from(block_store)).unwrap();
trace.prove_fee::<A, _>(VarunaVersion::V2, rng).unwrap()
}
#[test]
fn test_program_evaluate_function() {
let program = Program::<CurrentNetwork>::from_str(
r"
program example.aleo;
function foo:
input r0 as field.public;
input r1 as field.private;
add r0 r1 into r2;
output r2 as field.private;
",
)
.unwrap();
let function_name = Identifier::from_str("foo").unwrap();
let inputs = [
Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("2field").unwrap()),
Value::Plaintext(Plaintext::from_str("3field").unwrap()),
];
let process = crate::test_helpers::sample_process(&program);
let rng = &mut TestRng::default();
let authorization = {
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, inputs.iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
authorization
};
let stack = process.get_stack(program.id()).unwrap();
let expected = Value::Plaintext(Plaintext::<CurrentNetwork>::from_str("5field").unwrap());
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
}
#[test]
fn test_program_evaluate_struct_and_function() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program example.aleo;
struct message:
first as field;
second as field;
function compute:
input r0 as message.private;
add r0.first r0.second into r1;
output r1 as field.private;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let input = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("{ first: 2field, second: 3field }").unwrap());
let expected = Value::Plaintext(Plaintext::from_str("5field").unwrap());
let process = crate::test_helpers::sample_process(&program);
let rng = &mut TestRng::default();
let authorization = {
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
authorization
};
let stack = process.get_stack(program.id()).unwrap();
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
}
#[test]
fn test_program_evaluate_record_and_function() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program token.aleo;
record token:
owner as address.private;
token_amount as u64.private;
function compute:
input r0 as token.record;
add r0.token_amount r0.token_amount into r1;
output r1 as u64.private;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let input_record = Record::from_str(&format!(
"{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}"
))
.unwrap();
let input = Value::<CurrentNetwork>::Record(input_record);
let expected = Value::Plaintext(Plaintext::from_str("200u64").unwrap());
let process = crate::test_helpers::sample_process(&program);
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let stack = process.get_stack(program.id()).unwrap();
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
}
#[test]
fn test_program_evaluate_call() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program example_call.aleo;
// (a + (a + b)) + (a + b) == (3a + 2b)
closure execute:
input r0 as field;
input r1 as field;
add r0 r1 into r2;
add r0 r2 into r3;
add r2 r3 into r4;
output r4 as field;
output r3 as field;
output r2 as field;
function compute:
input r0 as field.private;
input r1 as field.public;
call execute r0 r1 into r2 r3 r4;
output r2 as field.private;
output r3 as field.private;
output r4 as field.private;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let r0 = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("3field").unwrap());
let r1 = Value::<CurrentNetwork>::Plaintext(Plaintext::from_str("5field").unwrap());
let r2 = Value::Plaintext(Plaintext::from_str("19field").unwrap());
let r3 = Value::Plaintext(Plaintext::from_str("11field").unwrap());
let r4 = Value::Plaintext(Plaintext::from_str("8field").unwrap());
{
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, &mut TestRng::default()).unwrap();
}
let process = crate::test_helpers::sample_process(&program);
let rng = &mut TestRng::default();
let authorization = {
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(
&caller_private_key,
program.id(),
function_name,
[r0.clone(), r1.clone()].iter(),
rng,
)
.unwrap();
assert_eq!(authorization.len(), 1);
authorization
};
let stack = process.get_stack(program.id()).unwrap();
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(r3, candidate[1]);
assert_eq!(r4, candidate[2]);
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(r3, candidate[1]);
assert_eq!(r4, candidate[2]);
use circuit::Environment;
assert_eq!(0, CurrentAleo::num_constants());
assert_eq!(1, CurrentAleo::num_public());
assert_eq!(0, CurrentAleo::num_private());
assert_eq!(0, CurrentAleo::num_constraints());
let rng = &mut TestRng::default();
let burner_private_key = PrivateKey::new(rng).unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&burner_private_key, program.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let trace = Arc::new(RwLock::new(Trace::new()));
let translations = Arc::new(RwLock::new(Vec::new()));
let call_stack = CallStack::execute(authorization, trace, translations).unwrap();
let response = stack.execute_function::<CurrentAleo, _>(call_stack, None, None, rng).unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(r3, candidate[1]);
assert_eq!(r4, candidate[2]);
}
#[test]
fn test_program_evaluate_cast() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program token_with_cast.aleo;
record token:
owner as address.private;
token_amount as u64.private;
function compute:
input r0 as token.record;
cast r0.owner r0.token_amount into r1 as token.record;
output r1 as token.record;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let input_record = Record::from_str(&format!(
"{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}"
))
.unwrap();
let input = Value::<CurrentNetwork>::Record(input_record);
let process = crate::test_helpers::sample_process(&program);
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let request = authorization.peek_next().unwrap();
let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(1)]).unwrap();
let nonce = CurrentNetwork::g_scalar_multiply(&randomizer);
let expected = Value::from_str(&format!(
"{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: {nonce}.public, _version: 1u8.public }}"
))
.unwrap();
let stack = process.get_stack(program.id()).unwrap();
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization.replicate()).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
let response = stack
.evaluate_function::<CurrentAleo, _>(CallStack::evaluate(authorization).unwrap(), None, None, rng)
.unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(expected, candidate[0]);
}
#[test]
fn test_process_execute_transfer_public_to_private() {
let program = Program::<CurrentNetwork>::credits().unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let recipient_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let recipient_view_key = ViewKey::try_from(&recipient_private_key).unwrap();
let recipient = Address::try_from(&recipient_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&format!("{recipient}")).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("99_000_000_000_000_u64").unwrap();
let process = Process::load().unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(
&caller_private_key,
program.id(),
Identifier::from_str("transfer_public_to_private").unwrap(),
[r0, r1].iter(),
rng,
)
.unwrap();
assert_eq!(authorization.len(), 1);
let request = authorization.peek_next().unwrap();
let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(2)]).unwrap();
let nonce = CurrentNetwork::g_scalar_multiply(&randomizer);
let r2 = Value::from_str(&format!(
"{{ owner: {recipient}.private, microcredits: 99_000_000_000_000_u64.private, _nonce: {nonce}.public, _version: 1u8.public }}"
))
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len());
assert_eq!(r2, candidate[0]);
{
let process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("credits.aleo", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
assert_eq!(1, execution.transitions().len());
let transition: Transition<_> = execution.into_transitions().next().unwrap();
assert_eq!(transition.program_id(), program.id());
assert_eq!(transition.function_name(), &Identifier::from_str("transfer_public_to_private").unwrap());
assert_eq!(2, transition.inputs().len());
assert_eq!(2, transition.outputs().len());
assert!(matches!(transition.outputs()[0], Output::Record(..)));
let output = transition.outputs()[0].clone();
let expected_caller = output.decrypt_sender_ciphertext(&recipient_view_key).unwrap();
assert_eq!(Some(caller), expected_caller);
assert!(output.decrypt_sender_ciphertext(&caller_view_key).is_err());
let different_view_key = ViewKey::try_from(&PrivateKey::<CurrentNetwork>::new(rng).unwrap()).unwrap();
assert!(output.decrypt_sender_ciphertext(&different_view_key).is_err());
}
}
#[test]
fn test_process_circuit_key() {
let program = Program::<CurrentNetwork>::from_str(
r#"program testing.aleo;
function hello_world:
input r0 as u32.public;
input r1 as u32.private;
add r0 r1 into r2;
output r2 as u32.private;
"#,
)
.unwrap();
let function_name = Identifier::from_str("hello_world").unwrap();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, &mut TestRng::default()).unwrap();
}
#[test]
fn test_process_multirecords() {
let program = Program::<CurrentNetwork>::from_str(
r"program multirecord.aleo;
record record_a:
owner as address.private;
item as u64.private;
record record_b:
owner as address.private;
item as u64.private;
record record_c:
owner as address.private;
item as u64.private;
function initialize:
input r0 as record_a.record;
input r1 as record_b.record;
input r2 as record_c.record;
cast r0.owner r0.item into r3 as record_a.record;
cast r1.owner r1.item into r4 as record_b.record;
cast r2.owner r2.item into r5 as record_c.record;
output r3 as record_a.record;
output r4 as record_b.record;
output r5 as record_c.record;",
)
.unwrap();
let function_name = Identifier::from_str("initialize").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let input_a =
Value::from_str(&format!("{{ owner: {caller}.private, item: 1234u64.private, _nonce: 0group.public }}"))
.unwrap();
let input_b =
Value::from_str(&format!("{{ owner: {caller}.private, item: 4321u64.private, _nonce: 0group.public }}"))
.unwrap();
let input_c =
Value::from_str(&format!("{{ owner: {caller}.private, item: 5678u64.private, _nonce: 0group.public }}"))
.unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(
&caller_private_key,
program.id(),
function_name,
[input_a, input_b, input_c].iter(),
rng,
)
.unwrap();
assert_eq!(authorization.len(), 1);
let request = authorization.peek_next().unwrap();
let randomizer_a = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(3)]).unwrap();
let nonce_a = CurrentNetwork::g_scalar_multiply(&randomizer_a);
let randomizer_b = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(4)]).unwrap();
let nonce_b = CurrentNetwork::g_scalar_multiply(&randomizer_b);
let randomizer_c = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(5)]).unwrap();
let nonce_c = CurrentNetwork::g_scalar_multiply(&randomizer_c);
let output_a = Value::from_str(&format!(
"{{ owner: {caller}.private, item: 1234u64.private, _nonce: {nonce_a}.public, _version: 1u8.public }}"
))
.unwrap();
let output_b = Value::from_str(&format!(
"{{ owner: {caller}.private, item: 4321u64.private, _nonce: {nonce_b}.public, _version: 1u8.public }}"
))
.unwrap();
let output_c = Value::from_str(&format!(
"{{ owner: {caller}.private, item: 5678u64.private, _nonce: {nonce_c}.public, _version: 1u8.public }}"
))
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(output_a, candidate[0]);
assert_eq!(output_b, candidate[1]);
assert_eq!(output_c, candidate[2]);
assert_eq!(authorization.len(), 1);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(output_a, candidate[0]);
assert_eq!(output_b, candidate[1]);
assert_eq!(output_c, candidate[2]);
}
#[test]
fn test_process_self_caller() {
let program = Program::<CurrentNetwork>::from_str(
r"program caller.aleo;
record data:
owner as address.private;
item as u64.private;
function initialize:
input r0 as data.record;
cast self.caller r0.item into r1 as data.record;
output r1 as data.record;",
)
.unwrap();
let function_name = Identifier::from_str("initialize").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let input =
Value::from_str(&format!("{{ owner: {caller}.private, item: 1234u64.private, _nonce: 0group.public }}"))
.unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [input].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let request = authorization.peek_next().unwrap();
let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(1)]).unwrap();
let nonce = CurrentNetwork::g_scalar_multiply(&randomizer);
let output = Value::from_str(&format!(
"{{ owner: {caller}.private, item: 1234u64.private, _nonce: {nonce}.public, _version: 1u8.public }}"
))
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
assert_eq!(authorization.len(), 1);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
}
#[test]
fn test_process_program_id() {
let program = Program::<CurrentNetwork>::from_str(
r"program id.aleo;
struct data:
user as address;
function initialize:
cast id.aleo into r0 as data;
output r0 as data.private;",
)
.unwrap();
let program_id = ProgramID::from_str("id.aleo").unwrap();
assert_eq!(*program.id(), program_id);
let function_name = Identifier::from_str("initialize").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let inputs: &[Value<CurrentNetwork>] = &[];
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, inputs.iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let output = Value::from_str(&format!("{{ user: {} }}", program_id.to_address().unwrap())).unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
assert_eq!(authorization.len(), 1);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
}
#[test]
fn test_process_output_operand() {
fn authorize_execute_and_verify(
program: &Program<CurrentNetwork>,
function_name: Identifier<CurrentNetwork>,
output: Value<CurrentNetwork>,
caller_private_key: &PrivateKey<CurrentNetwork>,
rng: &mut TestRng,
) {
let process = crate::test_helpers::sample_process(program);
let inputs: &[Value<CurrentNetwork>] = &[];
let authorization = process
.authorize::<CurrentAleo, _>(caller_private_key, program.id(), function_name, inputs.iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
assert_eq!(authorization.len(), 1);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(output, candidate[0]);
}
let program = Program::<CurrentNetwork>::from_str(
r"program operand.aleo;
function program_id:
output operand.aleo as address.private;
function literal:
output 1234u64 as u64.private;
function caller:
output self.caller as address.private;",
)
.unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
authorize_execute_and_verify(
&program,
Identifier::from_str("program_id").unwrap(),
Value::from_str(&program.id().to_address().unwrap().to_string()).unwrap(),
&caller_private_key,
rng,
);
authorize_execute_and_verify(
&program,
Identifier::from_str("literal").unwrap(),
Value::from_str("1234u64").unwrap(),
&caller_private_key,
rng,
);
authorize_execute_and_verify(
&program,
Identifier::from_str("caller").unwrap(),
Value::from_str(&format!("{caller}")).unwrap(),
&caller_private_key,
rng,
);
}
#[test]
fn test_process_execute_call_closure() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program token.aleo;
record token:
owner as address.private;
token_amount as u64.private;
// (a + (a + b)) + (a + b) == (3a + 2b)
closure execute:
input r0 as field;
input r1 as field;
add r0 r1 into r2;
add r0 r2 into r3;
add r2 r3 into r4;
output r4 as field;
output r3 as field;
output r2 as field;
closure check_not_equal:
input r0 as field;
input r1 as field;
assert.neq r0 r1;
function compute:
input r0 as field.private;
input r1 as field.public;
input r2 as token.record;
cast r2.owner r2.token_amount into r3 as token.record;
call check_not_equal r0 r1;
call execute r0 r1 into r4 r5 r6;
output r3 as token.record;
output r4 as field.private;
output r5 as field.private;
output r6 as field.private;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let process = crate::test_helpers::sample_process(&program);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let record_string = format!("{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: 0group.public }}");
let r0 = Value::<CurrentNetwork>::from_str("3field").unwrap();
let r1 = Value::<CurrentNetwork>::from_str("5field").unwrap();
let r2 = Value::<CurrentNetwork>::from_str(&record_string).unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let request = authorization.peek_next().unwrap();
let randomizer = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(3)]).unwrap();
let nonce = CurrentNetwork::g_scalar_multiply(&randomizer);
let r3 = Value::<CurrentNetwork>::from_str(&format!(
"{{ owner: {caller}.private, token_amount: 100u64.private, _nonce: {nonce}.public, _version: 1u8.public }}"
))
.unwrap();
let r4 = Value::from_str("19field").unwrap();
let r5 = Value::from_str("11field").unwrap();
let r6 = Value::from_str("8field").unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(4, candidate.len());
assert_eq!(r3, candidate[0]);
assert_eq!(r4, candidate[1]);
assert_eq!(r5, candidate[2]);
assert_eq!(r6, candidate[3]);
assert_eq!(authorization.len(), 1);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(4, candidate.len());
assert_eq!(r3, candidate[0]);
assert_eq!(r4, candidate[1]);
assert_eq!(r5, candidate[2]);
assert_eq!(r6, candidate[3]);
}
#[test]
fn test_process_execute_call_external_function() {
let (string, program0) = Program::<CurrentNetwork>::parse(
r"
program token.aleo;
record token:
owner as address.private;
amount as u64.private;
function mint:
input r0 as address.private;
input r1 as u64.private;
cast r0 r1 into r2 as token.record;
output r2 as token.record;
function produce_magic_number:
add 1234u64 0u64 into r0;
output r0 as u64.private;
function check_magic_number:
input r0 as u64.private;
assert.eq r0 1234u64;
function noop:
function transfer:
input r0 as token.record;
input r1 as address.private;
input r2 as u64.private;
sub r0.amount r2 into r3;
cast r1 r2 into r4 as token.record;
cast r0.owner r3 into r5 as token.record;
output r4 as token.record;
output r5 as token.record;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let mut process = crate::test_helpers::sample_process(&program0);
let (string, program1) = Program::<CurrentNetwork>::parse(
r"
import token.aleo;
program wallet.aleo;
function transfer:
input r0 as token.aleo/token.record;
input r1 as address.private;
input r2 as u64.private;
call token.aleo/noop;
call token.aleo/produce_magic_number into r3;
call token.aleo/check_magic_number r3;
call token.aleo/transfer r0 r1 r2 into r4 r5;
output r4 as token.aleo/token.record;
output r5 as token.aleo/token.record;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program1).unwrap();
let rng = &mut TestRng::default();
let caller0_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller0 = Address::try_from(&caller0_private_key).unwrap();
let caller1_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller1 = Address::try_from(&caller1_private_key).unwrap();
let function_name = Identifier::from_str("transfer").unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&format!(
"{{ owner: {caller0}.private, amount: 100u64.private, _nonce: 0group.public }}"
))
.unwrap();
let r1 = Value::<CurrentNetwork>::from_str(&caller1.to_string()).unwrap();
let r2 = Value::<CurrentNetwork>::from_str("99u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller0_private_key, program1.id(), function_name, [r0, r1, r2].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 5);
println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque());
let (output_a, output_b) = {
let request = authorization.to_vec_deque().pop_back().unwrap();
let randomizer_a = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(4)]).unwrap();
let nonce_a = CurrentNetwork::g_scalar_multiply(&randomizer_a);
let randomizer_b = CurrentNetwork::hash_to_scalar_psd2(&[*request.tvk(), Field::from_u64(5)]).unwrap();
let nonce_b = CurrentNetwork::g_scalar_multiply(&randomizer_b);
let output_a = Value::from_str(&format!(
"{{ owner: {caller1}.private, amount: 99u64.private, _nonce: {nonce_a}.public, _version: 1u8.public }}"
))
.unwrap();
let output_b = Value::from_str(&format!(
"{{ owner: {caller0}.private, amount: 1u64.private, _nonce: {nonce_b}.public, _version: 1u8.public }}"
))
.unwrap();
(output_a, output_b)
};
assert_eq!(authorization.len(), 5);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len());
assert_eq!(output_a, candidate[0]);
assert_eq!(output_b, candidate[1]);
assert_eq!(authorization.len(), 5);
let (response, _trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len());
assert_eq!(output_a, candidate[0]);
assert_eq!(output_b, candidate[1]);
}
#[test]
fn test_process_execute_and_finalize_get_add_set() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program testing.aleo;
mapping account:
key as address.public;
value as u64.public;
function compute:
input r0 as address.public;
input r1 as u64.public;
input r2 as u64.public;
add r1 r2 into r3;
async compute r0 r3 into r4;
output r4 as testing.aleo/compute.future;
finalize compute:
input r0 as address.public;
input r1 as u64.public;
get.or_use account[r0] 0u64 into r2;
add r2 r1 into r3;
set r3 into account[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let program_id = program.id();
let mapping_name = Identifier::from_str("account").unwrap();
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap();
let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 1);
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("8u64").unwrap());
}
#[test]
fn test_process_execute_and_finalize_increment_decrement_via_get_set() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program testing.aleo;
mapping account:
key as address.public;
value as u64.public;
function compute:
input r0 as address.public;
input r1 as u64.public;
input r2 as u64.public;
add r1 r2 into r3;
async compute r0 r3 into r4;
output r4 as testing.aleo/compute.future;
finalize compute:
input r0 as address.public;
input r1 as u64.public;
get.or_use account[r0] 0u64 into r2;
add r2 r1 into r3;
sub r3 r1 into r4;
set r4 into account[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let program_id = program.id();
let mapping_name = Identifier::from_str("account").unwrap();
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap();
let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 1);
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("0u64").unwrap());
}
#[test]
fn test_process_execute_mint_public() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program token.aleo;
// On-chain storage of an `account` map, with `owner` as the key,
// and `amount` as the value.
mapping account:
// The token owner.
key as address.public;
// The token amount.
value as u64.public;
// The function `mint_public` issues the specified token amount
// for the token receiver publicly on the network.
function mint_public:
// Input the token receiver.
input r0 as address.public;
// Input the token amount.
input r1 as u64.public;
// Mint the tokens publicly.
async mint_public r0 r1 into r2;
output r2 as token.aleo/mint_public.future;
// The finalize scope of `mint_public` increments the
// `account` of the token receiver by the specified amount.
finalize mint_public:
// Input the token receiver.
input r0 as address.public;
// Input the token amount.
input r1 as u64.public;
// Get `account[r0]` into `r2`, defaulting to 0u64 if the entry does not exist.
get.or_use account[r0] 0u64 into r2;
// Add `r1` to `r2`. If the operation overflows, `mint_public` is reverted.
add r2 r1 into r3;
// Set `r3` into `account[r0]`.
set r3 into account[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let program_id = program.id();
let mapping_name = Identifier::from_str("account").unwrap();
let function_name = Identifier::from_str("mint_public").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("token", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("3u64").unwrap());
}
#[test]
fn test_process_execute_call_mint_public() {
let (string, program0) = Program::<CurrentNetwork>::parse(
r"
program token.aleo;
// On-chain storage of an `account` map, with `owner` as the key,
// and `amount` as the value.
mapping account:
// The token owner.
key as address.public;
// The token amount.
value as u64.public;
// The function `mint_public` issues the specified token amount
// for the token receiver publicly on the network.
function mint_public:
// Input the token receiver.
input r0 as address.public;
// Input the token amount.
input r1 as u64.public;
// Mint the tokens publicly.
async mint_public r0 r1 into r2;
output r2 as token.aleo/mint_public.future;
// The finalize scope of `mint_public` increments the
// `account` of the token receiver by the specified amount.
finalize mint_public:
// Input the token receiver.
input r0 as address.public;
// Input the token amount.
input r1 as u64.public;
// Get `account[r0]` into `r2`, defaulting to 0u64 if the entry does not exist.
get.or_use account[r0] 0u64 into r2;
// Add `r1` to `r2`. If the operation overflows, `mint_public` is reverted.
add r2 r1 into r3;
// Set `r3` into `account[r0]`.
set r3 into account[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let mapping_name = Identifier::from_str("account").unwrap();
let function_name = Identifier::from_str("mint_public").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program0);
process.synthesize_key::<CurrentAleo, _>(program0.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program0, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
process.synthesize_key::<CurrentAleo, _>(program0.id(), &function_name, rng).unwrap();
let (string, program1) = Program::<CurrentNetwork>::parse(
r"
import token.aleo;
program public_wallet.aleo;
function init:
input r0 as address.public;
input r1 as u64.public;
call token.aleo/mint_public r0 r1 into r2;
async init r2 into r3;
output r3 as public_wallet.aleo/init.future;
finalize init:
input r0 as token.aleo/mint_public.future;
await r0;
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("init").unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program1, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(2), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
process.synthesize_key::<CurrentAleo, _>(program1.id(), &function_name, rng).unwrap();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("100u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program1.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 2);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 2);
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("public_wallet", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program0.id(), mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("100u64").unwrap());
}
#[test]
fn test_process_execute_and_finalize_get_set() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program testing.aleo;
mapping account:
key as address.public;
value as u64.public;
function compute:
input r0 as address.public;
input r1 as u64.public;
input r2 as u64.public;
add r1 r2 into r3;
async compute r0 r3 into r4;
output r4 as testing.aleo/compute.future;
finalize compute:
input r0 as address.public;
input r1 as u64.public;
get.or_use account[r0] 0u64 into r2;
add r1 r2 into r3;
set r3 into account[r0];
get account[r0] into r4;
add r1 r4 into r5;
set r5 into account[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let program_id = program.id();
let mapping_name = Identifier::from_str("account").unwrap();
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str(&caller.to_string()).unwrap();
let r1 = Value::<CurrentNetwork>::from_str("3u64").unwrap();
let r2 = Value::<CurrentNetwork>::from_str("5u64").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1, r2].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("16u64").unwrap());
}
#[test]
fn test_execution_order() {
let (string, program0) = Program::<CurrentNetwork>::parse(
r"
program zero.aleo;
mapping zero_data:
key as u8.public;
value as u8.public;
function c:
input r0 as u8.private;
input r1 as u8.private;
add r0 r1 into r2;
async c r2 into r3;
output r2 as u8.private;
output r3 as zero.aleo/c.future;
finalize c:
input r0 as u8.public;
set r0 into zero_data[r0];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let mut process = crate::test_helpers::sample_process(&program0);
let (string, program1) = Program::<CurrentNetwork>::parse(
r"
import zero.aleo;
program one.aleo;
mapping one_data:
key as u8.public;
value as u8.public;
function b:
input r0 as u8.private;
input r1 as u8.private;
call zero.aleo/c r0 r1 into r2 r3;
async b r3 r2 into r4;
output r2 as u8.private;
output r4 as one.aleo/b.future;
finalize b:
input r0 as zero.aleo/c.future;
input r1 as u8.public;
await r0;
set r1 into one_data[r1];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program1).unwrap();
let (string, program2) = Program::<CurrentNetwork>::parse(
r"
import zero.aleo;
import one.aleo;
program two.aleo;
mapping two_data:
key as u8.public;
value as u8.public;
function a:
input r0 as u8.private;
input r1 as u8.private;
call one.aleo/b r0 r1 into r2 r3;
async a r3 r2 into r4;
output r2 as u8.private;
output r4 as two.aleo/a.future;
finalize a:
input r0 as one.aleo/b.future;
input r1 as u8.public;
await r0;
set r1 into two_data[r1];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program2).unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let function_name = Identifier::from_str("a").unwrap();
let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap();
let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program2.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 3);
println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque());
let output = Value::<CurrentNetwork>::from_str("3u8").unwrap();
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len()); assert_eq!(output, candidate[0]);
assert_eq!(authorization.len(), 3);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len()); assert_eq!(output, candidate[0]);
let expected_order = [
(program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()),
(program1.id(), Identifier::from_str("b").unwrap()),
(program2.id(), Identifier::from_str("a").unwrap()),
];
for (transition, (expected_program_id, expected_function_name)) in
trace.transitions().iter().zip_eq(expected_order.iter())
{
assert_eq!(transition.program_id(), *expected_program_id);
assert_eq!(transition.function_name(), expected_function_name);
}
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("two", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
let stack = process.get_stack(program2.id()).unwrap();
let static_finalize_cost = crate::cost::minimum_cost_in_microcredits_v2(&stack, &function_name).unwrap();
let runtime_finalize_cost =
crate::cost::execution_finalize_cost(&process, &execution, crate::cost::ConsensusFeeVersion::V2).unwrap();
assert_eq!(static_finalize_cost, 31600, "Expected static finalize cost of 31600");
assert_eq!(runtime_finalize_cost, 31600, "Expected runtime finalize cost of 31600");
assert_eq!(static_finalize_cost, runtime_finalize_cost, "Static and runtime costs should match");
}
#[test]
fn test_complex_execution_order() {
let (string, program0) = Program::<CurrentNetwork>::parse(
r"
program zero.aleo;
mapping zero_data:
key as u8.public;
value as u8.public;
function c:
input r0 as u8.private;
input r1 as u8.private;
add r0 r1 into r2;
async c r2 into r3;
output r2 as u8.private;
output r3 as zero.aleo/c.future;
finalize c:
input r0 as u8.public;
set r0 into zero_data[r0];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let mut process = crate::test_helpers::sample_process(&program0);
let (string, program1) = Program::<CurrentNetwork>::parse(
r"
program one.aleo;
mapping one_data:
key as u8.public;
value as u8.public;
function d:
input r0 as u8.private;
input r1 as u8.private;
add r0 r1 into r2;
async d r2 into r3;
output r2 as u8.private;
output r3 as one.aleo/d.future;
finalize d:
input r0 as u8.public;
set r0 into one_data[r0];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program1).unwrap();
let (string, program2) = Program::<CurrentNetwork>::parse(
r"
import zero.aleo;
import one.aleo;
program two.aleo;
mapping two_data:
key as u8.public;
value as u8.public;
function b:
input r0 as u8.private;
input r1 as u8.private;
call zero.aleo/c r0 r1 into r2 r3;
call one.aleo/d r1 r2 into r4 r5;
async b r3 r5 r4 into r6;
output r4 as u8.private;
output r6 as two.aleo/b.future;
finalize b:
input r0 as zero.aleo/c.future;
input r1 as one.aleo/d.future;
input r2 as u8.public;
await r0;
await r1;
set r2 into two_data[r2];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program2).unwrap();
let (string, program3) = Program::<CurrentNetwork>::parse(
r"
import zero.aleo;
import one.aleo;
import two.aleo;
program three.aleo;
mapping three_data:
key as u8.public;
value as u8.public;
function e:
input r0 as u8.private;
input r1 as u8.private;
call two.aleo/b r0 r1 into r2 r3;
call one.aleo/d r1 r2 into r4 r5;
call zero.aleo/c r1 r2 into r6 r7;
async e r3 r5 r7 r6 into r8;
output r6 as u8.private;
output r8 as three.aleo/e.future;
finalize e:
input r0 as two.aleo/b.future;
input r1 as one.aleo/d.future;
input r2 as zero.aleo/c.future;
input r3 as u8.public;
await r0;
await r1;
await r2;
set r3 into three_data[r3];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program3).unwrap();
let (string, program4) = Program::<CurrentNetwork>::parse(
r"
import zero.aleo;
import one.aleo;
import two.aleo;
import three.aleo;
program four.aleo;
mapping four_data:
key as u8.public;
value as u8.public;
function a:
input r0 as u8.private;
input r1 as u8.private;
call two.aleo/b r0 r1 into r2 r3;
call three.aleo/e r1 r2 into r4 r5;
async a r3 r5 r4 into r6;
output r4 as u8.private;
output r6 as four.aleo/a.future;
finalize a:
input r0 as two.aleo/b.future;
input r1 as three.aleo/e.future;
input r2 as u8.public;
await r0;
await r1;
set r2 into four_data[r2];",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
process.add_program(&program4).unwrap();
let rng = &mut TestRng::default();
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let function_name = Identifier::from_str("a").unwrap();
let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap();
let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program4.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 10);
println!("\nAuthorize\n{:#?}\n\n", authorization.to_vec_deque());
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let output = Value::<CurrentNetwork>::from_str("17u8").unwrap();
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len()); assert_eq!(output, candidate[0]);
assert_eq!(authorization.len(), 10);
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(2, candidate.len()); assert_eq!(output, candidate[0]);
let expected_order = [
(program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()),
(program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()),
(program2.id(), Identifier::<MainnetV0>::from_str("b").unwrap()),
(program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()),
(program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()),
(program2.id(), Identifier::<MainnetV0>::from_str("b").unwrap()),
(program1.id(), Identifier::<MainnetV0>::from_str("d").unwrap()),
(program0.id(), Identifier::<MainnetV0>::from_str("c").unwrap()),
(program3.id(), Identifier::<MainnetV0>::from_str("e").unwrap()),
(program4.id(), Identifier::<MainnetV0>::from_str("a").unwrap()),
];
for (transition, (expected_program_id, expected_function_name)) in
trace.transitions().iter().zip_eq(expected_order.iter())
{
assert_eq!(transition.program_id(), *expected_program_id);
assert_eq!(transition.function_name(), expected_function_name);
}
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("four", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
let stack = process.get_stack(program4.id()).unwrap();
let static_finalize_cost = crate::cost::minimum_cost_in_microcredits_v2(&stack, &function_name).unwrap();
let runtime_finalize_cost =
crate::cost::execution_finalize_cost(&process, &execution, crate::cost::ConsensusFeeVersion::V2).unwrap();
assert_eq!(static_finalize_cost, 106500, "Expected static finalize cost of 106500");
assert_eq!(runtime_finalize_cost, 106500, "Expected runtime finalize cost of 106500");
assert_eq!(static_finalize_cost, runtime_finalize_cost, "Static and runtime costs should match");
}
#[test]
fn test_process_execute_and_finalize_get_set_with_struct() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program testing.aleo;
struct entry:
count as u8;
data as u8;
mapping entries:
key as address.public;
value as entry.public;
function compute:
input r0 as u8.public;
input r1 as u8.public;
cast r0 r1 into r2 as entry;
async compute self.caller r2 into r3;
output r3 as testing.aleo/compute.future;
finalize compute:
input r0 as address.public;
input r1 as entry.public;
get.or_use entries[r0] r1 into r2;
add r1.count r2.count into r3;
add r1.data r2.data into r4;
cast r3 r4 into r5 as entry;
set r5 into entries[r0];
get entries[r0] into r6;
add r6.count r1.count into r7;
add r6.data r1.data into r8;
cast r7 r8 into r9 as entry;
set r9 into entries[r0];
",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let program_id = program.id();
let mapping_name = Identifier::from_str("entries").unwrap();
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let _caller_view_key = ViewKey::try_from(&caller_private_key).unwrap();
let caller = Address::try_from(&caller_private_key).unwrap();
let r0 = Value::<CurrentNetwork>::from_str("1u8").unwrap();
let r1 = Value::<CurrentNetwork>::from_str("2u8").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(1, candidate.len());
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
process.finalize_execution(sample_finalize_state(1), &finalize_store, &execution, None).unwrap();
let candidate = finalize_store
.get_value_speculative(*program_id, mapping_name, &Plaintext::from(Literal::Address(caller)))
.unwrap()
.unwrap();
assert_eq!(candidate, Value::from_str("{ count: 3u8, data: 6u8 }").unwrap());
}
#[test]
fn test_process_execute_and_verify_call_to_closure() {
let (string, program) = Program::<CurrentNetwork>::parse(
r"
program testing.aleo;
// (a + (a + b)) + (a + b) == (3a + 2b)
closure execute:
input r0 as field;
input r1 as field;
add r0 r1 into r2;
add r0 r2 into r3;
add r2 r3 into r4;
output r4 as field;
output r3 as field;
output r2 as field;
closure check_not_equal:
input r0 as field;
input r1 as field;
assert.neq r0 r1;
function compute:
input r0 as field.private;
input r1 as field.public;
call check_not_equal r0 r1;
call execute r0 r1 into r2 r3 r4;
output r2 as field.private;
output r3 as field.private;
output r4 as field.private;",
)
.unwrap();
assert!(string.is_empty(), "Parser did not consume all of the string: '{string}'");
let function_name = Identifier::from_str("compute").unwrap();
let rng = &mut TestRng::default();
let process = crate::test_helpers::sample_process(&program);
process.synthesize_key::<CurrentAleo, _>(program.id(), &function_name, rng).unwrap();
let process = crate::test_helpers::sample_process(&program);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let r0 = Value::<CurrentNetwork>::from_str("3field").unwrap();
let r1 = Value::<CurrentNetwork>::from_str("5field").unwrap();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), function_name, [r0, r1].iter(), rng)
.unwrap();
assert_eq!(authorization.len(), 1);
let r2 = Value::from_str("19field").unwrap();
let r3 = Value::from_str("11field").unwrap();
let r4 = Value::from_str("8field").unwrap();
assert_eq!(authorization.len(), 1);
let response = process.evaluate::<CurrentAleo>(authorization.replicate()).unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(r3, candidate[1]);
assert_eq!(r4, candidate[2]);
assert_eq!(authorization.len(), 1);
let expected_execution_cost =
execution_cost_for_authorization(&process, &authorization, ConsensusVersion::V10).unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
let candidate = response.outputs();
assert_eq!(3, candidate.len());
assert_eq!(r2, candidate[0]);
assert_eq!(r3, candidate[1]);
assert_eq!(r4, candidate[2]);
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
trace.prepare(&Query::from(block_store)).unwrap();
let execution = trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap();
process.verify_execution(ConsensusVersion::V10, VarunaVersion::V2, InclusionVersion::V1, &execution).unwrap();
assert_eq!(execution_cost(&process, &execution, ConsensusVersion::V10).unwrap(), expected_execution_cost);
}
#[test]
fn test_process_deploy_credits_program() {
let rng = &mut TestRng::default();
let empty_process = Process {
universal_srs: UniversalSRS::<CurrentNetwork>::load().unwrap(),
stacks: Default::default(),
old_stacks: Default::default(),
};
let process = Process::load().unwrap();
let program = Program::credits().unwrap();
let deployment = empty_process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
empty_process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
assert!(process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).is_err());
let program = Program::from_str(
r"
program credits.aleo;
record token:
owner as address.private;
amount as u64.private;
function compute:
input r0 as u32.private;
add r0 r0 into r1;
output r1 as u32.public;",
)
.unwrap();
let deployment = empty_process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
empty_process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
assert!(process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).is_err());
}
#[test]
fn test_process_zero_input_zero_output_executions() {
let rng = &mut TestRng::default();
let function_name = Identifier::from_str("zero_inputs_zero_outputs").unwrap();
let program = Program::from_str(&format!(
r"
program testing.aleo;
function {function_name}:
add 0u8 1u8 into r0;",
))
.unwrap();
let mut process = Process::load().unwrap();
let block_store = BlockStore::<CurrentNetwork, BlockMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let finalize_store = FinalizeStore::<_, FinalizeMemory<_>>::open(StorageMode::new_test(None)).unwrap();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V10, &deployment, rng).unwrap();
let fee = sample_fee::<_, CurrentAleo, _, _>(&process, &block_store, &finalize_store, rng);
let (stack, _) = process.finalize_deployment(sample_finalize_state(1), &finalize_store, &deployment, &fee).unwrap();
process.add_stack(stack);
let caller_private_key = PrivateKey::<CurrentNetwork>::new(rng).unwrap();
let execution_1 = {
let inputs = Vec::<Value<CurrentNetwork>>::new();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), &function_name, inputs.iter(), rng)
.unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
assert_eq!(response.outputs().len(), 0);
trace.prepare(&Query::from(block_store.clone())).unwrap();
trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap()
};
assert_eq!(execution_1.len(), 1);
let execution_2 = {
let inputs = Vec::<Value<CurrentNetwork>>::new();
let authorization = process
.authorize::<CurrentAleo, _>(&caller_private_key, program.id(), &function_name, inputs.iter(), rng)
.unwrap();
let (response, mut trace) = process.execute::<CurrentAleo, _>(authorization, rng).unwrap();
assert_eq!(response.outputs().len(), 0);
trace.prepare(&Query::from(block_store)).unwrap();
trace.prove_execution::<CurrentAleo, _>("testing", VarunaVersion::V2, rng).unwrap()
};
assert_eq!(execution_2.len(), 1);
assert_ne!(execution_1.peek().unwrap().id(), execution_2.peek().unwrap().id());
assert_ne!(execution_1.to_execution_id().unwrap(), execution_2.to_execution_id().unwrap());
}
#[test]
fn test_long_import_chain() {
const MAX_PROGRAM_DEPTH: usize = 64;
let program = Program::<CurrentNetwork>::from_str(
r"
program test0.aleo;
function c:",
)
.unwrap();
let mut process = crate::test_helpers::sample_process(&program);
for i in 1..=MAX_PROGRAM_DEPTH {
println!("Adding program {i}");
let program = Program::from_str(&format!(
"
import test{}.aleo;
program test{}.aleo;
function c:",
i - 1,
i
))
.unwrap();
process.add_program(&program).unwrap();
}
let program = Program::from_str(&format!(
"
import test{}.aleo;
program test{}.aleo;
function c:",
MAX_PROGRAM_DEPTH,
MAX_PROGRAM_DEPTH + 1
))
.unwrap();
let result = process.add_program(&program);
assert!(result.is_ok());
}
#[test]
fn test_long_import_chain_with_calls() {
let program = Program::<CurrentNetwork>::from_str(
r"
program test0.aleo;
function c:",
)
.unwrap();
let mut process = crate::test_helpers::sample_process(&program);
for i in 1..(Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 1) {
println!("Adding program {i}");
let program = Program::from_str(&format!(
"
import test{}.aleo;
program test{}.aleo;
function c:
call test{}.aleo/c;",
i - 1,
i,
i - 1
))
.unwrap();
process.add_program(&program).unwrap();
let stack = process.get_stack(program.id()).unwrap();
let number_of_calls =
stack.get_minimum_number_of_calls(program.functions().into_iter().next().unwrap().0).unwrap();
assert_eq!(number_of_calls, i + 1);
}
let program = Program::from_str(&format!(
"
import test{}.aleo;
program test{}.aleo;
function c:
call test{}.aleo/c;",
Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 2,
Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 1,
Transaction::<CurrentNetwork>::MAX_TRANSITIONS - 2
))
.unwrap();
let result = process.add_program(&program);
assert!(result.is_err())
}
#[test]
fn test_max_imports() {
let mut process = Process::<CurrentNetwork>::load().unwrap();
for i in 0..CurrentNetwork::MAX_IMPORTS {
println!("Adding program {i}");
let program = Program::from_str(&format!("program test{i}.aleo; function c:")).unwrap();
process.add_program(&program).unwrap();
}
let import_string =
(0..CurrentNetwork::MAX_IMPORTS).map(|i| format!("import test{i}.aleo;")).collect::<Vec<_>>().join(" ");
let program =
Program::from_str(&format!("{import_string}program test{}.aleo; function c:", CurrentNetwork::MAX_IMPORTS))
.unwrap();
process.add_program(&program).unwrap();
let import_string =
(0..CurrentNetwork::MAX_IMPORTS + 1).map(|i| format!("import test{i}.aleo;")).collect::<Vec<_>>().join(" ");
let result = Program::<CurrentNetwork>::from_str(&format!(
"{import_string}program test{}.aleo; function c:",
CurrentNetwork::MAX_IMPORTS + 1
));
assert!(result.is_err());
}
#[test]
fn test_program_exceeding_transaction_spend_limit() {
let mut finalize_body = r"
cast 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 0u8 into r0 as [u8; 16u32];
cast r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 r0 into r1 as [[u8; 16u32]; 16u32];
cast r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 r1 into r2 as [[[u8; 16u32]; 16u32]; 16u32];"
.to_string();
(3..500).for_each(|i| {
finalize_body.push_str(&format!("hash.bhp256 r2 into r{i} as field;\n"));
});
let program = Program::from_str(&format!(
r"program test_max_spend_limit.aleo;
function foo:
async foo into r0;
output r0 as test_max_spend_limit.aleo/foo.future;
finalize foo:{finalize_body}",
))
.unwrap();
let process = Process::<CurrentNetwork>::load().unwrap();
let rng = &mut TestRng::default();
let deployment = process.deploy::<CurrentAleo, _>(&program, rng).unwrap();
assert!(process.verify_deployment::<CurrentAleo, _>(ConsensusVersion::V8, &deployment, rng).is_ok());
}