Skip to content

Commit 7c0dafb

Browse files
authored
Merge pull request #2611 from ProvableHQ/test/record-production-consumption-in-call
[Test] This PR adds a test that shows record production/consumption behaviors in an external call.
2 parents 59776cb + e73efc4 commit 7c0dafb

File tree

1 file changed

+261
-0
lines changed

1 file changed

+261
-0
lines changed

ledger/src/tests.rs

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3143,3 +3143,264 @@ fn test_forged_block_subdags() {
31433143
assert!(ledger.check_next_block(&forged_block_2_from_both_subdags, &mut rand::thread_rng()).is_err());
31443144
}
31453145
}
3146+
3147+
#[test]
3148+
fn test_record_creation_and_consumption_in_call() {
3149+
let rng = &mut TestRng::default();
3150+
3151+
// Sample the test environment.
3152+
let crate::test_helpers::TestEnv { ledger, private_key, view_key, .. } = crate::test_helpers::sample_test_env(rng);
3153+
3154+
// A helper function to get the record counts.
3155+
let get_record_counts = || {
3156+
let slow_spent_filter = RecordsFilter::SlowSpent(private_key);
3157+
let slow_unspent_filter = RecordsFilter::SlowUnspent(private_key);
3158+
let spent_records = ledger.find_records(&view_key, RecordsFilter::Spent).unwrap().collect_vec().len();
3159+
let slow_spent_records = ledger.find_records(&view_key, slow_spent_filter).unwrap().collect_vec().len();
3160+
let unspent_records = ledger.find_records(&view_key, RecordsFilter::Unspent).unwrap().collect_vec().len();
3161+
let slow_unspent_records = ledger.find_records(&view_key, slow_unspent_filter).unwrap().collect_vec().len();
3162+
let records = ledger.records().collect_vec().len();
3163+
(spent_records, slow_spent_records, unspent_records, slow_unspent_records, records)
3164+
};
3165+
3166+
// Check the initial record counts.
3167+
let (
3168+
initial_spent_records,
3169+
initial_slow_spent_records,
3170+
initial_unspent_records,
3171+
initial_slow_unspent_records,
3172+
initial_records,
3173+
) = get_record_counts();
3174+
assert_eq!(0, initial_spent_records);
3175+
assert_eq!(0, initial_slow_spent_records);
3176+
assert_eq!(4, initial_unspent_records);
3177+
assert_eq!(4, initial_slow_unspent_records);
3178+
assert_eq!(4, initial_records);
3179+
3180+
// Initialize the two programs.
3181+
let program_0 = Program::from_str(
3182+
r"
3183+
program child.aleo;
3184+
3185+
record data:
3186+
owner as address.private;
3187+
val as u64.private;
3188+
3189+
function mint:
3190+
cast self.signer 0u64 into r0 as data.record;
3191+
output r0 as data.record;
3192+
3193+
function burn:
3194+
input r0 as data.record;
3195+
",
3196+
)
3197+
.unwrap();
3198+
3199+
let program_1 = Program::from_str(
3200+
r"
3201+
import child.aleo;
3202+
3203+
program parent.aleo;
3204+
3205+
function create_without_output:
3206+
call child.aleo/mint into r0;
3207+
3208+
function create:
3209+
call child.aleo/mint into r0;
3210+
output r0 as child.aleo/data.record;
3211+
3212+
function consume_without_call:
3213+
input r0 as child.aleo/data.record;
3214+
3215+
function consume:
3216+
input r0 as child.aleo/data.record;
3217+
call child.aleo/burn r0;
3218+
3219+
function create_and_consume:
3220+
call child.aleo/mint into r0;
3221+
call child.aleo/burn r0;
3222+
",
3223+
)
3224+
.unwrap();
3225+
3226+
// Deploy the programs.
3227+
let deployment_0 = ledger.vm().deploy(&private_key, &program_0, None, 0, None, rng).unwrap();
3228+
let block =
3229+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![deployment_0], rng).unwrap();
3230+
assert_eq!(block.transactions().num_accepted(), 1);
3231+
ledger.advance_to_next_block(&block).unwrap();
3232+
3233+
let deployment_1 = ledger.vm().deploy(&private_key, &program_1, None, 0, None, rng).unwrap();
3234+
let block =
3235+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![deployment_1], rng).unwrap();
3236+
assert_eq!(block.transactions().num_accepted(), 1);
3237+
ledger.advance_to_next_block(&block).unwrap();
3238+
3239+
// Call the `mint` function.
3240+
let transaction = ledger
3241+
.vm()
3242+
.execute(&private_key, ("child.aleo", "mint"), Vec::<Value<CurrentNetwork>>::new().iter(), None, 0, None, rng)
3243+
.unwrap();
3244+
let mint_record = transaction.records().last().unwrap().1.decrypt(&view_key).unwrap();
3245+
let block =
3246+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3247+
assert_eq!(block.transactions().num_accepted(), 1);
3248+
ledger.advance_to_next_block(&block).unwrap();
3249+
3250+
// Check the record counts.
3251+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3252+
get_record_counts();
3253+
assert_eq!(num_spent_records, initial_spent_records);
3254+
assert_eq!(num_slow_spent_records, initial_slow_spent_records);
3255+
assert_eq!(num_unspent_records, initial_unspent_records + 1);
3256+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 1);
3257+
assert_eq!(num_records, initial_records + 1);
3258+
3259+
// Call the `create_without_output` function.
3260+
let transaction = ledger
3261+
.vm()
3262+
.execute(
3263+
&private_key,
3264+
("parent.aleo", "create_without_output"),
3265+
Vec::<Value<CurrentNetwork>>::new().iter(),
3266+
None,
3267+
0,
3268+
None,
3269+
rng,
3270+
)
3271+
.unwrap();
3272+
3273+
let block =
3274+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3275+
assert_eq!(block.transactions().num_accepted(), 1);
3276+
ledger.advance_to_next_block(&block).unwrap();
3277+
3278+
// Check the record counts.
3279+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3280+
get_record_counts();
3281+
assert_eq!(num_spent_records, initial_spent_records);
3282+
assert_eq!(num_slow_spent_records, initial_slow_spent_records);
3283+
assert_eq!(num_unspent_records, initial_unspent_records + 2);
3284+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 2);
3285+
assert_eq!(num_records, initial_records + 2);
3286+
3287+
// Call the `burn` function on record created by `create_without_output`.
3288+
let record = block.records().collect_vec().last().unwrap().1.decrypt(&view_key).unwrap();
3289+
let transaction = ledger
3290+
.vm()
3291+
.execute(&private_key, ("child.aleo", "burn"), vec![Value::Record(record)].iter(), None, 0, None, rng)
3292+
.unwrap();
3293+
let block =
3294+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3295+
assert_eq!(block.transactions().num_accepted(), 1);
3296+
ledger.advance_to_next_block(&block).unwrap();
3297+
3298+
// Check the record counts.
3299+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3300+
get_record_counts();
3301+
assert_eq!(num_spent_records, initial_spent_records + 1);
3302+
assert_eq!(num_slow_spent_records, initial_slow_spent_records + 1);
3303+
assert_eq!(num_unspent_records, initial_unspent_records + 1);
3304+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 1);
3305+
assert_eq!(num_records, initial_records + 2);
3306+
3307+
// Call the `create` function.
3308+
let transaction = ledger
3309+
.vm()
3310+
.execute(
3311+
&private_key,
3312+
("parent.aleo", "create"),
3313+
Vec::<Value<CurrentNetwork>>::new().iter(),
3314+
None,
3315+
0,
3316+
None,
3317+
rng,
3318+
)
3319+
.unwrap();
3320+
let block =
3321+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3322+
assert_eq!(block.transactions().num_accepted(), 1);
3323+
ledger.advance_to_next_block(&block).unwrap();
3324+
3325+
// Ensure that a record was created and spent.
3326+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3327+
get_record_counts();
3328+
assert_eq!(num_spent_records, initial_spent_records + 1);
3329+
assert_eq!(num_slow_spent_records, initial_slow_spent_records + 1);
3330+
assert_eq!(num_unspent_records, initial_unspent_records + 2);
3331+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 2);
3332+
assert_eq!(num_records, initial_records + 3);
3333+
3334+
// Call the `consume_without_call` function.
3335+
let transaction = ledger
3336+
.vm()
3337+
.execute(
3338+
&private_key,
3339+
("parent.aleo", "consume_without_call"),
3340+
vec![Value::Record(mint_record.clone())].iter(),
3341+
None,
3342+
0,
3343+
None,
3344+
rng,
3345+
)
3346+
.unwrap();
3347+
let block =
3348+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3349+
assert_eq!(block.transactions().num_accepted(), 1);
3350+
ledger.advance_to_next_block(&block).unwrap();
3351+
3352+
// Ensure that no records were created or spent.
3353+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3354+
get_record_counts();
3355+
assert_eq!(num_spent_records, initial_spent_records + 1);
3356+
assert_eq!(num_slow_spent_records, initial_slow_spent_records + 1);
3357+
assert_eq!(num_unspent_records, initial_unspent_records + 2);
3358+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 2);
3359+
assert_eq!(num_records, initial_records + 3);
3360+
3361+
// Call the `consume` function.
3362+
let transaction = ledger
3363+
.vm()
3364+
.execute(&private_key, ("parent.aleo", "consume"), vec![Value::Record(mint_record)].iter(), None, 0, None, rng)
3365+
.unwrap();
3366+
let block =
3367+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3368+
assert_eq!(block.transactions().num_accepted(), 1);
3369+
ledger.advance_to_next_block(&block).unwrap();
3370+
3371+
// Ensure that the record was spent.
3372+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3373+
get_record_counts();
3374+
assert_eq!(num_spent_records, initial_spent_records + 2);
3375+
assert_eq!(num_slow_spent_records, initial_slow_spent_records + 2);
3376+
assert_eq!(num_unspent_records, initial_unspent_records + 1);
3377+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 1);
3378+
assert_eq!(num_records, initial_records + 3);
3379+
3380+
// Call the `create_and_consume` function.
3381+
let transaction = ledger
3382+
.vm()
3383+
.execute(
3384+
&private_key,
3385+
("parent.aleo", "create_and_consume"),
3386+
Vec::<Value<CurrentNetwork>>::new().iter(),
3387+
None,
3388+
0,
3389+
None,
3390+
rng,
3391+
)
3392+
.unwrap();
3393+
let block =
3394+
ledger.prepare_advance_to_next_beacon_block(&private_key, vec![], vec![], vec![transaction], rng).unwrap();
3395+
assert_eq!(block.transactions().num_accepted(), 1);
3396+
ledger.advance_to_next_block(&block).unwrap();
3397+
3398+
// Ensure that a record was created and spent.
3399+
let (num_spent_records, num_slow_spent_records, num_unspent_records, num_slow_unspent_records, num_records) =
3400+
get_record_counts();
3401+
assert_eq!(num_spent_records, initial_spent_records + 3);
3402+
assert_eq!(num_slow_spent_records, initial_slow_spent_records + 3);
3403+
assert_eq!(num_unspent_records, initial_unspent_records + 1);
3404+
assert_eq!(num_slow_unspent_records, initial_slow_unspent_records + 1);
3405+
assert_eq!(num_records, initial_records + 4);
3406+
}

0 commit comments

Comments
 (0)